summaryrefslogtreecommitdiff
path: root/source/fitz/separation.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2017-09-28 18:11:43 +0100
committerRobin Watts <robin.watts@artifex.com>2017-10-24 15:16:37 +0100
commit7e6a2dda63ce59237723e3a64aba671228bb904c (patch)
tree68d0dade577a829259078cd922a0470dda880894 /source/fitz/separation.c
parent0e5d67165863b3e45a09aadd69671f878f8ee57e (diff)
downloadmupdf-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.c59
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;
}