MagickCore  7.0.10
gem-private.h
Go to the documentation of this file.
1 /*
2  Copyright 1999-2021 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 private graphic gems methods.
17 */
18 #ifndef MAGICKCORE_GEM_PRIVATE_H
19 #define MAGICKCORE_GEM_PRIVATE_H
20 
23 
24 #if defined(__cplusplus) || defined(c_plusplus)
25 extern "C" {
26 #endif
27 
28 #define D65X 0.950456
29 #define D65Y 1.0
30 #define D65Z 1.088754
31 #define CIEEpsilon (216.0/24389.0)
32 #define CIEK (24389.0/27.0)
33 
34 extern MagickPrivate double
36  const double);
37 
38 extern MagickPrivate size_t
39  GetOptimalKernelWidth(const double,const double),
40  GetOptimalKernelWidth1D(const double,const double),
41  GetOptimalKernelWidth2D(const double,const double);
42 
43 extern MagickPrivate void
44  ConvertHCLToRGB(const double,const double,const double,double *,double *,
45  double *),
46  ConvertHCLpToRGB(const double,const double,const double,double *,double *,
47  double *),
48  ConvertHSBToRGB(const double,const double,const double,double *,double *,
49  double *),
50  ConvertHSIToRGB(const double,const double,const double,double *,double *,
51  double *),
52  ConvertHSVToRGB(const double,const double,const double,double *,double *,
53  double *),
54  ConvertHWBToRGB(const double,const double,const double,double *,double *,
55  double *),
56  ConvertLCHabToRGB(const double,const double,const double,double *,double *,
57  double *),
58  ConvertLCHuvToRGB(const double,const double,const double,double *,double *,
59  double *),
60  ConvertRGBToHCL(const double,const double,const double,double *,double *,
61  double *),
62  ConvertRGBToHCLp(const double,const double,const double,double *,double *,
63  double *),
64  ConvertRGBToHSB(const double,const double,const double,double *,double *,
65  double *),
66  ConvertRGBToHSI(const double,const double,const double,double *,double *,
67  double *),
68  ConvertRGBToHSV(const double,const double,const double,double *,double *,
69  double *),
70  ConvertRGBToHWB(const double,const double,const double,double *,double *,
71  double *),
72  ConvertRGBToLab(const double,const double,const double,double *,double *,
73  double *),
74  ConvertRGBToLCHab(const double,const double,const double,double *,double *,
75  double *),
76  ConvertRGBToLCHuv(const double,const double,const double,double *,double *,
77  double *);
78 
79 static inline void ConvertAdobe98ToXYZ(const double red,const double green,
80  const double blue,double *X,double *Y,double *Z)
81 {
82  double
83  b,
84  g,
85  r;
86 
87  /*
88  Convert Adobe '98 to XYZ colorspace.
89  */
90  assert(X != (double *) NULL);
91  assert(Y != (double *) NULL);
92  assert(Z != (double *) NULL);
96  *X=0.57666904291013050*r+0.18555823790654630*g+0.18822864623499470*b;
97  *Y=0.29734497525053605*r+0.62736356625546610*g+0.07529145849399788*b;
98  *Z=0.02703136138641234*r+0.07068885253582723*g+0.99133753683763880*b;
99 }
100 
101 static inline void ConvertDisplayP3ToXYZ(const double red,const double green,
102  const double blue,double *X,double *Y,double *Z)
103 {
104  double
105  b,
106  g,
107  r;
108 
109  /*
110  Convert Display P3 to XYZ colorspace.
111  */
112  assert(X != (double *) NULL);
113  assert(Y != (double *) NULL);
114  assert(Z != (double *) NULL);
118  *X=0.4865709486482162*r+0.26566769316909306*g+0.1982172852343625*b;
119  *Y=0.2289745640697488*r+0.69173852183650640*g+0.0792869140937450*b;
120  *Z=0.0000000000000000*r+0.04511338185890264*g+1.0439443689009760*b;
121 }
122 
123 static inline void ConvertLabToXYZ(const double L,const double a,const double b,
124  double *X,double *Y,double *Z)
125 {
126  double
127  x,
128  y,
129  z;
130 
131  assert(X != (double *) NULL);
132  assert(Y != (double *) NULL);
133  assert(Z != (double *) NULL);
134  y=(L+16.0)/116.0;
135  x=y+a/500.0;
136  z=y-b/200.0;
137  if ((x*x*x) > CIEEpsilon)
138  x=(x*x*x);
139  else
140  x=(116.0*x-16.0)/CIEK;
141  if (L > (CIEK*CIEEpsilon))
142  y=(y*y*y);
143  else
144  y=L/CIEK;
145  if ((z*z*z) > CIEEpsilon)
146  z=(z*z*z);
147  else
148  z=(116.0*z-16.0)/CIEK;
149  *X=D65X*x;
150  *Y=D65Y*y;
151  *Z=D65Z*z;
152 }
153 
154 static inline void ConvertLuvToXYZ(const double L,const double u,const double v,
155  double *X,double *Y,double *Z)
156 {
157  double
158  gamma;
159 
160  assert(X != (double *) NULL);
161  assert(Y != (double *) NULL);
162  assert(Z != (double *) NULL);
163  if (L > (CIEK*CIEEpsilon))
164  *Y=(double) pow((L+16.0)/116.0,3.0);
165  else
166  *Y=L/CIEK;
167  gamma=PerceptibleReciprocal((((52.0*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+
168  3.0*D65Z))))-1.0)/3.0)-(-1.0/3.0));
169  *X=gamma*((*Y*((39.0*L/(v+13.0*L*(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z))))-5.0))+
170  5.0*(*Y));
171  *Z=(*X*(((52.0*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/3.0))-
172  5.0*(*Y);
173 }
174 
175 static inline void ConvertProPhotoToXYZ(const double red,const double green,
176  const double blue,double *X,double *Y,double *Z)
177 {
178  double
179  b,
180  g,
181  r;
182 
183  /*
184  Convert ProPhoto to XYZ colorspace.
185  */
186  assert(X != (double *) NULL);
187  assert(Y != (double *) NULL);
188  assert(Z != (double *) NULL);
192  *X=0.7977604896723027*r+0.13518583717574031*g+0.03134934958152480000*b;
193  *Y=0.2880711282292934*r+0.71184321781010140*g+0.00008565396060525902*b;
194  *Z=0.0000000000000000*r+0.00000000000000000*g+0.82510460251046010000*b;
195 }
196 
197 static inline void ConvertRGBToXYZ(const double red,const double green,
198  const double blue,double *X,double *Y,double *Z)
199 {
200  double
201  b,
202  g,
203  r;
204 
205  /*
206  Convert RGB to XYZ colorspace.
207  */
208  assert(X != (double *) NULL);
209  assert(Y != (double *) NULL);
210  assert(Z != (double *) NULL);
214  *X=0.4124564*r+0.3575761*g+0.1804375*b;
215  *Y=0.2126729*r+0.7151522*g+0.0721750*b;
216  *Z=0.0193339*r+0.1191920*g+0.9503041*b;
217 }
218 
219 static inline void ConvertXYZToAdobe98(const double X,const double Y,
220  const double Z,double *red,double *green,double *blue)
221 {
222  double
223  b,
224  g,
225  r;
226 
227  assert(red != (double *) NULL);
228  assert(green != (double *) NULL);
229  assert(blue != (double *) NULL);
230  r=2.041587903810746500*X-0.56500697427885960*Y-0.34473135077832956*Z;
231  g=(-0.969243636280879500)*X+1.87596750150772020*Y+0.04155505740717557*Z;
232  b=0.013444280632031142*X-0.11836239223101838*Y+1.01517499439120540*Z;
234  *green=EncodePixelGamma(QuantumRange*g);
236 }
237 
238 static inline void ConvertXYZToDisplayP3(const double X,const double Y,
239  const double Z,double *red,double *green,double *blue)
240 {
241  double
242  b,
243  g,
244  r;
245 
246  assert(red != (double *) NULL);
247  assert(green != (double *) NULL);
248  assert(blue != (double *) NULL);
249  r=2.49349691194142500*X-0.93138361791912390*Y-0.402710784450716840*Z;
250  g=(-0.82948896956157470)*X+1.76266406031834630*Y+0.023624685841943577*Z;
251  b=0.03584583024378447*X-0.07617238926804182*Y+0.956884524007687200*Z;
253  *green=EncodePixelGamma(QuantumRange*g);
255 }
256 
257 static inline void ConvertXYZToLab(const double X,const double Y,const double Z,
258  double *L,double *a,double *b)
259 {
260  double
261  x,
262  y,
263  z;
264 
265  assert(L != (double *) NULL);
266  assert(a != (double *) NULL);
267  assert(b != (double *) NULL);
268  if ((X/D65X) > CIEEpsilon)
269  x=pow(X/D65X,1.0/3.0);
270  else
271  x=(CIEK*X/D65X+16.0)/116.0;
272  if ((Y/D65Y) > CIEEpsilon)
273  y=pow(Y/D65Y,1.0/3.0);
274  else
275  y=(CIEK*Y/D65Y+16.0)/116.0;
276  if ((Z/D65Z) > CIEEpsilon)
277  z=pow(Z/D65Z,1.0/3.0);
278  else
279  z=(CIEK*Z/D65Z+16.0)/116.0;
280  *L=((116.0*y)-16.0)/100.0;
281  *a=(500.0*(x-y))/255.0+0.5;
282  *b=(200.0*(y-z))/255.0+0.5;
283 }
284 
285 static inline void ConvertXYZToLuv(const double X,const double Y,const double Z,
286  double *L,double *u,double *v)
287 {
288  double
289  alpha;
290 
291  assert(L != (double *) NULL);
292  assert(u != (double *) NULL);
293  assert(v != (double *) NULL);
294  if ((Y/D65Y) > CIEEpsilon)
295  *L=(double) (116.0*pow(Y/D65Y,1.0/3.0)-16.0);
296  else
297  *L=CIEK*(Y/D65Y);
298  alpha=PerceptibleReciprocal(X+15.0*Y+3.0*Z);
299  *u=13.0*(*L)*((4.0*alpha*X)-(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z)));
300  *v=13.0*(*L)*((9.0*alpha*Y)-(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z)));
301  *L/=100.0;
302  *u=(*u+134.0)/354.0;
303  *v=(*v+140.0)/262.0;
304 }
305 
306 static inline void ConvertXYZToProPhoto(const double X,const double Y,
307  const double Z,double *red,double *green,double *blue)
308 {
309  double
310  b,
311  g,
312  r;
313 
314  assert(red != (double *) NULL);
315  assert(green != (double *) NULL);
316  assert(blue != (double *) NULL);
317  r=1.3457989731028281*X-0.25558010007997534*Y-0.05110628506753401*Z;
318  g=(-0.5446224939028347)*X+1.50823274131327810*Y+0.02053603239147973*Z;
319  b=0.0000000000000000*X+0.0000000000000000*Y+1.21196754563894540*Z;
321  *green=EncodePixelGamma(QuantumRange*g);
323 }
324 
325 static inline void ConvertXYZToRGB(const double X,const double Y,const double Z,
326  double *red,double *green,double *blue)
327 {
328  double
329  b,
330  g,
331  r;
332 
333  assert(red != (double *) NULL);
334  assert(green != (double *) NULL);
335  assert(blue != (double *) NULL);
336  r=3.2404542*X-1.5371385*Y-0.4985314*Z;
337  g=(-0.9692660)*X+1.8760108*Y+0.0415560*Z;
338  b=0.0556434*X-0.2040259*Y+1.0572252*Z;
340  *green=EncodePixelGamma(QuantumRange*g);
342 }
343 
344 #if defined(__cplusplus) || defined(c_plusplus)
345 }
346 #endif
347 
348 #endif
MagickExport MagickRealType EncodePixelGamma(const MagickRealType pixel)
Definition: pixel.c:446
#define D65X
Definition: gem-private.h:28
MagickPrivate void ConvertLCHabToRGB(const double, const double, const double, double *, double *, double *)
static void ConvertXYZToDisplayP3(const double X, const double Y, const double Z, double *red, double *green, double *blue)
Definition: gem-private.h:238
MagickPrivate void ConvertHSIToRGB(const double, const double, const double, double *, double *, double *)
#define CIEK
Definition: gem-private.h:32
static void ConvertProPhotoToXYZ(const double red, const double green, const double blue, double *X, double *Y, double *Z)
Definition: gem-private.h:175
static void ConvertXYZToAdobe98(const double X, const double Y, const double Z, double *red, double *green, double *blue)
Definition: gem-private.h:219
#define CIEEpsilon
Definition: gem-private.h:31
MagickPrivate double GenerateDifferentialNoise(RandomInfo *, const Quantum, const NoiseType, const double)
Definition: gem.c:1494
static void ConvertAdobe98ToXYZ(const double red, const double green, const double blue, double *X, double *Y, double *Z)
Definition: gem-private.h:79
#define D65Z
Definition: gem-private.h:30
MagickPrivate size_t GetOptimalKernelWidth1D(const double, const double)
NoiseType
#define D65Y
Definition: gem-private.h:29
MagickPrivate void ConvertRGBToHSB(const double, const double, const double, double *, double *, double *)
MagickExport MagickRealType DecodePixelGamma(const MagickRealType pixel)
Definition: pixel.c:319
static double PerceptibleReciprocal(const double x)
MagickPrivate size_t GetOptimalKernelWidth2D(const double, const double)
Definition: gem.c:1674
MagickPrivate void ConvertLCHuvToRGB(const double, const double, const double, double *, double *, double *)
static void ConvertLuvToXYZ(const double L, const double u, const double v, double *X, double *Y, double *Z)
Definition: gem-private.h:154
static void ConvertXYZToProPhoto(const double X, const double Y, const double Z, double *red, double *green, double *blue)
Definition: gem-private.h:306
MagickPrivate void ConvertRGBToHSV(const double, const double, const double, double *, double *, double *)
static void ConvertDisplayP3ToXYZ(const double red, const double green, const double blue, double *X, double *Y, double *Z)
Definition: gem-private.h:101
static void ConvertXYZToLuv(const double X, const double Y, const double Z, double *L, double *u, double *v)
Definition: gem-private.h:285
MagickPrivate void ConvertRGBToHSI(const double, const double, const double, double *, double *, double *)
#define QuantumScale
Definition: magick-type.h:123
MagickPrivate void ConvertHWBToRGB(const double, const double, const double, double *, double *, double *)
static void ConvertXYZToLab(const double X, const double Y, const double Z, double *L, double *a, double *b)
Definition: gem-private.h:257
static void ConvertRGBToXYZ(const double red, const double green, const double blue, double *X, double *Y, double *Z)
Definition: gem-private.h:197
unsigned short Quantum
Definition: magick-type.h:90
MagickPrivate void ConvertRGBToLab(const double, const double, const double, double *, double *, double *)
MagickPrivate void ConvertHSVToRGB(const double, const double, const double, double *, double *, double *)
static void ConvertLabToXYZ(const double L, const double a, const double b, double *X, double *Y, double *Z)
Definition: gem-private.h:123
MagickPrivate size_t GetOptimalKernelWidth(const double, const double)
MagickPrivate void ConvertHCLToRGB(const double, const double, const double, double *, double *, double *)
MagickPrivate void ConvertRGBToHWB(const double, const double, const double, double *, double *, double *)
MagickPrivate void ConvertHCLpToRGB(const double, const double, const double, double *, double *, double *)
static void ConvertXYZToRGB(const double X, const double Y, const double Z, double *red, double *green, double *blue)
Definition: gem-private.h:325
MagickPrivate void ConvertRGBToLCHab(const double, const double, const double, double *, double *, double *)
#define MagickPrivate
MagickPrivate void ConvertHSBToRGB(const double, const double, const double, double *, double *, double *)
MagickPrivate void ConvertRGBToHCL(const double, const double, const double, double *, double *, double *)
MagickPrivate void ConvertRGBToLCHuv(const double, const double, const double, double *, double *, double *)
Definition: gem.c:1414
#define QuantumRange
Definition: magick-type.h:91
MagickPrivate void ConvertRGBToHCLp(const double, const double, const double, double *, double *, double *)