summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/pdf/pdf-stream.c')
-rw-r--r--source/pdf/pdf-stream.c287
1 files changed, 121 insertions, 166 deletions
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);