home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / formats / gif / gen_code / amiga / iff2gif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-02  |  9.2 KB  |  468 lines

  1. /***********************************************************
  2.  * Copyright (c) 1987                                      *
  3.  * by CompuServe Inc, Columbus, Ohio.  All Rights Reserved *
  4.  ***********************************************************/
  5.  
  6. /*
  7.  *                      IFF_TO_GIF
  8.  *
  9.  *                 Usage: IFF_TO_GIF <input filename>
  10.  *           Output file: <input filename>.GIF
  11.  */ 
  12.  
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <fcntl.h>
  16. #include <stdio.h>
  17. #include "buildgif.h"
  18.  
  19. #define UBYTE unsigned char
  20. #define WORD short
  21. #define UWORD unsigned short
  22.  
  23. #define mskNone 0
  24. #define mskHasMask 1
  25. #define mskHasTransparentColor 2
  26. #define mskLasso 3
  27. #define cmpNone 0
  28. #define cmpByteRun1 1
  29. #define MakeID(a, b, c, d) ( (a)<<24 | (b)<<16 | (c)<<8 | (d) )
  30. #define FORM MakeID('F', 'O', 'R', 'M')
  31. #define LIST MakeID('L', 'I', 'S', 'T')
  32. #define BODY MakeID('B', 'O', 'D', 'Y')
  33. #define BMHD MakeID('B', 'M', 'H', 'D')
  34. #define CMAP MakeID('C', 'M', 'A', 'P')
  35. #define ILBM MakeID('I', 'L', 'B', 'M')
  36. #define MILLION 1000000
  37. #define true -1
  38. #define false 0
  39.  
  40. ULONG class, type;
  41. UBYTE *buffer, *tempbuffer, **psource, **pdest;
  42. UBYTE *filebuffer, *tempfilebuffer, *savebuffer;
  43. UWORD BytesPerPlane, plane, BytesPerRow, pixcol, pixrow;
  44. ULONG pixel_count;
  45. long  TotalBytes;
  46. int   status, i, shift;
  47.  
  48. #define output_buffer_size    (512*16)
  49.  
  50. static long input_file, output_file;
  51. static unsigned char output_buffer[output_buffer_size];
  52. static unsigned char *output_bufptr;
  53. static short bytes_collected;
  54.  
  55. typedef unsigned long ID;
  56.  
  57. struct Chunk
  58.     {
  59.     ID ckID ;
  60.     long ckSize ;
  61.     };
  62.  
  63. struct Chunk chk;
  64.  
  65. typedef UBYTE Masking;
  66. typedef UBYTE Compression;
  67.  
  68. struct BitMapHeader
  69.     {
  70.     UWORD w, h;
  71.     WORD x, y;
  72.     UBYTE nPlanes;
  73.     Masking masking;
  74.     Compression compression;
  75.     UBYTE pad1;
  76.     UWORD transparentColor;
  77.     UBYTE xAspect, yAspect;
  78.     WORD pageWidth, pageHeight;
  79.     };
  80.  
  81. struct BitMapHeader bmhd;
  82.  
  83. #define UGetByte() (*source++)
  84. #define UPutByte(c) (*dest++ = (c))
  85.  
  86. /* Interlace Tables */
  87.  
  88. static UWORD
  89.     base_row[4] = {0, 4, 2, 1},
  90.     row_disp[4] = {8, 8, 4, 2},
  91.     interlaced_mode = 0,
  92.     interlace_pass = 0;
  93.     
  94. GetBits(psource, pdest, dstBytes0)
  95.     BYTE **psource, **pdest; WORD dstBytes0;
  96. {
  97.     register BYTE *source = *psource;
  98.     register BYTE *dest = *pdest;
  99.     register WORD dstBytes = dstBytes0;
  100.  
  101.     while(dstBytes>0)
  102.     {
  103.     UPutByte(UGetByte());
  104.     dstBytes--;
  105.     }
  106.  
  107.     *psource = source;
  108.     *pdest = dest;
  109. }
  110.  
  111.  
  112. UnPackBits(psource, pdest, dstBytes0)
  113.     BYTE **psource, **pdest; WORD dstBytes0;
  114. {
  115.     register BYTE *source = *psource;
  116.     register BYTE *dest = *pdest;
  117.     register BYTE n;
  118.     register BYTE c;
  119.     register WORD dstBytes = dstBytes0;
  120.     WORD minus128 = -128;
  121.  
  122.     while(dstBytes > 0)
  123.     {
  124.     n = UGetByte();
  125.  
  126.     if (n >= 0)
  127.         {
  128.         n++;
  129.         dstBytes -= n;
  130.         do UPutByte(UGetByte()); while (--n > 0);
  131.         }
  132.     else if (n != minus128)
  133.         {
  134.         n = -n + 1;
  135.         dstBytes -= n;
  136.         c = UGetByte();
  137.         do UPutByte(c); while (--n >0);
  138.         }
  139.     }
  140.  
  141.     *psource = source;
  142.     *pdest = dest;
  143. }
  144.  
  145. short Write_Byte(pbyte)
  146.     UBYTE pbyte;
  147. {
  148.     if (bytes_collected == output_buffer_size)
  149.     {
  150.     if (Write(output_file, output_buffer, output_buffer_size) != output_buffer_size)
  151.         return -5;
  152.  
  153.     bytes_collected = 0;
  154.     }
  155.  
  156.     output_buffer[bytes_collected++] = pbyte;
  157.     return 0;
  158. }   
  159.  
  160.  
  161. OutputUsage (Name)
  162.     char *Name;
  163. {
  164.     printf ("usage: iff2gif [-iv] input-filename [output-filename]\n");
  165.     printf ("  where -i = interlaced mode\n");
  166.     printf ("        -v = verbose\n");
  167.     printf ("  default output-file = input-file.GIF\n");
  168.     exit(0);
  169. }
  170.  
  171. short Read_Pixel()
  172. {
  173.     register short pixel, plane;
  174.     register UBYTE *buf, mask;;
  175.  
  176.     if (pixel_count == 0)
  177.     return -1;
  178.  
  179.     pixel = 0;
  180.     buf = &buffer[pixrow*BytesPerRow + (pixcol >> 3)];
  181.     mask = 1 << (7 - (pixcol & 7));
  182.  
  183.     for (plane = 0; plane < bmhd.nPlanes; plane++)
  184.     {
  185.     if (*buf & mask) pixel |= 1 << plane;
  186.         buf += BytesPerPlane;
  187.         }
  188.  
  189.     pixcol++;;
  190.  
  191.     if (pixcol == bmhd.w)
  192.     {
  193.     pixcol = 0;
  194.  
  195.     if (interlaced_mode)
  196.         {
  197.         pixrow += row_disp[interlace_pass];
  198.  
  199.         if (pixrow >= bmhd.h)
  200.         {
  201.         interlace_pass++;
  202.         pixrow = base_row[interlace_pass];
  203.         }
  204.         }
  205.     else
  206.         pixrow++;
  207.         }
  208.  
  209.     pixel_count--;
  210.     return pixel;
  211. }
  212.  
  213. main(argc, argv)
  214.     int argc;
  215.     char *argv[];
  216. {
  217.     char *infile, *outfile, *FlagArguments;
  218.     char *malloc(), *strcat();
  219.     int numColors, temp, ArgumentIndex;
  220.  
  221.     struct ColorEntry color_map[32];
  222.     
  223.     UBYTE
  224.         VerboseFlag = false;
  225.  
  226.     struct ColorRegister {
  227.         UBYTE red, green, blue;
  228.         };
  229.  
  230.     struct ColorRegister ColorMap[32];
  231.     long pos;
  232.  
  233.     /* Evaluate arguments */
  234.  
  235.     if (argc == 1)
  236.         OutputUsage(argv[0]);
  237.  
  238.     FlagArguments = argv[1];
  239.  
  240.     if (FlagArguments[0] == '-')
  241.         {
  242.         int i;
  243.  
  244.         i = 1;
  245.  
  246.         while (FlagArguments[i] != '\0')
  247.         {
  248.             switch (FlagArguments[i])
  249.              {
  250.             case 'i':
  251.               case 'I':
  252.             interlaced_mode = 1;
  253.                     break;
  254.  
  255.         case 'v':
  256.         case 'V':
  257.             VerboseFlag = true;
  258.             break;
  259.  
  260.         default:
  261.             printf ("%c is an invalid flag!\n", FlagArguments[i]);
  262.         }
  263.  
  264.         i++;
  265.         }
  266.  
  267.     ArgumentIndex = 2;
  268.     }
  269.     else
  270.     ArgumentIndex = 1;
  271.  
  272.     if ((ArgumentIndex + 1) <= argc)
  273.     {
  274.     infile = argv[ArgumentIndex];
  275.     ArgumentIndex += 1;
  276.     }
  277.     else
  278.     OutputUsage(argv[0]);
  279.  
  280.     if ((ArgumentIndex + 1) <= argc)
  281.         outfile = argv[ArgumentIndex];
  282.     else
  283.     {
  284.     outfile = (char *)malloc (strlen(infile) + 5);
  285.     strcpy (outfile, infile);
  286.     outfile = strcat(outfile, ".GIF");
  287.         }
  288.  
  289.     input_file = Open(infile, 1005);
  290.  
  291.     if (input_file == 0)
  292.         {
  293.         printf("input file open failed\n");
  294.         exit(0);
  295.         }
  296.  
  297.     output_file = Open(outfile, 1006);
  298.  
  299.     if (output_file == 0)
  300.     {
  301.     printf("output file open failed\n");
  302.     Close(input_file);
  303.     exit(0);
  304.     }
  305.  
  306.     status = Read(input_file, &chk, sizeof(chk));   /* check to see if FORM type */
  307.  
  308.     if (status == -1)
  309.     {
  310.     printf("read failed\n");
  311.     goto CleanUp;
  312.         }
  313.  
  314.     if (chk.ckID != FORM)
  315.     {
  316.     printf("not a picture file\n");
  317.     goto CleanUp;
  318.     }
  319.  
  320.     status = Read(input_file, &type, 4); /* get bit map header */
  321.  
  322.     if (status == -1)
  323.     {
  324.     printf("read failed\n");
  325.     goto CleanUp;
  326.     }
  327.  
  328.     if (type != ILBM)
  329.     {
  330.     printf("not a picture file\n");
  331.     goto CleanUp;
  332.     }
  333.  
  334.     status = Read(input_file, &chk, sizeof(chk));
  335.  
  336.     if (chk.ckID != BMHD)
  337.     {
  338.     printf("could not find bit map header\n");
  339.     goto CleanUp;
  340.     }
  341.  
  342.     status = Read(input_file, &bmhd, sizeof(bmhd));  /* get bmhd info */
  343.  
  344.     if (status == -1)
  345.     {
  346.     printf("read failed\n");
  347.     goto CleanUp;
  348.     }
  349.  
  350.     status = Read(input_file, &chk, sizeof(chk));
  351.  
  352.     while (chk.ckID != CMAP)
  353.         {
  354.         pos = Seek(input_file, chk.ckSize, 0);
  355.  
  356.     if (pos == -1)
  357.         {
  358.         printf("seek failed\n");
  359.         exit(0);
  360.         }
  361.  
  362.     status = Read(input_file, &chk, sizeof(chk));
  363.     }
  364.  
  365.     /* we have got the cmap!! */
  366.  
  367.     numColors = chk.ckSize/3;
  368.  
  369.     for (i = 0; i < numColors; i++)
  370.     status = Read(input_file, &ColorMap[i], 3);
  371.  
  372.     /* right justify color map entires */
  373.  
  374.     for (i = 0; i < numColors; i++)
  375.         {
  376.         color_map[i].red = ColorMap[i].red >> 4;
  377.         color_map[i].blue = ColorMap[i].blue >> 4;
  378.         color_map[i].green = ColorMap[i].green >> 4;
  379.         }
  380.  
  381.     /* skip over everything else until body is found */
  382.  
  383.     status = Read(input_file, &chk, sizeof(chk));
  384.  
  385.     while (chk.ckID != BODY)
  386.     {
  387.         pos = Seek(input_file, chk.ckSize, 0);
  388.  
  389.     if (pos == -1)
  390.         {
  391.         printf("seek failed\n");
  392.         exit(0);
  393.         }
  394.  
  395.     status = Read(input_file, &chk, sizeof(chk));
  396.     }
  397.  
  398.     /* we have got the body!! */
  399.  
  400.     BytesPerRow = ((bmhd.w + 15) >> 4) << 1;
  401.     BytesPerPlane = BytesPerRow*bmhd.h;
  402.     TotalBytes = BytesPerPlane*(UWORD)bmhd.nPlanes;
  403.     buffer = (UBYTE *)malloc(TotalBytes);
  404.  
  405.     if (buffer == NULL)
  406.     {
  407.     printf("no memory for buffer\n");
  408.     exit(0);
  409.     }
  410.  
  411.     filebuffer = (UBYTE *)malloc(chk.ckSize);
  412.  
  413.     if (filebuffer == NULL)
  414.     {
  415.     printf("no memory for file buffer\n");
  416.     exit(0);
  417.     }
  418.  
  419.     savebuffer = buffer;
  420.     tempfilebuffer = filebuffer;
  421.     status = Read(input_file, filebuffer, chk.ckSize);
  422.     pdest = &tempbuffer;
  423.     psource = &tempfilebuffer;
  424.  
  425.     for (i = 0; i < bmhd.h; i++)
  426.     {
  427.     for (plane = 0; plane < bmhd.nPlanes; plane++)
  428.         {
  429.         tempbuffer = buffer + (BytesPerRow*i) + (BytesPerPlane*plane);
  430.  
  431.         if (bmhd.compression == cmpByteRun1)
  432.         UnPackBits(psource, pdest, BytesPerRow);
  433.         else
  434.         GetBits(psource, pdest, BytesPerRow);
  435.         }
  436.     }
  437.  
  438.     if (VerboseFlag)
  439.     {
  440.     printf("Converting IFF file %s.\n", argv[1]);
  441.     printf("  Image size(width,height) = (%d,%d)\n", bmhd.w, bmhd.h);
  442.     printf("  Page size(width,height) = (%d,%d)\n", 
  443.         bmhd.pageWidth, bmhd.pageHeight);
  444.     printf("  Position (x,y) = (%d,%d)\n", bmhd.x, bmhd.y);
  445.     printf("  Aspect (x,y) = (%d,%d)\n", bmhd.xAspect, bmhd.yAspect);
  446.     printf("  Number of planes = %d\n", bmhd.nPlanes);
  447.     printf("  Masking = %d\n", bmhd.masking);
  448.     printf("  Compression = %d\n", bmhd.compression);
  449.     printf("  Transparent color = %d\n", bmhd.transparentColor);
  450.     }
  451.  
  452.     bytes_collected = 0;
  453.     pixrow = 0;
  454.     pixcol = 0;
  455.     pixel_count = bmhd.w*bmhd.h;
  456.  
  457.     status = Create_GIF(Read_Pixel,  Write_Byte, bmhd.w, bmhd.h,
  458.                         4, interlaced_mode, bmhd.nPlanes, color_map);
  459.  
  460.     Write(output_file, output_buffer, bytes_collected);
  461.     printf("Conversion completed.\n");
  462.  
  463. CleanUp:
  464.     Close(input_file);
  465.     Close(output_file);
  466.     exit(0);
  467. }
  468.