2 Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization
3 dedicated to making software imaging solutions freely available.
5 You may not use this file except in compliance with the License.
6 obtain a copy of the License at
8 http://www.imagemagick.org/script/license.php
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
16 MagickCore image composite private methods.
18 #ifndef _MAGICKCORE_COMPOSITE_PRIVATE_H
19 #define _MAGICKCORE_COMPOSITE_PRIVATE_H
21 #if defined(__cplusplus) || defined(c_plusplus)
26 ImageMagick Alpha Composite Inline Methods (special export)
29 #include "MagickCore/color.h"
30 #include "MagickCore/image.h"
31 #include "MagickCore/image-private.h"
32 #include "MagickCore/pixel-accessor.h"
33 #include "MagickCore/pixel-private.h"
35 static inline double MagickOver_(const double p,const double alpha,
36 const double q,const double beta)
42 Sa=QuantumScale*alpha;
44 return(Sa*p-Sa*Da*q+Da*q);
47 static inline void CompositePixelOver(const Image *image,const PixelInfo *p,
48 const double alpha,const Quantum *q,const double beta,Quantum *composite)
59 Compose pixel p over pixel q with the given alpha.
61 Sa=QuantumScale*alpha;
64 gamma=PerceptibleReciprocal(gamma);
65 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
76 channel=GetPixelChannelChannel(image,i);
77 traits=GetPixelChannelTraits(image,channel);
78 if (traits == UndefinedPixelTrait)
80 if (((traits & CopyPixelTrait) != 0) || (GetPixelMask(image,q) != 0) ||
81 (fabs(alpha-TransparentAlpha) < MagickEpsilon))
90 pixel=gamma*MagickOver_((double) p->red,alpha,(double) q[i],beta);
93 case GreenPixelChannel:
95 pixel=gamma*MagickOver_((double) p->green,alpha,(double) q[i],beta);
98 case BluePixelChannel:
100 pixel=gamma*MagickOver_((double) p->blue,alpha,(double) q[i],beta);
103 case BlackPixelChannel:
105 pixel=gamma*MagickOver_((double) p->black,alpha,(double) q[i],beta);
108 case AlphaPixelChannel:
110 pixel=QuantumRange*(Sa*(-Da)+Sa+Da);
119 composite[i]=ClampToQuantum(pixel);
123 static inline void CompositePixelInfoOver(const PixelInfo *p,const double alpha,
124 const PixelInfo *q,const double beta,PixelInfo *composite)
132 Compose pixel p over pixel q with the given opacities.
134 if (fabs(alpha-TransparentAlpha) < MagickEpsilon)
139 Sa=QuantumScale*alpha;
140 Da=QuantumScale*beta,
141 gamma=Sa*(-Da)+Sa+Da;
142 composite->alpha=(double) QuantumRange*gamma;
143 gamma=PerceptibleReciprocal(gamma);
144 composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta);
145 composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta);
146 composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta);
147 if (q->colorspace == CMYKColorspace)
148 composite->black=gamma*MagickOver_(p->black,alpha,q->black,beta);
151 static inline double RoundToUnity(const double value)
153 return(value < 0.0 ? 0.0 : (value > 1.0) ? 1.0 : value);
156 static inline void CompositePixelInfoPlus(const PixelInfo *p,const double alpha,
157 const PixelInfo *q,const double beta,PixelInfo *composite)
165 Add two pixels with the given opacities.
167 Sa=QuantumScale*alpha;
168 Da=QuantumScale*beta;
169 gamma=RoundToUnity(Sa+Da); /* 'Plus' blending -- not 'Over' blending */
170 composite->alpha=(double) QuantumRange*gamma;
171 gamma=PerceptibleReciprocal(gamma);
172 composite->red=gamma*(Sa*p->red+Da*q->red);
173 composite->green=gamma*(Sa*p->green+Da*q->green);
174 composite->blue=gamma*(Sa*p->blue+Da*q->blue);
175 if (q->colorspace == CMYKColorspace)
176 composite->black=gamma*(Sa*p->black+Da*q->black);
179 static inline void CompositePixelInfoAreaBlend(const PixelInfo *p,
180 const double alpha,const PixelInfo *q,const double beta,const double area,
181 PixelInfo *composite)
184 Blend pixel colors p and q by the amount given and area.
186 CompositePixelInfoPlus(p,(double) (1.0-area)*alpha,q,(double) (area*beta),
190 static inline void CompositePixelInfoBlend(const PixelInfo *p,
191 const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
194 Blend pixel colors p and q by the amount given.
196 CompositePixelInfoPlus(p,(double) (alpha*p->alpha),q,(double) (beta*q->alpha),
200 #if defined(__cplusplus) || defined(c_plusplus)