Skip to content

Commit 81dffdd

Browse files
authored
Merge pull request #2120 from libvips/revise-premultiply
Revise premultiply
2 parents b14bac5 + 0623a05 commit 81dffdd

File tree

8 files changed

+175
-117
lines changed

8 files changed

+175
-117
lines changed

ChangeLog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
- fix includes of glib headers in C++ [lovell]
88
- fix build with more modern librsvg [lovell]
99
- fix a possible segv with very wide images [f1ac]
10+
- revise premultiply, again [jjonesrs]
11+
- revise profile handling in vipsthumbnail
1012
- fix tiff deflate predictor setting [Adios]
1113

1214
18/12/20 started 8.10.5

libvips/conversion/flatten.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ typedef struct _VipsFlatten {
6767
*/
6868
VipsArrayDouble *background;
6969

70-
/* The [double] converted to the input image format.
70+
/* The [double] background converted to the input image format.
7171
*/
7272
VipsPel *ink;
7373

libvips/conversion/unpremultiply.c

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* - max_alpha defaults to 65535 for RGB16/GREY16
88
* 24/11/17 lovell
99
* - match normalised alpha to output type
10+
* 27/2/21 jjonesrs
11+
* - revise range clipping and 1/x, again
1012
*/
1113

1214
/*
@@ -70,26 +72,20 @@ typedef VipsConversionClass VipsUnpremultiplyClass;
7072

7173
G_DEFINE_TYPE( VipsUnpremultiply, vips_unpremultiply, VIPS_TYPE_CONVERSION );
7274

73-
/* Unpremultiply an N-band image.
75+
/* Unpremultiply an N-band image. Don't use clip_alpha to calculate factor: we
76+
* want over and undershoots on alpha and RGB to cancel.
7477
*/
7578
#define UNPRE_MANY( IN, OUT ) { \
7679
IN * restrict p = (IN *) in; \
7780
OUT * restrict q = (OUT *) out; \
7881
\
7982
for( x = 0; x < width; x++ ) { \
8083
IN alpha = p[alpha_band]; \
84+
OUT factor = alpha == 0 ? 0 : max_alpha / alpha; \
8185
\
82-
if( alpha != 0 ) { \
83-
OUT factor = max_alpha / alpha; \
84-
\
85-
for( i = 0; i < alpha_band; i++ ) \
86-
q[i] = factor * p[i]; \
87-
q[alpha_band] = alpha; \
88-
} \
89-
else \
90-
for( i = 0; i < alpha_band + 1; i++ ) \
91-
q[i] = 0; \
92-
\
86+
for( i = 0; i < alpha_band; i++ ) \
87+
q[i] = factor * p[i]; \
88+
q[alpha_band] = VIPS_CLIP( 0, alpha, max_alpha ); \
9389
for( i = alpha_band + 1; i < bands; i++ ) \
9490
q[i] = p[i]; \
9591
\
@@ -106,21 +102,12 @@ G_DEFINE_TYPE( VipsUnpremultiply, vips_unpremultiply, VIPS_TYPE_CONVERSION );
106102
\
107103
for( x = 0; x < width; x++ ) { \
108104
IN alpha = p[3]; \
105+
OUT factor = alpha == 0 ? 0 : max_alpha / alpha; \
109106
\
110-
if( alpha != 0 ) { \
111-
OUT factor = max_alpha / alpha; \
112-
\
113-
q[0] = factor * p[0]; \
114-
q[1] = factor * p[1]; \
115-
q[2] = factor * p[2]; \
116-
q[3] = alpha; \
117-
} \
118-
else { \
119-
q[0] = 0; \
120-
q[1] = 0; \
121-
q[2] = 0; \
122-
q[3] = 0; \
123-
} \
107+
q[0] = factor * p[0]; \
108+
q[1] = factor * p[1]; \
109+
q[2] = factor * p[2]; \
110+
q[3] = VIPS_CLIP( 0, alpha, max_alpha ); \
124111
\
125112
p += 4; \
126113
q += 4; \

0 commit comments

Comments
 (0)