2 Copyright 1999-2018 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 https://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,const double alpha,
36 const double q,const double beta)
42 Sa=QuantumScale*alpha;
44 return(Sa*p+Da*q*(1.0-Sa));
47 static inline double RoundToUnity(const double value)
49 return(value < 0.0 ? 0.0 : (value > 1.0) ? 1.0 : value);
52 static inline void CompositePixelOver(const Image *image,const PixelInfo *p,
53 const double alpha,const Quantum *q,const double beta,Quantum *composite)
64 Compose pixel p over pixel q with the given alpha.
66 Sa=QuantumScale*alpha;
69 gamma=PerceptibleReciprocal(gamma);
70 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
78 channel=GetPixelChannelChannel(image,i);
79 traits=GetPixelChannelTraits(image,channel);
80 if (traits == UndefinedPixelTrait)
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*RoundToUnity(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 Sa=QuantumScale*alpha;
134 Da=QuantumScale*beta,
136 composite->alpha=(double) QuantumRange*RoundToUnity(gamma);
137 gamma=PerceptibleReciprocal(gamma);
138 composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta);
139 composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta);
140 composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta);
141 if (q->colorspace == CMYKColorspace)
142 composite->black=gamma*MagickOver_(p->black,alpha,q->black,beta);
145 static inline void CompositePixelInfoPlus(const PixelInfo *p,
146 const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
154 Add two pixels with the given opacities.
156 Sa=QuantumScale*alpha;
157 Da=QuantumScale*beta;
158 gamma=RoundToUnity(Sa+Da); /* 'Plus' blending -- not 'Over' blending */
159 composite->alpha=(double) QuantumRange*RoundToUnity(gamma);
160 gamma=PerceptibleReciprocal(gamma);
161 composite->red=gamma*(Sa*p->red+Da*q->red);
162 composite->green=gamma*(Sa*p->green+Da*q->green);
163 composite->blue=gamma*(Sa*p->blue+Da*q->blue);
164 if (q->colorspace == CMYKColorspace)
165 composite->black=gamma*(Sa*p->black+Da*q->black);
168 static inline void CompositePixelInfoAreaBlend(const PixelInfo *p,
169 const double alpha,const PixelInfo *q,const double beta,const double area,
170 PixelInfo *composite)
173 Blend pixel colors p and q by the amount given and area.
175 CompositePixelInfoPlus(p,(double) (1.0-area)*alpha,q,(double) (area*beta),
179 static inline void CompositePixelInfoBlend(const PixelInfo *p,
180 const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
183 Blend pixel colors p and q by the amount given.
185 CompositePixelInfoPlus(p,(double) (alpha*p->alpha),q,(double) (beta*q->alpha),
189 static inline MagickBooleanType GetCompositeClipToSelf(
190 const CompositeOperator compose)
194 case ClearCompositeOp:
197 case SrcInCompositeOp:
199 case SrcOutCompositeOp:
200 case DstInCompositeOp:
201 case DstAtopCompositeOp:
202 case CopyAlphaCompositeOp:
203 case ChangeMaskCompositeOp:
214 #if defined(__cplusplus) || defined(c_plusplus)