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