MagickCore 6.9.13-12
Convert, Edit, Or Compose Bitmap Images
Loading...
Searching...
No Matches
gem-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 private graphic gems methods.
17*/
18#ifndef MAGICKCORE_GEM_PRIVATE_H
19#define MAGICKCORE_GEM_PRIVATE_H
20
21#include "magick/pixel-accessor.h"
22#include "magick/visual-effects.h"
23
24#if defined(__cplusplus) || defined(c_plusplus)
25extern "C" {
26#endif
27
28#define D65X 0.95047
29#define D65Y 1.0
30#define D65Z 1.08883
31#define CIEEpsilon (216.0/24389.0)
32#define CIEK (24389.0/27.0)
33
34static inline void ConvertLabToXYZ(const double L,const double a,const double b,
35 double *X,double *Y,double *Z)
36{
37 double
38 x,
39 y,
40 z;
41
42 assert(X != (double *) NULL);
43 assert(Y != (double *) NULL);
44 assert(Z != (double *) NULL);
45 y=(L+16.0)/116.0;
46 x=y+a/500.0;
47 z=y-b/200.0;
48 if ((x*x*x) > CIEEpsilon)
49 x=(x*x*x);
50 else
51 x=(116.0*x-16.0)/CIEK;
52 if (L > (CIEK*CIEEpsilon))
53 y=(y*y*y);
54 else
55 y=L/CIEK;
56 if ((z*z*z) > CIEEpsilon)
57 z=(z*z*z);
58 else
59 z=(116.0*z-16.0)/CIEK;
60 *X=D65X*x;
61 *Y=D65Y*y;
62 *Z=D65Z*z;
63}
64
65static inline void ConvertXYZToLuv(const double X,const double Y,const double Z,
66 double *L,double *u,double *v)
67{
68 double
69 alpha;
70
71 assert(L != (double *) NULL);
72 assert(u != (double *) NULL);
73 assert(v != (double *) NULL);
74 if ((Y/D65Y) > CIEEpsilon)
75 *L=(double) (116.0*pow(Y/D65Y,1.0/3.0)-16.0);
76 else
77 *L=CIEK*(Y/D65Y);
78 alpha=PerceptibleReciprocal(X+15.0*Y+3.0*Z);
79 *u=13.0*(*L)*((4.0*alpha*X)-(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z)));
80 *v=13.0*(*L)*((9.0*alpha*Y)-(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z)));
81 *L/=100.0;
82 *u=(*u+134.0)/354.0;
83 *v=(*v+140.0)/262.0;
84}
85
86static inline void ConvertRGBToXYZ(const Quantum red,const Quantum green,
87 const Quantum blue,double *X,double *Y,double *Z)
88{
89 double
90 b,
91 g,
92 r;
93
94 assert(X != (double *) NULL);
95 assert(Y != (double *) NULL);
96 assert(Z != (double *) NULL);
97 r=QuantumScale*DecodePixelGamma((MagickRealType) red);
98 g=QuantumScale*DecodePixelGamma((MagickRealType) green);
99 b=QuantumScale*DecodePixelGamma((MagickRealType) blue);
100 *X=0.4124564*r+0.3575761*g+0.1804375*b;
101 *Y=0.2126729*r+0.7151522*g+0.0721750*b;
102 *Z=0.0193339*r+0.1191920*g+0.9503041*b;
103}
104
105static inline void ConvertXYZToLab(const double X,const double Y,const double Z,
106 double *L,double *a,double *b)
107{
108 double
109 x,
110 y,
111 z;
112
113 assert(L != (double *) NULL);
114 assert(a != (double *) NULL);
115 assert(b != (double *) NULL);
116 if ((X/D65X) > CIEEpsilon)
117 x=pow(X/D65X,1.0/3.0);
118 else
119 x=(CIEK*X/D65X+16.0)/116.0;
120 if ((Y/D65Y) > CIEEpsilon)
121 y=pow(Y/D65Y,1.0/3.0);
122 else
123 y=(CIEK*Y/D65Y+16.0)/116.0;
124 if ((Z/D65Z) > CIEEpsilon)
125 z=pow(Z/D65Z,1.0/3.0);
126 else
127 z=(CIEK*Z/D65Z+16.0)/116.0;
128 *L=((116.0*y)-16.0)/100.0;
129 *a=(500.0*(x-y))/255.0+0.5;
130 *b=(200.0*(y-z))/255.0+0.5;
131}
132
133static inline void ConvertLuvToXYZ(const double L,const double u,const double v,
134 double *X,double *Y,double *Z)
135{
136 double
137 gamma;
138
139 assert(X != (double *) NULL);
140 assert(Y != (double *) NULL);
141 assert(Z != (double *) NULL);
142 if (L > (CIEK*CIEEpsilon))
143 *Y=(double) pow((L+16.0)/116.0,3.0);
144 else
145 *Y=L/CIEK;
146 gamma=PerceptibleReciprocal((((52.0*L*PerceptibleReciprocal(u+13.0*L*
147 (4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/3.0)-(-1.0/3.0));
148 *X=gamma*((*Y*((39.0*L*PerceptibleReciprocal(v+13.0*L*(9.0*D65Y/
149 (D65X+15.0*D65Y+3.0*D65Z))))-5.0))+5.0*(*Y));
150 *Z=(*X*(((52.0*L*PerceptibleReciprocal(u+13.0*L*(4.0*D65X/
151 (D65X+15.0*D65Y+3.0*D65Z))))-1.0)/3.0))-5.0*(*Y);
152}
153
154static inline void ConvertXYZToRGB(const double X,const double Y,const double Z,
155 Quantum *red,Quantum *green,Quantum *blue)
156{
157 double
158 b,
159 g,
160 r;
161
162 assert(red != (Quantum *) NULL);
163 assert(green != (Quantum *) NULL);
164 assert(blue != (Quantum *) NULL);
165 r=3.2404542*X-1.5371385*Y-0.4985314*Z;
166 g=(-0.9692660)*X+1.8760108*Y+0.0415560*Z;
167 b=0.0556434*X-0.2040259*Y+1.0572252*Z;
168 *red=ClampToQuantum((MagickRealType) EncodePixelGamma((MagickRealType)
169 QuantumRange*r));
170 *green=ClampToQuantum((MagickRealType) EncodePixelGamma((MagickRealType)
171 QuantumRange*g));
172 *blue=ClampToQuantum((MagickRealType) EncodePixelGamma((MagickRealType)
173 QuantumRange*b));
174}
175
176#if defined(__cplusplus) || defined(c_plusplus)
177}
178#endif
179
180#endif