diff options
author | Robin Watts <robin.watts@artifex.com> | 2017-09-28 18:11:43 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2017-10-24 15:16:37 +0100 |
commit | 7e6a2dda63ce59237723e3a64aba671228bb904c (patch) | |
tree | 68d0dade577a829259078cd922a0470dda880894 /source/fitz/separation.c | |
parent | 0e5d67165863b3e45a09aadd69671f878f8ee57e (diff) | |
download | mupdf-7e6a2dda63ce59237723e3a64aba671228bb904c.tar.xz |
Fix problem with spot shadings in isolated groups.
As seen with ../tests_private/comparefiles/Bug693541.pdf
This file has an RGB isolated group, within which it renders a
spot only shading. We therefore create the RGB+S+A pixmap, and
set it to all zeros. The shading is drawn to a new S+A pixmap.
The problem comes when the code writes the S+A pixmap to the
RGB+S+A one.
When we set the alpha values to be non zero in an additive space
we need to reset the process components to be full (scaled by
alpha).
Diffstat (limited to 'source/fitz/separation.c')
-rw-r--r-- | source/fitz/separation.c | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/source/fitz/separation.c b/source/fitz/separation.c index 4040e97a..dd8d18f0 100644 --- a/source/fitz/separation.c +++ b/source/fitz/separation.c @@ -300,7 +300,7 @@ fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *dst, fz_pixmap * dstride -= dn * dw; sstride -= sn * dw; - /* Process colorants first */ + /* Process colorants (and alpha) first */ if (dst->colorspace == src->colorspace && proof_cs == NULL) { /* Simple copy */ @@ -310,10 +310,12 @@ fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *dst, fz_pixmap * { for (x = dw; x > 0; x--) { - for (i = 0; i < dn; i++) + for (i = 0; i < dc; i++) dd[i] = sd[i]; dd += dn; sd += sn; + if (da) + dd[-1] = sd[-1]; } dd += dstride; sd += sstride; @@ -323,7 +325,52 @@ fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *dst, fz_pixmap * { device_n = fz_colorspace_is_device_n(ctx, src->colorspace); if (device_n) - fz_clear_pixmap(ctx, dst); + { + if (da) + { + if (fz_colorspace_is_subtractive(ctx, dst->colorspace)) + { + /* Copy the alpha, set process colors to 0. */ + unsigned char *dd = ddata; + const unsigned char *sd = sdata; + for (y = dh; y > 0; y--) + { + for (x = dw; x > 0; x--) + { + for (i = 0; i < dc; i++) + dd[i] = 0; + dd += dn; + sd += sn; + dd[-1] = sd[-1]; + } + dd += dstride; + sd += sstride; + } + } + else + { + /* Copy the alpha, set process colors to full, scaled by alpha - i.e. alpha */ + unsigned char *dd = ddata; + const unsigned char *sd = sdata + sn - 1; + for (y = dh; y > 0; y--) + { + for (x = dw; x > 0; x--) + { + int a = *sd; + for (i = 0; i < dc; i++) + dd[i] = a; + dd += dn; + sd += sn; + dd[-1] = a; + } + dd += dstride; + sd += sstride; + } + } + } + else + fz_clear_pixmap(ctx, dst); + } else { fz_pixmap_converter *pc = fz_lookup_pixmap_converter(ctx, dst->colorspace, src->colorspace); @@ -444,6 +491,8 @@ fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *dst, fz_pixmap * } else { + for (k = 0; k < dc; k++) + convert[k] = 1-convert[k]; if (fz_colorspace_is_subtractive(ctx, src->colorspace)) { unsigned char *dd = ddata; @@ -455,7 +504,7 @@ fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *dst, fz_pixmap * unsigned char v = sd[i]; if (v != 0) for (k = 0; k < dc; k++) - dd[k] = fz_clampi(dd[k] - v * (1-convert[k]), 0, 255); + dd[k] = fz_clampi(dd[k] - v * convert[k], 0, 255); dd += dn; sd += sn; } @@ -474,7 +523,7 @@ fz_copy_pixmap_area_converting_seps(fz_context *ctx, fz_pixmap *dst, fz_pixmap * unsigned char v = 0xff - sd[i]; if (v != 0) for (k = 0; k < dc; k++) - dd[k] = fz_clampi(dd[k] - v * (1-convert[k]), 0, 255); + dd[k] = fz_clampi(dd[k] - v * convert[k], 0, 255); dd += dn; sd += sn; } |