diff options
author | Michael Vrhel <michael.vrhel@artifex.com> | 2011-10-21 23:27:50 -0700 |
---|---|---|
committer | Michael Vrhel <michael.vrhel@artifex.com> | 2011-10-21 23:53:52 -0700 |
commit | a298a05dcf4ce3f1f530759680a2f65c3e72e3fc (patch) | |
tree | 08e04752eb979f8c2a7ea6d74c70a6a0da3eb950 | |
parent | 312255297353a9f62b5090e9137586a8ecfc8601 (diff) |
Fix to handle tiff associated alpha images correctly in XPS
TIFF images in XPS can come with an alpha channel that may or may
not be premultiplied. In our existing XPS flow, we currently store
the alpha channel in a separate channel and treat it as an image mask
in the graphics library. This is fine, but if the image data was
premultiplied by the alpha data, we will need to undo this operation
otherwise we end up applying the mask on image data that is already
scaled by the alpha data.
-rw-r--r-- | xps/xpstiff.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/xps/xpstiff.c b/xps/xpstiff.c index 302341dd9..7b6189548 100644 --- a/xps/xpstiff.c +++ b/xps/xpstiff.c @@ -506,6 +506,27 @@ xps_unpredict_tiff(byte *line, int width, int comps, int bits) } static void +xps_unassocalpha_tiff(byte *line, int width, int comps, int bits) +{ + int i, k, v, a; + int m = (1 << bits) - 1; + + for (i = 0; i < width; i++) + { + a = getcomp(line, i * comps + (comps - 1), bits); + for (k = 0; k < (comps - 1); k++) + { + if (a > 0) + { + v = getcomp(line, i * comps + k, bits); + v = (v * m) / a; + putcomp(line, i * comps + k, bits, v); + } + } + } +} + +static void xps_invert_tiff(byte *line, int width, int comps, int bits, int alpha) { int i, k, v; @@ -766,6 +787,14 @@ xps_decode_tiff_strips(xps_context_t *ctx, xps_tiff_t *tiff, xps_image_t *image) /* Premultiplied transparency */ if (tiff->extrasamples == 1) { + /* We have to unassociate the alpha with the image data in this case */ + /* otherwise it is applied twice */ + byte *p = image->samples; + for (i = 0; i < image->height; i++) + { + xps_unassocalpha_tiff(p, image->width, image->comps, image->bits); + p += image->stride; + } image->hasalpha = 1; } |