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