From 05c88cc1a6ab62f78ef9063838b851d46d2bb71a Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Wed, 5 Sep 2018 15:04:38 +0800 Subject: When decoding GIF, move pixmap into struct so it can be changed. This makes it possible to change the colorspace when encountering ICC colorspaces. --- source/fitz/load-gif.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'source') diff --git a/source/fitz/load-gif.c b/source/fitz/load-gif.c index ca73a537..ebd1d1b6 100644 --- a/source/fitz/load-gif.c +++ b/source/fitz/load-gif.c @@ -26,6 +26,8 @@ struct info int has_transparency; unsigned int transparent; unsigned char *mask; + + fz_pixmap *pix; }; /* default color table, where the first two entries are black and white */ @@ -212,10 +214,11 @@ gif_read_lct(fz_context *ctx, struct info *info, const unsigned char *p, const u } static void -gif_read_line(fz_context *ctx, struct info *info, unsigned char *dest, int ct_entries, const unsigned char *ct, unsigned int y, unsigned char *sp) +gif_read_line(fz_context *ctx, struct info *info, int ct_entries, const unsigned char *ct, unsigned int y, unsigned char *sp) { unsigned int index = (info->image_top + y) * info->width + info->image_left; - unsigned char *dp = &dest[index * 4]; + unsigned char *samples = fz_pixmap_samples(ctx, info->pix); + unsigned char *dp = &samples[index * 4]; unsigned char *mp = &info->mask[index]; unsigned int x, k; @@ -235,7 +238,7 @@ gif_read_line(fz_context *ctx, struct info *info, unsigned char *dest, int ct_en } static const unsigned char * -gif_read_tbid(fz_context *ctx, struct info *info, unsigned char *dest, const unsigned char *p, const unsigned char *end) +gif_read_tbid(fz_context *ctx, struct info *info, const unsigned char *p, const unsigned char *end) { fz_stream *stm = NULL, *lzwstm = NULL; unsigned int mincodesize, y; @@ -293,17 +296,17 @@ gif_read_tbid(fz_context *ctx, struct info *info, unsigned char *dest, const uns 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); + gif_read_line(ctx, info, 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); + gif_read_line(ctx, info, 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); + gif_read_line(ctx, info, 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); + gif_read_line(ctx, info, 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); + gif_read_line(ctx, info, ct_entries, ct, y, sp); } fz_always(ctx) { @@ -406,22 +409,21 @@ gif_read_ae(fz_context *ctx, struct info *info, const unsigned char *p, const un } static void -gif_mask_transparency(fz_context *ctx, fz_pixmap *image, struct info *info) +gif_mask_transparency(fz_context *ctx, struct info *info) { unsigned char *mp = info->mask; - unsigned char *dp = image->samples; + unsigned char *dp = fz_pixmap_samples(ctx, info->pix); unsigned int x, y; for (y = 0; y < info->height; y++) - for (x = 0; x < info->width; x++, mp++, dp += image->n) + for (x = 0; x < info->width; x++, mp++, dp += 4) if (*mp == 0x00) - dp[image->n - 1] = 0; + dp[3] = 0; } static fz_pixmap * gif_read_image(fz_context *ctx, struct info *info, const unsigned char *p, size_t total, int only_metadata) { - fz_pixmap *pix; const unsigned char *end = p + total; memset(info, 0x00, sizeof (*info)); @@ -435,7 +437,7 @@ gif_read_image(fz_context *ctx, struct info *info, const unsigned char *p, size_ if (only_metadata) return NULL; - pix = fz_new_pixmap(ctx, fz_device_rgb(ctx), info->width, info->height, NULL, 1); + info->pix = fz_new_pixmap(ctx, fz_device_rgb(ctx), info->width, info->height, NULL, 1); fz_try(ctx) { @@ -444,7 +446,7 @@ gif_read_image(fz_context *ctx, struct info *info, const unsigned char *p, size_ /* Read optional global color table */ if (info->has_gct) { - unsigned char *bp, *dp = pix->samples; + unsigned char *bp, *dp = fz_pixmap_samples(ctx, info->pix); unsigned int x, y, k; p = gif_read_gct(ctx, info, p, end); @@ -510,7 +512,7 @@ gif_read_image(fz_context *ctx, struct info *info, const unsigned char *p, size_ p = gif_read_lct(ctx, info, p, end); /* Read table based image data */ - p = gif_read_tbid(ctx, info, pix->samples, p, end); + p = gif_read_tbid(ctx, info, p, end); /* Graphic control extension applies only to the graphic rendering block following it */ info->transparent = 0; @@ -529,8 +531,8 @@ gif_read_image(fz_context *ctx, struct info *info, const unsigned char *p, size_ fz_throw(ctx, FZ_ERROR_GENERIC, "unsupported block indicator %02x in gif image", p[0]); } - gif_mask_transparency(ctx, pix, info); - fz_premultiply_pixmap(ctx, pix); + gif_mask_transparency(ctx, info); + fz_premultiply_pixmap(ctx, info->pix); } fz_always(ctx) { @@ -540,11 +542,11 @@ gif_read_image(fz_context *ctx, struct info *info, const unsigned char *p, size_ } fz_catch(ctx) { - fz_drop_pixmap(ctx, pix); + fz_drop_pixmap(ctx, info->pix); fz_rethrow(ctx); } - return pix; + return info->pix; } fz_pixmap * -- cgit v1.2.3