Example #1
0
/*
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);
}
Example #2
0
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);
}
Example #3
0
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;
}
Example #4
0
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);
}
Example #5
0
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;
}