home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d541 / gifmachine.lha / GIFMachine / Sources / doimage.c < prev    next >
C/C++ Source or Header  |  1991-09-17  |  6KB  |  252 lines

  1. /* Copyright 1990 by Christopher A. Wichura.
  2.    See file GIFMachine.doc for full description of rights.
  3. */
  4.  
  5. #include "GIFMachine.h"
  6.  
  7. extern struct GIFdescriptor gdesc;
  8. EXTERNBITPLANE;
  9.  
  10. static struct ImageDesc idesc;
  11. extern struct RGB GlobalColourTable[256];
  12. static struct RGB LocalColourTable[256];
  13. extern ULONG ImageNumber;
  14.  
  15. extern char *AbortMsg;
  16.  
  17. static UWORD Xpos, Ypos;
  18. static BOOL interleave;
  19.  
  20. static UBYTE LeaveStep[5]  = {1, 8, 8, 4, 2};
  21. static UBYTE LeaveFirst[5] = {0, 0, 4, 2, 1};
  22.  
  23. /* some variables used by the decompressor */
  24. static int ReadError;
  25. static UBYTE CodeSize;
  26. static int EOFCode;
  27. static UBYTE ReadMask;
  28. static int CompDataPointer;
  29. static int CompDataCount;
  30. static UBYTE CompData[256];
  31.  
  32. /* tables used by the decompressor */
  33. static UWORD Prefix[4096];
  34. static UBYTE Suffix[4096];
  35. static UBYTE OutCode[1025];
  36.  
  37. extern BOOL DisplayCounts;
  38.  
  39. BOOL DoImage(BPTR fh)
  40. {
  41.     register int index;
  42.     register int colours;
  43.     int Code;
  44.  
  45.     MyPrintf("...Image #%ld encountered.\n", ImageNumber++);
  46.  
  47.     if (FRead(fh, (char *)&idesc, 1, 9) != 9) {
  48.         PutStr("......Error reading image descriptor.\n");
  49.         return TRUE;
  50.     }
  51.  
  52.     FlipWord(&idesc.id_Left);
  53.     FlipWord(&idesc.id_Top);
  54.     FlipWord(&idesc.id_Width);
  55.     FlipWord(&idesc.id_Height);
  56.  
  57.     interleave = idesc.id_Info & 1L << 6;
  58.     if (interleave)
  59.         interleave = 1;
  60.  
  61.     MyPrintf("......Xpos from %ld to %ld, Ypos from %ld to %ld, %sinterlaced.\n",
  62.         idesc.id_Left, idesc.id_Left + idesc.id_Width - 1,
  63.         idesc.id_Top, idesc.id_Top + idesc.id_Height - 1,
  64.         interleave ? "" : "not ");
  65.  
  66.     if (idesc.id_Info & 1L << 7) {
  67.         colours = 1L << ((idesc.id_Info & 7) + 1);
  68.         MyPrintf("......Local colour map contains %ld entries.\n", colours);
  69.  
  70.         for (index = 0; index < colours; index++) {
  71.             if (FRead(fh, &LocalColourTable[index], 1, 3) != 3) {
  72.                 MyPrintf("......Error reading local colour #%ld.\n",
  73.                     index);
  74.                 return TRUE;
  75.             }
  76.         }
  77.     } else {
  78.         colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
  79.         CopyMem((char *)GlobalColourTable, (char *)LocalColourTable,
  80.             sizeof(LocalColourTable));
  81.     }
  82.  
  83.     Xpos = Ypos = 0;
  84.  
  85.     /* now we are ready to read the image in so do it! */
  86.  
  87.     {
  88.         int MaxCode, ClearCode, CurCode,
  89.             OldCode, InCode, FreeCode;
  90.         int OutCount;
  91.         int FirstFree;
  92.         UBYTE InitCodeSize, FinChar, BitMask;
  93.  
  94.         if (DisplayCounts)
  95.             MyPrintf("......Decompressing line number %5ld", Ypos);
  96.         else
  97.             PutStr("......Decompressing");
  98.         Flush(Output());
  99.  
  100.         /* get the codesize and do general setup for decompression */
  101.         if ((CodeSize = FGetC(fh)) == -1) {
  102.             PutStr("\n......I/O Error during decompression.\n");
  103.             return TRUE;
  104.         }
  105.  
  106.         ClearCode = 1L << CodeSize;
  107.         EOFCode = ClearCode + 1;
  108.         FreeCode = FirstFree = ClearCode + 2;
  109.  
  110.         CodeSize++;    /* per GIF spec */
  111.         InitCodeSize = CodeSize;
  112.         MaxCode = 1L << CodeSize;
  113.         ReadError = ReadMask = OutCount = 0;
  114.         CompDataPointer = CompDataCount = 0;
  115.  
  116.         BitMask = colours - 1;
  117.  
  118.         Code = ReadCode(fh);
  119.         while (Code != EOFCode) {
  120.             if (ReadError)
  121.                 return TRUE;
  122.  
  123.             if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  124.                 MyPrintf("\n%s", AbortMsg);
  125.                 MyExit(ABORTEXITVAL);
  126.             }
  127.  
  128.             if (Code == ClearCode) {
  129.                 CodeSize = InitCodeSize;
  130.                 MaxCode = 1L << CodeSize;
  131.                 FreeCode = FirstFree;
  132.                 FinChar = CurCode = OldCode = Code = ReadCode(fh);
  133.                 AddPixel(FinChar);
  134.             } else {
  135.                 CurCode = InCode = Code;
  136.  
  137.                 if (CurCode >= FreeCode) {
  138.                     CurCode = OldCode;
  139.                     OutCode[OutCount++] = FinChar;
  140.                 }
  141.  
  142.                 while (CurCode > BitMask) {
  143.                     if (OutCount > 1024) {
  144.                         PutStr("\n......Corrupt GIF file (OutCount)\n");
  145.                         return TRUE;
  146.                     }
  147.  
  148.                     OutCode[OutCount++] = Suffix[CurCode];
  149.                     CurCode = Prefix[CurCode];
  150.                 }
  151.  
  152.                 FinChar = CurCode;
  153.                 AddPixel(FinChar);
  154.  
  155.                 for (index = OutCount - 1; index >= 0; index--)
  156.                     AddPixel(OutCode[index]);
  157.                 OutCount = 0;
  158.  
  159.                 Prefix[FreeCode] = OldCode;
  160.                 Suffix[FreeCode] = FinChar;
  161.                 OldCode = InCode;
  162.  
  163.                 if (++FreeCode >= MaxCode) {
  164.                     if (CodeSize < 12) {
  165.                         CodeSize++;
  166.                         MaxCode <<= 1;
  167.                     }
  168.                 }
  169.             }
  170.  
  171.             Code = ReadCode(fh);
  172.         }
  173.     }
  174.  
  175.     if ((Code = FGetC(fh)) == -1)
  176.         return TRUE;
  177.  
  178.     /* done decompressing.  Erase decompressing message and exit */
  179.     MyPrintf("\x1B[%ldD\x1B[Ked.\n", (DisplayCounts ? 21 : 3));
  180.  
  181.     if (Code != 0) {
  182.         PutStr("......Warning:  Unaligned packet.\n");
  183.         UnGetC(fh, Code);
  184.     }
  185.  
  186.     return FALSE;
  187. }
  188.  
  189. static UBYTE ByteBuf;
  190.  
  191. int ReadCode(BPTR fh)
  192. {
  193.     register int temp;
  194.     register int DstMasked;
  195.     register int DstMask;
  196.     register LONG size;
  197.  
  198.     temp = 0;
  199.     DstMasked = 1L << CodeSize;
  200.     for (DstMask = 1; DstMask != DstMasked; DstMask <<= 1) {
  201.         if (!ReadMask) {
  202.             if (CompDataPointer == CompDataCount) {
  203.                 if ((size = FGetC(fh)) == -1) {
  204.                     PutStr("\n......I/O Error during decompression.\n");
  205.                     ReadError = 1;
  206.                     return EOFCode;
  207.                 }
  208.  
  209.                 if (FRead(fh, (char *)CompData, 1, size) != size) {
  210.                     PutStr("\n......I/O Error during decompression.\n");
  211.                     ReadError = 1;
  212.                     return EOFCode;
  213.                 }
  214.  
  215.                 CompDataCount = size;
  216.                 CompDataPointer = 0;
  217.             }
  218.  
  219.             ReadMask = 1;
  220.             ByteBuf = CompData[CompDataPointer++];
  221.         }
  222.  
  223.         if (ByteBuf & ReadMask)
  224.             temp |= DstMask;
  225.  
  226.         ReadMask <<= 1;
  227.     }
  228.  
  229.     return temp;
  230. }
  231.  
  232. void AddPixel(UBYTE index)
  233. {
  234.     register UWORD XStore;
  235.     register UWORD YStore;
  236.  
  237.     XStore = Xpos + idesc.id_Left;
  238.     YStore = Ypos + idesc.id_Top;
  239.  
  240.     BitPlane[YStore][XStore] = LocalColourTable[index];
  241.  
  242.     if (++Xpos == idesc.id_Width) {
  243.         Xpos = 0;
  244.         Ypos += LeaveStep[interleave];
  245.         if (Ypos >= idesc.id_Height)
  246.             Ypos = LeaveFirst[++interleave];
  247.  
  248.         if (DisplayCounts)
  249.             MyPrintf("\x1B[5D%5ld", Ypos + idesc.id_Top);
  250.     }
  251. }
  252.