summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2011-10-21 23:27:50 -0700
committerMichael Vrhel <michael.vrhel@artifex.com>2011-10-21 23:53:52 -0700
commita298a05dcf4ce3f1f530759680a2f65c3e72e3fc (patch)
tree08e04752eb979f8c2a7ea6d74c70a6a0da3eb950
parent312255297353a9f62b5090e9137586a8ecfc8601 (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.c29
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;
}