diff options
author | Robin Watts <robin.watts@artifex.com> | 2015-06-26 18:45:26 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2015-06-29 12:15:18 +0100 |
commit | 2bb213c70d42e398ef7ea3b6551c8fbb865cf3bd (patch) | |
tree | 450c7583241f2236c82fb8ae5bedbb1c0d664ec3 /source | |
parent | 051b4932219bed310e17505b2e73029d371a18ce (diff) | |
download | mupdf-2bb213c70d42e398ef7ea3b6551c8fbb865cf3bd.tar.xz |
Further tweaks to fz_image handling.
Ensure that subsampling and caching happen in the generic image
code, not in the specific.
Previously, the subsampling happened only for images that were
decoded from streams. Images that were loaded direct were never
subsampled and hence were always cached at full size. After this
change both classes of image are correctly subsampled, and
the subsampled version kept in the cache.
This produces various image diffs in the cluster, none of which
are noticable to the naked eye.
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/compressed-buffer.c | 23 | ||||
-rw-r--r-- | source/fitz/image.c | 104 | ||||
-rw-r--r-- | source/pdf/pdf-stream.c | 2 |
3 files changed, 66 insertions, 63 deletions
diff --git a/source/fitz/compressed-buffer.c b/source/fitz/compressed-buffer.c index d1c73351..2c5dd93f 100644 --- a/source/fitz/compressed-buffer.c +++ b/source/fitz/compressed-buffer.c @@ -24,11 +24,11 @@ fz_open_image_decomp_stream_from_buffer(fz_context *ctx, fz_compressed_buffer *b fz_stream * fz_open_image_decomp_stream(fz_context *ctx, fz_stream *chain, fz_compression_params *params, int *l2factor) { + int our_l2factor = 0; + switch (params->type) { case FZ_IMAGE_FAX: - if (l2factor) - *l2factor = 0; return fz_open_faxd(ctx, chain, params->u.fax.k, params->u.fax.end_of_line, @@ -38,30 +38,27 @@ fz_open_image_decomp_stream(fz_context *ctx, fz_stream *chain, fz_compression_pa params->u.fax.end_of_block, params->u.fax.black_is_1); case FZ_IMAGE_JPEG: - if (l2factor && *l2factor > 3) - *l2factor = 3; - return fz_open_dctd(ctx, chain, params->u.jpeg.color_transform, l2factor ? *l2factor : 0, NULL); - case FZ_IMAGE_RLD: if (l2factor) - *l2factor = 0; + { + our_l2factor = *l2factor; + if (our_l2factor > 3) + our_l2factor = 3; + *l2factor -= our_l2factor; + } + 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: - if (l2factor) - *l2factor = 0; 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: - if (l2factor) - *l2factor = 0; chain = fz_open_lzwd(ctx, chain, params->u.lzw.early_change); 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: - if (l2factor) - *l2factor = 0; break; } diff --git a/source/fitz/image.c b/source/fitz/image.c index 0cf06b33..3c7e7c0e 100644 --- a/source/fitz/image.c +++ b/source/fitz/image.c @@ -134,14 +134,14 @@ fz_unblend_masked_tile(fz_context *ctx, fz_pixmap *tile, fz_image *image) } fz_pixmap * -fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, int indexed, int l2factor, int native_l2factor) +fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, int indexed, int l2factor) { fz_pixmap *tile = NULL; int stride, len, i; unsigned char *samples = NULL; - int f = 1<<native_l2factor; - int w = (image->w + f-1) >> native_l2factor; - int h = (image->h + f-1) >> native_l2factor; + int f = 1<<l2factor; + int w = (image->w + f-1) >> l2factor; + int h = (image->h + f-1) >> l2factor; fz_var(tile); fz_var(samples); @@ -213,14 +213,6 @@ fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, in fz_rethrow(ctx); } - /* Now apply any extra subsampling required */ - if (l2factor - native_l2factor > 0) - { - if (l2factor - native_l2factor > 8) - l2factor = native_l2factor + 8; - fz_subsample_pixmap(ctx, tile, l2factor - native_l2factor); - } - return tile; } @@ -239,12 +231,11 @@ fz_drop_image_imp(fz_context *ctx, fz_storable *image_) } static fz_pixmap * -standard_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h, int l2factor) +standard_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h, int *l2factor) { - fz_stream *stm; int native_l2factor; + fz_stream *stm; int indexed; - fz_image_key *keyp; fz_pixmap *tile; /* We need to make a new one. */ @@ -280,11 +271,13 @@ standard_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h, int l2 /* fall through */ default: - native_l2factor = l2factor; - stm = fz_open_image_decomp_stream_from_buffer(ctx, image->buffer, &native_l2factor); + 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->colorspace); - tile = fz_decomp_image_from_stream(ctx, stm, image, indexed, l2factor, native_l2factor); + tile = fz_decomp_image_from_stream(ctx, stm, image, indexed, native_l2factor); /* CMYK JPEGs in XPS documents have to be inverted */ if (image->invert_cmyk_jpeg && @@ -298,35 +291,6 @@ standard_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h, int l2 break; } - /* Now we try to cache the pixmap. Any failure here will just result - * in us not caching. */ - fz_var(keyp); - fz_try(ctx) - { - fz_pixmap *existing_tile; - - keyp = fz_malloc_struct(ctx, fz_image_key); - keyp->refs = 1; - keyp->image = fz_keep_image(ctx, image); - keyp->l2factor = l2factor; - existing_tile = fz_store_item(ctx, keyp, tile, fz_pixmap_size(ctx, tile), &fz_image_store_type); - if (existing_tile) - { - /* We already have a tile. This must have been produced by a - * racing thread. We'll throw away ours and use that one. */ - fz_drop_pixmap(ctx, tile); - tile = existing_tile; - } - } - fz_always(ctx) - { - fz_drop_image_key(ctx, keyp); - } - fz_catch(ctx) - { - /* Do nothing */ - } - return tile; } @@ -334,8 +298,9 @@ fz_pixmap * fz_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h) { fz_pixmap *tile; - int l2factor; + int l2factor, l2factor_remaining; fz_image_key key; + fz_image_key *keyp; /* Check for 'simple' images which are just pixmaps */ if (image->buffer == NULL) @@ -374,7 +339,48 @@ fz_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h) } while (key.l2factor >= 0); - return image->get_pixmap(ctx, image, w, h, l2factor); + /* We'll have to decode the image; request the correct amount of + * downscaling. */ + l2factor_remaining = l2factor; + tile = image->get_pixmap(ctx, image, w, h, &l2factor_remaining); + + /* l2factor_remaining is updated to the amount of subscaling left to do */ + assert(l2factor_remaining >= 0 && l2factor_remaining < 8); + if (l2factor_remaining) + { + fz_subsample_pixmap(ctx, tile, l2factor_remaining); + } + + /* Now we try to cache the pixmap. Any failure here will just result + * in us not caching. */ + fz_var(keyp); + fz_try(ctx) + { + fz_pixmap *existing_tile; + + keyp = fz_malloc_struct(ctx, fz_image_key); + keyp->refs = 1; + keyp->image = fz_keep_image(ctx, image); + keyp->l2factor = l2factor; + existing_tile = fz_store_item(ctx, keyp, tile, fz_pixmap_size(ctx, tile), &fz_image_store_type); + if (existing_tile) + { + /* We already have a tile. This must have been produced by a + * racing thread. We'll throw away ours and use that one. */ + fz_drop_pixmap(ctx, tile); + tile = existing_tile; + } + } + fz_always(ctx) + { + fz_drop_image_key(ctx, keyp); + } + fz_catch(ctx) + { + /* Do nothing */ + } + + return tile; } fz_image * diff --git a/source/pdf/pdf-stream.c b/source/pdf/pdf-stream.c index 32440266..4636a1a7 100644 --- a/source/pdf/pdf-stream.c +++ b/source/pdf/pdf-stream.c @@ -349,7 +349,7 @@ pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *di stm = fz_open_leecher(ctx, stm, bc->buffer); stm = fz_open_image_decomp_stream(ctx, stm, &bc->params, &dummy_l2factor); - image->tile = fz_decomp_image_from_stream(ctx, stm, image, indexed, 0, 0); + image->tile = fz_decomp_image_from_stream(ctx, stm, image, indexed, 0); } fz_catch(ctx) { |