diff options
author | Robin Watts <robin.watts@artifex.com> | 2014-03-14 20:01:32 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2014-03-18 17:48:40 +0000 |
commit | 4c2715a0bcecfed6ebdfee901920631b09364d7e (patch) | |
tree | b0e5aa723719159a779425329ddc6ce48b8af0ce /source/pdf/pdf-stream.c | |
parent | 551de42088c58dc69fba06fb53e36c2ddb12367f (diff) | |
download | mupdf-4c2715a0bcecfed6ebdfee901920631b09364d7e.tar.xz |
Fix operator buffering of inline images.
Previously pdf_process buffer did not understand inline images.
In order to make this work without needlessly duplicating complex code
from within pdf-op-run, the parsing of inline images has been moved to
happen in pdf-interpret.c. When the op_table entry for BI is called
it now expects the inline image to be in csi->img and the dictionary
object to be in csi->obj.
To make this work, we have had to improve the handling of inline images
in general. While non-inline images have been loaded and held in
memory in their compressed form and only decoded when required, until
now we have always loaded and decoded inline images immediately. This
has been due to the difficulty in knowing how many bytes of data to
read from the stream - we know the length of the stream once
uncompressed, but relating this to the compressed length is hard.
To cure this we introduce a new type of filter stream, a 'leecher'.
We insert a leecher stream before we build the filters required to
decode the image. We then read and discard the appropriate number
of uncompressed bytes from the filters. This pulls the compressed
data through the leecher stream, which stores it in an fz_buffer.
Thus images are now always held in their compressed forms in memory.
The pdf-op-run implementation is now trivial. The only real complexity
in the pdf-op-buffer implementation is the need to ensure that the
/Filter entry in the dictionary object matches the exact point at
which we backstopped the decompression.
Diffstat (limited to 'source/pdf/pdf-stream.c')
-rw-r--r-- | source/pdf/pdf-stream.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/source/pdf/pdf-stream.c b/source/pdf/pdf-stream.c index e0b809c7..2c552e39 100644 --- a/source/pdf/pdf-stream.c +++ b/source/pdf/pdf-stream.c @@ -93,6 +93,9 @@ build_filter(fz_stream *chain, pdf_document *doc, pdf_obj *f, pdf_obj *p, int nu int colors = pdf_to_int(pdf_dict_gets(p, "Colors")); int bpc = pdf_to_int(pdf_dict_gets(p, "BitsPerComponent")); + if (params) + params->type = FZ_IMAGE_RAW; + if (!strcmp(s, "ASCIIHexDecode") || !strcmp(s, "AHx")) return fz_open_ahxd(chain); @@ -358,9 +361,43 @@ pdf_open_inline_stream(pdf_document *doc, pdf_obj *stmobj, int length, fz_stream if (pdf_array_len(filters) > 0) return build_filter_chain(chain, doc, filters, params, 0, 0, imparams); + if (imparams) + imparams->type = FZ_IMAGE_RAW; return fz_open_null(chain, length, fz_tell(chain)); } +void +pdf_load_compressed_inline_image(pdf_document *doc, pdf_obj *dict, int length, fz_stream *stm, int indexed, fz_image *image) +{ + fz_context *ctx = doc->ctx; + fz_compressed_buffer *bc = fz_malloc_struct(ctx, fz_compressed_buffer); + fz_stream *istm = NULL; + + fz_var(istm); + + fz_try(ctx) + { + int dummy_l2factor = 0; + bc->buffer = fz_new_buffer(ctx, 1024); + + stm = pdf_open_inline_stream(doc, dict, length, stm, &bc->params); + stm = fz_open_leecher(stm, bc->buffer); + istm = fz_open_image_decomp_stream(ctx, stm, &bc->params, &dummy_l2factor); + + image->tile = fz_decomp_image_from_stream(ctx, istm, image, indexed, 0, 0); + } + fz_always(ctx) + { + fz_close(istm); + } + fz_catch(ctx) + { + fz_free(ctx, bc); + fz_rethrow(ctx); + } + image->buffer = bc; +} + /* * Open a stream for reading the raw (compressed but decrypted) data. */ |