/* NETSCAPE2.0 http://odur.let.rug.nl/~kleiweg/gif/netscape.html http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension http://www.vurdalakov.net/misc/gif/netscape-buffering-application-extension https://code.google.com/p/gifdotnet/source/browse/src/GifDotNet/GifApplicationExtensionBlock.cs#95 http://trac.webkit.org/browser/trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp#L617 ANIMEXTS1.0 http://www.vurdalakov.net/misc/gif/animexts-looping-application-extension https://code.google.com/p/gifdotnet/source/browse/src/GifDotNet/GifApplicationExtensionBlock.cs#95 ICCRGBG1012 http://www.color.org/icc1V42.pdf XMP DataXMP http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart3.pdf fractint http://fractint.net/fractsvn/trunk/fractint/common/loadfile.c ZGATEXTI5 ZGATILEI5 ZGACTRLI5 ZGANPIMGI5 ZGAVECTI5 ZGAALPHAI5 ZGATITLE4.0 ZGATEXTI4.0 Zoner GIF animator 4.0 and 5.0 */ static unsigned char * gif_read_ae(fz_context *ctx, struct info *info, unsigned char *p, unsigned char *end) { static char *ignorable[] = { "NETSACPE2.0", "ANIMEXTS1.0", "ICCRGBG1012", "XMP DataXMP", "ZGATEXTI5\0\0", "ZGATILEI5\0\0", "ZGANPIMGI5\0", "ZGACTRLI5\0\0", "ZGAVECTI5\0\0", "ZGAALPHAI5\0", "ZGATITLE4.0", "ZGATEXTI4.0", }; int i, ignored; if (end - p < 14) fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in application extension in gif image"); if (p[2] != 0x0b) fz_throw(ctx, FZ_ERROR_GENERIC, "out of range application extension block size in gif image"); ignored = 0; for (i = 0; i < nelem(ignorable); i++) ignored |= memcmp(&p[3], ignorable[i], 8 + 3); if (!ignored) { char extension[9]; memmove(extension, &p[3], 8); extension[8] = '\0'; fz_warn(ctx, "ignoring unsupported application extension '%s' in gif image", extension); } return gif_read_subblocks(ctx, info, p + 14, end, NULL); }
static unsigned char* gif_read_pte(fz_context *ctx, struct info *info, unsigned char *p, unsigned char *end) { if (end - p < 15) fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in plain text extension in gif image"); if (p[2] != 0x0c) fz_throw(ctx, FZ_ERROR_GENERIC, "out of range plain text extension block size in gif image"); return gif_read_subblocks(ctx, info, p + 15, end, NULL); }
static unsigned char * gif_read_tbid(fz_context *ctx, struct info *info, unsigned char *dest, unsigned char *p, unsigned char *end) { fz_stream *stm, *lzwstm = NULL; unsigned int mincodesize, y; fz_buffer *compressed = NULL, *uncompressed = NULL; const unsigned char *ct; unsigned char *sp; if (end - p < 1) fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in table based image data in gif image"); mincodesize = *p; fz_var(compressed); fz_var(lzwstm); fz_var(uncompressed); fz_try(ctx) { compressed = fz_new_buffer(ctx, 0); p = gif_read_subblocks(ctx, info, p + 1, end, compressed); stm = fz_open_buffer(ctx, compressed); lzwstm = fz_open_lzwd(ctx, stm, 0, mincodesize + 1, 1, 0); uncompressed = fz_read_all(ctx, lzwstm, info->width * info->height); sp = uncompressed->data; if (info->has_lct) ct = info->lct; else if (info->has_gct) ct = info->gct; else ct = dct; if (info->image_interlaced) { for (y = 0; y < info->image_height; y += 8, sp += info->image_width) gif_read_line(ctx, info, dest, ct, y, sp); for (y = 4; y < info->image_height; y += 8, sp += info->image_width) gif_read_line(ctx, info, dest, ct, y, sp); for (y = 2; y < info->image_height; y += 4, sp += info->image_width) gif_read_line(ctx, info, dest, ct, y, sp); for (y = 1; y < info->image_height; y += 2, sp += info->image_width) gif_read_line(ctx, info, dest, ct, y, sp); } else for (y = 0; y < info->image_height; y++, sp += info->image_width) gif_read_line(ctx, info, dest, ct, y, sp); } fz_always(ctx) { fz_drop_buffer(ctx, uncompressed); fz_drop_buffer(ctx, compressed); fz_drop_stream(ctx, lzwstm); } fz_catch(ctx) { fz_rethrow(ctx); } return p; }
static unsigned char * gif_read_ce(fz_context *ctx, struct info *info, unsigned char *p, unsigned char *end) { return gif_read_subblocks(ctx, info, p + 2, end, NULL); }
static const unsigned char * gif_read_tbid(fz_context *ctx, struct info *info, unsigned char *dest, const unsigned char *p, const unsigned char *end) { fz_stream *stm, *lzwstm = NULL; unsigned int mincodesize, y; fz_buffer *compressed = NULL, *uncompressed = NULL; const unsigned char *ct; unsigned char *sp; int ct_entries; if (end - p < 1) fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in table based image data in gif image"); mincodesize = *p; /* if there is no overlap, avoid pasting image data, just consume it */ if (info->image_top >= info->height || info->image_left >= info->width) { p = gif_read_subblocks(ctx, info, p + 1, end, NULL); return p; } fz_var(compressed); fz_var(lzwstm); fz_var(uncompressed); fz_try(ctx) { compressed = fz_new_buffer(ctx, 0); p = gif_read_subblocks(ctx, info, p + 1, end, compressed); stm = fz_open_buffer(ctx, compressed); lzwstm = fz_open_lzwd(ctx, stm, 0, mincodesize + 1, 1, 1); uncompressed = fz_read_all(ctx, lzwstm, 0); if (uncompressed->len < info->image_width * info->image_height) fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in compressed table based image data in gif image"); if (info->has_lct) { ct = info->lct; ct_entries = info->lct_entries; } else if (info->has_gct) { ct = info->gct; ct_entries = info->gct_entries; } else { ct = dct; ct_entries = 256; } sp = uncompressed->data; if (info->image_interlaced) { for (y = 0; y < info->image_height; y += 8, sp += info->image_width) gif_read_line(ctx, info, dest, ct_entries, ct, y, sp); for (y = 4; y < info->image_height; y += 8, sp += info->image_width) gif_read_line(ctx, info, dest, ct_entries, ct, y, sp); for (y = 2; y < info->image_height; y += 4, sp += info->image_width) gif_read_line(ctx, info, dest, ct_entries, ct, y, sp); for (y = 1; y < info->image_height; y += 2, sp += info->image_width) gif_read_line(ctx, info, dest, ct_entries, ct, y, sp); } else for (y = 0; y < info->image_height; y++, sp += info->image_width) gif_read_line(ctx, info, dest, ct_entries, ct, y, sp); } fz_always(ctx) { fz_drop_buffer(ctx, uncompressed); fz_drop_buffer(ctx, compressed); fz_drop_stream(ctx, lzwstm); } fz_catch(ctx) { fz_rethrow(ctx); } return p; }