diff options
Diffstat (limited to 'xps/xps_image.c')
-rw-r--r-- | xps/xps_image.c | 79 |
1 files changed, 65 insertions, 14 deletions
diff --git a/xps/xps_image.c b/xps/xps_image.c index 10d3baee..1f46a756 100644 --- a/xps/xps_image.c +++ b/xps/xps_image.c @@ -1,41 +1,92 @@ -#include "fitz.h" -#include "muxps.h" +#include "muxps-internal.h" + +typedef struct xps_image_s xps_image; + +struct xps_image_s +{ + fz_image base; + fz_pixmap *pix; + int xres; + int yres; +}; + +static void +xps_free_image(fz_context *ctx, fz_storable *image_) +{ + xps_image *image = (xps_image *)image_; + + if (image == NULL) + return; + + fz_drop_colorspace(ctx, image->base.colorspace); + fz_drop_pixmap(ctx, image->pix); + fz_free(ctx, image); +} static fz_pixmap * +xps_image_to_pixmap(fz_context *ctx, fz_image *image_, int x, int w) +{ + xps_image *image = (xps_image *)image_; + + return fz_keep_pixmap(ctx, image->pix); +} + +static fz_image * xps_load_image(fz_context *ctx, byte *buf, int len) { - fz_pixmap *image; + fz_pixmap *pix; + xps_image *image; if (len < 8) fz_throw(ctx, "unknown image file format"); if (buf[0] == 0xff && buf[1] == 0xd8) - image = fz_load_jpeg(ctx, buf, len); + pix = fz_load_jpeg(ctx, buf, len); else if (memcmp(buf, "\211PNG\r\n\032\n", 8) == 0) - image = fz_load_png(ctx, buf, len); + pix = fz_load_png(ctx, buf, len); else if (memcmp(buf, "II", 2) == 0 && buf[2] == 0xBC) fz_throw(ctx, "JPEG-XR codec is not available"); else if (memcmp(buf, "MM", 2) == 0 || memcmp(buf, "II", 2) == 0) - image = fz_load_tiff(ctx, buf, len); + pix = fz_load_tiff(ctx, buf, len); else fz_throw(ctx, "unknown image file format"); - return image; + fz_try(ctx) + { + image = fz_malloc_struct(ctx, xps_image); + + FZ_INIT_STORABLE(&image->base, 1, xps_free_image); + image->base.w = pix->w; + image->base.h = pix->h; + image->base.mask = NULL; + image->base.colorspace = pix->colorspace; + image->base.get_pixmap = xps_image_to_pixmap; + image->xres = pix->xres; + image->yres = pix->yres; + image->pix = pix; + } + fz_catch(ctx) + { + fz_drop_pixmap(ctx, pix); + fz_rethrow(ctx); + } + + return &image->base; } static void xps_paint_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *root, void *vimage) { - fz_pixmap *pixmap = vimage; + xps_image *image = vimage; float xs, ys; - if (pixmap->xres == 0 || pixmap->yres == 0) + if (image->xres == 0 || image->yres == 0) return; - xs = pixmap->w * 96 / pixmap->xres; - ys = pixmap->h * 96 / pixmap->yres; + xs = image->base.w * 96 / image->xres; + ys = image->base.h * 96 / image->yres; ctm = fz_concat(fz_scale(xs, ys), ctm); - fz_fill_image(doc->dev, pixmap, ctm, doc->opacity[doc->opacity_top]); + fz_fill_image(doc->dev, &image->base, ctm, doc->opacity[doc->opacity_top]); } static xps_part * @@ -93,7 +144,7 @@ xps_parse_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *root) { xps_part *part; - fz_pixmap *image; + fz_image *image; fz_try(doc->ctx) { @@ -119,5 +170,5 @@ xps_parse_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area, xps_parse_tiling_brush(doc, ctm, area, base_uri, dict, root, xps_paint_image_brush, image); - fz_drop_pixmap(doc->ctx, image); + fz_drop_image(doc->ctx, image); } |