all tested and working
revised formula for in/out/dest-in/dest-out, for vector and scalar paths see https://github.com/libvips/libvips/issues/1301
This commit is contained in:
parent
447e0f3ea2
commit
d5ca1ddfd4
|
@ -13,6 +13,8 @@
|
||||||
* - don't stop on first non-transparent image [felixbuenemann, GDmac]
|
* - don't stop on first non-transparent image [felixbuenemann, GDmac]
|
||||||
* 6/12/18
|
* 6/12/18
|
||||||
* - do our own subimage positioning
|
* - do our own subimage positioning
|
||||||
|
* 8/5/19
|
||||||
|
* - revise in/out/dest-in/dest-out to make smoother alpha
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -461,14 +463,18 @@ vips_composite_base_blend( VipsCompositeBase *composite,
|
||||||
|
|
||||||
case VIPS_BLEND_MODE_IN:
|
case VIPS_BLEND_MODE_IN:
|
||||||
aR = aA * aB;
|
aR = aA * aB;
|
||||||
for( int b = 0; b < bands; b++ )
|
// if aA == 0, then aR == 0 and so B will already be 0
|
||||||
B[b] = A[b];
|
if( aA != 0 )
|
||||||
|
for( int b = 0; b < bands; b++ )
|
||||||
|
B[b] = A[b] * aR / aA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_BLEND_MODE_OUT:
|
case VIPS_BLEND_MODE_OUT:
|
||||||
aR = aA * (1 - aB);
|
aR = aA * (1 - aB);
|
||||||
for( int b = 0; b < bands; b++ )
|
// if aA == 0, then aR == 0 and so B will already be 0
|
||||||
B[b] = A[b];
|
if( aA != 0 )
|
||||||
|
for( int b = 0; b < bands; b++ )
|
||||||
|
B[b] = A[b] * aR / aA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_BLEND_MODE_ATOP:
|
case VIPS_BLEND_MODE_ATOP:
|
||||||
|
@ -493,11 +499,18 @@ vips_composite_base_blend( VipsCompositeBase *composite,
|
||||||
case VIPS_BLEND_MODE_DEST_IN:
|
case VIPS_BLEND_MODE_DEST_IN:
|
||||||
aR = aA * aB;
|
aR = aA * aB;
|
||||||
// B = B
|
// B = B
|
||||||
|
if( aB != 0 )
|
||||||
|
for( int b = 0; b < bands; b++ )
|
||||||
|
B[b] *= aR / aB;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_BLEND_MODE_DEST_OUT:
|
case VIPS_BLEND_MODE_DEST_OUT:
|
||||||
aR = (1 - aA) * aB;
|
aR = (1 - aA) * aB;
|
||||||
// B = B
|
// B = B
|
||||||
|
// if aB is 0, then B is already 0
|
||||||
|
if( aB != 0 )
|
||||||
|
for( int b = 0; b < bands; b++ )
|
||||||
|
B[b] *= aR / aB;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_BLEND_MODE_DEST_ATOP:
|
case VIPS_BLEND_MODE_DEST_ATOP:
|
||||||
|
@ -676,8 +689,8 @@ vips_composite_base_blend3( VipsCompositeBase *composite,
|
||||||
/* See https://www.cairographics.org/operators for a nice summary of
|
/* See https://www.cairographics.org/operators for a nice summary of
|
||||||
* the operators and their meaning.
|
* the operators and their meaning.
|
||||||
*
|
*
|
||||||
* Some operators need the unpremultiplied values, so we have to do an
|
* Some operators need the unpremultiplied values (eg. dest-in), so
|
||||||
* extra unpremultiply/premultiply.
|
* we have to do an extra unpremultiply/premultiply.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch( mode ) {
|
switch( mode ) {
|
||||||
|
@ -701,18 +714,14 @@ vips_composite_base_blend3( VipsCompositeBase *composite,
|
||||||
|
|
||||||
case VIPS_BLEND_MODE_IN:
|
case VIPS_BLEND_MODE_IN:
|
||||||
aR = aA * aB;
|
aR = aA * aB;
|
||||||
// we want to set B = A, but A has been premultiplied against
|
// if aA == 0, then aR == 0 and so B will already be 0
|
||||||
// aA ... we must undo that premul and redo against aR
|
|
||||||
// if aA == 0, then aR == 0 and so B will be set to 0
|
|
||||||
if( aA != 0 )
|
if( aA != 0 )
|
||||||
B = A * aR / aA;
|
B = A * aR / aA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_BLEND_MODE_OUT:
|
case VIPS_BLEND_MODE_OUT:
|
||||||
aR = aA * (1 - aB);
|
aR = aA * (1 - aB);
|
||||||
// we want to set B = A, but A has been premultiplied against
|
// if aA == 0, then aR == 0 and so B will already be 0
|
||||||
// aA ... we must undo that premul and redo against aR
|
|
||||||
// if aA == 0, then aR == 0 and so B will be set to 0
|
|
||||||
if( aA != 0 )
|
if( aA != 0 )
|
||||||
B = A * aR / aA;
|
B = A * aR / aA;
|
||||||
break;
|
break;
|
||||||
|
@ -736,17 +745,17 @@ vips_composite_base_blend3( VipsCompositeBase *composite,
|
||||||
|
|
||||||
case VIPS_BLEND_MODE_DEST_IN:
|
case VIPS_BLEND_MODE_DEST_IN:
|
||||||
aR = aA * aB;
|
aR = aA * aB;
|
||||||
// we need to simply copy B over, but B is premultiplied
|
// if aB is 0, then B is already 0
|
||||||
// against aB ... we must unpremultiply and premultiply
|
if( aB != 0 )
|
||||||
// against aR instead
|
B *= aR / aB;
|
||||||
// if aB is 0, then B is 0 too
|
|
||||||
//if( aB != 0 )
|
|
||||||
//B *= aR / aB;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_BLEND_MODE_DEST_OUT:
|
case VIPS_BLEND_MODE_DEST_OUT:
|
||||||
aR = (1 - aA) * aB;
|
aR = (1 - aA) * aB;
|
||||||
// B = B
|
// B = B
|
||||||
|
// if aB is 0, then B is already 0
|
||||||
|
if( aB != 0 )
|
||||||
|
B *= aR / aB;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_BLEND_MODE_DEST_ATOP:
|
case VIPS_BLEND_MODE_DEST_ATOP:
|
||||||
|
|
Loading…
Reference in New Issue