• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2   Copyright 1999-2020 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 
21 #include "MagickCore/pixel-accessor.h"
22 #include "MagickCore/visual-effects.h"
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
35   GenerateDifferentialNoise(RandomInfo *,const Quantum,const NoiseType,
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   ConvertRGBToLCHab(const double,const double,const double,double *,double *,
73     double *),
74   ConvertRGBToLCHuv(const double,const double,const double,double *,double *,
75     double *);
76 
ConvertLabToXYZ(const double L,const double a,const double b,double * X,double * Y,double * Z)77 static inline void ConvertLabToXYZ(const double L,const double a,const double b,
78   double *X,double *Y,double *Z)
79 {
80   double
81     x,
82     y,
83     z;
84 
85   assert(X != (double *) NULL);
86   assert(Y != (double *) NULL);
87   assert(Z != (double *) NULL);
88   y=(L+16.0)/116.0;
89   x=y+a/500.0;
90   z=y-b/200.0;
91   if ((x*x*x) > CIEEpsilon)
92     x=(x*x*x);
93   else
94     x=(116.0*x-16.0)/CIEK;
95   if ((y*y*y) > CIEEpsilon)
96     y=(y*y*y);
97   else
98     y=L/CIEK;
99   if ((z*z*z) > CIEEpsilon)
100     z=(z*z*z);
101   else
102     z=(116.0*z-16.0)/CIEK;
103   *X=D65X*x;
104   *Y=D65Y*y;
105   *Z=D65Z*z;
106 }
107 
ConvertLuvToXYZ(const double L,const double u,const double v,double * X,double * Y,double * Z)108 static inline void ConvertLuvToXYZ(const double L,const double u,const double v,
109   double *X,double *Y,double *Z)
110 {
111   double
112     gamma;
113 
114   assert(X != (double *) NULL);
115   assert(Y != (double *) NULL);
116   assert(Z != (double *) NULL);
117   if (L > (CIEK*CIEEpsilon))
118     *Y=(double) pow((L+16.0)/116.0,3.0);
119   else
120     *Y=L/CIEK;
121   gamma=PerceptibleReciprocal((((52.0*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+
122     3.0*D65Z))))-1.0)/3.0)-(-1.0/3.0));
123   *X=gamma*((*Y*((39.0*L/(v+13.0*L*(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z))))-5.0))+
124     5.0*(*Y));
125   *Z=(*X*(((52.0*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/3.0))-
126     5.0*(*Y);
127 }
128 
ConvertRGBToXYZ(const double red,const double green,const double blue,double * X,double * Y,double * Z)129 static inline void ConvertRGBToXYZ(const double red,const double green,
130   const double blue,double *X,double *Y,double *Z)
131 {
132   double
133     b,
134     g,
135     r;
136 
137   /*
138     Convert RGB to XYZ colorspace.
139   */
140   assert(X != (double *) NULL);
141   assert(Y != (double *) NULL);
142   assert(Z != (double *) NULL);
143   r=QuantumScale*DecodePixelGamma(red);
144   g=QuantumScale*DecodePixelGamma(green);
145   b=QuantumScale*DecodePixelGamma(blue);
146   *X=0.4124564*r+0.3575761*g+0.1804375*b;
147   *Y=0.2126729*r+0.7151522*g+0.0721750*b;
148   *Z=0.0193339*r+0.1191920*g+0.9503041*b;
149 }
150 
ConvertXYZToLab(const double X,const double Y,const double Z,double * L,double * a,double * b)151 static inline void ConvertXYZToLab(const double X,const double Y,const double Z,
152   double *L,double *a,double *b)
153 {
154   double
155     x,
156     y,
157     z;
158 
159   assert(L != (double *) NULL);
160   assert(a != (double *) NULL);
161   assert(b != (double *) NULL);
162   if ((X/D65X) > CIEEpsilon)
163     x=pow(X/D65X,1.0/3.0);
164   else
165     x=(CIEK*X/D65X+16.0)/116.0;
166   if ((Y/D65Y) > CIEEpsilon)
167     y=pow(Y/D65Y,1.0/3.0);
168   else
169     y=(CIEK*Y/D65Y+16.0)/116.0;
170   if ((Z/D65Z) > CIEEpsilon)
171     z=pow(Z/D65Z,1.0/3.0);
172   else
173     z=(CIEK*Z/D65Z+16.0)/116.0;
174   *L=((116.0*y)-16.0)/100.0;
175   *a=(500.0*(x-y))/255.0+0.5;
176   *b=(200.0*(y-z))/255.0+0.5;
177 }
178 
ConvertXYZToLuv(const double X,const double Y,const double Z,double * L,double * u,double * v)179 static inline void ConvertXYZToLuv(const double X,const double Y,const double Z,
180   double *L,double *u,double *v)
181 {
182   double
183     alpha;
184 
185   assert(L != (double *) NULL);
186   assert(u != (double *) NULL);
187   assert(v != (double *) NULL);
188   if ((Y/D65Y) > CIEEpsilon)
189     *L=(double) (116.0*pow(Y/D65Y,1.0/3.0)-16.0);
190   else
191     *L=CIEK*(Y/D65Y);
192   alpha=PerceptibleReciprocal(X+15.0*Y+3.0*Z);
193   *u=13.0*(*L)*((4.0*alpha*X)-(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z)));
194   *v=13.0*(*L)*((9.0*alpha*Y)-(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z)));
195   *L/=100.0;
196   *u=(*u+134.0)/354.0;
197   *v=(*v+140.0)/262.0;
198 }
199 
ConvertXYZToRGB(const double X,const double Y,const double Z,double * red,double * green,double * blue)200 static inline void ConvertXYZToRGB(const double X,const double Y,const double Z,
201   double *red,double *green,double *blue)
202 {
203   double
204     b,
205     g,
206     r;
207 
208   assert(red != (double *) NULL);
209   assert(green != (double *) NULL);
210   assert(blue != (double *) NULL);
211   r=3.2404542*X-1.5371385*Y-0.4985314*Z;
212   g=(-0.9692660)*X+1.8760108*Y+0.0415560*Z;
213   b=0.0556434*X-0.2040259*Y+1.0572252*Z;
214   *red=EncodePixelGamma(QuantumRange*r);
215   *green=EncodePixelGamma(QuantumRange*g);
216   *blue=EncodePixelGamma(QuantumRange*b);
217 }
218 
219 #if defined(__cplusplus) || defined(c_plusplus)
220 }
221 #endif
222 
223 #endif
224