summaryrefslogtreecommitdiff
path: root/xps/xps_tiff.c
diff options
context:
space:
mode:
Diffstat (limited to 'xps/xps_tiff.c')
-rw-r--r--xps/xps_tiff.c92
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;
}