summaryrefslogtreecommitdiffstats
path: root/tools/gifconv/decompress.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gifconv/decompress.c')
-rw-r--r--tools/gifconv/decompress.c497
1 files changed, 257 insertions, 240 deletions
diff --git a/tools/gifconv/decompress.c b/tools/gifconv/decompress.c
index abccb7f..a2682e5 100644
--- a/tools/gifconv/decompress.c
+++ b/tools/gifconv/decompress.c
@@ -1,38 +1,43 @@
+/*
+ * Copyright (C) 2001 National Center for Supercomputing Applications
+ * All rights reserved.
+ */
#include <stdio.h>
#include <stdlib.h>
+
#include "gif.h"
-#define NEXTBYTE (*ptr++)
-#define IMAGESEP 0x2c
-#define INTERLACEMASK 0x40
-#define COLORMAPMASK 0x80
-#define False 0
-#define True 1
+#define NEXTBYTE (*ptr++)
+
+#define IMAGESEP 0x2c
+#define INTERLACEMASK 0x40
+#define COLORMAPMASK 0x80
-WORD iWIDE,iHIGH,eWIDE,eHIGH,expand,numcols,strip,nostrip;
+WORD iWIDE, iHIGH, eWIDE, eHIGH, expand, numcols, strip, nostrip;
unsigned long cols[256];
-char *cmd;
+char *cmd;
FILE *fp;
-static int BitOffset = 0, /* Bit Offset of next code */
-XC = 0, YC = 0, /* Output X and Y coords of current pixel */
-Pass = 0, /* Used by output routine if WORDerlaced pic */
-OutCount = 0, /* Decompressor output 'stack count' */
-IWidth, IHeight, /* image dimensions */
-BytesPerScanline, /* Bytes per scanline in output raster */
-CodeSize, /* Code size, read from GIF header */
-InitCodeSize, /* Starting code size, used during Clear */
-Code, /* Value returned by ReadCode */
-MaxCode, /* limiting value for current code size */
-ClearCode, /* GIF clear code */
-EOFCode, /* GIF end-of-information code */
-CurCode, OldCode, InCode, /* Decompressor variables */
-FirstFree, /* First free code, generated per GIF spec */
-FreeCode, /* Decompressor, next free slot in hash table */
-FinChar, /* Decompressor variable */
-DataMask, /* AND mask for data size */
-ReadMask; /* Code AND mask for current code size */
+static int
+ BitOffset = 0, /* Bit Offset of next code */
+ XC = 0, YC = 0, /* Output X and Y coords of current pixel */
+ Pass = 0, /* Used by output routine if WORDerlaced pic */
+ OutCount = 0, /* Decompressor output 'stack count' */
+ IWidth, IHeight, /* image dimensions */
+ BytesPerScanline, /* Bytes per scanline in output raster */
+ CodeSize, /* Code size, read from GIF header */
+ InitCodeSize, /* Starting code size, used during Clear */
+ Code, /* Value returned by ReadCode */
+ MaxCode, /* limiting value for current code size */
+ ClearCode, /* GIF clear code */
+ EOFCode, /* GIF end-of-information code */
+ CurCode, OldCode, InCode, /* Decompressor variables */
+ FirstFree, /* First free code, generated per GIF spec */
+ FreeCode, /* Decompressor, next free slot in hash table */
+ FinChar, /* Decompressor variable */
+ DataMask, /* AND mask for data size */
+ ReadMask; /* Code AND mask for current code size */
/*MODIFICATIONS*/
BYTE tempbyte[10];
@@ -43,10 +48,9 @@ WORD ImageCount = 0;
boolean Interlace, HasColormap;
-
-BYTE *Image; /* The result array */
-BYTE *RawGIF; /* The heap array to hold it, raw */
-BYTE *Raster; /* The raster data stream, unblocked */
+BYTE *Image; /* The result array */
+BYTE *RawGIF; /* The heap array to hold it, raw */
+BYTE *Raster; /* The raster data stream, unblocked */
/* The hash table used by the decompressor */
@@ -61,233 +65,246 @@ int OutCode[1025];
int numused;
-/* Fetch the next code from the raster data stream. The codes can be
-* any length from 3 to 12 bits, packed WORDo 8-bit BYTEs, so we have to
-* maWORDain our location in the Raster array as a BIT Offset. We compute
-* the BYTE Offset WORDo the raster array by dividing this by 8, pick up
-* three BYTEs, compute the bit Offset WORDo our 24-bit chunk, shift to
-* bring the desired code to the bottom, then mask it off and return it.
-*/
-static int ReadCode(void)
+/*
+ * Fetch the next code from the raster data stream. The codes can be any
+ * length from 3 to 12 bits, packed WORDo 8-bit BYTEs, so we have to maWORDain
+ * our location in the Raster array as a BIT Offset. We compute the BYTE
+ * Offset WORDo the raster array by dividing this by 8, pick up three BYTEs,
+ * compute the bit Offset WORDo our 24-bit chunk, shift to bring the desired
+ * code to the bottom, then mask it off and return it.
+ */
+static int
+ReadCode(void)
{
- int RawCode, ByteOffset;
-
+ int RawCode, ByteOffset;
+
ByteOffset = BitOffset / 8;
RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]);
+
if (CodeSize >= 8)
- RawCode += (0x10000 * Raster[ByteOffset + 2]);
+ RawCode += (0x10000 * Raster[ByteOffset + 2]);
+
RawCode >>= (BitOffset % 8);
BitOffset += CodeSize;
- return(RawCode & ReadMask);
+ return (RawCode & ReadMask);
}
-
-static void AddToPixel(BYTE Index)
+static void
+AddToPixel(BYTE Index)
{
if (YC<IHeight)
- *(Image + YC * BytesPerScanline + XC) = Index;
-
+ *(Image + YC * BytesPerScanline + XC) = Index;
-
- /* Update the X-coordinate, and if it overflows, update the Y-coordinate */
+
+
+ /* Update the X-coordinate, and if it overflows, update the
+ * Y-coordinate */
if (++XC == IWidth) {
-
- /* If a non-WORDerlaced picture, just increment YC to the next scan line.
- * If it's WORDerlaced, deal with the WORDerlace as described in the GIF
- * spec. Put the decoded scan line out to the screen if we haven't gone
- * past the bottom of it.
- */
-
- XC = 0;
- if (!Interlace) YC++;
- else {
- switch (Pass) {
- case 0:
- YC += 8;
- if (YC >= IHeight) {
- Pass++;
- YC = 4;
- }
- break;
- case 1:
- YC += 8;
- if (YC >= IHeight) {
- Pass++;
- YC = 2;
- }
- break;
-
- case 2:
- YC += 4;
- if (YC >= IHeight) {
- Pass++;
- YC = 1;
- }
- break;
- case 3:
- YC += 2;
- break;
- default:
- break;
- }
- }
+ /*
+ * If a non-WORDerlaced picture, just increment YC to the next scan
+ * line. If it's WORDerlaced, deal with the WORDerlace as described
+ * in the GIF spec. Put the decoded scan line out to the screen if we
+ * haven't gone past the bottom of it.
+ */
+ XC = 0;
+
+ if (!Interlace) {
+ YC++;
+ } else {
+ switch (Pass) {
+ case 0:
+ YC += 8;
+
+ if (YC >= IHeight) {
+ Pass++;
+ YC = 4;
+ }
+
+ break;
+ case 1:
+ YC += 8;
+
+ if (YC >= IHeight) {
+ Pass++;
+ YC = 2;
+ }
+
+ break;
+ case 2:
+ YC += 4;
+
+ if (YC >= IHeight) {
+ Pass++;
+ YC = 1;
+ }
+
+ break;
+ case 3:
+ YC += 2;
+ break;
+ default:
+ break;
+ }
+ }
}
}
/* Main routine. Convert a GIF image to an HDF image */
-BYTE* Decompress(GifImageDesc , GifHead)
-GIFIMAGEDESC *GifImageDesc;
-GIFHEAD *GifHead;
+BYTE *
+Decompress(GIFIMAGEDESC *GifImageDesc, GIFHEAD *GifHead)
{
- int i;
-
- XC = 0;
- YC = 0;
- Pass = 0;
- OutCount = 0;
- BitOffset = 0;
-
- DataMask = (WORD)((1L << ((GifHead->PackedField & 0x07) +1)) -1);
- Raster = GifImageDesc->GIFImage;
-
-
- /* Check for image seperator */
-
- /* Now read in values from the image descriptor */
- IWidth = GifImageDesc->ImageWidth;
- IHeight = GifImageDesc->ImageHeight;
- Interlace = GifImageDesc->PackedField & 0x40;
-
- /* Note that I ignore the possible existence of a local color map.
- * I'm told there aren't many files around that use them, and the spec
- * says it's defined for future use. This could lead to an error
- * reading some files.
- */
-
- /* Start reading the raster data. First we get the WORDial code size
- * and compute decompressor constant values, based on this code size.
- */
-
- CodeSize = GifImageDesc->CodeSize;
- ClearCode = (1 << CodeSize);
- EOFCode = ClearCode + 1;
- FreeCode = FirstFree = ClearCode + 2;
-
- /* The GIF spec has it that the code size is the code size used to
- * compute the above values is the code size given in the file, but the
- * code size used in compression/decompression is the code size given in
- * the file plus one. (thus the ++).
- */
-
- CodeSize++;
- InitCodeSize = CodeSize;
- MaxCode = (1 << CodeSize);
- ReadMask = MaxCode - 1;
-
- /* Read the raster data. Here we just transpose it from the GIF array
- * to the Raster array, turning it from a series of blocks WORDo one long
- * data stream, which makes life much easier for ReadCode().
- */
-
-
-
- /* free(RawGIF); We're not done just yet - change made */
-
- /* Allocate the Image */
-
- if (!(Image = (BYTE *)malloc((size_t)IWidth*(size_t)IHeight))) {
- printf("Out of memory");
- exit(-1);
- }
-
- BytesPerScanline = IWidth;
-
- /* Decompress the file, continuing until you see the GIF EOF code.
- * One obvious enhancement is to add checking for corrupt files here.
- */
-
- Code = ReadCode();
- while (Code != EOFCode) {
-
- /* Clear code sets everything back to its initial value, then reads the
- * immediately subsequent code as uncompressed data.
- */
-
- if (Code == ClearCode) {
- CodeSize = InitCodeSize;
- MaxCode = (1 << CodeSize);
- ReadMask = MaxCode - 1;
- FreeCode = FirstFree;
- CurCode = OldCode = Code = ReadCode();
- FinChar = CurCode & DataMask;
- AddToPixel(FinChar);
- }
- else {
-
- /* If not a clear code, then must be data: save same as CurCode and InCode */
-
- CurCode = InCode = Code;
-
- /* If greater or equal to FreeCode, not in the hash table yet;
- * repeat the last character decoded
- */
-
- if (CurCode >= FreeCode) {
- CurCode = OldCode;
- OutCode[OutCount++] = FinChar;
- }
-
- /* Unless this code is raw data, pursue the chain poWORDed to by CurCode
- * through the hash table to its end; each code in the chain puts its
- * associated output code on the output queue.
- */
-
- while (CurCode > DataMask) {
- if (OutCount > 1024) {
- /*return error message*/
- }
- OutCode[OutCount++] = Suffix[CurCode];
- CurCode = Prefix[CurCode];
- }
-
- /* The last code in the chain is treated as raw data. */
-
- FinChar = CurCode & DataMask;
- OutCode[OutCount++] = FinChar;
-
- /* Now we put the data out to the Output routine.
- * It's been stacked LIFO, so deal with it that way...
- */
-
- for (i = OutCount - 1; i >= 0; i--)
- AddToPixel(OutCode[i]);
- OutCount = 0;
-
- /* Build the hash table on-the-fly. No table is stored in the file. */
-
- Prefix[FreeCode] = OldCode;
- Suffix[FreeCode] = FinChar;
- OldCode = InCode;
-
- /* PoWORD to the next slot in the table. If we exceed the current
- * MaxCode value, increment the code size unless it's already 12. If it
- * is, do nothing: the next code decompressed better be CLEAR
- */
-
- FreeCode++;
- if (FreeCode >= MaxCode) {
- if (CodeSize < 12) {
- CodeSize++;
- MaxCode *= 2;
- ReadMask = (1 << CodeSize) - 1;
- }
- }
- }
- Code = ReadCode();
- }
-
- return Image;
-}
+ int i;
+
+ XC = 0;
+ YC = 0;
+ Pass = 0;
+ OutCount = 0;
+ BitOffset = 0;
+
+ DataMask = (WORD)((1L << ((GifHead->PackedField & 0x07) +1)) -1);
+ Raster = GifImageDesc->GIFImage;
+
+ /* Check for image seperator */
+
+ /* Now read in values from the image descriptor */
+ IWidth = GifImageDesc->ImageWidth;
+ IHeight = GifImageDesc->ImageHeight;
+ Interlace = GifImageDesc->PackedField & 0x40;
+
+ /*
+ * Note that I ignore the possible existence of a local color map. I'm
+ * told there aren't many files around that use them, and the spec says
+ * it's defined for future use. This could lead to an error reading some
+ * files.
+ */
+
+ /*
+ * Start reading the raster data. First we get the WORDial code size and
+ * compute decompressor constant values, based on this code size.
+ */
+
+ CodeSize = GifImageDesc->CodeSize;
+ ClearCode = (1 << CodeSize);
+ EOFCode = ClearCode + 1;
+ FreeCode = FirstFree = ClearCode + 2;
+
+ /*
+ * The GIF spec has it that the code size is the code size used to compute
+ * the above values is the code size given in the file, but the code size
+ * used in compression/decompression is the code size given in the file
+ * plus one. (thus the ++).
+ */
+
+ CodeSize++;
+ InitCodeSize = CodeSize;
+ MaxCode = (1 << CodeSize);
+ ReadMask = MaxCode - 1;
+
+ /*
+ * Read the raster data. Here we just transpose it from the GIF array to
+ * the Raster array, turning it from a series of blocks WORDo one long
+ * data stream, which makes life much easier for ReadCode().
+ */
+
+ /* Allocate the Image */
+
+ if (!(Image = (BYTE *)malloc((size_t)IWidth*(size_t)IHeight))) {
+ printf("Out of memory");
+ exit(-1);
+ }
+
+ BytesPerScanline = IWidth;
+
+ /*
+ * Decompress the file, continuing until you see the GIF EOF code. One
+ * obvious enhancement is to add checking for corrupt files here.
+ */
+
+ Code = ReadCode();
+
+ while (Code != EOFCode) {
+ /*
+ * Clear code sets everything back to its initial value, then reads
+ * the immediately subsequent code as uncompressed data.
+ */
+ if (Code == ClearCode) {
+ CodeSize = InitCodeSize;
+ MaxCode = (1 << CodeSize);
+ ReadMask = MaxCode - 1;
+ FreeCode = FirstFree;
+ CurCode = OldCode = Code = ReadCode();
+ FinChar = CurCode & DataMask;
+ AddToPixel(FinChar);
+ } else {
+ /*
+ * If not a clear code, then must be data: save same as CurCode
+ * and InCode
+ */
+ CurCode = InCode = Code;
+ /*
+ * If greater or equal to FreeCode, not in the hash table yet;
+ * repeat the last character decoded
+ */
+ if (CurCode >= FreeCode) {
+ CurCode = OldCode;
+ OutCode[OutCount++] = FinChar;
+ }
+ /*
+ * Unless this code is raw data, pursue the chain poWORDed to by
+ * CurCode through the hash table to its end; each code in the
+ * chain puts its associated output code on the output queue.
+ */
+ while (CurCode > DataMask) {
+ if (OutCount > 1024) {
+ /*return error message*/
+ }
+
+ OutCode[OutCount++] = Suffix[CurCode];
+ CurCode = Prefix[CurCode];
+ }
+
+ /* The last code in the chain is treated as raw data. */
+ FinChar = CurCode & DataMask;
+ OutCode[OutCount++] = FinChar;
+
+ /*
+ * Now we put the data out to the Output routine. It's been
+ * stacked LIFO, so deal with it that way...
+ */
+ for (i = OutCount - 1; i >= 0; i--)
+ AddToPixel(OutCode[i]);
+
+ OutCount = 0;
+
+ /*
+ * Build the hash table on-the-fly. No table is stored in the
+ * file.
+ */
+ Prefix[FreeCode] = OldCode;
+ Suffix[FreeCode] = FinChar;
+ OldCode = InCode;
+
+ /*
+ * PoWORD to the next slot in the table. If we exceed the current
+ * MaxCode value, increment the code size unless it's already 12.
+ * If it is, do nothing: the next code decompressed better be
+ * CLEAR
+ */
+ FreeCode++;
+
+ if (FreeCode >= MaxCode)
+ if (CodeSize < 12) {
+ CodeSize++;
+ MaxCode *= 2;
+ ReadMask = (1 << CodeSize) - 1;
+ }
+ }
+
+ Code = ReadCode();
+ }
+
+ return Image;
+}