2 Copyright 1999-2012 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,
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,
60 Compose pixel p over pixel q with the given alpha.
62 Sa=QuantumScale*alpha;
65 gamma=MagickEpsilonReciprocal(gamma);
66 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
74 channel=GetPixelChannelMapChannel(image,i);
75 traits=GetPixelChannelMapTraits(image,channel);
76 if (traits == UndefinedPixelTrait)
82 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->red,
83 alpha,(double) q[i],beta));
86 case GreenPixelChannel:
88 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->green,
89 alpha,(double) q[i],beta));
92 case BluePixelChannel:
94 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->blue,
95 alpha,(double) q[i],beta));
98 case BlackPixelChannel:
100 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->black,
101 alpha,(double) q[i],beta));
104 case AlphaPixelChannel:
106 composite[i]=ClampToQuantum(QuantumRange*(Sa*(-Da)+Sa+Da));
115 static inline void CompositePixelInfoOver(const PixelInfo *p,
116 const double alpha,const PixelInfo *q,const double beta,
117 PixelInfo *composite)
125 Compose pixel p over pixel q with the given opacities.
127 if (fabs(alpha-OpaqueAlpha) < MagickEpsilon)
132 Sa=QuantumScale*alpha;
133 Da=QuantumScale*beta,
134 gamma=Sa*(-Da)+Sa+Da;
135 composite->alpha=(double) QuantumRange*gamma;
136 gamma=MagickEpsilonReciprocal(gamma);
137 composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta);
138 composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta);
139 composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta);
140 if (q->colorspace == CMYKColorspace)
141 composite->black=gamma*MagickOver_(p->black,alpha,q->black,beta);
144 static inline double RoundToUnity(const double value)
146 return(value < 0.0 ? 0.0 : (value > 1.0) ? 1.0 : value);
149 static inline void CompositePixelInfoPlus(const PixelInfo *p,
150 const double alpha,const PixelInfo *q,const double beta,
151 PixelInfo *composite)
159 Add two pixels with the given opacities.
161 Sa=QuantumScale*alpha;
162 Da=QuantumScale*beta;
163 gamma=RoundToUnity(Sa+Da); /* 'Plus' blending -- not 'Over' blending */
164 composite->alpha=(double) QuantumRange*gamma;
165 gamma=MagickEpsilonReciprocal(gamma);
166 composite->red=gamma*(Sa*p->red+Da*q->red);
167 composite->green=gamma*(Sa*p->green+Da*q->green);
168 composite->blue=gamma*(Sa*p->blue+Da*q->blue);
169 if (q->colorspace == CMYKColorspace)
170 composite->black=gamma*(Sa*p->black+Da*q->black);
173 static inline void CompositePixelInfoAreaBlend(const PixelInfo *p,
174 const double alpha,const PixelInfo *q,const double beta,
175 const double area,PixelInfo *composite)
178 Blend pixel colors p and q by the amount given and area.
180 CompositePixelInfoPlus(p,(double) (1.0-area)*alpha,q,(double)
181 (area*beta),composite);
184 static inline void CompositePixelInfoBlend(const PixelInfo *p,
185 const double alpha,const PixelInfo *q,const double beta,
186 PixelInfo *composite)
189 Blend pixel colors p and q by the amount given.
191 CompositePixelInfoPlus(p,(double) (alpha*p->alpha),q,(double)
192 (beta*q->alpha),composite);
195 #if defined(__cplusplus) || defined(c_plusplus)