summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2018-03-28 15:17:27 +0200
committerTor Andersson <tor.andersson@artifex.com>2018-04-03 21:21:44 +0200
commitef3cfb2a49b5be82d56d783f505319754dc65cb8 (patch)
treef299436312d6230c08289b61e9bad51a4dd31681
parentd9f0fdfe1ac986816a3376ee0271f84fb549b0bf (diff)
downloadmupdf-ef3cfb2a49b5be82d56d783f505319754dc65cb8.tar.xz
Don't implicitly drop in fz_open_* chained filters.
-rw-r--r--source/fitz/compressed-buffer.c130
-rw-r--r--source/fitz/filter-basic.c148
-rw-r--r--source/fitz/filter-dct.c30
-rw-r--r--source/fitz/filter-fax.c22
-rw-r--r--source/fitz/filter-flate.c38
-rw-r--r--source/fitz/filter-jbig2.c23
-rw-r--r--source/fitz/filter-leech.c21
-rw-r--r--source/fitz/filter-lzw.c74
-rw-r--r--source/fitz/filter-predict.c52
-rw-r--r--source/fitz/filter-sgi.c14
-rw-r--r--source/fitz/filter-thunder.c14
-rw-r--r--source/fitz/image.c27
-rw-r--r--source/fitz/load-gif.c4
-rw-r--r--source/fitz/load-png.c16
-rw-r--r--source/fitz/load-tiff.c7
-rw-r--r--source/fitz/stream-open.c2
-rw-r--r--source/gprf/gprf-doc.c12
-rw-r--r--source/pdf/pdf-crypt.c26
-rw-r--r--source/pdf/pdf-form.c2
-rw-r--r--source/pdf/pdf-stream.c287
20 files changed, 403 insertions, 546 deletions
diff --git a/source/fitz/compressed-buffer.c b/source/fitz/compressed-buffer.c
index 3846fcb2..e8ea08e0 100644
--- a/source/fitz/compressed-buffer.c
+++ b/source/fitz/compressed-buffer.c
@@ -6,77 +6,115 @@
void
fz_drop_compressed_buffer(fz_context *ctx, fz_compressed_buffer *buf)
{
- if (!buf)
- return;
-
- fz_drop_buffer(ctx, buf->buffer);
- fz_free(ctx, buf);
+ if (buf)
+ {
+ fz_drop_buffer(ctx, buf->buffer);
+ fz_free(ctx, buf);
+ }
}
fz_stream *
fz_open_image_decomp_stream_from_buffer(fz_context *ctx, fz_compressed_buffer *buffer, int *l2factor)
{
- fz_stream *chain = fz_open_buffer(ctx, buffer->buffer);
+ fz_stream *head, *tail;
- return fz_open_image_decomp_stream(ctx, chain, &buffer->params, l2factor);
+ tail = fz_open_buffer(ctx, buffer->buffer);
+ fz_try(ctx)
+ head = fz_open_image_decomp_stream(ctx, tail, &buffer->params, l2factor);
+ fz_always(ctx)
+ fz_drop_stream(ctx, tail);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+ return head;
}
fz_stream *
-fz_open_image_decomp_stream(fz_context *ctx, fz_stream *chain, fz_compression_params *params, int *l2factor)
+fz_open_image_decomp_stream(fz_context *ctx, fz_stream *tail, fz_compression_params *params, int *l2factor)
{
+ fz_stream *head = NULL, *body = NULL;
int our_l2factor = 0;
- switch (params->type)
+ fz_var(body);
+
+ fz_try(ctx)
{
- case FZ_IMAGE_FAX:
- return fz_open_faxd(ctx, chain,
- params->u.fax.k,
- params->u.fax.end_of_line,
- params->u.fax.encoded_byte_align,
- params->u.fax.columns,
- params->u.fax.rows,
- params->u.fax.end_of_block,
- params->u.fax.black_is_1);
- case FZ_IMAGE_JPEG:
- if (l2factor)
+ switch (params->type)
{
- our_l2factor = *l2factor;
- if (our_l2factor > 3)
- our_l2factor = 3;
- *l2factor -= our_l2factor;
+ default:
+ head = fz_keep_stream(ctx, tail);
+ break;
+
+ case FZ_IMAGE_FAX:
+ head = fz_open_faxd(ctx, tail,
+ params->u.fax.k,
+ params->u.fax.end_of_line,
+ params->u.fax.encoded_byte_align,
+ params->u.fax.columns,
+ params->u.fax.rows,
+ params->u.fax.end_of_block,
+ params->u.fax.black_is_1);
+ break;
+
+ case FZ_IMAGE_JPEG:
+ if (l2factor)
+ {
+ our_l2factor = *l2factor;
+ if (our_l2factor > 3)
+ our_l2factor = 3;
+ *l2factor -= our_l2factor;
+ }
+ head = fz_open_dctd(ctx, tail, params->u.jpeg.color_transform, our_l2factor, NULL);
+ break;
+
+ case FZ_IMAGE_RLD:
+ head = fz_open_rld(ctx, tail);
+ break;
+
+ case FZ_IMAGE_FLATE:
+ head = fz_open_flated(ctx, tail, 15);
+ if (params->u.flate.predictor > 1)
+ {
+ body = head;
+ head = fz_open_predict(ctx, body,
+ params->u.flate.predictor,
+ params->u.flate.columns,
+ params->u.flate.colors,
+ params->u.flate.bpc);
+ }
+ break;
+
+ case FZ_IMAGE_LZW:
+ head = fz_open_lzwd(ctx, tail, params->u.lzw.early_change, 9, 0, 0);
+ if (params->u.flate.predictor > 1)
+ {
+ body = head;
+ head = fz_open_predict(ctx, body,
+ params->u.lzw.predictor,
+ params->u.lzw.columns,
+ params->u.lzw.colors,
+ params->u.lzw.bpc);
+ }
+ break;
}
- return fz_open_dctd(ctx, chain, params->u.jpeg.color_transform, our_l2factor, NULL);
- case FZ_IMAGE_RLD:
- return fz_open_rld(ctx, chain);
- case FZ_IMAGE_FLATE:
- chain = fz_open_flated(ctx, chain, 15);
- if (params->u.flate.predictor > 1)
- chain = fz_open_predict(ctx, chain, params->u.flate.predictor, params->u.flate.columns, params->u.flate.colors, params->u.flate.bpc);
- return chain;
- case FZ_IMAGE_LZW:
- chain = fz_open_lzwd(ctx, chain, params->u.lzw.early_change, 9, 0, 0);
- if (params->u.lzw.predictor > 1)
- chain = fz_open_predict(ctx, chain, params->u.lzw.predictor, params->u.lzw.columns, params->u.lzw.colors, params->u.lzw.bpc);
- return chain;
- default:
- break;
}
+ fz_always(ctx)
+ fz_drop_stream(ctx, body);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
- return chain;
+ return head;
}
fz_stream *
fz_open_compressed_buffer(fz_context *ctx, fz_compressed_buffer *buffer)
{
- int l2factor = 0;
-
- return fz_open_image_decomp_stream_from_buffer(ctx, buffer, &l2factor);
+ return fz_open_image_decomp_stream_from_buffer(ctx, buffer, NULL);
}
size_t
fz_compressed_buffer_size(fz_compressed_buffer *buffer)
{
- if (!buffer || !buffer->buffer)
- return 0;
- return (size_t)buffer->buffer->cap;
+ if (buffer && buffer->buffer)
+ return (size_t)buffer->buffer->cap;
+ return 0;
}
diff --git a/source/fitz/filter-basic.c b/source/fitz/filter-basic.c
index e5d7a4e4..f558f43b 100644
--- a/source/fitz/filter-basic.c
+++ b/source/fitz/filter-basic.c
@@ -60,10 +60,9 @@ static void
close_null(fz_context *ctx, void *state_)
{
struct null_filter *state = (struct null_filter *)state_;
- fz_stream *chain = state->chain;
+ fz_drop_stream(ctx, state->chain);
fz_free(ctx, state->ranges);
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
}
fz_stream *
@@ -71,23 +70,32 @@ fz_open_null_n(fz_context *ctx, fz_stream *chain, fz_range *ranges, int nranges)
{
struct null_filter *state = NULL;
- fz_var(state);
+ state = fz_malloc_struct(ctx, struct null_filter);
fz_try(ctx)
{
- state = fz_malloc_struct(ctx, struct null_filter);
- state->ranges = fz_calloc(ctx, nranges, sizeof(*ranges));
- memcpy(state->ranges, ranges, nranges * sizeof(*ranges));
- state->nranges = nranges;
- state->next_range = 1;
- state->chain = chain;
- state->remain = nranges ? ranges[0].len : 0;
- state->offset = nranges ? ranges[0].offset : 0;
+ if (nranges > 0)
+ {
+ state->ranges = fz_calloc(ctx, nranges, sizeof(*ranges));
+ memcpy(state->ranges, ranges, nranges * sizeof(*ranges));
+ state->nranges = nranges;
+ state->next_range = 1;
+ state->remain = ranges[0].len;
+ state->offset = ranges[0].offset;
+ }
+ else
+ {
+ state->ranges = NULL;
+ state->nranges = 0;
+ state->next_range = 1;
+ state->remain = 0;
+ state->offset = 0;
+ }
+ state->chain = fz_keep_stream(ctx, chain);
}
fz_catch(ctx)
{
fz_free(ctx, state->ranges);
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
fz_rethrow(ctx);
}
@@ -303,28 +311,16 @@ static void
close_ahxd(fz_context *ctx, void *state_)
{
fz_ahxd *state = (fz_ahxd *)state_;
- fz_stream *chain = state->chain;
+ fz_drop_stream(ctx, state->chain);
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
}
fz_stream *
fz_open_ahxd(fz_context *ctx, fz_stream *chain)
{
- fz_ahxd *state = NULL;
-
- fz_try(ctx)
- {
- state = fz_malloc_struct(ctx, fz_ahxd);
- state->chain = chain;
- state->eod = 0;
- }
- fz_catch(ctx)
- {
- fz_drop_stream(ctx, chain);
- fz_rethrow(ctx);
- }
-
+ fz_ahxd *state = fz_malloc_struct(ctx, fz_ahxd);
+ state->chain = fz_keep_stream(ctx, chain);
+ state->eod = 0;
return fz_new_stream(ctx, state, next_ahxd, close_ahxd);
}
@@ -446,29 +442,16 @@ static void
close_a85d(fz_context *ctx, void *state_)
{
fz_a85d *state = (fz_a85d *)state_;
- fz_stream *chain = state->chain;
-
+ fz_drop_stream(ctx, state->chain);
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
}
fz_stream *
fz_open_a85d(fz_context *ctx, fz_stream *chain)
{
- fz_a85d *state = NULL;
-
- fz_try(ctx)
- {
- state = fz_malloc_struct(ctx, fz_a85d);
- state->chain = chain;
- state->eod = 0;
- }
- fz_catch(ctx)
- {
- fz_drop_stream(ctx, chain);
- fz_rethrow(ctx);
- }
-
+ fz_a85d *state = fz_malloc_struct(ctx, fz_a85d);
+ state->chain = fz_keep_stream(ctx, chain);
+ state->eod = 0;
return fz_new_stream(ctx, state, next_a85d, close_a85d);
}
@@ -557,31 +540,18 @@ static void
close_rld(fz_context *ctx, void *state_)
{
fz_rld *state = (fz_rld *)state_;
- fz_stream *chain = state->chain;
-
+ fz_drop_stream(ctx, state->chain);
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
}
fz_stream *
fz_open_rld(fz_context *ctx, fz_stream *chain)
{
- fz_rld *state = NULL;
-
- fz_try(ctx)
- {
- state = fz_malloc_struct(ctx, fz_rld);
- state->chain = chain;
- state->run = 0;
- state->n = 0;
- state->c = 0;
- }
- fz_catch(ctx)
- {
- fz_drop_stream(ctx, chain);
- fz_rethrow(ctx);
- }
-
+ fz_rld *state = fz_malloc_struct(ctx, fz_rld);
+ state->chain = fz_keep_stream(ctx, chain);
+ state->run = 0;
+ state->n = 0;
+ state->c = 0;
return fz_new_stream(ctx, state, next_rld, close_rld);
}
@@ -620,29 +590,16 @@ static void
close_arc4(fz_context *ctx, void *state_)
{
fz_arc4c *state = (fz_arc4c *)state_;
- fz_stream *chain = state->chain;
-
+ fz_drop_stream(ctx, state->chain);
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
}
fz_stream *
fz_open_arc4(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen)
{
- fz_arc4c *state = NULL;
-
- fz_try(ctx)
- {
- state = fz_malloc_struct(ctx, fz_arc4c);
- state->chain = chain;
- fz_arc4_init(&state->arc4, key, keylen);
- }
- fz_catch(ctx)
- {
- fz_drop_stream(ctx, chain);
- fz_rethrow(ctx);
- }
-
+ fz_arc4c *state = fz_malloc_struct(ctx, fz_arc4c);
+ state->chain = fz_keep_stream(ctx, chain);
+ fz_arc4_init(&state->arc4, key, keylen);
return fz_new_stream(ctx, state, next_arc4, close_arc4);
}
@@ -722,35 +679,22 @@ static void
close_aesd(fz_context *ctx, void *state_)
{
fz_aesd *state = (fz_aesd *)state_;
- fz_stream *chain = state->chain;
-
+ fz_drop_stream(ctx, state->chain);
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
}
fz_stream *
fz_open_aesd(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen)
{
- fz_aesd *state = NULL;
-
- fz_var(state);
-
- fz_try(ctx)
- {
- state = fz_malloc_struct(ctx, fz_aesd);
- state->chain = chain;
- if (fz_aes_setkey_dec(&state->aes, key, keylen * 8))
- fz_throw(ctx, FZ_ERROR_GENERIC, "AES key init failed (keylen=%d)", keylen * 8);
- state->ivcount = 0;
- state->rp = state->bp;
- state->wp = state->bp;
- }
- fz_catch(ctx)
+ fz_aesd *state = fz_malloc_struct(ctx, fz_aesd);
+ if (fz_aes_setkey_dec(&state->aes, key, keylen * 8))
{
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
- fz_rethrow(ctx);
+ fz_throw(ctx, FZ_ERROR_GENERIC, "AES key init failed (keylen=%d)", keylen * 8);
}
-
+ state->ivcount = 0;
+ state->rp = state->bp;
+ state->wp = state->bp;
+ state->chain = fz_keep_stream(ctx, chain);
return fz_new_stream(ctx, state, next_aesd, close_aesd);
}
diff --git a/source/fitz/filter-dct.c b/source/fitz/filter-dct.c
index 644d0dfc..a3ada67e 100644
--- a/source/fitz/filter-dct.c
+++ b/source/fitz/filter-dct.c
@@ -317,29 +317,17 @@ skip:
fz_stream *
fz_open_dctd(fz_context *ctx, fz_stream *chain, int color_transform, int l2factor, fz_stream *jpegtables)
{
- fz_dctd *state = NULL;
+ fz_dctd *state = fz_malloc_struct(ctx, fz_dctd);
- fz_var(state);
+ state->ctx = ctx;
+ state->color_transform = color_transform;
+ state->init = 0;
+ state->l2factor = l2factor;
+ state->cinfo.client_data = NULL;
- fz_try(ctx)
- {
- state = fz_malloc_struct(ctx, fz_dctd);
- state->ctx = ctx;
- state->chain = chain;
- state->jpegtables = jpegtables;
- state->curr_stm = chain;
- state->color_transform = color_transform;
- state->init = 0;
- state->l2factor = l2factor;
- state->cinfo.client_data = NULL;
- }
- fz_catch(ctx)
- {
- fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
- fz_drop_stream(ctx, jpegtables);
- fz_rethrow(ctx);
- }
+ state->chain = fz_keep_stream(ctx, chain);
+ state->jpegtables = fz_keep_stream(ctx, jpegtables);
+ state->curr_stm = state->chain;
return fz_new_stream(ctx, state, next_dctd, close_dctd);
}
diff --git a/source/fitz/filter-fax.c b/source/fitz/filter-fax.c
index a4ca8ab5..ae117029 100644
--- a/source/fitz/filter-fax.c
+++ b/source/fitz/filter-fax.c
@@ -775,18 +775,14 @@ fz_open_faxd(fz_context *ctx, fz_stream *chain,
int k, int end_of_line, int encoded_byte_align,
int columns, int rows, int end_of_block, int black_is_1)
{
- fz_faxd *fax = NULL;
+ fz_faxd *fax;
- fz_var(fax);
+ if (columns < 0 || columns >= INT_MAX - 7)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "too many columns lead to an integer overflow (%d)", columns);
+ fax = fz_malloc_struct(ctx, fz_faxd);
fz_try(ctx)
{
- if (columns < 0 || columns >= INT_MAX - 7)
- fz_throw(ctx, FZ_ERROR_GENERIC, "too many columns lead to an integer overflow (%d)", columns);
-
- fax = fz_malloc_struct(ctx, fz_faxd);
- fax->chain = chain;
-
fax->ref = NULL;
fax->dst = NULL;
@@ -816,16 +812,14 @@ fz_open_faxd(fz_context *ctx, fz_stream *chain,
memset(fax->ref, 0, fax->stride);
memset(fax->dst, 0, fax->stride);
+
+ fax->chain = fz_keep_stream(ctx, chain);
}
fz_catch(ctx)
{
- if (fax)
- {
- fz_free(ctx, fax->dst);
- fz_free(ctx, fax->ref);
- }
+ fz_free(ctx, fax->dst);
+ fz_free(ctx, fax->ref);
fz_free(ctx, fax);
- fz_drop_stream(ctx, chain);
fz_rethrow(ctx);
}
diff --git a/source/fitz/filter-flate.c b/source/fitz/filter-flate.c
index a7bbb273..b986a228 100644
--- a/source/fitz/filter-flate.c
+++ b/source/fitz/filter-flate.c
@@ -102,34 +102,24 @@ close_flated(fz_context *ctx, void *state_)
fz_stream *
fz_open_flated(fz_context *ctx, fz_stream *chain, int window_bits)
{
- fz_inflate_state *state = NULL;
- int code = Z_OK;
+ fz_inflate_state *state;
+ int code;
- fz_var(code);
- fz_var(state);
+ state = fz_malloc_struct(ctx, fz_inflate_state);
+ state->z.zalloc = zalloc_flate;
+ state->z.zfree = zfree_flate;
+ state->z.opaque = ctx;
+ state->z.next_in = NULL;
+ state->z.avail_in = 0;
- fz_try(ctx)
- {
- state = fz_malloc_struct(ctx, fz_inflate_state);
- state->chain = chain;
-
- state->z.zalloc = zalloc_flate;
- state->z.zfree = zfree_flate;
- state->z.opaque = ctx;
- state->z.next_in = NULL;
- state->z.avail_in = 0;
-
- code = inflateInit2(&state->z, window_bits);
- if (code != Z_OK)
- fz_throw(ctx, FZ_ERROR_GENERIC, "zlib error: inflateInit: %s", state->z.msg);
- }
- fz_catch(ctx)
+ code = inflateInit2(&state->z, window_bits);
+ if (code != Z_OK)
{
- if (state && code == Z_OK)
- inflateEnd(&state->z);
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
- fz_rethrow(ctx);
+ fz_throw(ctx, FZ_ERROR_GENERIC, "zlib error: inflateInit2 failed");
}
+
+ state->chain = fz_keep_stream(ctx, chain);
+
return fz_new_stream(ctx, state, next_flated, close_flated);
}
diff --git a/source/fitz/filter-jbig2.c b/source/fitz/filter-jbig2.c
index 74fdae66..0d581b95 100644
--- a/source/fitz/filter-jbig2.c
+++ b/source/fitz/filter-jbig2.c
@@ -220,27 +220,21 @@ fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals)
{
fz_jbig2d *state = NULL;
- fz_var(state);
-
fz_try(ctx)
- {
state = fz_malloc_struct(ctx, fz_jbig2d);
- state->ctx = ctx;
- state->gctx = globals;
- state->chain = chain;
- state->idx = 0;
- state->output = NULL;
- state->doc = NULL;
- fz_warn(ctx, "opening jbig2");
- }
fz_catch(ctx)
{
fz_drop_jbig2_globals(ctx, globals);
- fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
fz_rethrow(ctx);
}
+ state->ctx = ctx;
+ state->gctx = globals;
+ state->chain = fz_keep_stream(ctx, chain);
+ state->idx = 0;
+ state->output = NULL;
+ state->doc = NULL;
+
return fz_new_stream(ctx, state, next_jbig2d, close_jbig2d);
}
@@ -415,7 +409,6 @@ fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals)
{
state = fz_malloc_struct(ctx, fz_jbig2d);
state->gctx = globals;
- state->chain = chain;
state->alloc.ctx = ctx;
state->alloc.alloc.alloc = fz_jbig2_alloc;
state->alloc.alloc.free = fz_jbig2_free;
@@ -423,6 +416,7 @@ fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals)
state->ctx = jbig2_ctx_new((Jbig2Allocator *) &state->alloc, JBIG2_OPTIONS_EMBEDDED, globals ? globals->gctx : NULL, error_callback, ctx);
state->page = NULL;
state->idx = 0;
+ state->chain = fz_keep_stream(ctx, chain);
}
fz_catch(ctx)
{
@@ -433,7 +427,6 @@ fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals)
jbig2_ctx_free(state->ctx);
}
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
fz_rethrow(ctx);
}
diff --git a/source/fitz/filter-leech.c b/source/fitz/filter-leech.c
index cc98b972..77485068 100644
--- a/source/fitz/filter-leech.c
+++ b/source/fitz/filter-leech.c
@@ -41,29 +41,16 @@ static void
close_leech(fz_context *ctx, void *state_)
{
fz_leech *state = (fz_leech *)state_;
-
fz_drop_stream(ctx, state->chain);
+ fz_drop_buffer(ctx, state->buffer);
fz_free(ctx, state);
}
fz_stream *
fz_open_leecher(fz_context *ctx, fz_stream *chain, fz_buffer *buffer)
{
- fz_leech *state = NULL;
-
- fz_var(state);
-
- fz_try(ctx)
- {
- state = fz_malloc_struct(ctx, fz_leech);
- state->chain = chain;
- state->buffer = buffer;
- }
- fz_catch(ctx)
- {
- fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
- fz_rethrow(ctx);
- }
+ fz_leech *state = fz_malloc_struct(ctx, fz_leech);
+ state->chain = fz_keep_stream(ctx, chain);
+ state->buffer = fz_keep_buffer(ctx, buffer);
return fz_new_stream(ctx, state, next_leech, close_leech);
}
diff --git a/source/fitz/filter-lzw.c b/source/fitz/filter-lzw.c
index a7d7d430..9198d081 100644
--- a/source/fitz/filter-lzw.c
+++ b/source/fitz/filter-lzw.c
@@ -207,55 +207,45 @@ close_lzwd(fz_context *ctx, void *state_)
fz_stream *
fz_open_lzwd(fz_context *ctx, fz_stream *chain, int early_change, int min_bits, int reverse_bits, int old_tiff)
{
- fz_lzwd *lzw = NULL;
+ fz_lzwd *lzw;
int i;
- fz_var(lzw);
-
- fz_try(ctx)
+ if (min_bits > MAX_BITS)
{
- if (min_bits > MAX_BITS)
- {
- fz_warn(ctx, "out of range initial lzw code size");
- min_bits = MAX_BITS;
- }
-
- lzw = fz_malloc_struct(ctx, fz_lzwd);
- lzw->chain = chain;
- lzw->eod = 0;
- lzw->early_change = early_change;
- lzw->reverse_bits = reverse_bits;
- lzw->old_tiff = old_tiff;
- lzw->min_bits = min_bits;
- lzw->code_bits = lzw->min_bits;
- lzw->code = -1;
- lzw->next_code = LZW_FIRST(lzw);
- lzw->old_code = -1;
- lzw->rp = lzw->bp;
- lzw->wp = lzw->bp;
-
- for (i = 0; i < LZW_CLEAR(lzw); i++)
- {
- lzw->table[i].value = i;
- lzw->table[i].first_char = i;
- lzw->table[i].length = 1;
- lzw->table[i].prev = -1;
- }
+ fz_warn(ctx, "out of range initial lzw code size");
+ min_bits = MAX_BITS;
+ }
- for (i = LZW_CLEAR(lzw); i < NUM_CODES; i++)
- {
- lzw->table[i].value = 0;
- lzw->table[i].first_char = 0;
- lzw->table[i].length = 0;
- lzw->table[i].prev = -1;
- }
+ lzw = fz_malloc_struct(ctx, fz_lzwd);
+ lzw->eod = 0;
+ lzw->early_change = early_change;
+ lzw->reverse_bits = reverse_bits;
+ lzw->old_tiff = old_tiff;
+ lzw->min_bits = min_bits;
+ lzw->code_bits = lzw->min_bits;
+ lzw->code = -1;
+ lzw->next_code = LZW_FIRST(lzw);
+ lzw->old_code = -1;
+ lzw->rp = lzw->bp;
+ lzw->wp = lzw->bp;
+
+ for (i = 0; i < LZW_CLEAR(lzw); i++)
+ {
+ lzw->table[i].value = i;
+ lzw->table[i].first_char = i;
+ lzw->table[i].length = 1;
+ lzw->table[i].prev = -1;
}
- fz_catch(ctx)
+
+ for (i = LZW_CLEAR(lzw); i < NUM_CODES; i++)
{
- fz_free(ctx, lzw);
- fz_drop_stream(ctx, chain);
- fz_rethrow(ctx);
+ lzw->table[i].value = 0;
+ lzw->table[i].first_char = 0;
+ lzw->table[i].length = 0;
+ lzw->table[i].prev = -1;
}
+ lzw->chain = fz_keep_stream(ctx, chain);
+
return fz_new_stream(ctx, lzw, next_lzwd, close_lzwd);
}
diff --git a/source/fitz/filter-predict.c b/source/fitz/filter-predict.c
index 24007bfe..e00e07fd 100644
--- a/source/fitz/filter-predict.c
+++ b/source/fitz/filter-predict.c
@@ -226,9 +226,7 @@ close_predict(fz_context *ctx, void *state_)
fz_stream *
fz_open_predict(fz_context *ctx, fz_stream *chain, int predictor, int columns, int colors, int bpc)
{
- fz_predict *state = NULL;
-
- fz_var(state);
+ fz_predict *state;
if (predictor < 1)
predictor = 1;
@@ -239,34 +237,30 @@ fz_open_predict(fz_context *ctx, fz_stream *chain, int predictor, int columns, i
if (bpc < 1)
bpc = 8;
- fz_try(ctx)
+ if (bpc != 1 && bpc != 2 && bpc != 4 && bpc != 8 && bpc != 16)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "invalid number of bits per component: %d", bpc);
+ if (colors > FZ_MAX_COLORS)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "too many color components (%d > %d)", colors, FZ_MAX_COLORS);
+ if (columns >= INT_MAX / (bpc * colors))
+ fz_throw(ctx, FZ_ERROR_GENERIC, "too many columns lead to an integer overflow (%d)", columns);
+
+ if (predictor != 1 && predictor != 2 &&
+ predictor != 10 && predictor != 11 &&
+ predictor != 12 && predictor != 13 &&
+ predictor != 14 && predictor != 15)
{
- if (bpc != 1 && bpc != 2 && bpc != 4 && bpc != 8 && bpc != 16)
- fz_throw(ctx, FZ_ERROR_GENERIC, "invalid number of bits per component: %d", bpc);
- if (colors > FZ_MAX_COLORS)
- fz_throw(ctx, FZ_ERROR_GENERIC, "too many color components (%d > %d)", colors, FZ_MAX_COLORS);
- if (columns >= INT_MAX / (bpc * colors))
- fz_throw(ctx, FZ_ERROR_GENERIC, "too many columns lead to an integer overflow (%d)", columns);
-
- state = fz_malloc_struct(ctx, fz_predict);
- state->in = NULL;
- state->out = NULL;
- state->chain = chain;
+ fz_warn(ctx, "invalid predictor: %d", predictor);
+ predictor = 1;
+ }
+ state = fz_malloc_struct(ctx, fz_predict);
+ fz_try(ctx)
+ {
state->predictor = predictor;
state->columns = columns;
state->colors = colors;
state->bpc = bpc;
- if (state->predictor != 1 && state->predictor != 2 &&
- state->predictor != 10 && state->predictor != 11 &&
- state->predictor != 12 && state->predictor != 13 &&
- state->predictor != 14 && state->predictor != 15)
- {
- fz_warn(ctx, "invalid predictor: %d", state->predictor);
- state->predictor = 1;
- }
-
state->stride = (state->bpc * state->colors * state->columns + 7) / 8;
state->bpp = (state->bpc * state->colors + 7) / 8;
@@ -277,16 +271,14 @@ fz_open_predict(fz_context *ctx, fz_stream *chain, int predictor, int columns, i
state->wp = state->out;
memset(state->ref, 0, state->stride);
+
+ state->chain = fz_keep_stream(ctx, chain);
}
fz_catch(ctx)
{
- if (state)
- {
- fz_free(ctx, state->in);
- fz_free(ctx, state->out);
- }
+ fz_free(ctx, state->in);
+ fz_free(ctx, state->out);
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
fz_rethrow(ctx);
}
diff --git a/source/fitz/filter-sgi.c b/source/fitz/filter-sgi.c
index 518751ed..43bade71 100644
--- a/source/fitz/filter-sgi.c
+++ b/source/fitz/filter-sgi.c
@@ -645,36 +645,28 @@ static void
close_sgilog32(fz_context *ctx, void *state_)
{
fz_sgilog32 *state = (fz_sgilog32 *)state_;
- fz_stream *chain = state->chain;
-
+ fz_drop_stream(ctx, state->chain);
fz_free(ctx, state->temp);
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
}
fz_stream *
fz_open_sgilog32(fz_context *ctx, fz_stream *chain, int w)
{
- fz_sgilog32 *state = NULL;
-
- fz_var(state);
-
+ fz_sgilog32 *state = fz_malloc_struct(ctx, fz_sgilog32);
fz_try(ctx)
{
- state = fz_malloc_struct(ctx, fz_sgilog32);
- state->chain = chain;
state->run = 0;
state->n = 0;
state->c = 0;
state->w = w;
state->temp = fz_malloc(ctx, w * sizeof(uint32_t));
+ state->chain = fz_keep_stream(ctx, chain);
}
fz_catch(ctx)
{
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
fz_rethrow(ctx);
}
-
return fz_new_stream(ctx, state, next_sgilog32, close_sgilog32);
}
diff --git a/source/fitz/filter-thunder.c b/source/fitz/filter-thunder.c
index 82d313a0..db96fbeb 100644
--- a/source/fitz/filter-thunder.c
+++ b/source/fitz/filter-thunder.c
@@ -116,36 +116,28 @@ static void
close_thunder(fz_context *ctx, void *state_)
{
fz_thunder *state = (fz_thunder *)state_;
- fz_stream *chain = state->chain;
-
+ fz_drop_stream(ctx, state->chain);
fz_free(ctx, state->buffer);
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
}
fz_stream *
fz_open_thunder(fz_context *ctx, fz_stream *chain, int w)
{
- fz_thunder *state = NULL;
-
- fz_var(state);
-
+ fz_thunder *state = fz_malloc_struct(ctx, fz_thunder);
fz_try(ctx)
{
- state = fz_malloc_struct(ctx, fz_thunder);
- state->chain = chain;
state->run = 0;
state->pixel = 0;
state->lastpixel = 0;
state->len = w / 2;
state->buffer = fz_malloc(ctx, state->len);
+ state->chain = fz_keep_stream(ctx, chain);
}
fz_catch(ctx)
{
fz_free(ctx, state);
- fz_drop_stream(ctx, chain);
fz_rethrow(ctx);
}
-
return fz_new_stream(ctx, state, next_thunder, close_thunder);
}
diff --git a/source/fitz/image.c b/source/fitz/image.c
index b61a606d..51699772 100644
--- a/source/fitz/image.c
+++ b/source/fitz/image.c
@@ -427,10 +427,6 @@ fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_compressed_image
if (image->use_colorkey && image->mask)
fz_unblend_masked_tile(ctx, tile, image);
}
- fz_always(ctx)
- {
- fz_drop_stream(ctx, stm);
- }
fz_catch(ctx)
{
fz_drop_pixmap(ctx, tile);
@@ -532,12 +528,18 @@ compressed_image_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *subarea
default:
native_l2factor = l2factor ? *l2factor : 0;
stm = fz_open_image_decomp_stream_from_buffer(ctx, image->buffer, l2factor);
- if (l2factor)
- native_l2factor -= *l2factor;
-
- indexed = fz_colorspace_is_indexed(ctx, image->super.colorspace);
- can_sub = 1;
- tile = fz_decomp_image_from_stream(ctx, stm, image, subarea, indexed, native_l2factor);
+ fz_try(ctx)
+ {
+ if (l2factor)
+ native_l2factor -= *l2factor;
+ indexed = fz_colorspace_is_indexed(ctx, image->super.colorspace);
+ can_sub = 1;
+ tile = fz_decomp_image_from_stream(ctx, stm, image, subarea, indexed, native_l2factor);
+ }
+ fz_always(ctx)
+ fz_drop_stream(ctx, stm);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
/* CMYK JPEGs in XPS documents have to be inverted */
if (image->super.invert_cmyk_jpeg &&
@@ -925,7 +927,7 @@ fz_compressed_buffer *fz_compressed_image_buffer(fz_context *ctx, fz_image *imag
void fz_set_compressed_image_buffer(fz_context *ctx, fz_compressed_image *image, fz_compressed_buffer *buf)
{
assert(image != NULL && image->super.get_pixmap == compressed_image_get_pixmap);
- ((fz_compressed_image *)image)->buffer = buf;
+ ((fz_compressed_image *)image)->buffer = buf; /* Note: compressed buffers are not reference counted */
}
fz_pixmap *fz_compressed_image_tile(fz_context *ctx, fz_compressed_image *image)
@@ -938,7 +940,8 @@ fz_pixmap *fz_compressed_image_tile(fz_context *ctx, fz_compressed_image *image)
void fz_set_compressed_image_tile(fz_context *ctx, fz_compressed_image *image, fz_pixmap *pix)
{
assert(image != NULL && image->super.get_pixmap == compressed_image_get_pixmap);
- ((fz_compressed_image *)image)->tile = pix;
+ fz_drop_pixmap(ctx, ((fz_compressed_image *)image)->tile);
+ ((fz_compressed_image *)image)->tile = fz_keep_pixmap(ctx, pix);
}
fz_pixmap *fz_pixmap_image_tile(fz_context *ctx, fz_pixmap_image *image)
diff --git a/source/fitz/load-gif.c b/source/fitz/load-gif.c
index 25a37e3f..ca73a537 100644
--- a/source/fitz/load-gif.c
+++ b/source/fitz/load-gif.c
@@ -237,7 +237,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)
{
- fz_stream *stm, *lzwstm = NULL;
+ fz_stream *stm = NULL, *lzwstm = NULL;
unsigned int mincodesize, y;
fz_buffer *compressed = NULL, *uncompressed = NULL;
const unsigned char *ct;
@@ -258,6 +258,7 @@ gif_read_tbid(fz_context *ctx, struct info *info, unsigned char *dest, const uns
fz_var(compressed);
fz_var(lzwstm);
+ fz_var(stm);
fz_var(uncompressed);
fz_try(ctx)
@@ -309,6 +310,7 @@ gif_read_tbid(fz_context *ctx, struct info *info, unsigned char *dest, const uns
fz_drop_buffer(ctx, uncompressed);
fz_drop_buffer(ctx, compressed);
fz_drop_stream(ctx, lzwstm);
+ fz_drop_stream(ctx, stm);
}
fz_catch(ctx)
{
diff --git a/source/fitz/load-png.c b/source/fitz/load-png.c
index c5bc925c..39c4ea81 100644
--- a/source/fitz/load-png.c
+++ b/source/fitz/load-png.c
@@ -344,7 +344,7 @@ png_read_trns(fz_context *ctx, struct info *info, const unsigned char *p, unsign
static void
png_read_icc(fz_context *ctx, struct info *info, const unsigned char *p, unsigned int size)
{
- fz_stream *stm = NULL;
+ fz_stream *mstm = NULL, *zstm = NULL;
fz_colorspace *cs = NULL;
size_t m = fz_mini(80, size);
size_t n = strnlen((const char *)p, m);
@@ -354,17 +354,23 @@ png_read_icc(fz_context *ctx, struct info *info, const unsigned char *p, unsigne
return;
}
- stm = fz_open_memory(ctx, p + n + 2, size - n - 2);
- stm = fz_open_flated(ctx, stm, 15);
+ fz_var(mstm);
+ fz_var(zstm);
+
fz_try(ctx)
{
- cs = fz_new_icc_colorspace_from_stream(ctx, (const char *)p, stm);
+ mstm = fz_open_memory(ctx, p + n + 2, size - n - 2);
+ zstm = fz_open_flated(ctx, mstm, 15);
+ cs = fz_new_icc_colorspace_from_stream(ctx, (const char *)p, zstm);
/* drop old one in case we have multiple ICC profiles */
fz_drop_colorspace(ctx, info->cs);
info->cs = cs;
}
fz_always(ctx)
- fz_drop_stream(ctx, stm);
+ {
+ fz_drop_stream(ctx, mstm);
+ fz_drop_stream(ctx, zstm);
+ }
fz_catch(ctx)
fz_warn(ctx, "cannot read embedded ICC profile");
}
diff --git a/source/fitz/load-tiff.c b/source/fitz/load-tiff.c
index 2da9e635..3dad8a82 100644
--- a/source/fitz/load-tiff.c
+++ b/source/fitz/load-tiff.c
@@ -309,12 +309,12 @@ tiff_decode_data(fz_context *ctx, struct tiff *tiff, const unsigned char *rp, un
rp = reversed;
}
+ fz_var(jpegtables);
fz_var(encstm);
fz_var(stm);
fz_try(ctx)
{
- /* each decoder will close this */
encstm = fz_open_memory(ctx, rp, rlen);
/* switch on compression to create a filter */
@@ -331,7 +331,7 @@ tiff_decode_data(fz_context *ctx, struct tiff *tiff, const unsigned char *rp, un
{
case 1:
/* stm already open and reading uncompressed data */
- stm = encstm;
+ stm = fz_keep_stream(ctx, encstm);
break;
case 2:
case 3:
@@ -385,7 +385,6 @@ tiff_decode_data(fz_context *ctx, struct tiff *tiff, const unsigned char *rp, un
stm = fz_open_thunder(ctx, encstm, tiff->imagewidth);
break;
default:
- stm = encstm;
fz_throw(ctx, FZ_ERROR_GENERIC, "unknown TIFF compression: %d", tiff->compression);
}
@@ -393,6 +392,8 @@ tiff_decode_data(fz_context *ctx, struct tiff *tiff, const unsigned char *rp, un
}
fz_always(ctx)
{
+ fz_drop_stream(ctx, jpegtables);
+ fz_drop_stream(ctx, encstm);
fz_drop_stream(ctx, stm);
fz_free(ctx, reversed);
}
diff --git a/source/fitz/stream-open.c b/source/fitz/stream-open.c
index 813b7099..39994285 100644
--- a/source/fitz/stream-open.c
+++ b/source/fitz/stream-open.c
@@ -232,7 +232,7 @@ fz_open_memory(fz_context *ctx, const unsigned char *data, size_t len)
{
fz_stream *stm;
- stm = fz_new_stream(ctx, NULL, next_buffer, drop_buffer);
+ stm = fz_new_stream(ctx, NULL, next_buffer, NULL);
stm->seek = seek_buffer;
stm->rp = (unsigned char *)data;
diff --git a/source/gprf/gprf-doc.c b/source/gprf/gprf-doc.c
index 2c508139..44e12ebc 100644
--- a/source/gprf/gprf-doc.c
+++ b/source/gprf/gprf-doc.c
@@ -353,8 +353,9 @@ gprf_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *area, int w, int h,
unsigned char equiv[3 + FZ_MAX_SEPARATIONS][4];
int bytes_per_channel = image->super.w * image->super.h;
unsigned char *out = fz_pixmap_samples(ctx, pix);
+ fz_stream *tmp_file = NULL;
- fz_var(file);
+ fz_var(tmp_file);
if (area)
{
@@ -404,9 +405,11 @@ gprf_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *area, int w, int h,
read_sep[i] = 2;
memset(&data[i * decode_chunk_size], 0, decode_chunk_size);
}
- file[i] = fz_open_file(ctx, image->file->filename);
- fz_seek(ctx, file[i], image->offset[i], SEEK_SET);
- file[i] = fz_open_flated(ctx, file[i], 15);
+ tmp_file = fz_open_file(ctx, image->file->filename);
+ fz_seek(ctx, tmp_file, image->offset[i], SEEK_SET);
+ file[i] = fz_open_flated(ctx, tmp_file, 15);
+ fz_drop_stream(ctx, tmp_file);
+ tmp_file = NULL;
}
/* Now actually do the decode */
@@ -463,6 +466,7 @@ gprf_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *area, int w, int h,
}
fz_always(ctx)
{
+ fz_drop_stream(ctx, tmp_file);
for (i = 0; i < 3+num_seps; i++)
fz_drop_stream(ctx, file[i]);
}
diff --git a/source/pdf/pdf-crypt.c b/source/pdf/pdf-crypt.c
index 2e31f356..1056b4fe 100644
--- a/source/pdf/pdf-crypt.c
+++ b/source/pdf/pdf-crypt.c
@@ -1023,7 +1023,7 @@ pdf_open_crypt_imp(fz_context *ctx, fz_stream *chain, pdf_crypt *crypt, pdf_cryp
if (stmf->method == PDF_CRYPT_AESV2 || stmf->method == PDF_CRYPT_AESV3)
return fz_open_aesd(ctx, chain, key, len);
- return chain;
+ return fz_keep_stream(ctx, chain);
}
fz_stream *
@@ -1035,27 +1035,13 @@ pdf_open_crypt(fz_context *ctx, fz_stream *chain, pdf_crypt *crypt, int num, int
fz_stream *
pdf_open_crypt_with_filter(fz_context *ctx, fz_stream *chain, pdf_crypt *crypt, pdf_obj *name, int num, int gen)
{
- fz_var(chain);
-
- fz_try(ctx)
- {
- if (!pdf_name_eq(ctx, name, PDF_NAME_Identity))
- {
- pdf_crypt_filter cf;
- fz_stream *tmp;
- pdf_parse_crypt_filter(ctx, &cf, crypt, name);
- tmp = chain;
- chain = NULL;
- chain = pdf_open_crypt_imp(ctx, tmp, crypt, &cf, num, gen);
- }
- }
- fz_catch(ctx)
+ if (!pdf_name_eq(ctx, name, PDF_NAME_Identity))
{
- fz_drop_stream(ctx, chain);
- fz_rethrow(ctx);
+ pdf_crypt_filter cf;
+ pdf_parse_crypt_filter(ctx, &cf, crypt, name);
+ return pdf_open_crypt_imp(ctx, chain, crypt, &cf, num, gen);
}
-
- return chain;
+ return fz_keep_stream(ctx, chain);
}
void
diff --git a/source/pdf/pdf-form.c b/source/pdf/pdf-form.c
index f3d4e3c6..6c2e0434 100644
--- a/source/pdf/pdf-form.c
+++ b/source/pdf/pdf-form.c
@@ -1292,7 +1292,7 @@ fz_stream *pdf_signature_widget_hash_bytes(fz_context *ctx, pdf_document *doc, p
pdf_signature_widget_byte_range(ctx, doc, widget, byte_range);
}
- bytes = fz_open_null_n(ctx, fz_keep_stream(ctx, doc->file), byte_range, byte_range_len);
+ bytes = fz_open_null_n(ctx, doc->file, byte_range, byte_range_len);
}
fz_always(ctx)
{
diff --git a/source/pdf/pdf-stream.c b/source/pdf/pdf-stream.c
index 34ffe7af..379ed504 100644
--- a/source/pdf/pdf-stream.c
+++ b/source/pdf/pdf-stream.c
@@ -158,116 +158,93 @@ static fz_stream *
build_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *f, pdf_obj *p, int num, int gen, fz_compression_params *params)
{
fz_compression_params local_params;
- fz_stream *tmp;
- fz_var(chain);
+ if (params == NULL)
+ params = &local_params;
- fz_try(ctx)
- {
- if (params == NULL)
- params = &local_params;
+ build_compression_params(ctx, f, p, params);
- build_compression_params(ctx, f, p, params);
+ /* If we were using params we were passed in, and we successfully
+ * recognised the image type, we can use the existing filter and
+ * shortstop here. */
+ if (params != &local_params && params->type != FZ_IMAGE_RAW)
+ return fz_keep_stream(ctx, chain); /* nothing to do */
- /* If we were using params we were passed in, and we successfully
- * recognised the image type, we can use the existing filter and
- * shortstop here. */
- if (params != &local_params && params->type != FZ_IMAGE_RAW)
- break; /* nothing to do */
+ else if (params->type != FZ_IMAGE_RAW)
+ return fz_open_image_decomp_stream(ctx, chain, params, NULL);
- else if (params->type != FZ_IMAGE_RAW)
- {
- tmp = chain;
- chain = NULL;
- chain = fz_open_image_decomp_stream(ctx, tmp, params, NULL);
- }
+ else if (pdf_name_eq(ctx, f, PDF_NAME_ASCIIHexDecode) || pdf_name_eq(ctx, f, PDF_NAME_AHx))
+ return fz_open_ahxd(ctx, chain);
- else if (pdf_name_eq(ctx, f, PDF_NAME_ASCIIHexDecode) || pdf_name_eq(ctx, f, PDF_NAME_AHx))
- {
- tmp = chain;
- chain = NULL;
- chain = fz_open_ahxd(ctx, tmp);
- }
-
- else if (pdf_name_eq(ctx, f, PDF_NAME_ASCII85Decode) || pdf_name_eq(ctx, f, PDF_NAME_A85))
- {
- tmp = chain;
- chain = NULL;
- chain = fz_open_a85d(ctx, tmp);
- }
+ else if (pdf_name_eq(ctx, f, PDF_NAME_ASCII85Decode) || pdf_name_eq(ctx, f, PDF_NAME_A85))
+ return fz_open_a85d(ctx, chain);
- else if (pdf_name_eq(ctx, f, PDF_NAME_JBIG2Decode))
+ else if (pdf_name_eq(ctx, f, PDF_NAME_JBIG2Decode))
+ {
+ fz_jbig2_globals *globals = NULL;
+ pdf_obj *obj = pdf_dict_get(ctx, p, PDF_NAME_JBIG2Globals);
+ if (obj)
{
- fz_jbig2_globals *globals = NULL;
- pdf_obj *obj = pdf_dict_get(ctx, p, PDF_NAME_JBIG2Globals);
- if (obj)
- {
- if (!pdf_is_stream(ctx, obj))
- fz_warn(ctx, "jbig2 globals is not a stream, skipping globals");
- else
- globals = pdf_load_jbig2_globals(ctx, doc, obj);
- }
- tmp = chain;
- chain = NULL;
- chain = fz_open_jbig2d(ctx, tmp, globals);
+ if (!pdf_is_stream(ctx, obj))
+ fz_warn(ctx, "jbig2 globals is not a stream, skipping globals");
+ else
+ globals = pdf_load_jbig2_globals(ctx, doc, obj);
}
+ return fz_open_jbig2d(ctx, chain, globals); /* takes ownership of jbig2_globals */
+ }
- else if (pdf_name_eq(ctx, f, PDF_NAME_JPXDecode))
- break; /* JPX decoding is special cased in the image loading code */
+ else if (pdf_name_eq(ctx, f, PDF_NAME_JPXDecode))
+ return fz_keep_stream(ctx, chain); /* JPX decoding is special cased in the image loading code */
- else if (pdf_name_eq(ctx, f, PDF_NAME_Crypt))
+ else if (pdf_name_eq(ctx, f, PDF_NAME_Crypt))
+ {
+ if (!doc->crypt)
+ fz_warn(ctx, "crypt filter in unencrypted document");
+ else
{
- if (!doc->crypt)
- fz_warn(ctx, "crypt filter in unencrypted document");
- else
- {
- pdf_obj *name = pdf_dict_get(ctx, p, PDF_NAME_Name);
- if (pdf_is_name(ctx, name))
- {
- tmp = chain;
- chain = NULL;
- chain = pdf_open_crypt_with_filter(ctx, tmp, doc->crypt, name, num, gen);
- }
- }
+ pdf_obj *name = pdf_dict_get(ctx, p, PDF_NAME_Name);
+ if (pdf_is_name(ctx, name))
+ return pdf_open_crypt_with_filter(ctx, chain, doc->crypt, name, num, gen);
}
- else
- fz_warn(ctx, "unknown filter name (%s)", pdf_to_name(ctx, f));
}
+
+ else
+ fz_warn(ctx, "unknown filter name (%s)", pdf_to_name(ctx, f));
+
+ return fz_keep_stream(ctx, chain);
+}
+
+/* Build filter, and assume ownership of chain */
+static fz_stream *
+build_filter_drop(fz_context *ctx, fz_stream *tail, pdf_document *doc, pdf_obj *f, pdf_obj *p, int num, int gen, fz_compression_params *params)
+{
+ fz_stream *head;
+ fz_try(ctx)
+ head = build_filter(ctx, tail, doc, f, p, num, gen, params);
+ fz_always(ctx)
+ fz_drop_stream(ctx, tail);
fz_catch(ctx)
- {
- fz_drop_stream(ctx, chain);
fz_rethrow(ctx);
- }
-
- return chain;
+ return head;
}
/*
* Build a chain of filters given filter names and param dicts.
- * If head is given, start filter chain with it.
- * Assume ownership of head.
+ * If chain is given, start filter chain with it.
+ * Assume ownership of chain.
*/
static fz_stream *
-build_filter_chain(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *fs, pdf_obj *ps, int num, int gen, fz_compression_params *params)
+build_filter_chain_drop(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *fs, pdf_obj *ps, int num, int gen, fz_compression_params *params)
{
- pdf_obj *f;
- pdf_obj *p;
- int i, n;
-
fz_var(chain);
-
fz_try(ctx)
{
- n = pdf_array_len(ctx, fs);
+ int i, n = pdf_array_len(ctx, fs);
for (i = 0; i < n; i++)
{
- fz_stream *chain2;
-
- f = pdf_array_get(ctx, fs, i);
- p = pdf_array_get(ctx, ps, i);
- chain2 = chain;
- chain = NULL;
- chain = build_filter(ctx, chain2, doc, f, p, num, gen, (i == n-1 ? params : NULL));
+ pdf_obj *f = pdf_array_get(ctx, fs, i);
+ pdf_obj *p = pdf_array_get(ctx, ps, i);
+ chain = build_filter_drop(ctx, chain, doc, f, p, num, gen, (i == n-1 ? params : NULL));
}
}
fz_catch(ctx)
@@ -275,10 +252,15 @@ build_filter_chain(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj
fz_drop_stream(ctx, chain);
fz_rethrow(ctx);
}
-
return chain;
}
+static fz_stream *
+build_filter_chain(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *fs, pdf_obj *ps, int num, int gen, fz_compression_params *params)
+{
+ return build_filter_chain_drop(ctx, fz_keep_stream(ctx, chain), doc, fs, ps, num, gen, params);
+}
+
/*
* Build a filter for reading raw stream data.
* This is a null filter to constrain reading to the stream length (and to
@@ -288,10 +270,10 @@ build_filter_chain(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj
* orig_num and orig_gen are used purely to seed the encryption.
*/
static fz_stream *
-pdf_open_raw_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *stmobj, int num, int *orig_num, int *orig_gen, int64_t offset)
+pdf_open_raw_filter(fz_context *ctx, fz_stream *file_stm, pdf_document *doc, pdf_obj *stmobj, int num, int *orig_num, int *orig_gen, int64_t offset)
{
pdf_xref_entry *x = NULL;
- fz_stream *chain2;
+ fz_stream *null_stm, *crypt_stm;
int hascrypt;
int len;
@@ -311,33 +293,20 @@ pdf_open_raw_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_ob
*orig_gen = 0;
}
- chain = fz_keep_stream(ctx, chain);
-
- fz_var(chain);
-
- fz_try(ctx)
+ hascrypt = pdf_stream_has_crypt(ctx, stmobj);
+ len = pdf_to_int(ctx, pdf_dict_get(ctx, stmobj, PDF_NAME_Length));
+ null_stm = fz_open_null(ctx, file_stm, len, offset);
+ if (doc->crypt && !hascrypt)
{
- len = pdf_to_int(ctx, pdf_dict_get(ctx, stmobj, PDF_NAME_Length));
-
- chain2 = chain;
- chain = NULL;
- chain = fz_open_null(ctx, chain2, len, offset);
-
- hascrypt = pdf_stream_has_crypt(ctx, stmobj);
- if (doc->crypt && !hascrypt)
- {
- chain2 = chain;
- chain = NULL;
- chain = pdf_open_crypt(ctx, chain2, doc->crypt, *orig_num, *orig_gen);
- }
- }
- fz_catch(ctx)
- {
- fz_drop_stream(ctx, chain);
- fz_rethrow(ctx);
+ fz_try(ctx)
+ crypt_stm = pdf_open_crypt(ctx, null_stm, doc->crypt, *orig_num, *orig_gen);
+ fz_always(ctx)
+ fz_drop_stream(ctx, null_stm);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+ return crypt_stm;
}
-
- return chain;
+ return null_stm;
}
/*
@@ -345,41 +314,29 @@ pdf_open_raw_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_ob
* to stream length and decrypting.
*/
static fz_stream *
-pdf_open_filter(fz_context *ctx, pdf_document *doc, fz_stream *chain, pdf_obj *stmobj, int num, int64_t offset, fz_compression_params *imparams)
+pdf_open_filter(fz_context *ctx, pdf_document *doc, fz_stream *file_stm, pdf_obj *stmobj, int num, int64_t offset, fz_compression_params *imparams)
{
- pdf_obj *filters;
- pdf_obj *params;
+ pdf_obj *filters = pdf_dict_geta(ctx, stmobj, PDF_NAME_Filter, PDF_NAME_F);
+ pdf_obj *params = pdf_dict_geta(ctx, stmobj, PDF_NAME_DecodeParms, PDF_NAME_DP);
int orig_num, orig_gen;
+ fz_stream *rstm, *fstm;
- filters = pdf_dict_geta(ctx, stmobj, PDF_NAME_Filter, PDF_NAME_F);
- params = pdf_dict_geta(ctx, stmobj, PDF_NAME_DecodeParms, PDF_NAME_DP);
-
- chain = pdf_open_raw_filter(ctx, chain, doc, stmobj, num, &orig_num, &orig_gen, offset);
-
- fz_var(chain);
-
+ rstm = pdf_open_raw_filter(ctx, file_stm, doc, stmobj, num, &orig_num, &orig_gen, offset);
fz_try(ctx)
{
if (pdf_is_name(ctx, filters))
- {
- fz_stream *chain2 = chain;
- chain = NULL;
- chain = build_filter(ctx, chain2, doc, filters, params, orig_num, orig_gen, imparams);
- }
+ fstm = build_filter(ctx, rstm, doc, filters, params, orig_num, orig_gen, imparams);
else if (pdf_array_len(ctx, filters) > 0)
- {
- fz_stream *chain2 = chain;
- chain = NULL;
- chain = build_filter_chain(ctx, chain2, doc, filters, params, orig_num, orig_gen, imparams);
- }
+ fstm = build_filter_chain(ctx, rstm, doc, filters, params, orig_num, orig_gen, imparams);
+ else
+ fstm = fz_keep_stream(ctx, rstm);
}
+ fz_always(ctx)
+ fz_drop_stream(ctx, rstm);
fz_catch(ctx)
- {
- fz_drop_stream(ctx, chain);
fz_rethrow(ctx);
- }
- return chain;
+ return fstm;
}
/*
@@ -387,54 +344,52 @@ pdf_open_filter(fz_context *ctx, pdf_document *doc, fz_stream *chain, pdf_obj *s
* constraining to stream length, and without decryption.
*/
fz_stream *
-pdf_open_inline_stream(fz_context *ctx, pdf_document *doc, pdf_obj *stmobj, int length, fz_stream *chain, fz_compression_params *imparams)
+pdf_open_inline_stream(fz_context *ctx, pdf_document *doc, pdf_obj *stmobj, int length, fz_stream *file_stm, fz_compression_params *imparams)
{
- pdf_obj *filters;
- pdf_obj *params;
- int64_t offset;
-
- filters = pdf_dict_geta(ctx, stmobj, PDF_NAME_Filter, PDF_NAME_F);
- params = pdf_dict_geta(ctx, stmobj, PDF_NAME_DecodeParms, PDF_NAME_DP);
-
- /* don't close chain when we close this filter */
- fz_keep_stream(ctx, chain);
+ pdf_obj *filters = pdf_dict_geta(ctx, stmobj, PDF_NAME_Filter, PDF_NAME_F);
+ pdf_obj *params = pdf_dict_geta(ctx, stmobj, PDF_NAME_DecodeParms, PDF_NAME_DP);
if (pdf_is_name(ctx, filters))
- return build_filter(ctx, chain, doc, filters, params, 0, 0, imparams);
- if (pdf_array_len(ctx, filters) > 0)
- return build_filter_chain(ctx, chain, doc, filters, params, 0, 0, imparams);
+ return build_filter(ctx, file_stm, doc, filters, params, 0, 0, imparams);
+ else if (pdf_array_len(ctx, filters) > 0)
+ return build_filter_chain(ctx, file_stm, doc, filters, params, 0, 0, imparams);
if (imparams)
imparams->type = FZ_IMAGE_RAW;
-
- fz_try(ctx)
- offset = fz_tell(ctx, chain);
- fz_catch(ctx)
- {
- fz_drop_stream(ctx, chain);
- fz_rethrow(ctx);
- }
-
- return fz_open_null(ctx, chain, length, offset);
+ return fz_open_null(ctx, file_stm, length, fz_tell(ctx, file_stm));
}
void
-pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int length, fz_stream *stm, int indexed, fz_compressed_image *image)
+pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int length, fz_stream *file_stm, int indexed, fz_compressed_image *image)
{
- fz_compressed_buffer *bc = fz_malloc_struct(ctx, fz_compressed_buffer);
+ fz_stream *istm, *leech, *decomp;
+ fz_pixmap *pixmap;
+ fz_compressed_buffer *bc;
+ int dummy_l2factor = 0;
+ fz_var(istm);
+ fz_var(leech);
+ fz_var(decomp);
+ fz_var(pixmap);
+
+ bc = fz_malloc_struct(ctx, fz_compressed_buffer);
fz_try(ctx)
{
- int dummy_l2factor = 0;
bc->buffer = fz_new_buffer(ctx, 1024);
-
- stm = pdf_open_inline_stream(ctx, doc, dict, length, stm, &bc->params);
- stm = fz_open_leecher(ctx, stm, bc->buffer);
- stm = fz_open_image_decomp_stream(ctx, stm, &bc->params, &dummy_l2factor);
-
- fz_set_compressed_image_tile(ctx, image, fz_decomp_image_from_stream(ctx, stm, image, NULL, indexed, 0));
+ istm = pdf_open_inline_stream(ctx, doc, dict, length, file_stm, &bc->params);
+ leech = fz_open_leecher(ctx, istm, bc->buffer);
+ decomp = fz_open_image_decomp_stream(ctx, leech, &bc->params, &dummy_l2factor);
+ pixmap = fz_decomp_image_from_stream(ctx, leech, image, NULL, indexed, 0);
+ fz_set_compressed_image_tile(ctx, image, pixmap);
fz_set_compressed_image_buffer(ctx, image, bc);
}
+ fz_always(ctx)
+ {
+ fz_drop_stream(ctx, istm);
+ fz_drop_stream(ctx, leech);
+ fz_drop_stream(ctx, decomp);
+ fz_drop_pixmap(ctx, pixmap);
+ }
fz_catch(ctx)
{
fz_drop_compressed_buffer(ctx, bc);