1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 #include <stdio.h>
14 #include <stdlib.h>
15
16 #include "gif.h"
17
18 WORD iWIDE, iHIGH, eWIDE, eHIGH, expand, numcols, strip, nostrip;
19 unsigned long cols[256];
20 char *cmd;
21
22 FILE *fp;
23
24 static WORD
25 XC = 0, YC = 0, /* Output X and Y coords of current pixel */
26 InitCodeSize, /* Starting code size, used during Clear */
27 CodeSize, /* Code size, read from GIF header */
28 BytesPerScanline, /* Bytes per scanline in output raster */
29 IWidth, IHeight; /* image dimensions */
30 static int
31 BitOffset = 0, /* Bit Offset of next code */
32 Pass = 0, /* Used by output routine if WORDerlaced pic */
33 OutCount = 0, /* Decompressor output 'stack count' */
34 Code, /* Value returned by ReadCode */
35 MaxCode, /* limiting value for current code size */
36 ClearCode, /* GIF clear code */
37 EOFCode, /* GIF end-of-information code */
38 CurCode, OldCode, InCode, /* Decompressor variables */
39 FirstFree, /* First free code, generated per GIF spec */
40 FreeCode, /* Decompressor, next free slot in hash table */
41 FinChar, /* Decompressor variable */
42 DataMask, /* AND mask for data size */
43 ReadMask; /* Code AND mask for current code size */
44
45 /*MODIFICATIONS*/
46 BYTE tempbyte[10];
47 BYTE * tempBYTEptr[10];
48 WORD tempint[10];
49 WORD ImageCount = 0;
50 /*END MODIFICATION*/
51
52 boolean Interlace, HasColormap;
53
54 BYTE *Image; /* The result array */
55 BYTE *RawGIF; /* The heap array to hold it, raw */
56 BYTE *Raster; /* The raster data stream, unblocked */
57
58 /* The hash table used by the decompressor */
59
60 int Prefix[4096];
61 int Suffix[4096];
62
63 /* An output array used by the decompressor */
64
65 int OutCode[1025];
66
67 /* The color map, read from the GIF header */
68
69 int numused;
70
71 /*
72 * Fetch the next code from the raster data stream. The codes can be any
73 * length from 3 to 12 bits, packed WORDo 8-bit BYTEs, so we have to maWORDain
74 * our location in the Raster array as a BIT Offset. We compute the BYTE
75 * Offset WORDo the raster array by dividing this by 8, pick up three BYTEs,
76 * compute the bit Offset WORDo our 24-bit chunk, shift to bring the desired
77 * code to the bottom, then mask it off and return it.
78 */
79 static int
ReadCode(void)80 ReadCode(void)
81 {
82 int RawCode, ByteOffset;
83
84 ByteOffset = BitOffset / 8;
85 RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]);
86
87 if (CodeSize >= 8)
88 RawCode += (0x10000 * Raster[ByteOffset + 2]);
89
90 RawCode >>= (BitOffset % 8);
91 BitOffset += (int)CodeSize;
92 return (RawCode & ReadMask);
93 }
94
95 static void
AddToPixel(BYTE Index)96 AddToPixel(BYTE Index)
97 {
98 if (YC<IHeight)
99 *(Image + YC * BytesPerScanline + XC) = Index;
100
101
102
103 /* Update the X-coordinate, and if it overflows, update the
104 * Y-coordinate */
105 if (++XC == IWidth) {
106 /*
107 * If a non-WORDerlaced picture, just increment YC to the next scan
108 * line. If it's WORDerlaced, deal with the WORDerlace as described
109 * in the GIF spec. Put the decoded scan line out to the screen if we
110 * haven't gone past the bottom of it.
111 */
112 XC = 0;
113
114 if (!Interlace) {
115 YC++;
116 } else {
117 switch (Pass) {
118 case 0:
119 YC += 8;
120
121 if (YC >= IHeight) {
122 Pass++;
123 YC = 4;
124 }
125
126 break;
127 case 1:
128 YC += 8;
129
130 if (YC >= IHeight) {
131 Pass++;
132 YC = 2;
133 }
134
135 break;
136 case 2:
137 YC += 4;
138
139 if (YC >= IHeight) {
140 Pass++;
141 YC = 1;
142 }
143
144 break;
145 case 3:
146 YC += 2;
147 break;
148 default:
149 break;
150 }
151 }
152 }
153 }
154
155 /* Main routine. Convert a GIF image to an HDF image */
156
157 BYTE *
Decompress(GIFIMAGEDESC * GifImageDesc,GIFHEAD * GifHead)158 Decompress(GIFIMAGEDESC *GifImageDesc, GIFHEAD *GifHead)
159 {
160 int i;
161
162 XC = 0;
163 YC = 0;
164 Pass = 0;
165 OutCount = 0;
166 BitOffset = 0;
167
168 DataMask = (1 << ((GifHead->PackedField & 0x07) +1)) -1;
169 Raster = GifImageDesc->GIFImage;
170
171 /* Check for image seperator */
172
173 /* Now read in values from the image descriptor */
174 IWidth = GifImageDesc->ImageWidth;
175 IHeight = GifImageDesc->ImageHeight;
176 Interlace = GifImageDesc->PackedField & 0x40;
177
178 /*
179 * Note that I ignore the possible existence of a local color map. I'm
180 * told there aren't many files around that use them, and the spec says
181 * it's defined for future use. This could lead to an error reading some
182 * files.
183 */
184
185 /*
186 * Start reading the raster data. First we get the WORDial code size and
187 * compute decompressor constant values, based on this code size.
188 */
189
190 CodeSize = GifImageDesc->CodeSize;
191 ClearCode = (1 << CodeSize);
192 EOFCode = ClearCode + 1;
193 FreeCode = FirstFree = ClearCode + 2;
194
195 /*
196 * The GIF spec has it that the code size is the code size used to compute
197 * the above values is the code size given in the file, but the code size
198 * used in compression/decompression is the code size given in the file
199 * plus one. (thus the ++).
200 */
201
202 CodeSize++;
203 InitCodeSize = CodeSize;
204 MaxCode = (1 << CodeSize);
205 ReadMask = MaxCode - 1;
206
207 /*
208 * Read the raster data. Here we just transpose it from the GIF array to
209 * the Raster array, turning it from a series of blocks WORDo one long
210 * data stream, which makes life much easier for ReadCode().
211 */
212
213 /* Allocate the Image */
214
215 if (!(Image = (BYTE *)malloc((size_t)IWidth*(size_t)IHeight))) {
216 printf("Out of memory");
217 exit(EXIT_FAILURE);
218 }
219
220 BytesPerScanline = IWidth;
221
222 /*
223 * Decompress the file, continuing until you see the GIF EOF code. One
224 * obvious enhancement is to add checking for corrupt files here.
225 */
226
227 Code = ReadCode();
228
229 while (Code != EOFCode) {
230 /*
231 * Clear code sets everything back to its initial value, then reads
232 * the immediately subsequent code as uncompressed data.
233 */
234 if (Code == ClearCode) {
235 CodeSize = InitCodeSize;
236 MaxCode = (1 << CodeSize);
237 ReadMask = MaxCode - 1;
238 FreeCode = FirstFree;
239 CurCode = OldCode = Code = ReadCode();
240 FinChar = CurCode & DataMask;
241 AddToPixel((BYTE)FinChar);
242 } else {
243 /*
244 * If not a clear code, then must be data: save same as CurCode
245 * and InCode
246 */
247 CurCode = InCode = Code;
248
249 /*
250 * If greater or equal to FreeCode, not in the hash table yet;
251 * repeat the last character decoded
252 */
253 if (CurCode >= FreeCode) {
254 CurCode = OldCode;
255 OutCode[OutCount++] = FinChar;
256 }
257
258 /*
259 * Unless this code is raw data, pursue the chain poWORDed to by
260 * CurCode through the hash table to its end; each code in the
261 * chain puts its associated output code on the output queue.
262 */
263 while (CurCode > DataMask) {
264 if (OutCount >= 1024) {
265 /*return error message*/
266 }
267
268 OutCode[OutCount++] = Suffix[CurCode];
269 CurCode = Prefix[CurCode];
270 }
271
272 /* The last code in the chain is treated as raw data. */
273 FinChar = CurCode & DataMask;
274 OutCode[OutCount++] = FinChar;
275
276 /*
277 * Now we put the data out to the Output routine. It's been
278 * stacked LIFO, so deal with it that way...
279 */
280 for (i = OutCount - 1; i >= 0; i--)
281 AddToPixel((BYTE)OutCode[i]);
282
283 OutCount = 0;
284
285 /*
286 * Build the hash table on-the-fly. No table is stored in the
287 * file.
288 */
289 Prefix[FreeCode] = OldCode;
290 Suffix[FreeCode] = FinChar;
291 OldCode = InCode;
292
293 /*
294 * PoWORD to the next slot in the table. If we exceed the current
295 * MaxCode value, increment the code size unless it's already 12.
296 * If it is, do nothing: the next code decompressed better be
297 * CLEAR
298 */
299 FreeCode++;
300
301 if (FreeCode >= MaxCode)
302 if (CodeSize < 12) {
303 CodeSize++;
304 MaxCode *= 2;
305 ReadMask = (1 << CodeSize) - 1;
306 }
307 }
308
309 Code = ReadCode();
310 }
311
312 return Image;
313 }
314