1 /* gifread.c - Functions to read GIFs.
2    Copyright (C) 1997-9 Eddie Kohler, eddietwo@lcs.mit.edu
3    This file is part of the GIF library.
4 
5    The GIF library is free software*. It is distributed under the GNU General
6    Public License, version 2 or later; you can copy, distribute, or alter it
7    at will, as long as this notice is kept intact and this source code is made
8    available. There is no warranty, express or implied.
9 
10    *The LZW compression method used by GIFs is patented. Unisys, the patent
11    holder, allows the compression algorithm to be used without a license in
12    software distributed at no cost to the user. */
13 
14 #ifdef HAVE_CONFIG_H
15 # include "config.h"
16 #elif !defined(__cplusplus)
17 /* Assume we don't have inline by default */
18 # define inline
19 #endif
20 #include "gif.h"
21 #include <stdarg.h>
22 #include <assert.h>
23 #include <string.h>
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 typedef struct {
29 
30   Gif_Stream *stream;
31 
32   Gif_Code *prefix;
33   byte *suffix;
34   u_int16_t *length;
35 
36   u_int16_t width;
37   u_int16_t height;
38 
39   byte *image;
40   byte *maximage;
41 
42   unsigned decodepos;
43 
44   Gif_ReadErrorHandler handler;
45   void *handler_thunk;
46 
47 } Gif_Context;
48 
49 
50 typedef struct Gif_Reader {
51 
52   FILE *f;
53   const byte *v;
54   u_int32_t w;
55   u_int32_t length;
56   int is_record;
57   int is_eoi;
58   byte (*byte_getter)(struct Gif_Reader *);
59   void (*block_getter)(byte *, u_int32_t, struct Gif_Reader *);
60   u_int32_t (*offseter)(struct Gif_Reader *);
61   int (*eofer)(struct Gif_Reader *);
62 
63 } Gif_Reader;
64 
65 
66 #define gifgetc(grr)	((char)(*grr->byte_getter)(grr))
67 #define gifgetbyte(grr) ((*grr->byte_getter)(grr))
68 #define gifgetblock(ptr, size, grr) ((*grr->block_getter)(ptr, size, grr))
69 #define gifgetoffset(grr) ((*grr->offseter)(grr))
70 #define gifeof(grr)	((*grr->eofer)(grr))
71 
72 static inline u_int16_t
gifgetunsigned(Gif_Reader * grr)73 gifgetunsigned(Gif_Reader *grr)
74 {
75   byte one = gifgetbyte(grr);
76   byte two = gifgetbyte(grr);
77   return one | (two << 8);
78 }
79 
80 
81 static byte
file_byte_getter(Gif_Reader * grr)82 file_byte_getter(Gif_Reader *grr)
83 {
84   int i = getc(grr->f);
85   return i == EOF ? 0 : (byte)i;
86 }
87 
88 static void
file_block_getter(byte * p,u_int32_t s,Gif_Reader * grr)89 file_block_getter(byte *p, u_int32_t s, Gif_Reader *grr)
90 {
91   fread(p, 1, s, grr->f);
92 }
93 
94 static u_int32_t
file_offseter(Gif_Reader * grr)95 file_offseter(Gif_Reader *grr)
96 {
97   return ftell(grr->f);
98 }
99 
100 static int
file_eofer(Gif_Reader * grr)101 file_eofer(Gif_Reader *grr)
102 {
103   return feof(grr->f);
104 }
105 
106 
107 static byte
record_byte_getter(Gif_Reader * grr)108 record_byte_getter(Gif_Reader *grr)
109 {
110   return grr->w ? (grr->w--, *grr->v++) : 0;
111 }
112 
113 static void
record_block_getter(byte * p,u_int32_t s,Gif_Reader * grr)114 record_block_getter(byte *p, u_int32_t s, Gif_Reader *grr)
115 {
116   if (s > grr->w) s = grr->w;
117   memcpy(p, grr->v, s);
118   grr->w -= s, grr->v += s;
119 }
120 
121 static u_int32_t
record_offseter(Gif_Reader * grr)122 record_offseter(Gif_Reader *grr)
123 {
124   return grr->length - grr->w;
125 }
126 
127 static int
record_eofer(Gif_Reader * grr)128 record_eofer(Gif_Reader *grr)
129 {
130   return grr->w == 0;
131 }
132 
133 
134 static void
make_data_reader(Gif_Reader * grr,const byte * data,u_int32_t length)135 make_data_reader(Gif_Reader *grr, const byte *data, u_int32_t length)
136 {
137   grr->v = data;
138   grr->length = length;
139   grr->w = length;
140   grr->is_record = 1;
141   grr->byte_getter = record_byte_getter;
142   grr->block_getter = record_block_getter;
143   grr->offseter = record_offseter;
144   grr->eofer = record_eofer;
145 }
146 
147 
148 static void
gif_read_error(Gif_Context * gfc,const char * error)149 gif_read_error(Gif_Context *gfc, const char *error)
150 {
151   gfc->stream->errors++;
152   if (gfc->handler)
153     gfc->handler(error, gfc->stream->nimages, gfc->handler_thunk);
154 }
155 
156 
157 static byte
one_code(Gif_Context * gfc,Gif_Code code)158 one_code(Gif_Context *gfc, Gif_Code code)
159 {
160   byte *suffixes = gfc->suffix;
161   Gif_Code *prefixes = gfc->prefix;
162   byte *ptr;
163   int lastsuffix;
164   u_int16_t codelength = gfc->length[code];
165 
166   gfc->decodepos += codelength;
167   ptr = gfc->image + gfc->decodepos;
168   if (ptr > gfc->maximage || !codelength) {
169     gif_read_error(gfc, (!codelength ? "bad code" : "too much image data"));
170     /* 5/26/98 It's not good enough simply to count an error, because in the
171        read_image_data function, if code == next_code, we will store a byte in
172        gfc->image[gfc->decodepos-1]. Thus, fix decodepos so it's w/in the
173        image. */
174     gfc->decodepos = gfc->maximage - gfc->image;
175     return 0;
176   }
177 
178   /* codelength will always be greater than 0. */
179   do {
180     lastsuffix = suffixes[code];
181     *--ptr = lastsuffix;
182     code = prefixes[code];
183   } while (--codelength > 0);
184 
185   /* return the first pixel in the code, which, since we walked backwards
186      through the code, was the last suffix we processed. */
187   return lastsuffix;
188 }
189 
190 static int
read_image_block(Gif_Reader * grr,byte * buffer,int * bit_pos_store,int * bit_len_store,int bits_needed)191 read_image_block(Gif_Reader *grr, byte *buffer, int *bit_pos_store,
192 		 int *bit_len_store, int bits_needed)
193 {
194   int bit_position = *bit_pos_store;
195   int bit_length = *bit_len_store;
196   byte block_len;
197 
198   while (bit_position + bits_needed > bit_length) {
199     /* Read in the next data block. */
200     if (bit_position >= 8) {
201       /* Need to shift down the upper, unused part of `buffer' */
202       int i = bit_position / 8;
203       buffer[0] = buffer[i];
204       buffer[1] = buffer[i+1];
205       bit_position -= i * 8;
206       bit_length -= i * 8;
207     }
208     block_len = gifgetbyte(grr);
209     GIF_DEBUG(("\nimage_block(%d)", block_len));
210     if (block_len == 0) return 0;
211     gifgetblock(buffer + bit_length / 8, block_len, grr);
212     bit_length += block_len * 8;
213   }
214 
215   *bit_pos_store = bit_position;
216   *bit_len_store = bit_length;
217   return 1;
218 }
219 
220 
221 static void
read_image_data(Gif_Context * gfc,Gif_Reader * grr)222 read_image_data(Gif_Context *gfc, Gif_Reader *grr)
223 {
224   /* we need a bit more than GIF_MAX_BLOCK in case a single code is split
225      across blocks */
226   byte buffer[GIF_MAX_BLOCK + 5];
227   int i;
228   u_int32_t accum;
229 
230   int bit_position;
231   int bit_length;
232 
233   Gif_Code code;
234   Gif_Code old_code;
235   Gif_Code clear_code;
236   Gif_Code eoi_code;
237   Gif_Code next_code;
238 #define CUR_BUMP_CODE (1 << bits_needed)
239 #define CUR_CODE_MASK ((1 << bits_needed) - 1)
240 
241   int min_code_size;
242   int bits_needed;
243 
244   gfc->decodepos = 0;
245 
246   min_code_size = gifgetbyte(grr);
247   GIF_DEBUG(("\n\nmin_code_size(%d)", min_code_size));
248   if (min_code_size >= GIF_MAX_CODE_BITS) {
249     gif_read_error(gfc, "min_code_size too big");
250     min_code_size = GIF_MAX_CODE_BITS - 1;
251   } else if (min_code_size < 2) {
252     gif_read_error(gfc, "min_code_size too small");
253     min_code_size = 2;
254   }
255   clear_code = 1 << min_code_size;
256   for (code = 0; code < clear_code; code++) {
257     gfc->prefix[code] = 49428;
258     gfc->suffix[code] = (byte)code;
259     gfc->length[code] = 1;
260   }
261   eoi_code = clear_code + 1;
262 
263   next_code = eoi_code;
264   bits_needed = min_code_size + 1;
265 
266   code = clear_code;
267 
268   bit_length = bit_position = 0;
269   /* Thus the `Read in the next data block.' code below will be invoked on the
270      first time through: exactly right! */
271 
272   while (1) {
273 
274     old_code = code;
275 
276     /* GET A CODE INTO THE `code' VARIABLE.
277      *
278      * 9.Dec.1998 - Rather than maintain a byte pointer and a bit offset into
279      * the current byte (and the processing associated with that), we maintain
280      * one number: the offset, in bits, from the beginning of `buffer'. This
281      * much cleaner choice was inspired by Patrick J. Naughton
282      * <naughton@wind.sun.com>'s GIF-reading code, which does the same thing.
283      * His code distributed as part of XV in xvgif.c. */
284 
285     if (bit_position + bits_needed > bit_length)
286       /* Read in the next data block. */
287       if (!read_image_block(grr, buffer, &bit_position, &bit_length,
288 			    bits_needed))
289 	goto zero_length_block;
290 
291     i = bit_position / 8;
292     accum = buffer[i] + (buffer[i+1] << 8);
293     if (bits_needed >= 8)
294       accum |= (buffer[i+2]) << 16;
295     code = (Gif_Code)((accum >> (bit_position % 8)) & CUR_CODE_MASK);
296     bit_position += bits_needed;
297 
298     GIF_DEBUG(("%d", code));
299 
300     /* CHECK FOR SPECIAL OR BAD CODES: clear_code, eoi_code, or a code that is
301      * too large. */
302     if (code == clear_code) {
303       bits_needed = min_code_size + 1;
304       next_code = eoi_code;
305       continue;
306 
307     } else if (code == eoi_code)
308       break;
309 
310     else if (code > next_code && next_code) {
311       /* code > next_code: a (hopefully recoverable) error.
312 
313 	 Bug fix, 5/27: Do this even if old_code == clear_code, and set code
314 	 to 0 to prevent errors later. (If we didn't zero code, we'd later set
315 	 old_code = code; then we had old_code >= next_code; so the prefixes
316 	 array got all screwed up!) */
317       gif_read_error(gfc, "unexpected code");
318       code = 0;
319     }
320 
321     /* PROCESS THE CURRENT CODE and define the next code. If no meaningful
322      * next code should be defined, then we have set next_code to either
323      * `eoi_code' or `clear_code' -- so we'll store useless prefix/suffix data
324      * in a useless place. */
325 
326     /* *First,* set up the prefix and length for the next code
327        (in case code == next_code). */
328     gfc->prefix[next_code] = old_code;
329     gfc->length[next_code] = gfc->length[old_code] + 1;
330 
331     /* Use one_code to process code. It's nice that it returns the first
332        pixel in code: that's what we need. */
333     gfc->suffix[next_code] = one_code(gfc, code);
334 
335     /* Special processing if code == next_code: we didn't know code's final
336        suffix when we called one_code, but we do now. */
337     if (code == next_code)
338       gfc->image[gfc->decodepos - 1] = gfc->suffix[next_code];
339 
340     /* Increment next_code except for the `clear_code' special case (that's
341        when we're reading at the end of a GIF) */
342     if (next_code != clear_code) {
343       next_code++;
344       if (next_code == CUR_BUMP_CODE) {
345 	if (bits_needed < GIF_MAX_CODE_BITS)
346 	  bits_needed++;
347 	else
348 	  next_code = clear_code;
349       }
350     }
351 
352   }
353 
354   /* read blocks until zero-length reached. */
355   i = gifgetbyte(grr);
356   GIF_DEBUG(("\nafter_image(%d)\n", i));
357   while (i > 0) {
358     gifgetblock(buffer, i, grr);
359     i = gifgetbyte(grr);
360     GIF_DEBUG(("\nafter_image(%d)\n", i));
361   }
362 
363   /* zero-length block reached. */
364  zero_length_block:
365 
366   if (gfc->image + gfc->decodepos < gfc->maximage)
367     gif_read_error(gfc, "not enough image data for image size");
368   else if (gfc->image + gfc->decodepos > gfc->maximage)
369     gif_read_error(gfc, "too much image data for image size");
370 }
371 
372 
373 static Gif_Colormap *
read_color_table(int size,Gif_Reader * grr)374 read_color_table(int size, Gif_Reader *grr)
375 {
376   Gif_Colormap *gfcm = Gif_NewFullColormap(size, size);
377   Gif_Color *c;
378   if (!gfcm) return 0;
379 
380   GIF_DEBUG(("colormap(%d)", size));
381   for (c = gfcm->col; size; size--, c++) {
382     c->red = gifgetbyte(grr);
383     c->green = gifgetbyte(grr);
384     c->blue = gifgetbyte(grr);
385     c->haspixel = 0;
386   }
387 
388   return gfcm;
389 }
390 
391 
392 static int
read_logical_screen_descriptor(Gif_Stream * gfs,Gif_Reader * grr)393 read_logical_screen_descriptor(Gif_Stream *gfs, Gif_Reader *grr)
394      /* returns 0 on memory error */
395 {
396   byte packed;
397 
398   /* we don't care about logical screen width or height */
399   gfs->screen_width = gifgetunsigned(grr);
400   gfs->screen_height = gifgetunsigned(grr);
401 
402   packed = gifgetbyte(grr);
403   gfs->background = gifgetbyte(grr);
404 
405   /* don't care about pixel aspect ratio */
406   gifgetbyte(grr);
407 
408   if (packed & 0x80) { /* have a global color table */
409     int ncol = 1 << ((packed & 0x07) + 1);
410     gfs->global = read_color_table(ncol, grr);
411     if (!gfs->global) return 0;
412     gfs->global->refcount = 1;
413   }
414 
415   return 1;
416 }
417 
418 
419 static int
read_compressed_image(Gif_Image * gfi,Gif_Reader * grr,int read_flags)420 read_compressed_image(Gif_Image *gfi, Gif_Reader *grr, int read_flags)
421 {
422   if (grr->is_record) {
423     const byte *first = grr->v;
424     u_int32_t pos;
425 
426     /* scan over image */
427     pos = 1;			/* skip min code size */
428     while (pos < grr->w) {
429       int amt = grr->v[pos];
430       pos += amt + 1;
431       if (amt == 0) break;
432     }
433     if (pos > grr->w) pos = grr->w;
434 
435     gfi->compressed_len = pos;
436     if (read_flags & GIF_READ_CONST_RECORD) {
437       gfi->compressed = (byte *)first;
438       gfi->free_compressed = 0;
439     } else {
440       gfi->compressed = Gif_NewArray(byte, gfi->compressed_len);
441       gfi->free_compressed = Gif_DeleteArrayFunc;
442       if (!gfi->compressed) return 0;
443       memcpy(gfi->compressed, first, gfi->compressed_len);
444     }
445 
446     /* move reader over that image */
447     grr->v += pos;
448     grr->w -= pos;
449 
450   } else {
451     /* non-record; have to read it block by block. */
452     u_int32_t comp_cap = 1024;
453     u_int32_t comp_len;
454     byte *comp = Gif_NewArray(byte, comp_cap);
455     int i;
456     if (!comp) return 0;
457 
458     /* min code size */
459     i = gifgetbyte(grr);
460     comp[0] = i;
461     comp_len = 1;
462 
463     i = gifgetbyte(grr);
464     while (i > 0) {
465       /* add 2 before check so we don't have to check after loop when appending
466 	 0 block */
467       if (comp_len + i + 2 > comp_cap) {
468 	comp_cap *= 2;
469 	Gif_ReArray(comp, byte, comp_cap);
470 	if (!comp) return 0;
471       }
472       comp[comp_len] = i;
473       gifgetblock(comp + comp_len + 1, i, grr);
474       comp_len += i + 1;
475       i = gifgetbyte(grr);
476     }
477     comp[comp_len++] = 0;
478 
479     gfi->compressed = comp;
480     gfi->compressed_len = comp_len;
481     gfi->free_compressed = Gif_DeleteArrayFunc;
482   }
483 
484   return 1;
485 }
486 
487 
488 static int
uncompress_image(Gif_Context * gfc,Gif_Image * gfi,Gif_Reader * grr)489 uncompress_image(Gif_Context *gfc, Gif_Image *gfi, Gif_Reader *grr)
490 {
491   if (!Gif_CreateUncompressedImage(gfi)) return 0;
492   gfc->width = gfi->width;
493   gfc->height = gfi->height;
494   gfc->image = gfi->image_data;
495   gfc->maximage = gfi->image_data + gfi->width * gfi->height;
496   read_image_data(gfc, grr);
497   return 1;
498 }
499 
500 
501 int
Gif_FullUncompressImage(Gif_Image * gfi,Gif_ReadErrorHandler h,void * hthunk)502 Gif_FullUncompressImage(Gif_Image *gfi, Gif_ReadErrorHandler h, void *hthunk)
503 {
504   Gif_Context gfc;
505   Gif_Stream fake_gfs;
506   Gif_Reader grr;
507   int ok = 0;
508 
509   /* return right away if image is already uncompressed. this might screw over
510      people who expect re-uncompressing to restore the compressed version. */
511   if (gfi->img)
512     return 1;
513   if (gfi->image_data)
514     /* we have uncompressed data, but not an `img' array;
515        this shouldn't happen */
516     return 0;
517 
518   fake_gfs.errors = 0;
519   gfc.stream = &fake_gfs;
520   gfc.prefix = Gif_NewArray(Gif_Code, GIF_MAX_CODE);
521   gfc.suffix = Gif_NewArray(byte, GIF_MAX_CODE);
522   gfc.length = Gif_NewArray(u_int16_t, GIF_MAX_CODE);
523   gfc.handler = h;
524   gfc.handler_thunk = hthunk;
525 
526   if (gfi && gfc.prefix && gfc.suffix && gfc.length && gfi->compressed) {
527     make_data_reader(&grr, gfi->compressed, gfi->compressed_len);
528     ok = uncompress_image(&gfc, gfi, &grr);
529   }
530 
531   Gif_DeleteArray(gfc.prefix);
532   Gif_DeleteArray(gfc.suffix);
533   Gif_DeleteArray(gfc.length);
534   return ok && !fake_gfs.errors;
535 }
536 
537 
538 static int
read_image(Gif_Reader * grr,Gif_Context * gfc,Gif_Image * gfi,int read_flags)539 read_image(Gif_Reader *grr, Gif_Context *gfc, Gif_Image *gfi, int read_flags)
540      /* returns 0 on memory error */
541 {
542   byte packed;
543 
544   gfi->left = gifgetunsigned(grr);
545   gfi->top = gifgetunsigned(grr);
546   gfi->width = gifgetunsigned(grr);
547   gfi->height = gifgetunsigned(grr);
548   packed = gifgetbyte(grr);
549   GIF_DEBUG(("<%ux%u>", gfi->width, gfi->height));
550 
551   if (packed & 0x80) { /* have a local color table */
552     int ncol = 1 << ((packed & 0x07) + 1);
553     gfi->local = read_color_table(ncol, grr);
554     if (!gfi->local) return 0;
555     gfi->local->refcount = 1;
556   }
557 
558   gfi->interlace = (packed & 0x40) != 0;
559 
560   /* Keep the compressed data if asked */
561   if (read_flags & GIF_READ_COMPRESSED) {
562     if (!read_compressed_image(gfi, grr, read_flags))
563       return 0;
564     if (read_flags & GIF_READ_UNCOMPRESSED) {
565       Gif_Reader new_grr;
566       make_data_reader(&new_grr, gfi->compressed, gfi->compressed_len);
567       if (!uncompress_image(gfc, gfi, &new_grr))
568 	return 0;
569     }
570 
571   } else if (read_flags & GIF_READ_UNCOMPRESSED) {
572     if (!uncompress_image(gfc, gfi, grr))
573       return 0;
574 
575   } else {
576     /* skip over the image */
577     byte buffer[GIF_MAX_BLOCK];
578     int i = gifgetbyte(grr);
579     while (i > 0) {
580       gifgetblock(buffer, i, grr);
581       i = gifgetbyte(grr);
582     }
583   }
584 
585   return 1;
586 }
587 
588 
589 static void
read_graphic_control_extension(Gif_Context * gfc,Gif_Image * gfi,Gif_Reader * grr)590 read_graphic_control_extension(Gif_Context *gfc, Gif_Image *gfi,
591 			       Gif_Reader *grr)
592 {
593   byte len;
594   byte crap[GIF_MAX_BLOCK];
595 
596   len = gifgetbyte(grr);
597 
598   if (len == 4) {
599     byte packed = gifgetbyte(grr);
600     gfi->disposal = (packed >> 2) & 0x07;
601     gfi->delay = gifgetunsigned(grr);
602     gfi->transparent = gifgetbyte(grr);
603     if (!(packed & 0x01)) /* transparent color doesn't exist */
604       gfi->transparent = -1;
605     len -= 4;
606   }
607 
608   if (len > 0) {
609     gif_read_error(gfc, "odd graphic extension format");
610     gifgetblock(crap, len, grr);
611   }
612 
613   len = gifgetbyte(grr);
614   while (len > 0) {
615     gif_read_error(gfc, "odd graphic extension format");
616     gifgetblock(crap, len, grr);
617     len = gifgetbyte(grr);
618   }
619 }
620 
621 
622 static char *last_name;
623 
624 
625 static char *
suck_data(char * data,int * store_len,Gif_Reader * grr)626 suck_data(char *data, int *store_len, Gif_Reader *grr)
627 {
628   byte len = gifgetbyte(grr);
629   int total_len = 0;
630 
631   while (len > 0) {
632     Gif_ReArray(data, char, total_len + len + 1);
633     if (!data) return 0;
634     gifgetblock((byte *)data, len, grr);
635 
636     total_len += len;
637     data[total_len] = 0;
638 
639     len = gifgetbyte(grr);
640   }
641 
642   if (store_len) *store_len = total_len;
643   return data;
644 }
645 
646 
647 static int
read_unknown_extension(Gif_Stream * gfs,int kind,char * app_name,int position,Gif_Reader * grr)648 read_unknown_extension(Gif_Stream *gfs, int kind, char *app_name, int position,
649 		       Gif_Reader *grr)
650 {
651   byte block_len = gifgetbyte(grr);
652   byte *data = 0;
653   byte data_len = 0;
654   Gif_Extension *gfex = 0;
655 
656   while (block_len > 0) {
657     if (data) Gif_ReArray(data, byte, data_len + block_len + 1);
658     else data = Gif_NewArray(byte, block_len + 1);
659     if (!data) goto done;
660     gifgetblock(data + data_len, block_len, grr);
661     data_len += block_len;
662     block_len = gifgetbyte(grr);
663   }
664 
665   if (data)
666     gfex = Gif_NewExtension(kind, app_name);
667   if (gfex) {
668     gfex->data = data;
669     gfex->length = data_len;
670     data[data_len] = 0;
671     Gif_AddExtension(gfs, gfex, position);
672   }
673 
674  done:
675   if (!gfex) Gif_DeleteArray(data);
676   while (block_len > 0) {
677     byte buffer[GIF_MAX_BLOCK];
678     gifgetblock(buffer, block_len, grr);
679     block_len = gifgetbyte(grr);
680   }
681   return gfex != 0;
682 }
683 
684 
685 static int
read_application_extension(Gif_Context * gfc,Gif_Image * gfi,int position,Gif_Reader * grr)686 read_application_extension(Gif_Context *gfc, Gif_Image *gfi, int position,
687 			   Gif_Reader *grr)
688 {
689   Gif_Stream *gfs = gfc->stream;
690   byte buffer[GIF_MAX_BLOCK + 1];
691   byte len = gifgetbyte(grr);
692   gifgetblock(buffer, len, grr);
693 
694   /* Read the Netscape loop extension. */
695   if (len == 11 && memcmp(buffer, "NETSCAPE2.0", 11) == 0) {
696 
697     len = gifgetbyte(grr);
698     if (len == 3) {
699       gifgetbyte(grr); /* throw away the 1 */
700       gfs->loopcount = gifgetunsigned(grr);
701       len = gifgetbyte(grr);
702       if (len) gif_read_error(gfc, "bad loop extension");
703     } else
704       gif_read_error(gfc, "bad loop extension");
705 
706     while (len > 0) {
707       gifgetblock(buffer, len, grr);
708       len = gifgetbyte(grr);
709     }
710     return 1;
711 
712   } else {
713     buffer[len] = 0;
714     return read_unknown_extension(gfs, 0xFF, (char *)buffer, position, grr);
715   }
716 }
717 
718 
719 static int
read_comment_extension(Gif_Image * gfi,Gif_Reader * grr)720 read_comment_extension(Gif_Image *gfi, Gif_Reader *grr)
721 {
722   int len;
723   Gif_Comment *gfcom = gfi->comment;
724   char *m = suck_data(0, &len, grr);
725   if (m) {
726     if (!gfcom)
727       gfcom = gfi->comment = Gif_NewComment();
728     if (!gfcom || !Gif_AddCommentTake(gfcom, m, len))
729       return 0;
730   }
731   return 1;
732 }
733 
734 
735 static Gif_Stream *
read_gif(Gif_Reader * grr,int read_flags,Gif_ReadErrorHandler handler,void * handler_thunk)736 read_gif(Gif_Reader *grr, int read_flags,
737 	 Gif_ReadErrorHandler handler, void *handler_thunk)
738 {
739   Gif_Stream *gfs;
740   Gif_Image *gfi;
741   Gif_Image *new_gfi;
742   Gif_Context gfc;
743   int extension_position = 0;
744   int unknown_block_type = 0;
745 
746   if (gifgetc(grr) != 'G' ||
747       gifgetc(grr) != 'I' ||
748       gifgetc(grr) != 'F')
749     return 0;
750   (void)gifgetc(grr);
751   (void)gifgetc(grr);
752   (void)gifgetc(grr);
753 
754   gfs = Gif_NewStream();
755   gfi = Gif_NewImage();
756 
757   gfc.stream = gfs;
758   gfc.prefix = Gif_NewArray(Gif_Code, GIF_MAX_CODE);
759   gfc.suffix = Gif_NewArray(byte, GIF_MAX_CODE);
760   gfc.length = Gif_NewArray(u_int16_t, GIF_MAX_CODE);
761   gfc.handler = handler;
762   gfc.handler_thunk = handler_thunk;
763 
764   if (!gfs || !gfi || !gfc.prefix || !gfc.suffix || !gfc.length)
765     goto done;
766 
767   GIF_DEBUG(("\nGIF"));
768   if (!read_logical_screen_descriptor(gfs, grr))
769     goto done;
770   GIF_DEBUG(("logscrdesc"));
771 
772   while (!gifeof(grr)) {
773 
774     byte block = gifgetbyte(grr);
775 
776     switch (block) {
777 
778      case ',': /* image block */
779       GIF_DEBUG(("imageread %d", gfs->nimages));
780 
781       gfi->identifier = last_name;
782       last_name = 0;
783       if (!read_image(grr, &gfc, gfi, read_flags)
784 	  || !Gif_AddImage(gfs, gfi)) {
785 	Gif_DeleteImage(gfi);
786 	goto done;
787       }
788 
789       new_gfi = Gif_NewImage();
790       if (!new_gfi) goto done;
791 
792       gfi = new_gfi;
793       extension_position++;
794       break;
795 
796      case ';': /* terminator */
797       GIF_DEBUG(("term\n"));
798       goto done;
799 
800      case '!': /* extension */
801       block = gifgetbyte(grr);
802       GIF_DEBUG(("ext(0x%02X)", block));
803       switch (block) {
804 
805        case 0xF9:
806 	read_graphic_control_extension(&gfc, gfi, grr);
807 	break;
808 
809        case 0xCE:
810 	last_name = suck_data(last_name, 0, grr);
811 	break;
812 
813        case 0xFE:
814 	if (!read_comment_extension(gfi, grr)) goto done;
815 	break;
816 
817        case 0xFF:
818 	read_application_extension(&gfc, gfi, extension_position, grr);
819 	break;
820 
821        default:
822 	read_unknown_extension(gfs, block, 0, extension_position, grr);
823 	break;
824 
825       }
826       break;
827 
828      default:
829        if (!unknown_block_type) {
830 	 char buf[256];
831 	 sprintf(buf, "unknown block type %d at file offset %d", block, gifgetoffset(grr) - 1);
832 	 gif_read_error(&gfc, buf);
833 	 unknown_block_type = 1;
834        }
835        break;
836 
837     }
838 
839   }
840 
841  done:
842 
843   /* Move comments after last image into stream. */
844   gfs->comment = gfi->comment;
845   gfi->comment = 0;
846 
847   Gif_DeleteImage(gfi);
848   Gif_DeleteArray(last_name);
849   Gif_DeleteArray(gfc.prefix);
850   Gif_DeleteArray(gfc.suffix);
851   Gif_DeleteArray(gfc.length);
852   return gfs;
853 }
854 
855 
856 Gif_Stream *
Gif_FullReadFile(FILE * f,int read_flags,Gif_ReadErrorHandler h,void * hthunk)857 Gif_FullReadFile(FILE *f, int read_flags,
858 		 Gif_ReadErrorHandler h, void *hthunk)
859 {
860   Gif_Reader grr;
861   if (!f) return 0;
862   grr.f = f;
863   grr.is_record = 0;
864   grr.byte_getter = file_byte_getter;
865   grr.block_getter = file_block_getter;
866   grr.offseter = file_offseter;
867   grr.eofer = file_eofer;
868   return read_gif(&grr, read_flags, h, hthunk);
869 }
870 
871 Gif_Stream *
Gif_FullReadRecord(const Gif_Record * gifrec,int read_flags,Gif_ReadErrorHandler h,void * hthunk)872 Gif_FullReadRecord(const Gif_Record *gifrec, int read_flags,
873 		   Gif_ReadErrorHandler h, void *hthunk)
874 {
875   Gif_Reader grr;
876   if (!gifrec) return 0;
877   make_data_reader(&grr, gifrec->data, gifrec->length);
878   if (read_flags & GIF_READ_CONST_RECORD)
879     read_flags |= GIF_READ_COMPRESSED;
880   return read_gif(&grr, read_flags, h, hthunk);
881 }
882 
883 
884 #undef Gif_ReadFile
885 #undef Gif_ReadRecord
886 
887 Gif_Stream *
Gif_ReadFile(FILE * f)888 Gif_ReadFile(FILE *f)
889 {
890   return Gif_FullReadFile(f, GIF_READ_UNCOMPRESSED, 0, 0);
891 }
892 
893 Gif_Stream *
Gif_ReadRecord(const Gif_Record * gifrec)894 Gif_ReadRecord(const Gif_Record *gifrec)
895 {
896   return Gif_FullReadRecord(gifrec, GIF_READ_UNCOMPRESSED, 0, 0);
897 }
898 
899 
900 #ifdef __cplusplus
901 }
902 #endif
903