From: anthony Date: Wed, 5 May 2010 06:16:16 +0000 (+0000) Subject: Exclude "Plus" from using 'over' alpha-blending as per SVG definition X-Git-Tag: 7.0.1-0~9558 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=320be8b3cd438d893d3fa76129b07f8c829a72af;p=imagemagick Exclude "Plus" from using 'over' alpha-blending as per SVG definition --- diff --git a/ChangeLog b/ChangeLog index aaf409f6e..bdf8b44c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,12 +2,22 @@ * Rename of "Add" and "Subtract" compositions to "ModulusAdd" and "ModulusSubtract" for more clarity of there functions. Old names will continue to work as expected. - * Fix "Plus", "Minus", "ModulusAdd", and "ModulusSubtract" to follow + * Fix "Minus", "ModulusAdd", and "ModulusSubtract" to follow normal SVG 'Over' blending specifications, (see next for override) - * Allow the "-channel sync" flag to allow mathematical compositions to work - for SVG specified handling, or if turned off, to perform image mathematics - on specific individual channels. You can now use math compose methods - with the alpha channels of images, or with just one channel of an image. + Note that this does NOT include the "Plus" composition method which has + SVG defintion for it to use a 'Plus' blending rather than 'Over' blending. + + * By default mathematical compositions work as per SVG definition. That is + the results are syncronized with 'Over' alpha-blending (except "Plus" + which uses 'plus' alpha-blending). + + By removing the default 'sync' flag from the -channel setting however + Break this inter-channel syncronization and do the mathematical operations + only on the individual channels as specified by the -channel setting. + That is do 'channel' math rather than 'SVG' composition. + + With this change you can then use mathematical composition methods on + individual channels or even with the alpha channel of images. 2010-04-28 6.6.1-6 Anthony Thyssen * Special case handling in Barrel distortion (pixel at image center) diff --git a/magick/composite-private.h b/magick/composite-private.h index 29e2ecf1c..9b8b455f1 100644 --- a/magick/composite-private.h +++ b/magick/composite-private.h @@ -105,15 +105,14 @@ static inline void MagickPixelCompositeOver(const MagickPixelPacket *p, composite->index=gamma*MagickOver_(p->index,alpha,q->index,beta); } -#if 0 static inline void MagickPixelCompositePlus(const MagickPixelPacket *p, const MagickRealType alpha,const MagickPixelPacket *q, const MagickRealType beta,MagickPixelPacket *composite) { MagickRealType - Sa, Da, - gamma; + gamma, + Sa; /* Add two pixels with the given opacities. @@ -129,7 +128,6 @@ static inline void MagickPixelCompositePlus(const MagickPixelPacket *p, if (q->colorspace == CMYKColorspace) composite->index=gamma*(Sa*p->index+Da*q->index); } -#endif /* Blend pixel colors p and q by the amount given. @@ -138,27 +136,9 @@ static inline void MagickPixelCompositeBlend(const MagickPixelPacket *p, const MagickRealType alpha,const MagickPixelPacket *q, const MagickRealType beta,MagickPixelPacket *composite) { -#if 0 MagickPixelCompositePlus(p,(MagickRealType) (QuantumRange-alpha* (QuantumRange-p->opacity)),q,(MagickRealType) (QuantumRange-beta* GetAlphaPixelComponent(q)),composite); -#else - MagickRealType - Sa, - Da, - gamma; - - Sa=alpha*(1.0-QuantumScale*p->opacity); - Da=beta*(1.0-QuantumScale*q->opacity); - gamma=RoundToUnity(Sa+Da); /* 'Plus' blending -- not 'Over' blending */ - composite->opacity=(MagickRealType) QuantumRange*(1.0-gamma); - gamma=1.0/(fabs(gamma) <= MagickEpsilon ? 1.0 : gamma); - composite->red=gamma*(Sa*p->red+Da*q->red); - composite->green=gamma*(Sa*p->green+Da*q->green); - composite->blue=gamma*(Sa*p->blue+Da*q->blue); - if (q->colorspace == CMYKColorspace) - composite->index=gamma*(Sa*p->index+Da*q->index); -#endif } /* @@ -169,28 +149,9 @@ static inline void MagickPixelCompositeAreaBlend(const MagickPixelPacket *p, const MagickRealType beta,const MagickRealType area, MagickPixelPacket *composite) { -#if 0 MagickPixelCompositePlus(p,(MagickRealType) QuantumRange-(1.0-area)* (QuantumRange-alpha),q,(MagickRealType) (QuantumRange-area*(QuantumRange- beta)),composite); -#else - MagickRealType - Sa, - Da, - gamma; - - Sa=(1.0-area)*(1.0-QuantumScale*alpha); - Da=area*(1.0-QuantumScale*beta); - gamma=RoundToUnity(Sa+Da); /* 'Plus' blending -- not 'Over' blending */ - composite->opacity=(MagickRealType) QuantumRange*(1.0-gamma); - gamma=1.0/(fabs(gamma) <= MagickEpsilon ? 1.0 : gamma); - composite->red=gamma*(Sa*p->red+Da*q->red); - composite->green=gamma*(Sa*p->green+Da*q->green); - composite->blue=gamma*(Sa*p->blue+Da*q->blue); - if (q->colorspace == CMYKColorspace) - composite->index=gamma*(Sa*p->index+Da*q->index); -#endif - } #if defined(__cplusplus) || defined(c_plusplus) diff --git a/magick/composite.c b/magick/composite.c index e328f574d..0200d324a 100644 --- a/magick/composite.c +++ b/magick/composite.c @@ -891,27 +891,22 @@ static inline void CompositePlus(const MagickPixelPacket *p, MagickPixelPacket *composite) { if ( (channel & SyncChannels) != 0 ) { -#if 0 - MagickRealType - Sa, - Da, - gamma; + /* + NOTE: "Plus" does not use 'over' alpha-blending but uses a + special 'plus' form of alph-blending. It is the ONLY mathematical + operator to do this. this is what makes it different to the + otherwise equivelent "LinearDodge" composition method. - Sa=1.0-QuantumScale*p->opacity; /* simplify and speed up equations */ - Da=1.0-QuantumScale*q->opacity; - /* gamma=RoundToUnity(Sa+Da); ** is this correct? - I do not think so! */ - gamma=RoundToUnity(Sa+Da-Sa*Da); /* over blend, as per SVG doc */ - composite->opacity=(MagickRealType) QuantumRange*(1.0-gamma); - gamma=1.0/(fabs(gamma) <= MagickEpsilon ? 1.0 : gamma); - composite->red=gamma*(p->red*Sa+q->red*Da); - composite->green=gamma*(p->green*Sa+q->green*Da); - composite->blue=gamma*(p->blue*Sa+q->blue*Da); - if (q->colorspace == CMYKColorspace) - composite->index=gamma*(p->index*Sa+q->index*Da); -#else - /* Actually this is just LinearDodge! */ - CompositeLinearDodge(p,q,composite); -#endif + Note however that color channels are still effected by the alpha channel + as a result of the blending, making it just as useless for independant + channel maths, just like all other mathematical composition methods. + + As such the removal of the 'sync' flag, is still a usful convention. + + The MagickPixelCompositePlus() function is defined in + "composite-private.h" so it can also be used for Image Blending. + */ + MagickPixelCompositePlus(p,p->opacity,q,q->opacity,composite); } else { /* handle channels as separate grayscale channels */ if ( (channel | AlphaChannel) != 0 )