MagickCore  7.0.7
Convert, Edit, Or Compose Bitmap Images
composite-private.h
Go to the documentation of this file.
1 /*
2  Copyright 1999-2018 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.
6  obtain a copy of the License at
7 
8  https://www.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"
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  register 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  {
73  channel;
74 
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(QuantumRange*RoundToUnity(Sa+Da-Sa*Da));
111  break;
112  }
113  default:
114  {
115  composite[i]=q[i];
116  break;
117  }
118  }
119  }
120 }
121 
122 static inline void CompositePixelInfoOver(const PixelInfo *p,
123  const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
124 {
125  double
126  Da,
127  gamma,
128  Sa;
129 
130  /*
131  Compose pixel p over pixel q with the given opacities.
132  */
133  Sa=QuantumScale*alpha;
134  Da=QuantumScale*beta,
135  gamma=Sa+Da-Sa*Da;
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);
143 }
144 
145 static inline void CompositePixelInfoPlus(const PixelInfo *p,
146  const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
147 {
148  double
149  Da,
150  gamma,
151  Sa;
152 
153  /*
154  Add two pixels with the given opacities.
155  */
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);
166 }
167 
168 static inline void CompositePixelInfoAreaBlend(const PixelInfo *p,
169  const double alpha,const PixelInfo *q,const double beta,const double area,
170  PixelInfo *composite)
171 {
172  /*
173  Blend pixel colors p and q by the amount given and area.
174  */
175  CompositePixelInfoPlus(p,(double) (1.0-area)*alpha,q,(double) (area*beta),
176  composite);
177 }
178 
179 static inline void CompositePixelInfoBlend(const PixelInfo *p,
180  const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
181 {
182  /*
183  Blend pixel colors p and q by the amount given.
184  */
185  CompositePixelInfoPlus(p,(double) (alpha*p->alpha),q,(double) (beta*q->alpha),
186  composite);
187 }
188 
189 #if defined(__cplusplus) || defined(c_plusplus)
190 }
191 #endif
192 
193 #endif
static double MagickOver_(const double p, const double alpha, const double q, const double beta)
static void CompositePixelInfoPlus(const PixelInfo *p, const double alpha, const PixelInfo *q, const double beta, PixelInfo *composite)
MagickRealType red
Definition: pixel.h:188
static PixelTrait GetPixelChannelTraits(const Image *magick_restrict image, const PixelChannel channel)
MagickRealType alpha
Definition: pixel.h:188
Definition: image.h:151
static double PerceptibleReciprocal(const double x)
static void CompositePixelInfoOver(const PixelInfo *p, const double alpha, const PixelInfo *q, const double beta, PixelInfo *composite)
static void CompositePixelInfoAreaBlend(const PixelInfo *p, const double alpha, const PixelInfo *q, const double beta, const double area, PixelInfo *composite)
MagickRealType blue
Definition: pixel.h:188
#define QuantumScale
Definition: magick-type.h:113
PixelChannel
Definition: pixel.h:66
static double RoundToUnity(const double value)
static size_t GetPixelChannels(const Image *magick_restrict image)
static Quantum ClampToQuantum(const MagickRealType value)
Definition: quantum.h:84
static PixelChannel GetPixelChannelChannel(const Image *magick_restrict image, const ssize_t offset)
unsigned short Quantum
Definition: magick-type.h:82
MagickRealType black
Definition: pixel.h:188
MagickRealType green
Definition: pixel.h:188
static void CompositePixelInfoBlend(const PixelInfo *p, const double alpha, const PixelInfo *q, const double beta, PixelInfo *composite)
ColorspaceType colorspace
Definition: pixel.h:173
PixelTrait
Definition: pixel.h:132
#define QuantumRange
Definition: magick-type.h:83
static void CompositePixelOver(const Image *image, const PixelInfo *p, const double alpha, const Quantum *q, const double beta, Quantum *composite)