From 051b4932219bed310e17505b2e73029d371a18ce Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Fri, 26 Jun 2015 17:43:06 +0100 Subject: Rejig the internals of fz_image slightly. Previously, we had people calling image->get_pixmap directly. Now we have them all call fz_image_get_pixmap, which will look for a cached version in the store, and only call get_pixmap if required. Previously fz_image_get_pixmap used to look for the cached version in the store, and decode if not - hence the decoding code is now extracted out into standard_image_get_pixmap. This was the original intent of the code, it just somehow didn't end up like that. This nicely queues us up for being able to have fz_images that use a different get_pixel implementation, such as that which will be required for the gprf code. --- include/mupdf/fitz/image.h | 9 ++-- source/fitz/draw-device.c | 6 +-- source/fitz/image.c | 100 ++++++++++++++++++++++++--------------------- source/fitz/test-device.c | 2 +- source/pdf/pdf-device.c | 2 +- source/tools/pdfextract.c | 2 +- 6 files changed, 66 insertions(+), 55 deletions(-) diff --git a/include/mupdf/fitz/image.h b/include/mupdf/fitz/image.h index 3d40cb1d..9c9a9ac4 100644 --- a/include/mupdf/fitz/image.h +++ b/include/mupdf/fitz/image.h @@ -67,17 +67,20 @@ struct fz_image_s int w, h, n, bpc; fz_image *mask; fz_colorspace *colorspace; - fz_pixmap *(*get_pixmap)(fz_context *, fz_image *, int w, int h); - fz_compressed_buffer *buffer; + fz_pixmap *(*get_pixmap)(fz_context *, fz_image *, int w, int h, int l2factor); int colorkey[FZ_MAX_COLORS * 2]; float decode[FZ_MAX_COLORS * 2]; int imagemask; int interpolate; int usecolorkey; - fz_pixmap *tile; /* Private to the implementation */ int xres; /* As given in the image, not necessarily as rendered */ int yres; /* As given in the image, not necessarily as rendered */ int invert_cmyk_jpeg; + + /* Only 'standard' images use these currently. Maybe they should be + * moved out into a derived image class. */ + fz_compressed_buffer *buffer; + fz_pixmap *tile; }; fz_pixmap *fz_load_jpx(fz_context *ctx, unsigned char *data, int size, fz_colorspace *cs, int indexed); diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index b2819a0b..a2499016 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -1116,7 +1116,7 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m dx = sqrtf(local_ctm.a * local_ctm.a + local_ctm.b * local_ctm.b); dy = sqrtf(local_ctm.c * local_ctm.c + local_ctm.d * local_ctm.d); - pixmap = fz_new_pixmap_from_image(ctx, image, dx, dy); + pixmap = fz_image_get_pixmap(ctx, image, dx, dy); orig_pixmap = pixmap; /* convert images with more components (cmyk->rgb) before scaling */ @@ -1216,7 +1216,7 @@ fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const dx = sqrtf(local_ctm.a * local_ctm.a + local_ctm.b * local_ctm.b); dy = sqrtf(local_ctm.c * local_ctm.c + local_ctm.d * local_ctm.d); - pixmap = fz_new_pixmap_from_image(ctx, image, dx, dy); + pixmap = fz_image_get_pixmap(ctx, image, dx, dy); orig_pixmap = pixmap; fz_try(ctx) @@ -1319,7 +1319,7 @@ fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_try(ctx) { - pixmap = fz_new_pixmap_from_image(ctx, image, dx, dy); + pixmap = fz_image_get_pixmap(ctx, image, dx, dy); orig_pixmap = pixmap; state[1].mask = mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); diff --git a/source/fitz/image.c b/source/fitz/image.c index 77999ff1..0cf06b33 100644 --- a/source/fitz/image.c +++ b/source/fitz/image.c @@ -7,7 +7,7 @@ fz_new_pixmap_from_image(fz_context *ctx, fz_image *image, int w, int h) { if (image == NULL) return NULL; - return image->get_pixmap(ctx, image, w, h); + return fz_image_get_pixmap(ctx, image, w, h); } fz_image * @@ -108,7 +108,7 @@ fz_mask_color_key(fz_pixmap *pix, int n, int *colorkey) static void fz_unblend_masked_tile(fz_context *ctx, fz_pixmap *tile, fz_image *image) { - fz_pixmap *mask = image->mask->get_pixmap(ctx, image->mask, tile->w, tile->h); + fz_pixmap *mask = fz_image_get_pixmap(ctx, image->mask, tile->w, tile->h); unsigned char *s = mask->samples, *end = s + mask->w * mask->h; unsigned char *d = tile->samples; int k; @@ -238,53 +238,14 @@ fz_drop_image_imp(fz_context *ctx, fz_storable *image_) fz_free(ctx, image); } -fz_pixmap * -fz_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h) +static fz_pixmap * +standard_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h, int l2factor) { - fz_pixmap *tile; fz_stream *stm; - int l2factor; - fz_image_key key; int native_l2factor; int indexed; fz_image_key *keyp; - - /* Check for 'simple' images which are just pixmaps */ - if (image->buffer == NULL) - { - tile = image->tile; - if (!tile) - return NULL; - return fz_keep_pixmap(ctx, tile); /* That's all we can give you! */ - } - - /* Ensure our expectations for tile size are reasonable */ - if (w < 0 || w > image->w) - w = image->w; - if (h < 0 || h > image->h) - h = image->h; - - /* What is our ideal factor? We search for the largest factor where - * we can subdivide and stay larger than the required size. We add - * a fudge factor of +2 here to allow for the possibility of - * expansion due to grid fitting. */ - if (w == 0 || h == 0) - l2factor = 0; - else - for (l2factor=0; image->w>>(l2factor+1) >= w+2 && image->h>>(l2factor+1) >= h+2 && l2factor < 8; l2factor++); - - /* Can we find any suitable tiles in the cache? */ - key.refs = 1; - key.image = image; - key.l2factor = l2factor; - do - { - tile = fz_find_item(ctx, fz_drop_pixmap_imp, &key, &fz_image_store_type); - if (tile) - return tile; - key.l2factor--; - } - while (key.l2factor >= 0); + fz_pixmap *tile; /* We need to make a new one. */ /* First check for ones that we can't decode using streams */ @@ -369,6 +330,53 @@ fz_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h) return tile; } +fz_pixmap * +fz_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h) +{ + fz_pixmap *tile; + int l2factor; + fz_image_key key; + + /* Check for 'simple' images which are just pixmaps */ + if (image->buffer == NULL) + { + tile = image->tile; + if (!tile) + return NULL; + return fz_keep_pixmap(ctx, tile); /* That's all we can give you! */ + } + + /* Ensure our expectations for tile size are reasonable */ + if (w < 0 || w > image->w) + w = image->w; + if (h < 0 || h > image->h) + h = image->h; + + /* What is our ideal factor? We search for the largest factor where + * we can subdivide and stay larger than the required size. We add + * a fudge factor of +2 here to allow for the possibility of + * expansion due to grid fitting. */ + if (w == 0 || h == 0) + l2factor = 0; + else + for (l2factor=0; image->w>>(l2factor+1) >= w+2 && image->h>>(l2factor+1) >= h+2 && l2factor < 8; l2factor++); + + /* Can we find any suitable tiles in the cache? */ + key.refs = 1; + key.image = image; + key.l2factor = l2factor; + do + { + tile = fz_find_item(ctx, fz_drop_pixmap_imp, &key, &fz_image_store_type); + if (tile) + return tile; + key.l2factor--; + } + while (key.l2factor >= 0); + + return image->get_pixmap(ctx, image, w, h, l2factor); +} + fz_image * fz_new_image_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, fz_image *mask) { @@ -386,7 +394,7 @@ fz_new_image_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, fz_image *mask) image->colorspace = fz_keep_colorspace(ctx, pixmap->colorspace); image->bpc = 8; image->buffer = NULL; - image->get_pixmap = fz_image_get_pixmap; + image->get_pixmap = NULL; image->xres = pixmap->xres; image->yres = pixmap->yres; image->tile = fz_keep_pixmap(ctx, pixmap); @@ -413,7 +421,7 @@ fz_new_image(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace, { image = fz_malloc_struct(ctx, fz_image); FZ_INIT_STORABLE(image, 1, fz_drop_image_imp); - image->get_pixmap = fz_image_get_pixmap; + image->get_pixmap = standard_image_get_pixmap; image->w = w; image->h = h; image->xres = xres; diff --git a/source/fitz/test-device.c b/source/fitz/test-device.c index d0bd08c7..45642cd0 100644 --- a/source/fitz/test-device.c +++ b/source/fitz/test-device.c @@ -184,7 +184,7 @@ fz_test_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, const fz_ma return; } - pix = fz_new_pixmap_from_image(ctx, image, 0, 0); + pix = fz_image_get_pixmap(ctx, image, 0, 0); if (pix == NULL) /* Should never happen really, but... */ return; diff --git a/source/pdf/pdf-device.c b/source/pdf/pdf-device.c index 8b99c4f0..c65377ae 100644 --- a/source/pdf/pdf-device.c +++ b/source/pdf/pdf-device.c @@ -146,7 +146,7 @@ send_image(fz_context *ctx, pdf_device *pdev, fz_image *image, int mask, int sma int n; /* Currently, set to maintain resolution; should we consider * subsampling here according to desired output res? */ - pixmap = image->get_pixmap(ctx, image, image->w, image->h); + pixmap = fz_image_get_pixmap(ctx, image, image->w, image->h); colorspace = pixmap->colorspace; /* May be different to image->colorspace! */ n = (pixmap->n == 1 ? 1 : pixmap->n-1); size = image->w * image->h * n; diff --git a/source/tools/pdfextract.c b/source/tools/pdfextract.c index a89566cc..a558f264 100644 --- a/source/tools/pdfextract.c +++ b/source/tools/pdfextract.c @@ -72,7 +72,7 @@ static void saveimage(int num) /* TODO: detect DCTD and save as jpeg */ image = pdf_load_image(ctx, doc, ref); - pix = fz_new_pixmap_from_image(ctx, image, 0, 0); + pix = fz_image_get_pixmap(ctx, image, 0, 0); fz_drop_image(ctx, image); snprintf(buf, sizeof(buf), "img-%04d", num); -- cgit v1.2.3