summaryrefslogtreecommitdiff
path: root/source/fitz/draw-blend.c
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2017-06-30 13:13:32 -0700
committerRobin Watts <robin.watts@artifex.com>2017-07-17 19:32:06 +0100
commit1a6d9daf03db3c45569b4a74141131a979b05c33 (patch)
treec9c7fab591051ac575be502f8311839c21913818 /source/fitz/draw-blend.c
parentd4d4dcf1d64d4b0d3a510ed218f17e815b68c012 (diff)
downloadmupdf-1a6d9daf03db3c45569b4a74141131a979b05c33.tar.xz
Fix softlight blend mode. Make nonseparable blends work with CMYK
Softlight blend mode was broken as the constants were not properly scaled for 255 arithmetic. The nonseparable blending code needs to do special handling of K when the color space is CMYK.
Diffstat (limited to 'source/fitz/draw-blend.c')
-rw-r--r--source/fitz/draw-blend.c87
1 files changed, 63 insertions, 24 deletions
diff --git a/source/fitz/draw-blend.c b/source/fitz/draw-blend.c
index 8694408d..17300ec7 100644
--- a/source/fitz/draw-blend.c
+++ b/source/fitz/draw-blend.c
@@ -100,14 +100,13 @@ static inline int fz_color_burn_byte(int b, int s)
static inline int fz_soft_light_byte(int b, int s)
{
- /* review this */
if (s < 128) {
return b - fz_mul255(fz_mul255((255 - (s<<1)), b), 255 - b);
}
else {
int dbd;
if (b < 64)
- dbd = fz_mul255(fz_mul255((b << 4) - 12, b) + 4, b);
+ dbd = fz_mul255(fz_mul255((b << 4) - 3060, b) + 1020, b);
else
dbd = (int)sqrtf(255.0f * b);
return b + fz_mul255(((s<<1) - 255), (dbd - b));
@@ -322,14 +321,14 @@ fz_blend_separable(byte * restrict bp, int bal, const byte * restrict sp, int sa
}
static void
-fz_blend_nonseparable(byte * restrict bp, int bal, const byte * restrict sp, int sal, int w, int blendmode)
+fz_blend_nonseparable(byte * restrict bp, int bal, const byte * restrict sp, int sal, int n, int w, int blendmode)
{
do
{
unsigned char rr, rg, rb;
- int sa = (sal ? sp[3] : 255);
- int ba = (bal ? bp[3] : 255);
+ int sa = (sal ? sp[n] : 255);
+ int ba = (bal ? bp[n] : 255);
int saba = fz_mul255(sa, ba);
/* ugh, division to get non-premul components */
@@ -365,10 +364,29 @@ fz_blend_nonseparable(byte * restrict bp, int bal, const byte * restrict sp, int
bp[1] = fz_mul255(255 - sa, bp[1]) + fz_mul255(255 - ba, sp[1]) + fz_mul255(saba, rg);
bp[2] = fz_mul255(255 - sa, bp[2]) + fz_mul255(255 - ba, sp[2]) + fz_mul255(saba, rb);
if (bal)
- bp[3] = ba + sa - saba;
+ bp[n] = ba + sa - saba;
- sp += 3 + sal;
- bp += 3 + bal;
+ /* Black */
+ if (n == 4)
+ {
+ int sk = (sp[3] * invsa) >> 8;
+ int bk = (bp[3] * invba) >> 8;
+
+ switch (blendmode)
+ {
+ default:
+ case FZ_BLEND_HUE:
+ case FZ_BLEND_SATURATION:
+ case FZ_BLEND_COLOR:
+ bp[3] = fz_mul255(bp[n], bk);
+ break;
+ case FZ_BLEND_LUMINOSITY:
+ bp[3] = fz_mul255(bp[n], sk);
+ break;
+ }
+ }
+ sp += n + sal;
+ bp += n + bal;
}
while (--w);
}
@@ -507,7 +525,7 @@ fz_blend_separable_nonisolated(byte * restrict bp, int bal, const byte * restric
}
static inline void
-fz_blend_nonseparable_nonisolated(byte * restrict bp, int bal, const byte * restrict sp, int sal, int w, int blendmode, const byte * restrict hp, int alpha)
+fz_blend_nonseparable_nonisolated(byte * restrict bp, int bal, const byte * restrict sp, int sal, int n, int w, int blendmode, const byte * restrict hp, int alpha)
{
do
{
@@ -515,14 +533,14 @@ fz_blend_nonseparable_nonisolated(byte * restrict bp, int bal, const byte * rest
int haa = fz_mul255(ha, alpha);
if (haa != 0)
{
- int sa = (sal ? sp[3] : 255);
- int ba = (bal ? bp[3] : 255);
+ int sa = (sal ? sp[n] : 255);
+ int ba = (bal ? bp[n] : 255);
int baha = fz_mul255(ba, haa);
/* Calculate result_alpha */
int ra = ba - baha + haa;
if (bal)
- bp[3] = ra;
+ bp[n] = ra;
if (ra != 0)
{
/* Because we are a non-isolated group, we
@@ -578,11 +596,32 @@ fz_blend_nonseparable_nonisolated(byte * restrict bp, int bal, const byte * rest
bp[0] = fz_mul255(ra, rr);
bp[1] = fz_mul255(ra, rg);
bp[2] = fz_mul255(ra, rb);
+
+ /* Black */
+ if (n == 4)
+ {
+ int sk = (sp[3] * invsa) >> 8;
+ int bk = (bp[3] * invba) >> 8;
+ sk = (((sk - bk)*invha) >> 8) + bk;
+
+ switch (blendmode)
+ {
+ default:
+ case FZ_BLEND_HUE:
+ case FZ_BLEND_SATURATION:
+ case FZ_BLEND_COLOR:
+ bp[3] = fz_mul255(ra, bk);
+ break;
+ case FZ_BLEND_LUMINOSITY:
+ bp[3] = fz_mul255(ra, sk);
+ break;
+ }
+ }
}
}
- sp += 3 + sal;
- bp += 3 + bal;
+ sp += n + sal;
+ bp += n + bal;
}
while (--w);
}
@@ -644,17 +683,17 @@ fz_blend_pixmap(fz_pixmap * restrict dst, fz_pixmap * restrict src, int alpha, i
while (h--)
{
- if (n == 3 && blendmode >= FZ_BLEND_HUE)
+ if (blendmode >= FZ_BLEND_HUE)
if (da)
if (sa)
- fz_blend_nonseparable_nonisolated(dp, 1, sp, 1, w, blendmode, hp, alpha);
+ fz_blend_nonseparable_nonisolated(dp, 1, sp, 1, n, w, blendmode, hp, alpha);
else
- fz_blend_nonseparable_nonisolated(dp, 1, sp, 0, w, blendmode, hp, alpha);
+ fz_blend_nonseparable_nonisolated(dp, 1, sp, 0, n, w, blendmode, hp, alpha);
else
if (sa)
- fz_blend_nonseparable_nonisolated(dp, 0, sp, 1, w, blendmode, hp, alpha);
+ fz_blend_nonseparable_nonisolated(dp, 0, sp, 1, n, w, blendmode, hp, alpha);
else
- fz_blend_nonseparable_nonisolated(dp, 0, sp, 0, w, blendmode, hp, alpha);
+ fz_blend_nonseparable_nonisolated(dp, 0, sp, 0, n, w, blendmode, hp, alpha);
else
if (da)
if (sa)
@@ -675,17 +714,17 @@ fz_blend_pixmap(fz_pixmap * restrict dst, fz_pixmap * restrict src, int alpha, i
{
while (h--)
{
- if (n == 3 && blendmode >= FZ_BLEND_HUE)
+ if (blendmode >= FZ_BLEND_HUE)
if (da)
if (sa)
- fz_blend_nonseparable(dp, 1, sp, 1, w, blendmode);
+ fz_blend_nonseparable(dp, 1, sp, 1, n, w, blendmode);
else
- fz_blend_nonseparable(dp, 1, sp, 0, w, blendmode);
+ fz_blend_nonseparable(dp, 1, sp, 0, n, w, blendmode);
else
if (sa)
- fz_blend_nonseparable(dp, 0, sp, 1, w, blendmode);
+ fz_blend_nonseparable(dp, 0, sp, 1, n, w, blendmode);
else
- fz_blend_nonseparable(dp, 0, sp, 0, w, blendmode);
+ fz_blend_nonseparable(dp, 0, sp, 0, n, w, blendmode);
else
if (da)
if (sa)