summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2015-08-03 12:06:56 +0200
committerTor Andersson <tor.andersson@artifex.com>2015-08-20 11:22:56 +0200
commit574732c2534f5da73701fd322f72a5590bb32258 (patch)
tree111518787eecd64b5663abf6383c3ffec7a9fb7d /source
parenta58eed4ff202ef40c0fec931b2078d711bdd5890 (diff)
downloadmupdf-574732c2534f5da73701fd322f72a5590bb32258.tar.xz
Do not decode png image when getting image metadata.
Diffstat (limited to 'source')
-rw-r--r--source/fitz/load-png.c100
1 files changed, 54 insertions, 46 deletions
diff --git a/source/fitz/load-png.c b/source/fitz/load-png.c
index 9c947148..956827c0 100644
--- a/source/fitz/load-png.c
+++ b/source/fitz/load-png.c
@@ -367,7 +367,7 @@ png_read_phys(fz_context *ctx, struct info *info, unsigned char *p, unsigned int
}
static void
-png_read_image(fz_context *ctx, struct info *info, unsigned char *p, unsigned int total)
+png_read_image(fz_context *ctx, struct info *info, unsigned char *p, unsigned int total, int only_metadata)
{
unsigned int passw[7], passh[7], passofs[8];
unsigned int code, size;
@@ -401,31 +401,33 @@ png_read_image(fz_context *ctx, struct info *info, unsigned char *p, unsigned in
total -= size + 12;
/* Prepare output buffer */
-
- if (!info->interlace)
+ if (!only_metadata)
{
- info->size = info->height * (1 + (info->width * info->n * info->depth + 7) / 8);
- }
- else
- {
- png_deinterlace_passes(ctx, info, passw, passh, passofs);
- info->size = passofs[7];
- }
+ if (!info->interlace)
+ {
+ info->size = info->height * (1 + (info->width * info->n * info->depth + 7) / 8);
+ }
+ else
+ {
+ png_deinterlace_passes(ctx, info, passw, passh, passofs);
+ info->size = passofs[7];
+ }
- info->samples = fz_malloc(ctx, info->size);
+ info->samples = fz_malloc(ctx, info->size);
- stm.zalloc = zalloc;
- stm.zfree = zfree;
- stm.opaque = ctx;
+ stm.zalloc = zalloc;
+ stm.zfree = zfree;
+ stm.opaque = ctx;
- stm.next_out = info->samples;
- stm.avail_out = info->size;
+ stm.next_out = info->samples;
+ stm.avail_out = info->size;
- code = inflateInit(&stm);
- if (code != Z_OK)
- {
- fz_free(ctx, info->samples);
- fz_throw(ctx, FZ_ERROR_GENERIC, "zlib error: %s", stm.msg);
+ code = inflateInit(&stm);
+ if (code != Z_OK)
+ {
+ fz_free(ctx, info->samples);
+ fz_throw(ctx, FZ_ERROR_GENERIC, "zlib error: %s", stm.msg);
+ }
}
fz_try(ctx)
@@ -438,13 +440,13 @@ png_read_image(fz_context *ctx, struct info *info, unsigned char *p, unsigned in
if (total < 12 || size > total - 12)
fz_throw(ctx, FZ_ERROR_GENERIC, "premature end of data in png image");
- if (!memcmp(p + 4, "PLTE", 4))
+ if (!memcmp(p + 4, "PLTE", 4) && !only_metadata)
png_read_plte(ctx, info, p + 8, size);
- if (!memcmp(p + 4, "tRNS", 4))
+ if (!memcmp(p + 4, "tRNS", 4) && !only_metadata)
png_read_trns(ctx, info, p + 8, size);
if (!memcmp(p + 4, "pHYs", 4))
png_read_phys(ctx, info, p + 8, size);
- if (!memcmp(p + 4, "IDAT", 4))
+ if (!memcmp(p + 4, "IDAT", 4) && !only_metadata)
png_read_idat(ctx, info, p + 8, size, &stm);
if (!memcmp(p + 4, "IEND", 4))
break;
@@ -452,7 +454,7 @@ png_read_image(fz_context *ctx, struct info *info, unsigned char *p, unsigned in
p += size + 12;
total -= size + 12;
}
- if (stm.avail_out != 0)
+ if (stm.avail_out != 0 && !only_metadata)
{
memset(stm.next_out, 0xff, stm.avail_out);
fz_warn(ctx, "missing pixel data in png image; possibly truncated");
@@ -462,30 +464,36 @@ png_read_image(fz_context *ctx, struct info *info, unsigned char *p, unsigned in
}
fz_catch(ctx)
{
- inflateEnd(&stm);
- fz_free(ctx, info->samples);
+ if (!only_metadata)
+ {
+ inflateEnd(&stm);
+ fz_free(ctx, info->samples);
+ }
fz_rethrow(ctx);
}
- code = inflateEnd(&stm);
- if (code != Z_OK)
+ if (!only_metadata)
{
- fz_free(ctx, info->samples);
- fz_throw(ctx, FZ_ERROR_GENERIC, "zlib error: %s", stm.msg);
- }
+ code = inflateEnd(&stm);
+ if (code != Z_OK)
+ {
+ fz_free(ctx, info->samples);
+ fz_throw(ctx, FZ_ERROR_GENERIC, "zlib error: %s", stm.msg);
+ }
- /* Apply prediction filter and deinterlacing */
- fz_try(ctx)
- {
- if (!info->interlace)
- png_predict(info->samples, info->width, info->height, info->n, info->depth);
- else
- png_deinterlace(ctx, info, passw, passh, passofs);
- }
- fz_catch(ctx)
- {
- fz_free(ctx, info->samples);
- fz_rethrow(ctx);
+ /* Apply prediction filter and deinterlacing */
+ fz_try(ctx)
+ {
+ if (!info->interlace)
+ png_predict(info->samples, info->width, info->height, info->n, info->depth);
+ else
+ png_deinterlace(ctx, info, passw, passh, passofs);
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, info->samples);
+ fz_rethrow(ctx);
+ }
}
}
@@ -549,7 +557,7 @@ fz_load_png(fz_context *ctx, unsigned char *p, int total)
struct info png;
int stride;
- png_read_image(ctx, &png, p, total);
+ png_read_image(ctx, &png, p, total, 0);
if (png.n == 3 || png.n == 4)
colorspace = fz_device_rgb(ctx);
@@ -602,7 +610,7 @@ fz_load_png_info(fz_context *ctx, unsigned char *p, int total, int *wp, int *hp,
{
struct info png;
- png_read_image(ctx, &png, p, total);
+ png_read_image(ctx, &png, p, total, 1);
if (png.n == 3 || png.n == 4)
*cspacep = fz_device_rgb(ctx);