MagickCore  7.1.1-43
Convert, Edit, Or Compose Bitmap Images
composite-private.h
1 /*
2  Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization
3  dedicated to making software imaging solutions freely available.
4 
5  You may not use this file except in compliance with the License. You may
6  obtain a copy of the License at
7 
8  https://imagemagick.org/script/license.php
9 
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.
15 
16  MagickCore image composite private methods.
17 */
18 #ifndef MAGICKCORE_COMPOSITE_PRIVATE_H
19 #define MAGICKCORE_COMPOSITE_PRIVATE_H
20 
21 
22 #include "MagickCore/color.h"
23 #include "MagickCore/image.h"
24 #include "MagickCore/artifact.h"
25 #include "MagickCore/image-private.h"
26 #include "MagickCore/pixel-accessor.h"
27 
28 #if defined(__cplusplus) || defined(c_plusplus)
29 extern "C" {
30 #endif
31 
32 /*
33  ImageMagick Alpha Composite Inline Methods (special export)
34 */
35 static inline double MagickOver_(const double p,const double alpha,
36  const double q,const double beta)
37 {
38  double
39  Da,
40  Sa;
41 
42  Sa=QuantumScale*alpha;
43  Da=QuantumScale*beta;
44  return(Sa*p+Da*q*(1.0-Sa));
45 }
46 
47 static inline double RoundToUnity(const double value)
48 {
49  return(value < 0.0 ? 0.0 : (value > 1.0) ? 1.0 : value);
50 }
51 
52 static inline void CompositePixelOver(const Image *image,const PixelInfo *p,
53  const double alpha,const Quantum *q,const double beta,Quantum *composite)
54 {
55  double
56  Da,
57  gamma,
58  Sa;
59 
60  ssize_t
61  i;
62 
63  /*
64  Compose pixel p over pixel q with the given alpha.
65  */
66  Sa=QuantumScale*alpha;
67  Da=QuantumScale*beta;
68  gamma=Sa+Da-Sa*Da;
69  gamma=PerceptibleReciprocal(gamma);
70  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
71  {
72  PixelChannel
73  channel;
74 
75  PixelTrait
76  traits;
77 
78  channel=GetPixelChannelChannel(image,i);
79  traits=GetPixelChannelTraits(image,channel);
80  if (traits == UndefinedPixelTrait)
81  continue;
82  switch (channel)
83  {
84  case RedPixelChannel:
85  {
86  composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->red,alpha,
87  (double) q[i],beta));
88  break;
89  }
90  case GreenPixelChannel:
91  {
92  composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->green,alpha,
93  (double) q[i],beta));
94  break;
95  }
96  case BluePixelChannel:
97  {
98  composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->blue,alpha,
99  (double) q[i],beta));
100  break;
101  }
102  case BlackPixelChannel:
103  {
104  composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->black,alpha,
105  (double) q[i],beta));
106  break;
107  }
108  case AlphaPixelChannel:
109  {
110  composite[i]=ClampToQuantum((double) QuantumRange*
111  RoundToUnity(Sa+Da-Sa*Da));
112  break;
113  }
114  default:
115  {
116  composite[i]=q[i];
117  break;
118  }
119  }
120  }
121 }
122 
123 static inline void CompositePixelInfoOver(const PixelInfo *p,const double alpha,
124  const PixelInfo *q,const double beta,PixelInfo *composite)
125 {
126  double
127  Da,
128  gamma,
129  Sa;
130 
131  /*
132  Compose pixel p over pixel q with the given opacities.
133  */
134  Sa=QuantumScale*alpha;
135  Da=QuantumScale*beta,
136  gamma=Sa+Da-Sa*Da;
137  composite->alpha=(double) QuantumRange*RoundToUnity(gamma);
138  gamma=PerceptibleReciprocal(gamma);
139  composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta);
140  composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta);
141  composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta);
142  if (q->colorspace == CMYKColorspace)
143  composite->black=gamma*MagickOver_(p->black,alpha,q->black,beta);
144 }
145 
146 static inline void CompositePixelInfoPlus(const PixelInfo *p,
147  const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
148 {
149  double
150  Da,
151  gamma,
152  Sa;
153 
154  /*
155  Add two pixels with the given opacities.
156  */
157  Sa=QuantumScale*alpha;
158  Da=QuantumScale*beta;
159  gamma=RoundToUnity(Sa+Da); /* 'Plus' blending -- not 'Over' blending */
160  composite->alpha=(double) QuantumRange*RoundToUnity(gamma);
161  gamma=PerceptibleReciprocal(gamma);
162  composite->red=gamma*(Sa*p->red+Da*q->red);
163  composite->green=gamma*(Sa*p->green+Da*q->green);
164  composite->blue=gamma*(Sa*p->blue+Da*q->blue);
165  if (q->colorspace == CMYKColorspace)
166  composite->black=gamma*(Sa*p->black+Da*q->black);
167 }
168 
169 static inline void CompositePixelInfoAreaBlend(const PixelInfo *p,
170  const double alpha,const PixelInfo *q,const double beta,const double area,
171  PixelInfo *composite)
172 {
173  /*
174  Blend pixel colors p and q by the amount given and area.
175  */
176  CompositePixelInfoPlus(p,(double) (1.0-area)*alpha,q,(double) (area*beta),
177  composite);
178 }
179 
180 static inline void CompositePixelInfoBlend(const PixelInfo *p,
181  const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
182 {
183  /*
184  Blend pixel colors p and q by the amount given.
185  */
186  CompositePixelInfoPlus(p,(double) (alpha*p->alpha),q,(double) (beta*q->alpha),
187  composite);
188 }
189 
190 static inline void DisableCompositeClampUnlessSpecified(Image *image)
191 {
192  if (GetImageArtifact(image,"compose:clamp") == (const char *) NULL)
193  (void) SetImageArtifact(image,"compose:clamp","off");
194 }
195 
196 static inline MagickBooleanType GetCompositeClipToSelf(
197  const CompositeOperator compose)
198 {
199  switch (compose)
200  {
201  case ClearCompositeOp:
202  case SrcCompositeOp:
203  case InCompositeOp:
204  case SrcInCompositeOp:
205  case OutCompositeOp:
206  case SrcOutCompositeOp:
207  case DstInCompositeOp:
208  case DstAtopCompositeOp:
209  case CopyAlphaCompositeOp:
210  case ChangeMaskCompositeOp:
211  {
212  return(MagickFalse);
213  break;
214  }
215  default:
216  break;
217  }
218  return(MagickTrue);
219 }
220 
221 #if defined(__cplusplus) || defined(c_plusplus)
222 }
223 #endif
224 
225 #endif
_Image
Definition: image.h:131
_PixelInfo
Definition: pixel.h:181