diff options
Diffstat (limited to 'xps/xps_tiff.c')
-rw-r--r-- | xps/xps_tiff.c | 92 |
1 files changed, 51 insertions, 41 deletions
diff --git a/xps/xps_tiff.c b/xps/xps_tiff.c index b7d8ee04..9fae5e2d 100644 --- a/xps/xps_tiff.c +++ b/xps/xps_tiff.c @@ -503,6 +503,20 @@ xps_decode_tiff_strips(struct tiff *tiff) p += tiff->stride; } } + + /* Premultiplied transparency */ + if (tiff->extrasamples == 1) + { + /* In GhostXPS we undo the premultiplication here; muxps holds + * all our images premultiplied by default, so nothing to do. + */ + } + + /* Non-premultiplied transparency */ + if (tiff->extrasamples == 2) + { + /* Premultiplied files are corrected for elsewhere */ + } } static inline int readbyte(struct tiff *tiff) @@ -765,62 +779,58 @@ xps_decode_tiff(fz_context *ctx, byte *buf, int len) fz_pixmap *image; struct tiff tiff; - xps_decode_tiff_header(ctx, &tiff, buf, len); - - /* Decode the image strips */ + fz_try(ctx) + { + xps_decode_tiff_header(ctx, &tiff, buf, len); - if (tiff.rowsperstrip > tiff.imagelength) - tiff.rowsperstrip = tiff.imagelength; + /* Decode the image strips */ - xps_decode_tiff_strips(&tiff); + if (tiff.rowsperstrip > tiff.imagelength) + tiff.rowsperstrip = tiff.imagelength; - /* Byte swap 16-bit images to big endian if necessary */ - if (tiff.bitspersample == 16) - if (tiff.order == TII) - xps_swap_byte_order(tiff.samples, tiff.imagewidth * tiff.imagelength * tiff.samplesperpixel); + xps_decode_tiff_strips(&tiff); - /* Expand into fz_pixmap struct */ + /* Byte swap 16-bit images to big endian if necessary */ + if (tiff.bitspersample == 16) + if (tiff.order == TII) + xps_swap_byte_order(tiff.samples, tiff.imagewidth * tiff.imagelength * tiff.samplesperpixel); - fz_try(ctx) - { + /* Expand into fz_pixmap struct */ image = fz_new_pixmap(tiff.ctx, tiff.colorspace, tiff.imagewidth, tiff.imagelength); + image->xres = tiff.xresolution; + image->yres = tiff.yresolution; + + fz_unpack_tile(image, tiff.samples, tiff.samplesperpixel, tiff.bitspersample, tiff.stride, 0); + + /* We should only do this on non-pre-multiplied images, but files in the wild are bad */ + if (tiff.extrasamples /* == 2 */) + { + /* CMYK is a subtractive colorspace, we want additive for premul alpha */ + if (image->n == 5) + { + fz_pixmap *rgb = fz_new_pixmap(tiff.ctx, fz_device_rgb, image->w, image->h); + fz_convert_pixmap(tiff.ctx, image, rgb); + rgb->xres = image->xres; + rgb->yres = image->yres; + fz_drop_pixmap(ctx, image); + image = rgb; + } + fz_premultiply_pixmap(image); + } } - fz_catch(ctx) + fz_always(ctx) { + /* Clean up scratch memory */ if (tiff.colormap) fz_free(ctx, tiff.colormap); if (tiff.stripoffsets) fz_free(ctx, tiff.stripoffsets); if (tiff.stripbytecounts) fz_free(ctx, tiff.stripbytecounts); if (tiff.samples) fz_free(ctx, tiff.samples); - fz_throw(ctx, "out of memory"); + if (tiff.profile) fz_free(ctx, tiff.profile); } - - image->xres = tiff.xresolution; - image->yres = tiff.yresolution; - - fz_unpack_tile(image, tiff.samples, tiff.samplesperpixel, tiff.bitspersample, tiff.stride, 0); - - /* We should only do this on non-pre-multiplied images, but files in the wild are bad */ - if (tiff.extrasamples /* == 2 */) + fz_catch(ctx) { - /* CMYK is a subtractive colorspace, we want additive for premul alpha */ - if (image->n == 5) - { - fz_pixmap *rgb = fz_new_pixmap(tiff.ctx, fz_device_rgb, image->w, image->h); - fz_convert_pixmap(tiff.ctx, image, rgb); - rgb->xres = image->xres; - rgb->yres = image->yres; - fz_drop_pixmap(ctx, image); - image = rgb; - } - fz_premultiply_pixmap(image); + fz_throw(ctx, "out of memory"); } - /* Clean up scratch memory */ - - if (tiff.colormap) fz_free(ctx, tiff.colormap); - if (tiff.stripoffsets) fz_free(ctx, tiff.stripoffsets); - if (tiff.stripbytecounts) fz_free(ctx, tiff.stripbytecounts); - if (tiff.samples) fz_free(ctx, tiff.samples); - return image; } |