diff options
-rw-r--r-- | include/mupdf/fitz/image.h | 26 | ||||
-rw-r--r-- | include/mupdf/pdf/xref.h | 2 | ||||
-rw-r--r-- | source/fitz/image.c | 276 | ||||
-rw-r--r-- | source/fitz/stext-output.c | 7 | ||||
-rw-r--r-- | source/fitz/svg-device.c | 24 | ||||
-rw-r--r-- | source/fitz/test-device.c | 6 | ||||
-rw-r--r-- | source/gprf/gprf-doc.c | 2 | ||||
-rw-r--r-- | source/pdf/pdf-image.c | 37 | ||||
-rw-r--r-- | source/pdf/pdf-op-buffer.c | 2 | ||||
-rw-r--r-- | source/pdf/pdf-stream.c | 6 |
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; } /* |