diff options
author | Robin Watts <robin.watts@artifex.com> | 2016-10-06 19:51:29 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2016-10-07 16:56:46 +0100 |
commit | c5f8d745e4dc42404409a2c166181d85bc87934b (patch) | |
tree | 1ff341b87b3891a998aba07fb3699b1dd4148ce4 | |
parent | 7836643e0d6e9cc8e9d0d5c71cbfac5ee772ae21 (diff) | |
download | mupdf-c5f8d745e4dc42404409a2c166181d85bc87934b.tar.xz |
Correct maths error in painters.
As part of the blending calculations, we do:
dst = src * mask_alpha + dst * (1-mask_alpha.src_alpha)
We calculate mask_alpha as ma, and 1-mask_alpha.src_alpha as masa.
In full accuracy, we should never have ma + masa >= 1.
Unfortunately, with the formulation used in the painters at the
moment, we can. We therefore rejig the calculations slightly.
-rw-r--r-- | include/mupdf/fitz/math.h | 5 | ||||
-rw-r--r-- | source/fitz/draw-paint.c | 12 |
2 files changed, 9 insertions, 8 deletions
diff --git a/include/mupdf/fitz/math.h b/include/mupdf/fitz/math.h index 9ba79697..5e25f871 100644 --- a/include/mupdf/fitz/math.h +++ b/include/mupdf/fitz/math.h @@ -19,6 +19,11 @@ static inline int fz_mul255(int a, int b) * to give a single value in the same range as A was. */ #define FZ_COMBINE(A,B) (((A)*(B))>>8) +/* Combine values A (in the 0..255 range) and B (in the 0..256 range), + * then reverse it within that range to give a single value in the + * 0..256 range. */ +#define FZ_REVERSE_COMBINE(A,B) ((0xFF00 - (A)*(B))>>8) + /* Combine values A and C (in the same (any) range) and B and D (in the * 0..256 range), to give a single value in the same range as A and C were. */ #define FZ_COMBINE2(A,B,C,D) (FZ_COMBINE((A), (B)) + FZ_COMBINE((C), (D))) diff --git a/source/fitz/draw-paint.c b/source/fitz/draw-paint.c index 50112d00..33ab20c8 100644 --- a/source/fitz/draw-paint.c +++ b/source/fitz/draw-paint.c @@ -885,8 +885,7 @@ template_span_with_mask_1_general(byte * restrict dp, int da, const byte * restr dp += 1+da; continue; } - masa = FZ_COMBINE(sp[1], ma); - masa = 255 - masa; + masa = FZ_REVERSE_COMBINE(sp[1], ma); masa = FZ_EXPAND(masa); *dp = FZ_COMBINE2(*sp, ma, *dp, masa); sp++; dp++; @@ -999,8 +998,7 @@ template_span_with_mask_3_general(byte * restrict dp, int da, const byte * restr dp += 3+da; continue; } - masa = FZ_COMBINE(sp[3], ma); - masa = 255 - masa; + masa = FZ_REVERSE_COMBINE(sp[3], ma); masa = FZ_EXPAND(masa); *dp = FZ_COMBINE2(*sp, ma, *dp, masa); sp++; dp++; @@ -1092,8 +1090,7 @@ template_span_with_mask_4_general(byte * restrict dp, int da, const byte * restr dp += 4+da; continue; } - masa = FZ_COMBINE(sp[4], ma); - masa = 255 - masa; + masa = FZ_REVERSE_COMBINE(sp[4], ma); masa = FZ_EXPAND(masa); *dp = FZ_COMBINE2(*sp, ma, *dp, masa); sp++; dp++; @@ -1187,8 +1184,7 @@ template_span_with_mask_N_general(byte * restrict dp, int da, const byte * restr dp += n+da; continue; } - masa = FZ_COMBINE(sp[n], ma); - masa = 255-masa; + masa = FZ_REVERSE_COMBINE(sp[n], ma); masa = FZ_EXPAND(masa); while (k--) { |