|  | /* | 
|  | Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization | 
|  | dedicated to making software imaging solutions freely available. | 
|  |  | 
|  | You may not use this file except in compliance with the License. | 
|  | obtain a copy of the License at | 
|  |  | 
|  | http://www.imagemagick.org/script/license.php | 
|  |  | 
|  | Unless required by applicable law or agreed to in writing, software | 
|  | distributed under the License is distributed on an "AS IS" BASIS, | 
|  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | See the License for the specific language governing permissions and | 
|  | limitations under the License. | 
|  |  | 
|  | MagickCore image composite private methods. | 
|  | */ | 
|  | #ifndef _MAGICKCORE_COMPOSITE_PRIVATE_H | 
|  | #define _MAGICKCORE_COMPOSITE_PRIVATE_H | 
|  |  | 
|  |  | 
|  | #include "MagickCore/color.h" | 
|  | #include "MagickCore/image.h" | 
|  | #include "MagickCore/image-private.h" | 
|  | #include "MagickCore/pixel-accessor.h" | 
|  | #include "MagickCore/pixel-private.h" | 
|  |  | 
|  | #if defined(__cplusplus) || defined(c_plusplus) | 
|  | extern "C" { | 
|  | #endif | 
|  |  | 
|  | /* | 
|  | ImageMagick Alpha Composite Inline Methods (special export) | 
|  | */ | 
|  | static inline double MagickOver_(const double p,const double alpha, | 
|  | const double q,const double beta) | 
|  | { | 
|  | double | 
|  | Da, | 
|  | Sa; | 
|  |  | 
|  | Sa=QuantumScale*alpha; | 
|  | Da=QuantumScale*beta; | 
|  | return(Sa*p+Da*q*(1.0-Sa)); | 
|  | } | 
|  |  | 
|  | static inline double RoundToUnity(const double value) | 
|  | { | 
|  | return(value < 0.0 ? 0.0 : (value > 1.0) ? 1.0 : value); | 
|  | } | 
|  |  | 
|  | static inline void CompositePixelOver(const Image *image,const PixelInfo *p, | 
|  | const double alpha,const Quantum *q,const double beta,Quantum *composite) | 
|  | { | 
|  | double | 
|  | Da, | 
|  | gamma, | 
|  | Sa; | 
|  |  | 
|  | register ssize_t | 
|  | i; | 
|  |  | 
|  | /* | 
|  | Compose pixel p over pixel q with the given alpha. | 
|  | */ | 
|  | Sa=QuantumScale*alpha; | 
|  | Da=QuantumScale*beta; | 
|  | gamma=Sa+Da-Sa*Da; | 
|  | gamma=PerceptibleReciprocal(gamma); | 
|  | for (i=0; i < (ssize_t) GetPixelChannels(image); i++) | 
|  | { | 
|  | PixelChannel | 
|  | channel; | 
|  |  | 
|  | PixelTrait | 
|  | traits; | 
|  |  | 
|  | channel=GetPixelChannelChannel(image,i); | 
|  | traits=GetPixelChannelTraits(image,channel); | 
|  | if (traits == UndefinedPixelTrait) | 
|  | continue; | 
|  | switch (channel) | 
|  | { | 
|  | case RedPixelChannel: | 
|  | { | 
|  | composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->red,alpha, | 
|  | (double) q[i],beta)); | 
|  | break; | 
|  | } | 
|  | case GreenPixelChannel: | 
|  | { | 
|  | composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->green,alpha, | 
|  | (double) q[i],beta)); | 
|  | break; | 
|  | } | 
|  | case BluePixelChannel: | 
|  | { | 
|  | composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->blue,alpha, | 
|  | (double) q[i],beta)); | 
|  | break; | 
|  | } | 
|  | case BlackPixelChannel: | 
|  | { | 
|  | composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->black,alpha, | 
|  | (double) q[i],beta)); | 
|  | break; | 
|  | } | 
|  | case AlphaPixelChannel: | 
|  | { | 
|  | composite[i]=ClampToQuantum(QuantumRange*RoundToUnity(Sa+Da-Sa*Da)); | 
|  | break; | 
|  | } | 
|  | default: | 
|  | { | 
|  | composite[i]=q[i]; | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | static inline void CompositePixelInfoOver(const PixelInfo *p, | 
|  | const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite) | 
|  | { | 
|  | double | 
|  | Da, | 
|  | gamma, | 
|  | Sa; | 
|  |  | 
|  | /* | 
|  | Compose pixel p over pixel q with the given opacities. | 
|  | */ | 
|  | Sa=QuantumScale*alpha; | 
|  | Da=QuantumScale*beta, | 
|  | gamma=Sa+Da-Sa*Da; | 
|  | composite->alpha=(double) QuantumRange*RoundToUnity(gamma); | 
|  | gamma=PerceptibleReciprocal(gamma); | 
|  | composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta); | 
|  | composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta); | 
|  | composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta); | 
|  | if (q->colorspace == CMYKColorspace) | 
|  | composite->black=gamma*MagickOver_(p->black,alpha,q->black,beta); | 
|  | } | 
|  |  | 
|  | static inline void CompositePixelInfoPlus(const PixelInfo *p, | 
|  | const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite) | 
|  | { | 
|  | double | 
|  | Da, | 
|  | gamma, | 
|  | Sa; | 
|  |  | 
|  | /* | 
|  | Add two pixels with the given opacities. | 
|  | */ | 
|  | Sa=QuantumScale*alpha; | 
|  | Da=QuantumScale*beta; | 
|  | gamma=RoundToUnity(Sa+Da);  /* 'Plus' blending -- not 'Over' blending */ | 
|  | composite->alpha=(double) QuantumRange*RoundToUnity(gamma); | 
|  | gamma=PerceptibleReciprocal(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->black=gamma*(Sa*p->black+Da*q->black); | 
|  | } | 
|  |  | 
|  | static inline void CompositePixelInfoAreaBlend(const PixelInfo *p, | 
|  | const double alpha,const PixelInfo *q,const double beta,const double area, | 
|  | PixelInfo *composite) | 
|  | { | 
|  | /* | 
|  | Blend pixel colors p and q by the amount given and area. | 
|  | */ | 
|  | CompositePixelInfoPlus(p,(double) (1.0-area)*alpha,q,(double) (area*beta), | 
|  | composite); | 
|  | } | 
|  |  | 
|  | static inline void CompositePixelInfoBlend(const PixelInfo *p, | 
|  | const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite) | 
|  | { | 
|  | /* | 
|  | Blend pixel colors p and q by the amount given. | 
|  | */ | 
|  | CompositePixelInfoPlus(p,(double) (alpha*p->alpha),q,(double) (beta*q->alpha), | 
|  | composite); | 
|  | } | 
|  |  | 
|  | #if defined(__cplusplus) || defined(c_plusplus) | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #endif |