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,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)
81 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->red,
82 alpha,(double) q[i],beta));
85 case GreenPixelChannel:
87 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->green,
88 alpha,(double) q[i],beta));
91 case BluePixelChannel:
93 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->blue,
94 alpha,(double) q[i],beta));
97 case BlackPixelChannel:
99 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->black,
100 alpha,(double) q[i],beta));
103 case AlphaPixelChannel:
105 composite[i]=ClampToQuantum(QuantumRange*(Sa*(-Da)+Sa+Da));
114 static inline void CompositePixelInfoOver(const PixelInfo *p,
115 const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
123 Compose pixel p over pixel q with the given opacities.
125 if (fabs(alpha-OpaqueAlpha) < MagickEpsilon)
130 Sa=QuantumScale*alpha;
131 Da=QuantumScale*beta,
132 gamma=Sa*(-Da)+Sa+Da;
133 composite->alpha=(double) QuantumRange*gamma;
134 gamma=PerceptibleReciprocal(gamma);
135 composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta);
136 composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta);
137 composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta);
138 if (q->colorspace == CMYKColorspace)
139 composite->black=gamma*MagickOver_(p->black,alpha,q->black,beta);
142 static inline double RoundToUnity(const double value)
144 return(value < 0.0 ? 0.0 : (value > 1.0) ? 1.0 : value);
147 static inline void CompositePixelInfoPlus(const PixelInfo *p,
148 const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
156 Add two pixels with the given opacities.
158 Sa=QuantumScale*alpha;
159 Da=QuantumScale*beta;
160 gamma=RoundToUnity(Sa+Da); /* 'Plus' blending -- not 'Over' blending */
161 composite->alpha=(double) QuantumRange*gamma;
162 gamma=PerceptibleReciprocal(gamma);
163 composite->red=gamma*(Sa*p->red+Da*q->red);
164 composite->green=gamma*(Sa*p->green+Da*q->green);
165 composite->blue=gamma*(Sa*p->blue+Da*q->blue);
166 if (q->colorspace == CMYKColorspace)
167 composite->black=gamma*(Sa*p->black+Da*q->black);
170 static inline void CompositePixelInfoAreaBlend(const PixelInfo *p,
171 const double alpha,const PixelInfo *q,const double beta,const double area,
172 PixelInfo *composite)
175 Blend pixel colors p and q by the amount given and area.
177 CompositePixelInfoPlus(p,(double) (1.0-area)*alpha,q,(double) (area*beta),
181 static inline void CompositePixelInfoBlend(const PixelInfo *p,
182 const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
185 Blend pixel colors p and q by the amount given.
187 CompositePixelInfoPlus(p,(double) (alpha*p->alpha),q,(double) (beta*q->alpha),
191 #if defined(__cplusplus) || defined(c_plusplus)