summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2018-09-05 15:04:38 +0800
committerSebastian Rasmussen <sebras@gmail.com>2018-09-05 19:48:46 +0800
commit05c88cc1a6ab62f78ef9063838b851d46d2bb71a (patch)
treecf7fa118e8d31d2b296e43b9ee7294d036135f2a
parent5cd88798b95cf672f21a3296c673724a162ac1fa (diff)
downloadmupdf-05c88cc1a6ab62f78ef9063838b851d46d2bb71a.tar.xz
When decoding GIF, move pixmap into struct so it can be changed.
This makes it possible to change the colorspace when encountering ICC colorspaces.
-rw-r--r--source/fitz/load-gif.c42
1 files changed, 22 insertions, 20 deletions
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 *