2 Copyright 1999-2015 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
22 #include "MagickCore/color.h"
23 #include "MagickCore/image.h"
24 #include "MagickCore/image-private.h"
25 #include "MagickCore/pixel-accessor.h"
26 #include "MagickCore/pixel-private.h"
28 #if defined(__cplusplus) || defined(c_plusplus)
33 ImageMagick Alpha Composite Inline Methods (special export)
35 static inline double MagickOver_(const double p,
36 const double alpha,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++)
73 channel=GetPixelChannelChannel(image,i);
74 traits=GetPixelChannelTraits(image,channel);
75 if (traits == UndefinedPixelTrait)
77 if (fabs(alpha-TransparentAlpha) < MagickEpsilon)
86 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->red,alpha,
90 case GreenPixelChannel:
92 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->green,alpha,
96 case BluePixelChannel:
98 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->blue,alpha,
102 case BlackPixelChannel:
104 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->black,alpha,
105 (double) q[i],beta));
108 case AlphaPixelChannel:
110 composite[i]=ClampToQuantum(QuantumRange*(Sa*(-Da)+Sa+Da));
122 static inline void CompositePixelInfoOver(const PixelInfo *p,
123 const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
131 Compose pixel p over pixel q with the given opacities.
133 if (fabs(alpha-TransparentAlpha) < MagickEpsilon)
138 Sa=QuantumScale*alpha;
139 Da=QuantumScale*beta,
140 gamma=Sa*(-Da)+Sa+Da;
141 composite->alpha=(double) QuantumRange*gamma;
142 gamma=PerceptibleReciprocal(gamma);
143 composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta);
144 composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta);
145 composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta);
146 if (q->colorspace == CMYKColorspace)
147 composite->black=gamma*MagickOver_(p->black,alpha,q->black,beta);
150 static inline double RoundToUnity(const double value)
152 return(value < 0.0 ? 0.0 : (value > 1.0) ? 1.0 : value);
155 static inline void CompositePixelInfoPlus(const PixelInfo *p,
156 const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
164 Add two pixels with the given opacities.
166 Sa=QuantumScale*alpha;
167 Da=QuantumScale*beta;
168 gamma=RoundToUnity(Sa+Da); /* 'Plus' blending -- not 'Over' blending */
169 composite->alpha=(double) QuantumRange*gamma;
170 gamma=PerceptibleReciprocal(gamma);
171 composite->red=gamma*(Sa*p->red+Da*q->red);
172 composite->green=gamma*(Sa*p->green+Da*q->green);
173 composite->blue=gamma*(Sa*p->blue+Da*q->blue);
174 if (q->colorspace == CMYKColorspace)
175 composite->black=gamma*(Sa*p->black+Da*q->black);
178 static inline void CompositePixelInfoAreaBlend(const PixelInfo *p,
179 const double alpha,const PixelInfo *q,const double beta,const double area,
180 PixelInfo *composite)
183 Blend pixel colors p and q by the amount given and area.
185 CompositePixelInfoPlus(p,(double) (1.0-area)*alpha,q,(double) (area*beta),
189 static inline void CompositePixelInfoBlend(const PixelInfo *p,
190 const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
193 Blend pixel colors p and q by the amount given.
195 CompositePixelInfoPlus(p,(double) (alpha*p->alpha),q,(double) (beta*q->alpha),
199 #if defined(__cplusplus) || defined(c_plusplus)