summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-04-14 13:51:32 +0100
committerRobin Watts <robin.watts@artifex.com>2016-04-28 12:30:43 +0100
commit44fff08dc64d358df441a9e615bbaacf7b01d54a (patch)
treebab4f36472952ccdfff594fd699230f2f15b1b23
parent88e9fd50724cff8d656060715fa56409ba7dab84 (diff)
downloadmupdf-44fff08dc64d358df441a9e615bbaacf7b01d54a.tar.xz
Refactor fz_image code cases.
Split compressed images (images based on a compressed buffer) and pixmap images (images based on a pixmap) out into separate subclasses.
-rw-r--r--include/mupdf/fitz/image.h26
-rw-r--r--include/mupdf/pdf/xref.h2
-rw-r--r--source/fitz/image.c276
-rw-r--r--source/fitz/stext-output.c7
-rw-r--r--source/fitz/svg-device.c24
-rw-r--r--source/fitz/test-device.c6
-rw-r--r--source/gprf/gprf-doc.c2
-rw-r--r--source/pdf/pdf-image.c37
-rw-r--r--source/pdf/pdf-op-buffer.c2
-rw-r--r--source/pdf/pdf-stream.c6
10 files changed, 268 insertions, 120 deletions
diff --git a/include/mupdf/fitz/image.h b/include/mupdf/fitz/image.h
index 7ddbfb69..41c4b80c 100644
--- a/include/mupdf/fitz/image.h
+++ b/include/mupdf/fitz/image.h
@@ -18,6 +18,7 @@
demand.
*/
typedef struct fz_image_s fz_image;
+typedef struct fz_compressed_image_s fz_compressed_image;
/*
fz_get_pixmap_from_image: Called to get a handle to a pixmap from an image.
@@ -58,14 +59,20 @@ void fz_drop_image(fz_context *ctx, fz_image *image);
*/
fz_image *fz_keep_image(fz_context *ctx, fz_image *image);
-fz_image *fz_new_image(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace, int xres, int yres, int interpolate, int imagemask, float *decode, int *colorkey, fz_compressed_buffer *buffer, fz_image *mask);
+typedef void (fz_drop_image_fn)(fz_context *ctx, fz_image *image);
+typedef fz_pixmap *(fz_image_get_pixmap_fn)(fz_context *, fz_image *, fz_irect *, int, int, int *);
+typedef size_t (fz_image_get_size_fn)(fz_context *, fz_image *);
+
+fz_image *fz_new_image(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace, int xres, int yres, int interpolate, int imagemask, float *decode, int *colorkey, fz_image *mask, int size, fz_image_get_pixmap_fn *get, fz_image_get_size_fn *get_size, fz_drop_image_fn *drop);
+fz_image *fz_new_image_from_compressed_buffer(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace, int xres, int yres, int interpolate, int imagemask, float *decode, int *colorkey, fz_compressed_buffer *buffer, fz_image *mask);
fz_image *fz_new_image_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, fz_image *mask);
fz_image *fz_new_image_from_data(fz_context *ctx, unsigned char *data, int len);
fz_image *fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer);
fz_image *fz_new_image_from_file(fz_context *ctx, const char *path);
void fz_drop_image_imp(fz_context *ctx, fz_storable *image);
-fz_pixmap *fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, fz_irect *subarea, int indexed, int l2factor);
+fz_pixmap *fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_compressed_image *image, fz_irect *subarea, int indexed, int l2factor);
fz_pixmap *fz_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src);
+size_t fz_image_size(fz_context *ctx, fz_image *im);
struct fz_image_s
{
@@ -77,18 +84,16 @@ struct fz_image_s
unsigned int interpolate:1;
unsigned int use_colorkey:1;
unsigned int invert_cmyk_jpeg:1;
+ unsigned int decoded:1;
fz_image *mask;
int xres; /* As given in the image, not necessarily as rendered */
int yres; /* As given in the image, not necessarily as rendered */
fz_colorspace *colorspace;
- fz_pixmap *(*get_pixmap)(fz_context *, fz_image *, fz_irect *subarea, int w, int h, int *l2factor);
+ fz_drop_image_fn *drop_image;
+ fz_image_get_pixmap_fn *get_pixmap;
+ fz_image_get_size_fn *get_size;
int colorkey[FZ_MAX_COLORS * 2];
float decode[FZ_MAX_COLORS * 2];
-
- /* 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_jpeg(fz_context *ctx, unsigned char *data, int size);
@@ -111,4 +116,9 @@ fz_pixmap *fz_load_tiff_subimage(fz_context *ctx, unsigned char *buf, int len, i
void fz_image_resolution(fz_image *image, int *xres, int *yres);
+fz_pixmap *fz_compressed_image_tile(fz_context *ctx, fz_compressed_image *cimg);
+void fz_set_compressed_image_tile(fz_context *ctx, fz_compressed_image *cimg, fz_pixmap *pix);
+fz_compressed_buffer *fz_compressed_image_buffer(fz_context *ctx, fz_image *image);
+void fz_set_compressed_image_buffer(fz_context *ctx, fz_compressed_image *cimg, fz_compressed_buffer *buf);
+
#endif
diff --git a/include/mupdf/pdf/xref.h b/include/mupdf/pdf/xref.h
index 410791c7..a6692cab 100644
--- a/include/mupdf/pdf/xref.h
+++ b/include/mupdf/pdf/xref.h
@@ -85,7 +85,7 @@ fz_stream *pdf_open_stream(fz_context *ctx, pdf_document *doc, int num, int gen)
fz_stream *pdf_open_inline_stream(fz_context *ctx, pdf_document *doc, pdf_obj *stmobj, int length, fz_stream *chain, fz_compression_params *params);
fz_compressed_buffer *pdf_load_compressed_stream(fz_context *ctx, pdf_document *doc, int num, int gen);
-void pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int length, fz_stream *cstm, int indexed, fz_image *image);
+void pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int length, fz_stream *cstm, int indexed, fz_compressed_image *image);
fz_stream *pdf_open_stream_with_offset(fz_context *ctx, pdf_document *doc, int num, int gen, pdf_obj *dict, fz_off_t stm_ofs);
fz_stream *pdf_open_compressed_stream(fz_context *ctx, fz_compressed_buffer *);
fz_stream *pdf_open_contents_stream(fz_context *ctx, pdf_document *doc, pdf_obj *obj);
diff --git a/source/fitz/image.c b/source/fitz/image.c
index 931eb44e..538f52ec 100644
--- a/source/fitz/image.c
+++ b/source/fitz/image.c
@@ -3,6 +3,19 @@
#define SANE_DPI 72.0f
#define INSANE_DPI 4800.0f
+struct fz_compressed_image_s
+{
+ fz_image super;
+ fz_pixmap *tile;
+ fz_compressed_buffer *buffer;
+};
+
+typedef struct fz_pixmap_image_s
+{
+ fz_image super;
+ fz_pixmap *tile;
+} fz_pixmap_image;
+
fz_image *
fz_keep_image(fz_context *ctx, fz_image *image)
{
@@ -124,8 +137,9 @@ 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, fz_irect *subarea, int indexed, int l2factor)
+fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_compressed_image *cimg, fz_irect *subarea, int indexed, int l2factor)
{
+ fz_image *image = &cimg->super;
fz_pixmap *tile = NULL;
int stride, len, i;
unsigned char *samples = NULL;
@@ -275,18 +289,40 @@ fz_drop_image_imp(fz_context *ctx, fz_storable *image_)
{
fz_image *image = (fz_image *)image_;
- if (image == NULL)
- return;
- fz_drop_pixmap(ctx, image->tile);
- fz_drop_compressed_buffer(ctx, image->buffer);
+ image->drop_image(ctx, image);
+}
+
+void
+fz_drop_image_base(fz_context *ctx, fz_image *image)
+{
fz_drop_colorspace(ctx, image->colorspace);
fz_drop_image(ctx, image->mask);
fz_free(ctx, image);
}
+static void
+drop_compressed_image(fz_context *ctx, fz_image *image_)
+{
+ fz_compressed_image *image = (fz_compressed_image *)image_;
+
+ fz_drop_pixmap(ctx, image->tile);
+ fz_drop_compressed_buffer(ctx, image->buffer);
+ fz_drop_image_base(ctx, &image->super);
+}
+
+static void
+drop_pixmap_image(fz_context *ctx, fz_image *image_)
+{
+ fz_pixmap_image *image = (fz_pixmap_image *)image_;
+
+ fz_drop_pixmap(ctx, image->tile);
+ fz_drop_image_base(ctx, &image->super);
+}
+
static fz_pixmap *
-standard_image_get_pixmap(fz_context *ctx, fz_image *image, fz_irect *subarea, int w, int h, int *l2factor)
+compressed_image_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *subarea, int w, int h, int *l2factor)
{
+ fz_compressed_image *image = (fz_compressed_image *)image_;
int native_l2factor;
fz_stream *stm;
int indexed;
@@ -322,10 +358,10 @@ standard_image_get_pixmap(fz_context *ctx, fz_image *image, fz_irect *subarea, i
{
if (d[1] < 0xC0 || (0xC3 < d[1] && d[1] < 0xC9) || 0xCB < d[1])
continue;
- if ((d[5] == 0 && d[6] == 0) || ((d[5] << 8) | d[6]) > image->h)
+ if ((d[5] == 0 && d[6] == 0) || ((d[5] << 8) | d[6]) > image->super.h)
{
- d[5] = (image->h >> 8) & 0xFF;
- d[6] = image->h & 0xFF;
+ d[5] = (image->super.h >> 8) & 0xFF;
+ d[6] = image->super.h & 0xFF;
}
}
}
@@ -337,14 +373,14 @@ standard_image_get_pixmap(fz_context *ctx, fz_image *image, fz_irect *subarea, i
if (l2factor)
native_l2factor -= *l2factor;
- indexed = fz_colorspace_is_indexed(ctx, image->colorspace);
+ 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);
/* CMYK JPEGs in XPS documents have to be inverted */
- if (image->invert_cmyk_jpeg &&
+ if (image->super.invert_cmyk_jpeg &&
image->buffer->params.type == FZ_IMAGE_JPEG &&
- image->colorspace == fz_device_cmyk(ctx) &&
+ image->super.colorspace == fz_device_cmyk(ctx) &&
image->buffer->params.u.jpeg.color_transform)
{
fz_invert_pixmap(ctx, tile);
@@ -357,13 +393,26 @@ standard_image_get_pixmap(fz_context *ctx, fz_image *image, fz_irect *subarea, i
{
subarea->x0 = 0;
subarea->y0 = 0;
- subarea->x1 = image->w;
- subarea->y1 = image->h;
+ subarea->x1 = image->super.w;
+ subarea->y1 = image->super.h;
}
return tile;
}
+static fz_pixmap *
+pixmap_image_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *subarea, int w, int h, int *l2factor)
+{
+ fz_pixmap_image *image = (fz_pixmap_image *)image_;
+
+ /* 'Simple' images created direct from pixmaps will have no buffer
+ * of compressed data. We cannot do any better than just returning
+ * a pointer to the original 'tile'.
+ */
+ return fz_keep_pixmap(ctx, image->tile); /* That's all we can give you! */
+
+}
+
static void
update_ctm_for_subarea(fz_matrix *ctm, const fz_irect *subarea, int w, int h)
{
@@ -437,20 +486,16 @@ fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, const fz_irect *subar
h = image->h;
}
- /* 'Simple' images created direct from pixmaps will have no buffer
- * of compressed data. We cannot do any better than just returning
- * a pointer to the original 'tile'.
- *
- * Note, that we can get image->tile != NULL for jpeg 2000 images
- * with masks applied, so we need both parts of the following test.
- */
- if (image->buffer == NULL && image->tile != NULL)
+ if (image->decoded)
{
+ /* If the image is already decoded, then we can't offer a subarea,
+ * or l2factor, and we don't want to cache. */
+ l2factor_remaining = 0;
if (dw)
*dw = w;
if (dh)
*dh = h;
- return fz_keep_pixmap(ctx, image->tile); /* That's all we can give you! */
+ return image->get_pixmap(ctx, image, NULL, image->w, image->h, &l2factor_remaining);
}
/* What is our ideal factor? We search for the largest factor where
@@ -573,78 +618,131 @@ fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, const fz_irect *subar
return tile;
}
+static size_t
+pixmap_image_get_size(fz_context *ctx, fz_image *image)
+{
+ fz_pixmap_image *im = (fz_pixmap_image *)image;
+
+ if (image == NULL)
+ return 0;
+
+ return sizeof(fz_pixmap_image) + fz_pixmap_size(ctx, im->tile);
+}
+
+size_t fz_image_size(fz_context *ctx, fz_image *im)
+{
+ if (im == NULL)
+ return 0;
+
+ return im->get_size(ctx, im);
+}
+
fz_image *
fz_new_image_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, fz_image *mask)
{
- fz_image *image;
+ fz_pixmap_image *image;
assert(mask == NULL || mask->mask == NULL);
fz_try(ctx)
{
- image = fz_malloc_struct(ctx, fz_image);
- FZ_INIT_STORABLE(image, 1, fz_drop_image_imp);
- image->w = pixmap->w;
- image->h = pixmap->h;
- image->n = pixmap->n;
- image->colorspace = fz_keep_colorspace(ctx, pixmap->colorspace);
- image->invert_cmyk_jpeg = 1;
- image->bpc = 8;
- image->buffer = NULL;
- image->get_pixmap = NULL;
- image->xres = pixmap->xres;
- image->yres = pixmap->yres;
+ image = (fz_pixmap_image *)
+ fz_new_image(ctx, pixmap->w, pixmap->h,
+ pixmap->n, pixmap->colorspace,
+ pixmap->xres, pixmap->yres, 0, 0,
+ NULL, NULL, mask,
+ sizeof(fz_pixmap_image),
+ pixmap_image_get_pixmap,
+ pixmap_image_get_size,
+ drop_pixmap_image);
image->tile = fz_keep_pixmap(ctx, pixmap);
- image->mask = mask;
+ image->super.decoded = 1;
}
fz_catch(ctx)
{
fz_drop_image(ctx, mask);
fz_rethrow(ctx);
}
- return image;
+ return &image->super;
}
fz_image *
fz_new_image(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace,
- int xres, int yres, int interpolate, int imagemask, float *decode,
- int *colorkey, fz_compressed_buffer *buffer, fz_image *mask)
+ int xres, int yres, int interpolate, int imagemask, float *decode,
+ int *colorkey, fz_image *mask, int size, fz_image_get_pixmap_fn *get,
+ fz_image_get_size_fn *get_size, fz_drop_image_fn *drop)
{
fz_image *image;
assert(mask == NULL || mask->mask == NULL);
-
- fz_try(ctx)
+ assert(size >= sizeof(fz_image));
+
+ image = Memento_label(fz_calloc(ctx, 1, size), "fz_image");
+ FZ_INIT_STORABLE(image, 1, fz_drop_image_imp);
+ image->drop_image = drop;
+ image->get_pixmap = get;
+ image->get_size = get_size;
+ image->w = w;
+ image->h = h;
+ image->xres = xres;
+ image->yres = yres;
+ image->bpc = bpc;
+ image->n = (colorspace ? colorspace->n : 1);
+ image->colorspace = fz_keep_colorspace(ctx, colorspace);
+ image->invert_cmyk_jpeg = 1;
+ image->interpolate = interpolate;
+ image->imagemask = imagemask;
+ image->use_colorkey = (colorkey != NULL);
+ if (colorkey)
+ memcpy(image->colorkey, colorkey, sizeof(int)*image->n*2);
+ if (decode)
+ memcpy(image->decode, decode, sizeof(float)*image->n*2);
+ else
{
- image = fz_malloc_struct(ctx, fz_image);
- FZ_INIT_STORABLE(image, 1, fz_drop_image_imp);
- image->get_pixmap = standard_image_get_pixmap;
- image->w = w;
- image->h = h;
- image->xres = xres;
- image->yres = yres;
- image->bpc = bpc;
- image->n = (colorspace ? colorspace->n : 1);
- image->colorspace = colorspace;
- image->invert_cmyk_jpeg = 1;
- image->interpolate = interpolate;
- image->imagemask = imagemask;
- image->use_colorkey = (colorkey != NULL);
- if (colorkey)
- memcpy(image->colorkey, colorkey, sizeof(int)*image->n*2);
- if (decode)
- memcpy(image->decode, decode, sizeof(float)*image->n*2);
- else
+ float maxval = fz_colorspace_is_indexed(ctx, colorspace) ? (1 << bpc) - 1 : 1;
+ int i;
+ for (i = 0; i < image->n; i++)
{
- float maxval = fz_colorspace_is_indexed(ctx, colorspace) ? (1 << bpc) - 1 : 1;
- int i;
- for (i = 0; i < image->n; i++)
- {
- image->decode[2*i] = 0;
- image->decode[2*i+1] = maxval;
- }
+ image->decode[2*i] = 0;
+ image->decode[2*i+1] = maxval;
}
- image->mask = mask;
+ }
+ image->mask = mask;
+
+ return image;
+}
+
+static size_t
+compressed_image_get_size(fz_context *ctx, fz_image *image)
+{
+ fz_compressed_image *im = (fz_compressed_image *)image;
+
+ if (image == NULL)
+ return 0;
+
+ return sizeof(fz_pixmap_image) + fz_pixmap_size(ctx, im->tile) + (im->buffer && im->buffer->buffer ? im->buffer->buffer->cap : 0);
+}
+
+
+fz_image *
+fz_new_image_from_compressed_buffer(fz_context *ctx, int w, int h,
+ int bpc, fz_colorspace *colorspace,
+ int xres, int yres, int interpolate, int imagemask, float *decode,
+ int *colorkey, fz_compressed_buffer *buffer, fz_image *mask)
+{
+ fz_compressed_image *image;
+
+ fz_try(ctx)
+ {
+ image = (fz_compressed_image *)
+ fz_new_image(ctx, w, h, bpc,
+ colorspace, xres, yres,
+ interpolate, imagemask, decode,
+ colorkey, mask,
+ sizeof(fz_compressed_image),
+ compressed_image_get_pixmap,
+ compressed_image_get_size,
+ drop_compressed_image);
image->buffer = buffer;
}
fz_catch(ctx)
@@ -653,7 +751,33 @@ fz_new_image(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace,
fz_rethrow(ctx);
}
- return image;
+ return &image->super;
+}
+
+fz_compressed_buffer *fz_compressed_image_buffer(fz_context *ctx, fz_image *image)
+{
+ if (image == NULL || image->get_pixmap != compressed_image_get_pixmap)
+ return NULL;
+ return ((fz_compressed_image *)image)->buffer;
+}
+
+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_pixmap *fz_compressed_image_tile(fz_context *ctx, fz_compressed_image *image)
+{
+ if (image == NULL || image->super.get_pixmap != compressed_image_get_pixmap)
+ return NULL;
+ return ((fz_compressed_image *)image)->tile;
+}
+
+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_image *
@@ -689,11 +813,13 @@ fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer)
{
fz_compressed_buffer *bc = NULL;
int w, h, xres, yres;
- fz_colorspace *cspace;
+ fz_colorspace *cspace = NULL;
int len = buffer->len;
unsigned char *buf = buffer->data;
+ fz_image *image;
fz_var(bc);
+ fz_var(cspace);
fz_try(ctx)
{
@@ -736,6 +862,12 @@ fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer)
}
else
fz_throw(ctx, FZ_ERROR_GENERIC, "unknown image file format");
+
+ image = fz_new_image_from_compressed_buffer(ctx, w, h, 8, cspace, xres, yres, 0, 0, NULL, NULL, bc, NULL);
+ }
+ fz_always(ctx)
+ {
+ fz_drop_colorspace(ctx, cspace);
}
fz_catch(ctx)
{
@@ -743,7 +875,7 @@ fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer)
fz_rethrow(ctx);
}
- return fz_new_image(ctx, w, h, 8, cspace, xres, yres, 0, 0, NULL, NULL, bc, NULL);
+ return image;
}
fz_image *
diff --git a/source/fitz/stext-output.c b/source/fitz/stext-output.c
index 70b0bf7e..c19c5b4b 100644
--- a/source/fitz/stext-output.c
+++ b/source/fitz/stext-output.c
@@ -245,16 +245,17 @@ fz_print_stext_page_html(fz_context *ctx, fz_output *out, fz_stext_page *page)
case FZ_PAGE_BLOCK_IMAGE:
{
fz_image_block *image = page->blocks[block_n].u.image;
+ fz_compressed_buffer *buffer = fz_compressed_image_buffer(ctx, image->image);
fz_printf(ctx, out, "<img width=%d height=%d src=\"data:", image->image->w, image->image->h);
- switch (image->image->buffer == NULL ? FZ_IMAGE_JPX : image->image->buffer->params.type)
+ switch (buffer == NULL ? FZ_IMAGE_JPX : buffer->params.type)
{
case FZ_IMAGE_JPEG:
fz_printf(ctx, out, "image/jpeg;base64,");
- send_data_base64(ctx, out, image->image->buffer->buffer);
+ send_data_base64(ctx, out, buffer->buffer);
break;
case FZ_IMAGE_PNG:
fz_printf(ctx, out, "image/png;base64,");
- send_data_base64(ctx, out, image->image->buffer->buffer);
+ send_data_base64(ctx, out, buffer->buffer);
break;
default:
{
diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c
index 5f60cf75..97a1acca 100644
--- a/source/fitz/svg-device.c
+++ b/source/fitz/svg-device.c
@@ -718,6 +718,7 @@ svg_dev_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, const fz_ma
{
svg_device *sdev = (svg_device*)dev;
fz_output *out = sdev->out;
+ fz_compressed_buffer *buffer;
fz_matrix local_ctm = *ctm;
fz_matrix scale = { 0 };
@@ -730,16 +731,17 @@ svg_dev_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, const fz_ma
fz_printf(ctx, out, "<g opacity=\"%g\">", alpha);
fz_printf(ctx, out, "<image");
svg_dev_ctm(ctx, sdev, &local_ctm);
+ buffer = fz_compressed_image_buffer(ctx, image);
fz_printf(ctx, out, " width=\"%dpx\" height=\"%dpx\" xlink:href=\"data:", image->w, image->h);
- switch (image->buffer == NULL ? FZ_IMAGE_JPX : image->buffer->params.type)
+ switch (buffer == NULL ? FZ_IMAGE_JPX : buffer->params.type)
{
case FZ_IMAGE_JPEG:
fz_printf(ctx, out, "image/jpeg;base64,");
- send_data_base64(ctx, out, image->buffer->buffer);
+ send_data_base64(ctx, out, buffer->buffer);
break;
case FZ_IMAGE_PNG:
fz_printf(ctx, out, "image/png;base64,");
- send_data_base64(ctx, out, image->buffer->buffer);
+ send_data_base64(ctx, out, buffer->buffer);
break;
default:
{
@@ -805,6 +807,7 @@ svg_dev_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const
fz_colorspace *colorspace, const float *color, float alpha)
{
svg_device *sdev = (svg_device*)dev;
+ fz_compressed_buffer *buffer;
fz_output *out;
fz_matrix local_ctm = *ctm;
@@ -818,15 +821,16 @@ svg_dev_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const
out = start_def(ctx, sdev);
fz_printf(ctx, out, "<mask id=\"ma%d\"><image", mask);
fz_printf(ctx, out, " width=\"%dpx\" height=\"%dpx\" xlink:href=\"data:", image->w, image->h);
- switch (image->buffer == NULL ? FZ_IMAGE_JPX : image->buffer->params.type)
+ buffer = fz_compressed_image_buffer(ctx, image);
+ switch (buffer == NULL ? FZ_IMAGE_JPX : buffer->params.type)
{
case FZ_IMAGE_JPEG:
fz_printf(ctx, out, "image/jpeg;base64,");
- send_data_base64(ctx, out, image->buffer->buffer);
+ send_data_base64(ctx, out, buffer->buffer);
break;
case FZ_IMAGE_PNG:
fz_printf(ctx, out, "image/png;base64,");
- send_data_base64(ctx, out, image->buffer->buffer);
+ send_data_base64(ctx, out, buffer->buffer);
break;
default:
{
@@ -853,6 +857,7 @@ svg_dev_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const
fz_matrix local_ctm = *ctm;
fz_matrix scale = { 0 };
int mask = sdev->id++;
+ fz_compressed_buffer *buffer;
scale.a = 1.0f / image->w;
scale.d = 1.0f / image->h;
@@ -862,15 +867,16 @@ svg_dev_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const
fz_printf(ctx, out, "<mask id=\"ma%d\"><image", mask);
svg_dev_ctm(ctx, sdev, &local_ctm);
fz_printf(ctx, out, " width=\"%dpx\" height=\"%dpx\" xlink:href=\"data:", image->w, image->h);
- switch (image->buffer == NULL ? FZ_IMAGE_JPX : image->buffer->params.type)
+ buffer = fz_compressed_image_buffer(ctx, image);
+ switch (buffer == NULL ? FZ_IMAGE_JPX : buffer->params.type)
{
case FZ_IMAGE_JPEG:
fz_printf(ctx, out, "image/jpeg;base64,");
- send_data_base64(ctx, out, image->buffer->buffer);
+ send_data_base64(ctx, out, buffer->buffer);
break;
case FZ_IMAGE_PNG:
fz_printf(ctx, out, "image/png;base64,");
- send_data_base64(ctx, out, image->buffer->buffer);
+ send_data_base64(ctx, out, buffer->buffer);
break;
default:
{
diff --git a/source/fitz/test-device.c b/source/fitz/test-device.c
index 6a4e0127..c0fb95f9 100644
--- a/source/fitz/test-device.c
+++ b/source/fitz/test-device.c
@@ -129,13 +129,15 @@ fz_test_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, const fz_ma
fz_pixmap *pix;
unsigned int count, i, k;
unsigned char *s;
+ fz_compressed_buffer *buffer;
if (*t->is_color || !image->colorspace || image->colorspace == fz_device_gray(ctx))
return;
- if (image->buffer && image->bpc == 8)
+ buffer = fz_compressed_image_buffer(ctx, image);
+ if (buffer && image->bpc == 8)
{
- fz_stream *stream = fz_open_compressed_buffer(ctx, image->buffer);
+ fz_stream *stream = fz_open_compressed_buffer(ctx, buffer);
count = (unsigned int)image->w * (unsigned int)image->h;
if (image->colorspace == fz_device_rgb(ctx))
{
diff --git a/source/gprf/gprf-doc.c b/source/gprf/gprf-doc.c
index d1dc4aa3..18a8d812 100644
--- a/source/gprf/gprf-doc.c
+++ b/source/gprf/gprf-doc.c
@@ -165,7 +165,7 @@ fz_drop_image_gprf_imp(fz_context *ctx, fz_storable *image_)
fz_drop_gprf_file(ctx, image->file);
fz_drop_separations(ctx, image->separations);
- fz_drop_image_imp(ctx, &image->base.storable);
+ fz_drop_image_base(ctx, &image->super);
}
static inline unsigned char *cmyk_to_rgba(unsigned char *out, uint32_t c, uint32_t m, uint32_t y, uint32_t k)
diff --git a/source/pdf/pdf-image.c b/source/pdf/pdf-image.c
index 86ec41d8..4fec9faa 100644
--- a/source/pdf/pdf-image.c
+++ b/source/pdf/pdf-image.c
@@ -37,20 +37,22 @@ pdf_load_image_imp(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *di
if (forcemask)
{
+ fz_compressed_image *cimg = (fz_compressed_image *)image;
fz_pixmap *mask_pixmap;
+ fz_pixmap *tile = fz_compressed_image_tile(ctx, cimg);
if (image->n != 2)
{
fz_pixmap *gray;
fz_irect bbox;
fz_warn(ctx, "soft mask should be grayscale");
- gray = fz_new_pixmap_with_bbox(ctx, fz_device_gray(ctx), fz_pixmap_bbox(ctx, image->tile, &bbox));
- fz_convert_pixmap(ctx, gray, image->tile);
- fz_drop_pixmap(ctx, image->tile);
- image->tile = gray;
+ gray = fz_new_pixmap_with_bbox(ctx, fz_device_gray(ctx), fz_pixmap_bbox(ctx, tile, &bbox));
+ fz_convert_pixmap(ctx, gray, tile);
+ fz_drop_pixmap(ctx, tile);
+ tile = gray;
}
- mask_pixmap = fz_alpha_from_gray(ctx, image->tile, 1);
- fz_drop_pixmap(ctx, image->tile);
- image->tile = mask_pixmap;
+ mask_pixmap = fz_alpha_from_gray(ctx, tile, 1);
+ fz_drop_pixmap(ctx, tile);
+ fz_set_compressed_image_tile(ctx, cimg, mask_pixmap);
}
break; /* Out of fz_try */
}
@@ -158,21 +160,24 @@ pdf_load_image_imp(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *di
int num = pdf_to_num(ctx, dict);
int gen = pdf_to_gen(ctx, dict);
buffer = pdf_load_compressed_stream(ctx, doc, num, gen);
- image = fz_new_image(ctx, w, h, bpc, colorspace, 96, 96, interpolate, imagemask, decode, use_colorkey ? colorkey : NULL, buffer, mask);
+ image = fz_new_image_from_compressed_buffer(ctx, w, h, bpc, colorspace, 96, 96, interpolate, imagemask, decode, use_colorkey ? colorkey : NULL, buffer, mask);
image->invert_cmyk_jpeg = 0;
}
else
{
/* Inline stream */
stride = (w * n * bpc + 7) / 8;
- image = fz_new_image(ctx, w, h, bpc, colorspace, 96, 96, interpolate, imagemask, decode, use_colorkey ? colorkey : NULL, NULL, mask);
+ image = fz_new_image_from_compressed_buffer(ctx, w, h, bpc, colorspace, 96, 96, interpolate, imagemask, decode, use_colorkey ? colorkey : NULL, NULL, mask);
image->invert_cmyk_jpeg = 0;
- pdf_load_compressed_inline_image(ctx, doc, dict, stride * h, cstm, indexed, image);
+ pdf_load_compressed_inline_image(ctx, doc, dict, stride * h, cstm, indexed, (fz_compressed_image *)image);
}
}
- fz_catch(ctx)
+ fz_always(ctx)
{
fz_drop_colorspace(ctx, colorspace);
+ }
+ fz_catch(ctx)
+ {
fz_drop_image(ctx, mask);
fz_drop_image(ctx, image);
fz_rethrow(ctx);
@@ -269,14 +274,6 @@ pdf_load_jpx(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int forcemask)
return img;
}
-static int
-fz_image_size(fz_context *ctx, fz_image *im)
-{
- if (im == NULL)
- return 0;
- return sizeof(*im) + fz_pixmap_size(ctx, im->tile) + (im->buffer && im->buffer->buffer ? im->buffer->buffer->cap : 0);
-}
-
fz_image *
pdf_load_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
{
@@ -303,7 +300,7 @@ pdf_add_image(fz_context *ctx, pdf_document *doc, fz_image *image, int mask)
unsigned char digest[16];
/* If we can maintain compression, do so */
- cbuffer = image->buffer;
+ cbuffer = fz_compressed_image_buffer(ctx, image);
fz_var(pixmap);
fz_var(buffer);
diff --git a/source/pdf/pdf-op-buffer.c b/source/pdf/pdf-op-buffer.c
index 241b096f..163848a0 100644
--- a/source/pdf/pdf-op-buffer.c
+++ b/source/pdf/pdf-op-buffer.c
@@ -551,7 +551,7 @@ pdf_out_BI(fz_context *ctx, pdf_processor *proc, fz_image *img)
if (img == NULL)
return;
- cbuf = img->buffer;
+ cbuf = fz_compressed_image_buffer(ctx, img);
if (cbuf == NULL)
return;
buf = cbuf->buffer;
diff --git a/source/pdf/pdf-stream.c b/source/pdf/pdf-stream.c
index 3c275d2d..167db0a7 100644
--- a/source/pdf/pdf-stream.c
+++ b/source/pdf/pdf-stream.c
@@ -344,7 +344,7 @@ pdf_open_inline_stream(fz_context *ctx, pdf_document *doc, pdf_obj *stmobj, int
}
void
-pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int length, fz_stream *stm, int indexed, fz_image *image)
+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)
{
fz_compressed_buffer *bc = fz_malloc_struct(ctx, fz_compressed_buffer);
@@ -357,14 +357,14 @@ 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, NULL, indexed, 0);
+ fz_set_compressed_image_tile(ctx, image, fz_decomp_image_from_stream(ctx, stm, image, NULL, indexed, 0));
+ fz_set_compressed_image_buffer(ctx, image, bc);
}
fz_catch(ctx)
{
fz_drop_compressed_buffer(ctx, bc);
fz_rethrow(ctx);
}
- image->buffer = bc;
}
/*