1*3ac0a46fSAndroid Build Coastguard Worker //---------------------------------------------------------------------------------
2*3ac0a46fSAndroid Build Coastguard Worker //
3*3ac0a46fSAndroid Build Coastguard Worker // Little Color Management System
4*3ac0a46fSAndroid Build Coastguard Worker // Copyright (c) 1998-2023 Marti Maria Saguer
5*3ac0a46fSAndroid Build Coastguard Worker //
6*3ac0a46fSAndroid Build Coastguard Worker // Permission is hereby granted, free of charge, to any person obtaining
7*3ac0a46fSAndroid Build Coastguard Worker // a copy of this software and associated documentation files (the "Software"),
8*3ac0a46fSAndroid Build Coastguard Worker // to deal in the Software without restriction, including without limitation
9*3ac0a46fSAndroid Build Coastguard Worker // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*3ac0a46fSAndroid Build Coastguard Worker // and/or sell copies of the Software, and to permit persons to whom the Software
11*3ac0a46fSAndroid Build Coastguard Worker // is furnished to do so, subject to the following conditions:
12*3ac0a46fSAndroid Build Coastguard Worker //
13*3ac0a46fSAndroid Build Coastguard Worker // The above copyright notice and this permission notice shall be included in
14*3ac0a46fSAndroid Build Coastguard Worker // all copies or substantial portions of the Software.
15*3ac0a46fSAndroid Build Coastguard Worker //
16*3ac0a46fSAndroid Build Coastguard Worker // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17*3ac0a46fSAndroid Build Coastguard Worker // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
18*3ac0a46fSAndroid Build Coastguard Worker // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19*3ac0a46fSAndroid Build Coastguard Worker // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20*3ac0a46fSAndroid Build Coastguard Worker // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21*3ac0a46fSAndroid Build Coastguard Worker // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22*3ac0a46fSAndroid Build Coastguard Worker // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23*3ac0a46fSAndroid Build Coastguard Worker //
24*3ac0a46fSAndroid Build Coastguard Worker //---------------------------------------------------------------------------------
25*3ac0a46fSAndroid Build Coastguard Worker //
26*3ac0a46fSAndroid Build Coastguard Worker
27*3ac0a46fSAndroid Build Coastguard Worker #include "lcms2_internal.h"
28*3ac0a46fSAndroid Build Coastguard Worker
29*3ac0a46fSAndroid Build Coastguard Worker // inter PCS conversions XYZ <-> CIE L* a* b*
30*3ac0a46fSAndroid Build Coastguard Worker /*
31*3ac0a46fSAndroid Build Coastguard Worker
32*3ac0a46fSAndroid Build Coastguard Worker
33*3ac0a46fSAndroid Build Coastguard Worker CIE 15:2004 CIELab is defined as:
34*3ac0a46fSAndroid Build Coastguard Worker
35*3ac0a46fSAndroid Build Coastguard Worker L* = 116*f(Y/Yn) - 16 0 <= L* <= 100
36*3ac0a46fSAndroid Build Coastguard Worker a* = 500*[f(X/Xn) - f(Y/Yn)]
37*3ac0a46fSAndroid Build Coastguard Worker b* = 200*[f(Y/Yn) - f(Z/Zn)]
38*3ac0a46fSAndroid Build Coastguard Worker
39*3ac0a46fSAndroid Build Coastguard Worker and
40*3ac0a46fSAndroid Build Coastguard Worker
41*3ac0a46fSAndroid Build Coastguard Worker f(t) = t^(1/3) 1 >= t > (24/116)^3
42*3ac0a46fSAndroid Build Coastguard Worker (841/108)*t + (16/116) 0 <= t <= (24/116)^3
43*3ac0a46fSAndroid Build Coastguard Worker
44*3ac0a46fSAndroid Build Coastguard Worker
45*3ac0a46fSAndroid Build Coastguard Worker Reverse transform is:
46*3ac0a46fSAndroid Build Coastguard Worker
47*3ac0a46fSAndroid Build Coastguard Worker X = Xn*[a* / 500 + (L* + 16) / 116] ^ 3 if (X/Xn) > (24/116)
48*3ac0a46fSAndroid Build Coastguard Worker = Xn*(a* / 500 + L* / 116) / 7.787 if (X/Xn) <= (24/116)
49*3ac0a46fSAndroid Build Coastguard Worker
50*3ac0a46fSAndroid Build Coastguard Worker
51*3ac0a46fSAndroid Build Coastguard Worker
52*3ac0a46fSAndroid Build Coastguard Worker PCS in Lab2 is encoded as:
53*3ac0a46fSAndroid Build Coastguard Worker
54*3ac0a46fSAndroid Build Coastguard Worker 8 bit Lab PCS:
55*3ac0a46fSAndroid Build Coastguard Worker
56*3ac0a46fSAndroid Build Coastguard Worker L* 0..100 into a 0..ff byte.
57*3ac0a46fSAndroid Build Coastguard Worker a* t + 128 range is -128.0 +127.0
58*3ac0a46fSAndroid Build Coastguard Worker b*
59*3ac0a46fSAndroid Build Coastguard Worker
60*3ac0a46fSAndroid Build Coastguard Worker 16 bit Lab PCS:
61*3ac0a46fSAndroid Build Coastguard Worker
62*3ac0a46fSAndroid Build Coastguard Worker L* 0..100 into a 0..ff00 word.
63*3ac0a46fSAndroid Build Coastguard Worker a* t + 128 range is -128.0 +127.9961
64*3ac0a46fSAndroid Build Coastguard Worker b*
65*3ac0a46fSAndroid Build Coastguard Worker
66*3ac0a46fSAndroid Build Coastguard Worker
67*3ac0a46fSAndroid Build Coastguard Worker
68*3ac0a46fSAndroid Build Coastguard Worker Interchange Space Component Actual Range Encoded Range
69*3ac0a46fSAndroid Build Coastguard Worker CIE XYZ X 0 -> 1.99997 0x0000 -> 0xffff
70*3ac0a46fSAndroid Build Coastguard Worker CIE XYZ Y 0 -> 1.99997 0x0000 -> 0xffff
71*3ac0a46fSAndroid Build Coastguard Worker CIE XYZ Z 0 -> 1.99997 0x0000 -> 0xffff
72*3ac0a46fSAndroid Build Coastguard Worker
73*3ac0a46fSAndroid Build Coastguard Worker Version 2,3
74*3ac0a46fSAndroid Build Coastguard Worker -----------
75*3ac0a46fSAndroid Build Coastguard Worker
76*3ac0a46fSAndroid Build Coastguard Worker CIELAB (16 bit) L* 0 -> 100.0 0x0000 -> 0xff00
77*3ac0a46fSAndroid Build Coastguard Worker CIELAB (16 bit) a* -128.0 -> +127.996 0x0000 -> 0x8000 -> 0xffff
78*3ac0a46fSAndroid Build Coastguard Worker CIELAB (16 bit) b* -128.0 -> +127.996 0x0000 -> 0x8000 -> 0xffff
79*3ac0a46fSAndroid Build Coastguard Worker
80*3ac0a46fSAndroid Build Coastguard Worker
81*3ac0a46fSAndroid Build Coastguard Worker Version 4
82*3ac0a46fSAndroid Build Coastguard Worker ---------
83*3ac0a46fSAndroid Build Coastguard Worker
84*3ac0a46fSAndroid Build Coastguard Worker CIELAB (16 bit) L* 0 -> 100.0 0x0000 -> 0xffff
85*3ac0a46fSAndroid Build Coastguard Worker CIELAB (16 bit) a* -128.0 -> +127 0x0000 -> 0x8080 -> 0xffff
86*3ac0a46fSAndroid Build Coastguard Worker CIELAB (16 bit) b* -128.0 -> +127 0x0000 -> 0x8080 -> 0xffff
87*3ac0a46fSAndroid Build Coastguard Worker
88*3ac0a46fSAndroid Build Coastguard Worker */
89*3ac0a46fSAndroid Build Coastguard Worker
90*3ac0a46fSAndroid Build Coastguard Worker // Conversions
cmsXYZ2xyY(cmsCIExyY * Dest,const cmsCIEXYZ * Source)91*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsXYZ2xyY(cmsCIExyY* Dest, const cmsCIEXYZ* Source)
92*3ac0a46fSAndroid Build Coastguard Worker {
93*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number ISum;
94*3ac0a46fSAndroid Build Coastguard Worker
95*3ac0a46fSAndroid Build Coastguard Worker ISum = 1./(Source -> X + Source -> Y + Source -> Z);
96*3ac0a46fSAndroid Build Coastguard Worker
97*3ac0a46fSAndroid Build Coastguard Worker Dest -> x = (Source -> X) * ISum;
98*3ac0a46fSAndroid Build Coastguard Worker Dest -> y = (Source -> Y) * ISum;
99*3ac0a46fSAndroid Build Coastguard Worker Dest -> Y = Source -> Y;
100*3ac0a46fSAndroid Build Coastguard Worker }
101*3ac0a46fSAndroid Build Coastguard Worker
cmsxyY2XYZ(cmsCIEXYZ * Dest,const cmsCIExyY * Source)102*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsxyY2XYZ(cmsCIEXYZ* Dest, const cmsCIExyY* Source)
103*3ac0a46fSAndroid Build Coastguard Worker {
104*3ac0a46fSAndroid Build Coastguard Worker Dest -> X = (Source -> x / Source -> y) * Source -> Y;
105*3ac0a46fSAndroid Build Coastguard Worker Dest -> Y = Source -> Y;
106*3ac0a46fSAndroid Build Coastguard Worker Dest -> Z = ((1 - Source -> x - Source -> y) / Source -> y) * Source -> Y;
107*3ac0a46fSAndroid Build Coastguard Worker }
108*3ac0a46fSAndroid Build Coastguard Worker
109*3ac0a46fSAndroid Build Coastguard Worker /*
110*3ac0a46fSAndroid Build Coastguard Worker The break point (24/116)^3 = (6/29)^3 is a very small amount of tristimulus
111*3ac0a46fSAndroid Build Coastguard Worker primary (0.008856). Generally, this only happens for
112*3ac0a46fSAndroid Build Coastguard Worker nearly ideal blacks and for some orange / amber colors in transmission mode.
113*3ac0a46fSAndroid Build Coastguard Worker For example, the Z value of the orange turn indicator lamp lens on an
114*3ac0a46fSAndroid Build Coastguard Worker automobile will often be below this value. But the Z does not
115*3ac0a46fSAndroid Build Coastguard Worker contribute to the perceived color directly.
116*3ac0a46fSAndroid Build Coastguard Worker */
117*3ac0a46fSAndroid Build Coastguard Worker
118*3ac0a46fSAndroid Build Coastguard Worker static
f(cmsFloat64Number t)119*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number f(cmsFloat64Number t)
120*3ac0a46fSAndroid Build Coastguard Worker {
121*3ac0a46fSAndroid Build Coastguard Worker const cmsFloat64Number Limit = (24.0/116.0) * (24.0/116.0) * (24.0/116.0);
122*3ac0a46fSAndroid Build Coastguard Worker
123*3ac0a46fSAndroid Build Coastguard Worker if (t <= Limit)
124*3ac0a46fSAndroid Build Coastguard Worker return (841.0/108.0) * t + (16.0/116.0);
125*3ac0a46fSAndroid Build Coastguard Worker else
126*3ac0a46fSAndroid Build Coastguard Worker return pow(t, 1.0/3.0);
127*3ac0a46fSAndroid Build Coastguard Worker }
128*3ac0a46fSAndroid Build Coastguard Worker
129*3ac0a46fSAndroid Build Coastguard Worker static
f_1(cmsFloat64Number t)130*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number f_1(cmsFloat64Number t)
131*3ac0a46fSAndroid Build Coastguard Worker {
132*3ac0a46fSAndroid Build Coastguard Worker const cmsFloat64Number Limit = (24.0/116.0);
133*3ac0a46fSAndroid Build Coastguard Worker
134*3ac0a46fSAndroid Build Coastguard Worker if (t <= Limit) {
135*3ac0a46fSAndroid Build Coastguard Worker return (108.0/841.0) * (t - (16.0/116.0));
136*3ac0a46fSAndroid Build Coastguard Worker }
137*3ac0a46fSAndroid Build Coastguard Worker
138*3ac0a46fSAndroid Build Coastguard Worker return t * t * t;
139*3ac0a46fSAndroid Build Coastguard Worker }
140*3ac0a46fSAndroid Build Coastguard Worker
141*3ac0a46fSAndroid Build Coastguard Worker
142*3ac0a46fSAndroid Build Coastguard Worker // Standard XYZ to Lab. it can handle negative XZY numbers in some cases
cmsXYZ2Lab(const cmsCIEXYZ * WhitePoint,cmsCIELab * Lab,const cmsCIEXYZ * xyz)143*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsXYZ2Lab(const cmsCIEXYZ* WhitePoint, cmsCIELab* Lab, const cmsCIEXYZ* xyz)
144*3ac0a46fSAndroid Build Coastguard Worker {
145*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number fx, fy, fz;
146*3ac0a46fSAndroid Build Coastguard Worker
147*3ac0a46fSAndroid Build Coastguard Worker if (WhitePoint == NULL)
148*3ac0a46fSAndroid Build Coastguard Worker WhitePoint = cmsD50_XYZ();
149*3ac0a46fSAndroid Build Coastguard Worker
150*3ac0a46fSAndroid Build Coastguard Worker fx = f(xyz->X / WhitePoint->X);
151*3ac0a46fSAndroid Build Coastguard Worker fy = f(xyz->Y / WhitePoint->Y);
152*3ac0a46fSAndroid Build Coastguard Worker fz = f(xyz->Z / WhitePoint->Z);
153*3ac0a46fSAndroid Build Coastguard Worker
154*3ac0a46fSAndroid Build Coastguard Worker Lab->L = 116.0*fy - 16.0;
155*3ac0a46fSAndroid Build Coastguard Worker Lab->a = 500.0*(fx - fy);
156*3ac0a46fSAndroid Build Coastguard Worker Lab->b = 200.0*(fy - fz);
157*3ac0a46fSAndroid Build Coastguard Worker }
158*3ac0a46fSAndroid Build Coastguard Worker
159*3ac0a46fSAndroid Build Coastguard Worker
160*3ac0a46fSAndroid Build Coastguard Worker // Standard XYZ to Lab. It can return negative XYZ in some cases
cmsLab2XYZ(const cmsCIEXYZ * WhitePoint,cmsCIEXYZ * xyz,const cmsCIELab * Lab)161*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsLab2XYZ(const cmsCIEXYZ* WhitePoint, cmsCIEXYZ* xyz, const cmsCIELab* Lab)
162*3ac0a46fSAndroid Build Coastguard Worker {
163*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number x, y, z;
164*3ac0a46fSAndroid Build Coastguard Worker
165*3ac0a46fSAndroid Build Coastguard Worker if (WhitePoint == NULL)
166*3ac0a46fSAndroid Build Coastguard Worker WhitePoint = cmsD50_XYZ();
167*3ac0a46fSAndroid Build Coastguard Worker
168*3ac0a46fSAndroid Build Coastguard Worker y = (Lab-> L + 16.0) / 116.0;
169*3ac0a46fSAndroid Build Coastguard Worker x = y + 0.002 * Lab -> a;
170*3ac0a46fSAndroid Build Coastguard Worker z = y - 0.005 * Lab -> b;
171*3ac0a46fSAndroid Build Coastguard Worker
172*3ac0a46fSAndroid Build Coastguard Worker xyz -> X = f_1(x) * WhitePoint -> X;
173*3ac0a46fSAndroid Build Coastguard Worker xyz -> Y = f_1(y) * WhitePoint -> Y;
174*3ac0a46fSAndroid Build Coastguard Worker xyz -> Z = f_1(z) * WhitePoint -> Z;
175*3ac0a46fSAndroid Build Coastguard Worker
176*3ac0a46fSAndroid Build Coastguard Worker }
177*3ac0a46fSAndroid Build Coastguard Worker
178*3ac0a46fSAndroid Build Coastguard Worker static
L2float2(cmsUInt16Number v)179*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number L2float2(cmsUInt16Number v)
180*3ac0a46fSAndroid Build Coastguard Worker {
181*3ac0a46fSAndroid Build Coastguard Worker return (cmsFloat64Number) v / 652.800;
182*3ac0a46fSAndroid Build Coastguard Worker }
183*3ac0a46fSAndroid Build Coastguard Worker
184*3ac0a46fSAndroid Build Coastguard Worker // the a/b part
185*3ac0a46fSAndroid Build Coastguard Worker static
ab2float2(cmsUInt16Number v)186*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number ab2float2(cmsUInt16Number v)
187*3ac0a46fSAndroid Build Coastguard Worker {
188*3ac0a46fSAndroid Build Coastguard Worker return ((cmsFloat64Number) v / 256.0) - 128.0;
189*3ac0a46fSAndroid Build Coastguard Worker }
190*3ac0a46fSAndroid Build Coastguard Worker
191*3ac0a46fSAndroid Build Coastguard Worker static
L2Fix2(cmsFloat64Number L)192*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number L2Fix2(cmsFloat64Number L)
193*3ac0a46fSAndroid Build Coastguard Worker {
194*3ac0a46fSAndroid Build Coastguard Worker return _cmsQuickSaturateWord(L * 652.8);
195*3ac0a46fSAndroid Build Coastguard Worker }
196*3ac0a46fSAndroid Build Coastguard Worker
197*3ac0a46fSAndroid Build Coastguard Worker static
ab2Fix2(cmsFloat64Number ab)198*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number ab2Fix2(cmsFloat64Number ab)
199*3ac0a46fSAndroid Build Coastguard Worker {
200*3ac0a46fSAndroid Build Coastguard Worker return _cmsQuickSaturateWord((ab + 128.0) * 256.0);
201*3ac0a46fSAndroid Build Coastguard Worker }
202*3ac0a46fSAndroid Build Coastguard Worker
203*3ac0a46fSAndroid Build Coastguard Worker
204*3ac0a46fSAndroid Build Coastguard Worker static
L2float4(cmsUInt16Number v)205*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number L2float4(cmsUInt16Number v)
206*3ac0a46fSAndroid Build Coastguard Worker {
207*3ac0a46fSAndroid Build Coastguard Worker return (cmsFloat64Number) v / 655.35;
208*3ac0a46fSAndroid Build Coastguard Worker }
209*3ac0a46fSAndroid Build Coastguard Worker
210*3ac0a46fSAndroid Build Coastguard Worker // the a/b part
211*3ac0a46fSAndroid Build Coastguard Worker static
ab2float4(cmsUInt16Number v)212*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number ab2float4(cmsUInt16Number v)
213*3ac0a46fSAndroid Build Coastguard Worker {
214*3ac0a46fSAndroid Build Coastguard Worker return ((cmsFloat64Number) v / 257.0) - 128.0;
215*3ac0a46fSAndroid Build Coastguard Worker }
216*3ac0a46fSAndroid Build Coastguard Worker
217*3ac0a46fSAndroid Build Coastguard Worker
cmsLabEncoded2FloatV2(cmsCIELab * Lab,const cmsUInt16Number wLab[3])218*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsLabEncoded2FloatV2(cmsCIELab* Lab, const cmsUInt16Number wLab[3])
219*3ac0a46fSAndroid Build Coastguard Worker {
220*3ac0a46fSAndroid Build Coastguard Worker Lab->L = L2float2(wLab[0]);
221*3ac0a46fSAndroid Build Coastguard Worker Lab->a = ab2float2(wLab[1]);
222*3ac0a46fSAndroid Build Coastguard Worker Lab->b = ab2float2(wLab[2]);
223*3ac0a46fSAndroid Build Coastguard Worker }
224*3ac0a46fSAndroid Build Coastguard Worker
225*3ac0a46fSAndroid Build Coastguard Worker
cmsLabEncoded2Float(cmsCIELab * Lab,const cmsUInt16Number wLab[3])226*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsLabEncoded2Float(cmsCIELab* Lab, const cmsUInt16Number wLab[3])
227*3ac0a46fSAndroid Build Coastguard Worker {
228*3ac0a46fSAndroid Build Coastguard Worker Lab->L = L2float4(wLab[0]);
229*3ac0a46fSAndroid Build Coastguard Worker Lab->a = ab2float4(wLab[1]);
230*3ac0a46fSAndroid Build Coastguard Worker Lab->b = ab2float4(wLab[2]);
231*3ac0a46fSAndroid Build Coastguard Worker }
232*3ac0a46fSAndroid Build Coastguard Worker
233*3ac0a46fSAndroid Build Coastguard Worker static
Clamp_L_doubleV2(cmsFloat64Number L)234*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Clamp_L_doubleV2(cmsFloat64Number L)
235*3ac0a46fSAndroid Build Coastguard Worker {
236*3ac0a46fSAndroid Build Coastguard Worker const cmsFloat64Number L_max = (cmsFloat64Number) (0xFFFF * 100.0) / 0xFF00;
237*3ac0a46fSAndroid Build Coastguard Worker
238*3ac0a46fSAndroid Build Coastguard Worker if (L < 0) L = 0;
239*3ac0a46fSAndroid Build Coastguard Worker if (L > L_max) L = L_max;
240*3ac0a46fSAndroid Build Coastguard Worker
241*3ac0a46fSAndroid Build Coastguard Worker return L;
242*3ac0a46fSAndroid Build Coastguard Worker }
243*3ac0a46fSAndroid Build Coastguard Worker
244*3ac0a46fSAndroid Build Coastguard Worker
245*3ac0a46fSAndroid Build Coastguard Worker static
Clamp_ab_doubleV2(cmsFloat64Number ab)246*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Clamp_ab_doubleV2(cmsFloat64Number ab)
247*3ac0a46fSAndroid Build Coastguard Worker {
248*3ac0a46fSAndroid Build Coastguard Worker if (ab < MIN_ENCODEABLE_ab2) ab = MIN_ENCODEABLE_ab2;
249*3ac0a46fSAndroid Build Coastguard Worker if (ab > MAX_ENCODEABLE_ab2) ab = MAX_ENCODEABLE_ab2;
250*3ac0a46fSAndroid Build Coastguard Worker
251*3ac0a46fSAndroid Build Coastguard Worker return ab;
252*3ac0a46fSAndroid Build Coastguard Worker }
253*3ac0a46fSAndroid Build Coastguard Worker
cmsFloat2LabEncodedV2(cmsUInt16Number wLab[3],const cmsCIELab * fLab)254*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsFloat2LabEncodedV2(cmsUInt16Number wLab[3], const cmsCIELab* fLab)
255*3ac0a46fSAndroid Build Coastguard Worker {
256*3ac0a46fSAndroid Build Coastguard Worker cmsCIELab Lab;
257*3ac0a46fSAndroid Build Coastguard Worker
258*3ac0a46fSAndroid Build Coastguard Worker Lab.L = Clamp_L_doubleV2(fLab ->L);
259*3ac0a46fSAndroid Build Coastguard Worker Lab.a = Clamp_ab_doubleV2(fLab ->a);
260*3ac0a46fSAndroid Build Coastguard Worker Lab.b = Clamp_ab_doubleV2(fLab ->b);
261*3ac0a46fSAndroid Build Coastguard Worker
262*3ac0a46fSAndroid Build Coastguard Worker wLab[0] = L2Fix2(Lab.L);
263*3ac0a46fSAndroid Build Coastguard Worker wLab[1] = ab2Fix2(Lab.a);
264*3ac0a46fSAndroid Build Coastguard Worker wLab[2] = ab2Fix2(Lab.b);
265*3ac0a46fSAndroid Build Coastguard Worker }
266*3ac0a46fSAndroid Build Coastguard Worker
267*3ac0a46fSAndroid Build Coastguard Worker
268*3ac0a46fSAndroid Build Coastguard Worker static
Clamp_L_doubleV4(cmsFloat64Number L)269*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Clamp_L_doubleV4(cmsFloat64Number L)
270*3ac0a46fSAndroid Build Coastguard Worker {
271*3ac0a46fSAndroid Build Coastguard Worker if (L < 0) L = 0;
272*3ac0a46fSAndroid Build Coastguard Worker if (L > 100.0) L = 100.0;
273*3ac0a46fSAndroid Build Coastguard Worker
274*3ac0a46fSAndroid Build Coastguard Worker return L;
275*3ac0a46fSAndroid Build Coastguard Worker }
276*3ac0a46fSAndroid Build Coastguard Worker
277*3ac0a46fSAndroid Build Coastguard Worker static
Clamp_ab_doubleV4(cmsFloat64Number ab)278*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Clamp_ab_doubleV4(cmsFloat64Number ab)
279*3ac0a46fSAndroid Build Coastguard Worker {
280*3ac0a46fSAndroid Build Coastguard Worker if (ab < MIN_ENCODEABLE_ab4) ab = MIN_ENCODEABLE_ab4;
281*3ac0a46fSAndroid Build Coastguard Worker if (ab > MAX_ENCODEABLE_ab4) ab = MAX_ENCODEABLE_ab4;
282*3ac0a46fSAndroid Build Coastguard Worker
283*3ac0a46fSAndroid Build Coastguard Worker return ab;
284*3ac0a46fSAndroid Build Coastguard Worker }
285*3ac0a46fSAndroid Build Coastguard Worker
286*3ac0a46fSAndroid Build Coastguard Worker static
L2Fix4(cmsFloat64Number L)287*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number L2Fix4(cmsFloat64Number L)
288*3ac0a46fSAndroid Build Coastguard Worker {
289*3ac0a46fSAndroid Build Coastguard Worker return _cmsQuickSaturateWord(L * 655.35);
290*3ac0a46fSAndroid Build Coastguard Worker }
291*3ac0a46fSAndroid Build Coastguard Worker
292*3ac0a46fSAndroid Build Coastguard Worker static
ab2Fix4(cmsFloat64Number ab)293*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number ab2Fix4(cmsFloat64Number ab)
294*3ac0a46fSAndroid Build Coastguard Worker {
295*3ac0a46fSAndroid Build Coastguard Worker return _cmsQuickSaturateWord((ab + 128.0) * 257.0);
296*3ac0a46fSAndroid Build Coastguard Worker }
297*3ac0a46fSAndroid Build Coastguard Worker
cmsFloat2LabEncoded(cmsUInt16Number wLab[3],const cmsCIELab * fLab)298*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsFloat2LabEncoded(cmsUInt16Number wLab[3], const cmsCIELab* fLab)
299*3ac0a46fSAndroid Build Coastguard Worker {
300*3ac0a46fSAndroid Build Coastguard Worker cmsCIELab Lab;
301*3ac0a46fSAndroid Build Coastguard Worker
302*3ac0a46fSAndroid Build Coastguard Worker Lab.L = Clamp_L_doubleV4(fLab ->L);
303*3ac0a46fSAndroid Build Coastguard Worker Lab.a = Clamp_ab_doubleV4(fLab ->a);
304*3ac0a46fSAndroid Build Coastguard Worker Lab.b = Clamp_ab_doubleV4(fLab ->b);
305*3ac0a46fSAndroid Build Coastguard Worker
306*3ac0a46fSAndroid Build Coastguard Worker wLab[0] = L2Fix4(Lab.L);
307*3ac0a46fSAndroid Build Coastguard Worker wLab[1] = ab2Fix4(Lab.a);
308*3ac0a46fSAndroid Build Coastguard Worker wLab[2] = ab2Fix4(Lab.b);
309*3ac0a46fSAndroid Build Coastguard Worker }
310*3ac0a46fSAndroid Build Coastguard Worker
311*3ac0a46fSAndroid Build Coastguard Worker // Auxiliary: convert to Radians
312*3ac0a46fSAndroid Build Coastguard Worker static
RADIANS(cmsFloat64Number deg)313*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number RADIANS(cmsFloat64Number deg)
314*3ac0a46fSAndroid Build Coastguard Worker {
315*3ac0a46fSAndroid Build Coastguard Worker return (deg * M_PI) / 180.;
316*3ac0a46fSAndroid Build Coastguard Worker }
317*3ac0a46fSAndroid Build Coastguard Worker
318*3ac0a46fSAndroid Build Coastguard Worker
319*3ac0a46fSAndroid Build Coastguard Worker // Auxiliary: atan2 but operating in degrees and returning 0 if a==b==0
320*3ac0a46fSAndroid Build Coastguard Worker static
atan2deg(cmsFloat64Number a,cmsFloat64Number b)321*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number atan2deg(cmsFloat64Number a, cmsFloat64Number b)
322*3ac0a46fSAndroid Build Coastguard Worker {
323*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number h;
324*3ac0a46fSAndroid Build Coastguard Worker
325*3ac0a46fSAndroid Build Coastguard Worker if (a == 0 && b == 0)
326*3ac0a46fSAndroid Build Coastguard Worker h = 0;
327*3ac0a46fSAndroid Build Coastguard Worker else
328*3ac0a46fSAndroid Build Coastguard Worker h = atan2(a, b);
329*3ac0a46fSAndroid Build Coastguard Worker
330*3ac0a46fSAndroid Build Coastguard Worker h *= (180. / M_PI);
331*3ac0a46fSAndroid Build Coastguard Worker
332*3ac0a46fSAndroid Build Coastguard Worker while (h > 360.)
333*3ac0a46fSAndroid Build Coastguard Worker h -= 360.;
334*3ac0a46fSAndroid Build Coastguard Worker
335*3ac0a46fSAndroid Build Coastguard Worker while ( h < 0)
336*3ac0a46fSAndroid Build Coastguard Worker h += 360.;
337*3ac0a46fSAndroid Build Coastguard Worker
338*3ac0a46fSAndroid Build Coastguard Worker return h;
339*3ac0a46fSAndroid Build Coastguard Worker }
340*3ac0a46fSAndroid Build Coastguard Worker
341*3ac0a46fSAndroid Build Coastguard Worker
342*3ac0a46fSAndroid Build Coastguard Worker // Auxiliary: Square
343*3ac0a46fSAndroid Build Coastguard Worker static
Sqr(cmsFloat64Number v)344*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Sqr(cmsFloat64Number v)
345*3ac0a46fSAndroid Build Coastguard Worker {
346*3ac0a46fSAndroid Build Coastguard Worker return v * v;
347*3ac0a46fSAndroid Build Coastguard Worker }
348*3ac0a46fSAndroid Build Coastguard Worker // From cylindrical coordinates. No check is performed, then negative values are allowed
cmsLab2LCh(cmsCIELCh * LCh,const cmsCIELab * Lab)349*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsLab2LCh(cmsCIELCh* LCh, const cmsCIELab* Lab)
350*3ac0a46fSAndroid Build Coastguard Worker {
351*3ac0a46fSAndroid Build Coastguard Worker LCh -> L = Lab -> L;
352*3ac0a46fSAndroid Build Coastguard Worker LCh -> C = pow(Sqr(Lab ->a) + Sqr(Lab ->b), 0.5);
353*3ac0a46fSAndroid Build Coastguard Worker LCh -> h = atan2deg(Lab ->b, Lab ->a);
354*3ac0a46fSAndroid Build Coastguard Worker }
355*3ac0a46fSAndroid Build Coastguard Worker
356*3ac0a46fSAndroid Build Coastguard Worker
357*3ac0a46fSAndroid Build Coastguard Worker // To cylindrical coordinates. No check is performed, then negative values are allowed
cmsLCh2Lab(cmsCIELab * Lab,const cmsCIELCh * LCh)358*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsLCh2Lab(cmsCIELab* Lab, const cmsCIELCh* LCh)
359*3ac0a46fSAndroid Build Coastguard Worker {
360*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number h = (LCh -> h * M_PI) / 180.0;
361*3ac0a46fSAndroid Build Coastguard Worker
362*3ac0a46fSAndroid Build Coastguard Worker Lab -> L = LCh -> L;
363*3ac0a46fSAndroid Build Coastguard Worker Lab -> a = LCh -> C * cos(h);
364*3ac0a46fSAndroid Build Coastguard Worker Lab -> b = LCh -> C * sin(h);
365*3ac0a46fSAndroid Build Coastguard Worker }
366*3ac0a46fSAndroid Build Coastguard Worker
367*3ac0a46fSAndroid Build Coastguard Worker // In XYZ All 3 components are encoded using 1.15 fixed point
368*3ac0a46fSAndroid Build Coastguard Worker static
XYZ2Fix(cmsFloat64Number d)369*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number XYZ2Fix(cmsFloat64Number d)
370*3ac0a46fSAndroid Build Coastguard Worker {
371*3ac0a46fSAndroid Build Coastguard Worker return _cmsQuickSaturateWord(d * 32768.0);
372*3ac0a46fSAndroid Build Coastguard Worker }
373*3ac0a46fSAndroid Build Coastguard Worker
cmsFloat2XYZEncoded(cmsUInt16Number XYZ[3],const cmsCIEXYZ * fXYZ)374*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsFloat2XYZEncoded(cmsUInt16Number XYZ[3], const cmsCIEXYZ* fXYZ)
375*3ac0a46fSAndroid Build Coastguard Worker {
376*3ac0a46fSAndroid Build Coastguard Worker cmsCIEXYZ xyz;
377*3ac0a46fSAndroid Build Coastguard Worker
378*3ac0a46fSAndroid Build Coastguard Worker xyz.X = fXYZ -> X;
379*3ac0a46fSAndroid Build Coastguard Worker xyz.Y = fXYZ -> Y;
380*3ac0a46fSAndroid Build Coastguard Worker xyz.Z = fXYZ -> Z;
381*3ac0a46fSAndroid Build Coastguard Worker
382*3ac0a46fSAndroid Build Coastguard Worker // Clamp to encodeable values.
383*3ac0a46fSAndroid Build Coastguard Worker if (xyz.Y <= 0) {
384*3ac0a46fSAndroid Build Coastguard Worker
385*3ac0a46fSAndroid Build Coastguard Worker xyz.X = 0;
386*3ac0a46fSAndroid Build Coastguard Worker xyz.Y = 0;
387*3ac0a46fSAndroid Build Coastguard Worker xyz.Z = 0;
388*3ac0a46fSAndroid Build Coastguard Worker }
389*3ac0a46fSAndroid Build Coastguard Worker
390*3ac0a46fSAndroid Build Coastguard Worker if (xyz.X > MAX_ENCODEABLE_XYZ)
391*3ac0a46fSAndroid Build Coastguard Worker xyz.X = MAX_ENCODEABLE_XYZ;
392*3ac0a46fSAndroid Build Coastguard Worker
393*3ac0a46fSAndroid Build Coastguard Worker if (xyz.X < 0)
394*3ac0a46fSAndroid Build Coastguard Worker xyz.X = 0;
395*3ac0a46fSAndroid Build Coastguard Worker
396*3ac0a46fSAndroid Build Coastguard Worker if (xyz.Y > MAX_ENCODEABLE_XYZ)
397*3ac0a46fSAndroid Build Coastguard Worker xyz.Y = MAX_ENCODEABLE_XYZ;
398*3ac0a46fSAndroid Build Coastguard Worker
399*3ac0a46fSAndroid Build Coastguard Worker if (xyz.Y < 0)
400*3ac0a46fSAndroid Build Coastguard Worker xyz.Y = 0;
401*3ac0a46fSAndroid Build Coastguard Worker
402*3ac0a46fSAndroid Build Coastguard Worker if (xyz.Z > MAX_ENCODEABLE_XYZ)
403*3ac0a46fSAndroid Build Coastguard Worker xyz.Z = MAX_ENCODEABLE_XYZ;
404*3ac0a46fSAndroid Build Coastguard Worker
405*3ac0a46fSAndroid Build Coastguard Worker if (xyz.Z < 0)
406*3ac0a46fSAndroid Build Coastguard Worker xyz.Z = 0;
407*3ac0a46fSAndroid Build Coastguard Worker
408*3ac0a46fSAndroid Build Coastguard Worker
409*3ac0a46fSAndroid Build Coastguard Worker XYZ[0] = XYZ2Fix(xyz.X);
410*3ac0a46fSAndroid Build Coastguard Worker XYZ[1] = XYZ2Fix(xyz.Y);
411*3ac0a46fSAndroid Build Coastguard Worker XYZ[2] = XYZ2Fix(xyz.Z);
412*3ac0a46fSAndroid Build Coastguard Worker }
413*3ac0a46fSAndroid Build Coastguard Worker
414*3ac0a46fSAndroid Build Coastguard Worker
415*3ac0a46fSAndroid Build Coastguard Worker // To convert from Fixed 1.15 point to cmsFloat64Number
416*3ac0a46fSAndroid Build Coastguard Worker static
XYZ2float(cmsUInt16Number v)417*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number XYZ2float(cmsUInt16Number v)
418*3ac0a46fSAndroid Build Coastguard Worker {
419*3ac0a46fSAndroid Build Coastguard Worker cmsS15Fixed16Number fix32;
420*3ac0a46fSAndroid Build Coastguard Worker
421*3ac0a46fSAndroid Build Coastguard Worker // From 1.15 to 15.16
422*3ac0a46fSAndroid Build Coastguard Worker fix32 = v << 1;
423*3ac0a46fSAndroid Build Coastguard Worker
424*3ac0a46fSAndroid Build Coastguard Worker // From fixed 15.16 to cmsFloat64Number
425*3ac0a46fSAndroid Build Coastguard Worker return _cms15Fixed16toDouble(fix32);
426*3ac0a46fSAndroid Build Coastguard Worker }
427*3ac0a46fSAndroid Build Coastguard Worker
428*3ac0a46fSAndroid Build Coastguard Worker
cmsXYZEncoded2Float(cmsCIEXYZ * fXYZ,const cmsUInt16Number XYZ[3])429*3ac0a46fSAndroid Build Coastguard Worker void CMSEXPORT cmsXYZEncoded2Float(cmsCIEXYZ* fXYZ, const cmsUInt16Number XYZ[3])
430*3ac0a46fSAndroid Build Coastguard Worker {
431*3ac0a46fSAndroid Build Coastguard Worker fXYZ -> X = XYZ2float(XYZ[0]);
432*3ac0a46fSAndroid Build Coastguard Worker fXYZ -> Y = XYZ2float(XYZ[1]);
433*3ac0a46fSAndroid Build Coastguard Worker fXYZ -> Z = XYZ2float(XYZ[2]);
434*3ac0a46fSAndroid Build Coastguard Worker }
435*3ac0a46fSAndroid Build Coastguard Worker
436*3ac0a46fSAndroid Build Coastguard Worker
437*3ac0a46fSAndroid Build Coastguard Worker // Returns dE on two Lab values
cmsDeltaE(const cmsCIELab * Lab1,const cmsCIELab * Lab2)438*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number CMSEXPORT cmsDeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2)
439*3ac0a46fSAndroid Build Coastguard Worker {
440*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number dL, da, db;
441*3ac0a46fSAndroid Build Coastguard Worker
442*3ac0a46fSAndroid Build Coastguard Worker dL = fabs(Lab1 -> L - Lab2 -> L);
443*3ac0a46fSAndroid Build Coastguard Worker da = fabs(Lab1 -> a - Lab2 -> a);
444*3ac0a46fSAndroid Build Coastguard Worker db = fabs(Lab1 -> b - Lab2 -> b);
445*3ac0a46fSAndroid Build Coastguard Worker
446*3ac0a46fSAndroid Build Coastguard Worker return pow(Sqr(dL) + Sqr(da) + Sqr(db), 0.5);
447*3ac0a46fSAndroid Build Coastguard Worker }
448*3ac0a46fSAndroid Build Coastguard Worker
449*3ac0a46fSAndroid Build Coastguard Worker
450*3ac0a46fSAndroid Build Coastguard Worker // Return the CIE94 Delta E
cmsCIE94DeltaE(const cmsCIELab * Lab1,const cmsCIELab * Lab2)451*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number CMSEXPORT cmsCIE94DeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2)
452*3ac0a46fSAndroid Build Coastguard Worker {
453*3ac0a46fSAndroid Build Coastguard Worker cmsCIELCh LCh1, LCh2;
454*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number dE, dL, dC, dh, dhsq;
455*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number c12, sc, sh;
456*3ac0a46fSAndroid Build Coastguard Worker
457*3ac0a46fSAndroid Build Coastguard Worker dL = fabs(Lab1 ->L - Lab2 ->L);
458*3ac0a46fSAndroid Build Coastguard Worker
459*3ac0a46fSAndroid Build Coastguard Worker cmsLab2LCh(&LCh1, Lab1);
460*3ac0a46fSAndroid Build Coastguard Worker cmsLab2LCh(&LCh2, Lab2);
461*3ac0a46fSAndroid Build Coastguard Worker
462*3ac0a46fSAndroid Build Coastguard Worker dC = fabs(LCh1.C - LCh2.C);
463*3ac0a46fSAndroid Build Coastguard Worker dE = cmsDeltaE(Lab1, Lab2);
464*3ac0a46fSAndroid Build Coastguard Worker
465*3ac0a46fSAndroid Build Coastguard Worker dhsq = Sqr(dE) - Sqr(dL) - Sqr(dC);
466*3ac0a46fSAndroid Build Coastguard Worker if (dhsq < 0)
467*3ac0a46fSAndroid Build Coastguard Worker dh = 0;
468*3ac0a46fSAndroid Build Coastguard Worker else
469*3ac0a46fSAndroid Build Coastguard Worker dh = pow(dhsq, 0.5);
470*3ac0a46fSAndroid Build Coastguard Worker
471*3ac0a46fSAndroid Build Coastguard Worker c12 = sqrt(LCh1.C * LCh2.C);
472*3ac0a46fSAndroid Build Coastguard Worker
473*3ac0a46fSAndroid Build Coastguard Worker sc = 1.0 + (0.048 * c12);
474*3ac0a46fSAndroid Build Coastguard Worker sh = 1.0 + (0.014 * c12);
475*3ac0a46fSAndroid Build Coastguard Worker
476*3ac0a46fSAndroid Build Coastguard Worker return sqrt(Sqr(dL) + Sqr(dC) / Sqr(sc) + Sqr(dh) / Sqr(sh));
477*3ac0a46fSAndroid Build Coastguard Worker }
478*3ac0a46fSAndroid Build Coastguard Worker
479*3ac0a46fSAndroid Build Coastguard Worker
480*3ac0a46fSAndroid Build Coastguard Worker // Auxiliary
481*3ac0a46fSAndroid Build Coastguard Worker static
ComputeLBFD(const cmsCIELab * Lab)482*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number ComputeLBFD(const cmsCIELab* Lab)
483*3ac0a46fSAndroid Build Coastguard Worker {
484*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number yt;
485*3ac0a46fSAndroid Build Coastguard Worker
486*3ac0a46fSAndroid Build Coastguard Worker if (Lab->L > 7.996969)
487*3ac0a46fSAndroid Build Coastguard Worker yt = (Sqr((Lab->L+16)/116)*((Lab->L+16)/116))*100;
488*3ac0a46fSAndroid Build Coastguard Worker else
489*3ac0a46fSAndroid Build Coastguard Worker yt = 100 * (Lab->L / 903.3);
490*3ac0a46fSAndroid Build Coastguard Worker
491*3ac0a46fSAndroid Build Coastguard Worker return (54.6 * (M_LOG10E * (log(yt + 1.5))) - 9.6);
492*3ac0a46fSAndroid Build Coastguard Worker }
493*3ac0a46fSAndroid Build Coastguard Worker
494*3ac0a46fSAndroid Build Coastguard Worker
495*3ac0a46fSAndroid Build Coastguard Worker
496*3ac0a46fSAndroid Build Coastguard Worker // bfd - gets BFD(1:1) difference between Lab1, Lab2
cmsBFDdeltaE(const cmsCIELab * Lab1,const cmsCIELab * Lab2)497*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number CMSEXPORT cmsBFDdeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2)
498*3ac0a46fSAndroid Build Coastguard Worker {
499*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number lbfd1,lbfd2,AveC,Aveh,dE,deltaL,
500*3ac0a46fSAndroid Build Coastguard Worker deltaC,deltah,dc,t,g,dh,rh,rc,rt,bfd;
501*3ac0a46fSAndroid Build Coastguard Worker cmsCIELCh LCh1, LCh2;
502*3ac0a46fSAndroid Build Coastguard Worker
503*3ac0a46fSAndroid Build Coastguard Worker
504*3ac0a46fSAndroid Build Coastguard Worker lbfd1 = ComputeLBFD(Lab1);
505*3ac0a46fSAndroid Build Coastguard Worker lbfd2 = ComputeLBFD(Lab2);
506*3ac0a46fSAndroid Build Coastguard Worker deltaL = lbfd2 - lbfd1;
507*3ac0a46fSAndroid Build Coastguard Worker
508*3ac0a46fSAndroid Build Coastguard Worker cmsLab2LCh(&LCh1, Lab1);
509*3ac0a46fSAndroid Build Coastguard Worker cmsLab2LCh(&LCh2, Lab2);
510*3ac0a46fSAndroid Build Coastguard Worker
511*3ac0a46fSAndroid Build Coastguard Worker deltaC = LCh2.C - LCh1.C;
512*3ac0a46fSAndroid Build Coastguard Worker AveC = (LCh1.C+LCh2.C)/2;
513*3ac0a46fSAndroid Build Coastguard Worker Aveh = (LCh1.h+LCh2.h)/2;
514*3ac0a46fSAndroid Build Coastguard Worker
515*3ac0a46fSAndroid Build Coastguard Worker dE = cmsDeltaE(Lab1, Lab2);
516*3ac0a46fSAndroid Build Coastguard Worker
517*3ac0a46fSAndroid Build Coastguard Worker if (Sqr(dE)>(Sqr(Lab2->L-Lab1->L)+Sqr(deltaC)))
518*3ac0a46fSAndroid Build Coastguard Worker deltah = sqrt(Sqr(dE)-Sqr(Lab2->L-Lab1->L)-Sqr(deltaC));
519*3ac0a46fSAndroid Build Coastguard Worker else
520*3ac0a46fSAndroid Build Coastguard Worker deltah =0;
521*3ac0a46fSAndroid Build Coastguard Worker
522*3ac0a46fSAndroid Build Coastguard Worker
523*3ac0a46fSAndroid Build Coastguard Worker dc = 0.035 * AveC / (1 + 0.00365 * AveC)+0.521;
524*3ac0a46fSAndroid Build Coastguard Worker g = sqrt(Sqr(Sqr(AveC))/(Sqr(Sqr(AveC))+14000));
525*3ac0a46fSAndroid Build Coastguard Worker t = 0.627+(0.055*cos((Aveh-254)/(180/M_PI))-
526*3ac0a46fSAndroid Build Coastguard Worker 0.040*cos((2*Aveh-136)/(180/M_PI))+
527*3ac0a46fSAndroid Build Coastguard Worker 0.070*cos((3*Aveh-31)/(180/M_PI))+
528*3ac0a46fSAndroid Build Coastguard Worker 0.049*cos((4*Aveh+114)/(180/M_PI))-
529*3ac0a46fSAndroid Build Coastguard Worker 0.015*cos((5*Aveh-103)/(180/M_PI)));
530*3ac0a46fSAndroid Build Coastguard Worker
531*3ac0a46fSAndroid Build Coastguard Worker dh = dc*(g*t+1-g);
532*3ac0a46fSAndroid Build Coastguard Worker rh = -0.260*cos((Aveh-308)/(180/M_PI))-
533*3ac0a46fSAndroid Build Coastguard Worker 0.379*cos((2*Aveh-160)/(180/M_PI))-
534*3ac0a46fSAndroid Build Coastguard Worker 0.636*cos((3*Aveh+254)/(180/M_PI))+
535*3ac0a46fSAndroid Build Coastguard Worker 0.226*cos((4*Aveh+140)/(180/M_PI))-
536*3ac0a46fSAndroid Build Coastguard Worker 0.194*cos((5*Aveh+280)/(180/M_PI));
537*3ac0a46fSAndroid Build Coastguard Worker
538*3ac0a46fSAndroid Build Coastguard Worker rc = sqrt((AveC*AveC*AveC*AveC*AveC*AveC)/((AveC*AveC*AveC*AveC*AveC*AveC)+70000000));
539*3ac0a46fSAndroid Build Coastguard Worker rt = rh*rc;
540*3ac0a46fSAndroid Build Coastguard Worker
541*3ac0a46fSAndroid Build Coastguard Worker bfd = sqrt(Sqr(deltaL)+Sqr(deltaC/dc)+Sqr(deltah/dh)+(rt*(deltaC/dc)*(deltah/dh)));
542*3ac0a46fSAndroid Build Coastguard Worker
543*3ac0a46fSAndroid Build Coastguard Worker return bfd;
544*3ac0a46fSAndroid Build Coastguard Worker }
545*3ac0a46fSAndroid Build Coastguard Worker
546*3ac0a46fSAndroid Build Coastguard Worker
547*3ac0a46fSAndroid Build Coastguard Worker // cmc - CMC(l:c) difference between Lab1, Lab2
cmsCMCdeltaE(const cmsCIELab * Lab1,const cmsCIELab * Lab2,cmsFloat64Number l,cmsFloat64Number c)548*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number CMSEXPORT cmsCMCdeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2, cmsFloat64Number l, cmsFloat64Number c)
549*3ac0a46fSAndroid Build Coastguard Worker {
550*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number dE,dL,dC,dh,sl,sc,sh,t,f,cmc;
551*3ac0a46fSAndroid Build Coastguard Worker cmsCIELCh LCh1, LCh2;
552*3ac0a46fSAndroid Build Coastguard Worker
553*3ac0a46fSAndroid Build Coastguard Worker if (Lab1 ->L == 0 && Lab2 ->L == 0) return 0;
554*3ac0a46fSAndroid Build Coastguard Worker
555*3ac0a46fSAndroid Build Coastguard Worker cmsLab2LCh(&LCh1, Lab1);
556*3ac0a46fSAndroid Build Coastguard Worker cmsLab2LCh(&LCh2, Lab2);
557*3ac0a46fSAndroid Build Coastguard Worker
558*3ac0a46fSAndroid Build Coastguard Worker
559*3ac0a46fSAndroid Build Coastguard Worker dL = Lab2->L-Lab1->L;
560*3ac0a46fSAndroid Build Coastguard Worker dC = LCh2.C-LCh1.C;
561*3ac0a46fSAndroid Build Coastguard Worker
562*3ac0a46fSAndroid Build Coastguard Worker dE = cmsDeltaE(Lab1, Lab2);
563*3ac0a46fSAndroid Build Coastguard Worker
564*3ac0a46fSAndroid Build Coastguard Worker if (Sqr(dE)>(Sqr(dL)+Sqr(dC)))
565*3ac0a46fSAndroid Build Coastguard Worker dh = sqrt(Sqr(dE)-Sqr(dL)-Sqr(dC));
566*3ac0a46fSAndroid Build Coastguard Worker else
567*3ac0a46fSAndroid Build Coastguard Worker dh =0;
568*3ac0a46fSAndroid Build Coastguard Worker
569*3ac0a46fSAndroid Build Coastguard Worker if ((LCh1.h > 164) && (LCh1.h < 345))
570*3ac0a46fSAndroid Build Coastguard Worker t = 0.56 + fabs(0.2 * cos(((LCh1.h + 168)/(180/M_PI))));
571*3ac0a46fSAndroid Build Coastguard Worker else
572*3ac0a46fSAndroid Build Coastguard Worker t = 0.36 + fabs(0.4 * cos(((LCh1.h + 35 )/(180/M_PI))));
573*3ac0a46fSAndroid Build Coastguard Worker
574*3ac0a46fSAndroid Build Coastguard Worker sc = 0.0638 * LCh1.C / (1 + 0.0131 * LCh1.C) + 0.638;
575*3ac0a46fSAndroid Build Coastguard Worker sl = 0.040975 * Lab1->L /(1 + 0.01765 * Lab1->L);
576*3ac0a46fSAndroid Build Coastguard Worker
577*3ac0a46fSAndroid Build Coastguard Worker if (Lab1->L<16)
578*3ac0a46fSAndroid Build Coastguard Worker sl = 0.511;
579*3ac0a46fSAndroid Build Coastguard Worker
580*3ac0a46fSAndroid Build Coastguard Worker f = sqrt((LCh1.C * LCh1.C * LCh1.C * LCh1.C)/((LCh1.C * LCh1.C * LCh1.C * LCh1.C)+1900));
581*3ac0a46fSAndroid Build Coastguard Worker sh = sc*(t*f+1-f);
582*3ac0a46fSAndroid Build Coastguard Worker cmc = sqrt(Sqr(dL/(l*sl))+Sqr(dC/(c*sc))+Sqr(dh/sh));
583*3ac0a46fSAndroid Build Coastguard Worker
584*3ac0a46fSAndroid Build Coastguard Worker return cmc;
585*3ac0a46fSAndroid Build Coastguard Worker }
586*3ac0a46fSAndroid Build Coastguard Worker
587*3ac0a46fSAndroid Build Coastguard Worker // dE2000 The weightings KL, KC and KH can be modified to reflect the relative
588*3ac0a46fSAndroid Build Coastguard Worker // importance of lightness, chroma and hue in different industrial applications
cmsCIE2000DeltaE(const cmsCIELab * Lab1,const cmsCIELab * Lab2,cmsFloat64Number Kl,cmsFloat64Number Kc,cmsFloat64Number Kh)589*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number CMSEXPORT cmsCIE2000DeltaE(const cmsCIELab* Lab1, const cmsCIELab* Lab2,
590*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Kl, cmsFloat64Number Kc, cmsFloat64Number Kh)
591*3ac0a46fSAndroid Build Coastguard Worker {
592*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number L1 = Lab1->L;
593*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number a1 = Lab1->a;
594*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number b1 = Lab1->b;
595*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number C = sqrt( Sqr(a1) + Sqr(b1) );
596*3ac0a46fSAndroid Build Coastguard Worker
597*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Ls = Lab2 ->L;
598*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number as = Lab2 ->a;
599*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number bs = Lab2 ->b;
600*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Cs = sqrt( Sqr(as) + Sqr(bs) );
601*3ac0a46fSAndroid Build Coastguard Worker
602*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number G = 0.5 * ( 1 - sqrt(pow((C + Cs) / 2 , 7.0) / (pow((C + Cs) / 2, 7.0) + pow(25.0, 7.0) ) ));
603*3ac0a46fSAndroid Build Coastguard Worker
604*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number a_p = (1 + G ) * a1;
605*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number b_p = b1;
606*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number C_p = sqrt( Sqr(a_p) + Sqr(b_p));
607*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number h_p = atan2deg(b_p, a_p);
608*3ac0a46fSAndroid Build Coastguard Worker
609*3ac0a46fSAndroid Build Coastguard Worker
610*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number a_ps = (1 + G) * as;
611*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number b_ps = bs;
612*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number C_ps = sqrt(Sqr(a_ps) + Sqr(b_ps));
613*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number h_ps = atan2deg(b_ps, a_ps);
614*3ac0a46fSAndroid Build Coastguard Worker
615*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number meanC_p =(C_p + C_ps) / 2;
616*3ac0a46fSAndroid Build Coastguard Worker
617*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number hps_plus_hp = h_ps + h_p;
618*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number hps_minus_hp = h_ps - h_p;
619*3ac0a46fSAndroid Build Coastguard Worker
620*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number meanh_p = fabs(hps_minus_hp) <= 180.000001 ? (hps_plus_hp)/2 :
621*3ac0a46fSAndroid Build Coastguard Worker (hps_plus_hp) < 360 ? (hps_plus_hp + 360)/2 :
622*3ac0a46fSAndroid Build Coastguard Worker (hps_plus_hp - 360)/2;
623*3ac0a46fSAndroid Build Coastguard Worker
624*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number delta_h = (hps_minus_hp) <= -180.000001 ? (hps_minus_hp + 360) :
625*3ac0a46fSAndroid Build Coastguard Worker (hps_minus_hp) > 180 ? (hps_minus_hp - 360) :
626*3ac0a46fSAndroid Build Coastguard Worker (hps_minus_hp);
627*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number delta_L = (Ls - L1);
628*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number delta_C = (C_ps - C_p );
629*3ac0a46fSAndroid Build Coastguard Worker
630*3ac0a46fSAndroid Build Coastguard Worker
631*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number delta_H =2 * sqrt(C_ps*C_p) * sin(RADIANS(delta_h) / 2);
632*3ac0a46fSAndroid Build Coastguard Worker
633*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number T = 1 - 0.17 * cos(RADIANS(meanh_p-30))
634*3ac0a46fSAndroid Build Coastguard Worker + 0.24 * cos(RADIANS(2*meanh_p))
635*3ac0a46fSAndroid Build Coastguard Worker + 0.32 * cos(RADIANS(3*meanh_p + 6))
636*3ac0a46fSAndroid Build Coastguard Worker - 0.2 * cos(RADIANS(4*meanh_p - 63));
637*3ac0a46fSAndroid Build Coastguard Worker
638*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Sl = 1 + (0.015 * Sqr((Ls + L1) /2- 50) )/ sqrt(20 + Sqr( (Ls+L1)/2 - 50) );
639*3ac0a46fSAndroid Build Coastguard Worker
640*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Sc = 1 + 0.045 * (C_p + C_ps)/2;
641*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Sh = 1 + 0.015 * ((C_ps + C_p)/2) * T;
642*3ac0a46fSAndroid Build Coastguard Worker
643*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number delta_ro = 30 * exp( -Sqr(((meanh_p - 275 ) / 25)));
644*3ac0a46fSAndroid Build Coastguard Worker
645*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Rc = 2 * sqrt(( pow(meanC_p, 7.0) )/( pow(meanC_p, 7.0) + pow(25.0, 7.0)));
646*3ac0a46fSAndroid Build Coastguard Worker
647*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number Rt = -sin(2 * RADIANS(delta_ro)) * Rc;
648*3ac0a46fSAndroid Build Coastguard Worker
649*3ac0a46fSAndroid Build Coastguard Worker cmsFloat64Number deltaE00 = sqrt( Sqr(delta_L /(Sl * Kl)) +
650*3ac0a46fSAndroid Build Coastguard Worker Sqr(delta_C/(Sc * Kc)) +
651*3ac0a46fSAndroid Build Coastguard Worker Sqr(delta_H/(Sh * Kh)) +
652*3ac0a46fSAndroid Build Coastguard Worker Rt*(delta_C/(Sc * Kc)) * (delta_H / (Sh * Kh)));
653*3ac0a46fSAndroid Build Coastguard Worker
654*3ac0a46fSAndroid Build Coastguard Worker return deltaE00;
655*3ac0a46fSAndroid Build Coastguard Worker }
656*3ac0a46fSAndroid Build Coastguard Worker
657*3ac0a46fSAndroid Build Coastguard Worker // This function returns a number of gridpoints to be used as LUT table. It assumes same number
658*3ac0a46fSAndroid Build Coastguard Worker // of gripdpoints in all dimensions. Flags may override the choice.
_cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace,cmsUInt32Number dwFlags)659*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags)
660*3ac0a46fSAndroid Build Coastguard Worker {
661*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number nChannels;
662*3ac0a46fSAndroid Build Coastguard Worker
663*3ac0a46fSAndroid Build Coastguard Worker // Already specified?
664*3ac0a46fSAndroid Build Coastguard Worker if (dwFlags & 0x00FF0000) {
665*3ac0a46fSAndroid Build Coastguard Worker // Yes, grab'em
666*3ac0a46fSAndroid Build Coastguard Worker return (dwFlags >> 16) & 0xFF;
667*3ac0a46fSAndroid Build Coastguard Worker }
668*3ac0a46fSAndroid Build Coastguard Worker
669*3ac0a46fSAndroid Build Coastguard Worker nChannels = cmsChannelsOf(Colorspace);
670*3ac0a46fSAndroid Build Coastguard Worker
671*3ac0a46fSAndroid Build Coastguard Worker // HighResPrecalc is maximum resolution
672*3ac0a46fSAndroid Build Coastguard Worker if (dwFlags & cmsFLAGS_HIGHRESPRECALC) {
673*3ac0a46fSAndroid Build Coastguard Worker
674*3ac0a46fSAndroid Build Coastguard Worker if (nChannels > 4)
675*3ac0a46fSAndroid Build Coastguard Worker return 7; // 7 for Hifi
676*3ac0a46fSAndroid Build Coastguard Worker
677*3ac0a46fSAndroid Build Coastguard Worker if (nChannels == 4) // 23 for CMYK
678*3ac0a46fSAndroid Build Coastguard Worker return 23;
679*3ac0a46fSAndroid Build Coastguard Worker
680*3ac0a46fSAndroid Build Coastguard Worker return 49; // 49 for RGB and others
681*3ac0a46fSAndroid Build Coastguard Worker }
682*3ac0a46fSAndroid Build Coastguard Worker
683*3ac0a46fSAndroid Build Coastguard Worker
684*3ac0a46fSAndroid Build Coastguard Worker // LowResPrecal is lower resolution
685*3ac0a46fSAndroid Build Coastguard Worker if (dwFlags & cmsFLAGS_LOWRESPRECALC) {
686*3ac0a46fSAndroid Build Coastguard Worker
687*3ac0a46fSAndroid Build Coastguard Worker if (nChannels > 4)
688*3ac0a46fSAndroid Build Coastguard Worker return 6; // 6 for more than 4 channels
689*3ac0a46fSAndroid Build Coastguard Worker
690*3ac0a46fSAndroid Build Coastguard Worker if (nChannels == 1)
691*3ac0a46fSAndroid Build Coastguard Worker return 33; // For monochrome
692*3ac0a46fSAndroid Build Coastguard Worker
693*3ac0a46fSAndroid Build Coastguard Worker return 17; // 17 for remaining
694*3ac0a46fSAndroid Build Coastguard Worker }
695*3ac0a46fSAndroid Build Coastguard Worker
696*3ac0a46fSAndroid Build Coastguard Worker // Default values
697*3ac0a46fSAndroid Build Coastguard Worker if (nChannels > 4)
698*3ac0a46fSAndroid Build Coastguard Worker return 7; // 7 for Hifi
699*3ac0a46fSAndroid Build Coastguard Worker
700*3ac0a46fSAndroid Build Coastguard Worker if (nChannels == 4)
701*3ac0a46fSAndroid Build Coastguard Worker return 17; // 17 for CMYK
702*3ac0a46fSAndroid Build Coastguard Worker
703*3ac0a46fSAndroid Build Coastguard Worker return 33; // 33 for RGB
704*3ac0a46fSAndroid Build Coastguard Worker }
705*3ac0a46fSAndroid Build Coastguard Worker
706*3ac0a46fSAndroid Build Coastguard Worker
_cmsEndPointsBySpace(cmsColorSpaceSignature Space,cmsUInt16Number ** White,cmsUInt16Number ** Black,cmsUInt32Number * nOutputs)707*3ac0a46fSAndroid Build Coastguard Worker cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
708*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number **White,
709*3ac0a46fSAndroid Build Coastguard Worker cmsUInt16Number **Black,
710*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number *nOutputs)
711*3ac0a46fSAndroid Build Coastguard Worker {
712*3ac0a46fSAndroid Build Coastguard Worker // Only most common spaces
713*3ac0a46fSAndroid Build Coastguard Worker
714*3ac0a46fSAndroid Build Coastguard Worker static cmsUInt16Number RGBblack[4] = { 0, 0, 0 };
715*3ac0a46fSAndroid Build Coastguard Worker static cmsUInt16Number RGBwhite[4] = { 0xffff, 0xffff, 0xffff };
716*3ac0a46fSAndroid Build Coastguard Worker static cmsUInt16Number CMYKblack[4] = { 0xffff, 0xffff, 0xffff, 0xffff }; // 400% of ink
717*3ac0a46fSAndroid Build Coastguard Worker static cmsUInt16Number CMYKwhite[4] = { 0, 0, 0, 0 };
718*3ac0a46fSAndroid Build Coastguard Worker static cmsUInt16Number LABblack[4] = { 0, 0x8080, 0x8080 }; // V4 Lab encoding
719*3ac0a46fSAndroid Build Coastguard Worker static cmsUInt16Number LABwhite[4] = { 0xFFFF, 0x8080, 0x8080 };
720*3ac0a46fSAndroid Build Coastguard Worker static cmsUInt16Number CMYblack[4] = { 0xffff, 0xffff, 0xffff };
721*3ac0a46fSAndroid Build Coastguard Worker static cmsUInt16Number CMYwhite[4] = { 0, 0, 0 };
722*3ac0a46fSAndroid Build Coastguard Worker static cmsUInt16Number Grayblack[4] = { 0 };
723*3ac0a46fSAndroid Build Coastguard Worker static cmsUInt16Number GrayWhite[4] = { 0xffff };
724*3ac0a46fSAndroid Build Coastguard Worker
725*3ac0a46fSAndroid Build Coastguard Worker switch (Space) {
726*3ac0a46fSAndroid Build Coastguard Worker
727*3ac0a46fSAndroid Build Coastguard Worker case cmsSigGrayData: if (White) *White = GrayWhite;
728*3ac0a46fSAndroid Build Coastguard Worker if (Black) *Black = Grayblack;
729*3ac0a46fSAndroid Build Coastguard Worker if (nOutputs) *nOutputs = 1;
730*3ac0a46fSAndroid Build Coastguard Worker return TRUE;
731*3ac0a46fSAndroid Build Coastguard Worker
732*3ac0a46fSAndroid Build Coastguard Worker case cmsSigRgbData: if (White) *White = RGBwhite;
733*3ac0a46fSAndroid Build Coastguard Worker if (Black) *Black = RGBblack;
734*3ac0a46fSAndroid Build Coastguard Worker if (nOutputs) *nOutputs = 3;
735*3ac0a46fSAndroid Build Coastguard Worker return TRUE;
736*3ac0a46fSAndroid Build Coastguard Worker
737*3ac0a46fSAndroid Build Coastguard Worker case cmsSigLabData: if (White) *White = LABwhite;
738*3ac0a46fSAndroid Build Coastguard Worker if (Black) *Black = LABblack;
739*3ac0a46fSAndroid Build Coastguard Worker if (nOutputs) *nOutputs = 3;
740*3ac0a46fSAndroid Build Coastguard Worker return TRUE;
741*3ac0a46fSAndroid Build Coastguard Worker
742*3ac0a46fSAndroid Build Coastguard Worker case cmsSigCmykData: if (White) *White = CMYKwhite;
743*3ac0a46fSAndroid Build Coastguard Worker if (Black) *Black = CMYKblack;
744*3ac0a46fSAndroid Build Coastguard Worker if (nOutputs) *nOutputs = 4;
745*3ac0a46fSAndroid Build Coastguard Worker return TRUE;
746*3ac0a46fSAndroid Build Coastguard Worker
747*3ac0a46fSAndroid Build Coastguard Worker case cmsSigCmyData: if (White) *White = CMYwhite;
748*3ac0a46fSAndroid Build Coastguard Worker if (Black) *Black = CMYblack;
749*3ac0a46fSAndroid Build Coastguard Worker if (nOutputs) *nOutputs = 3;
750*3ac0a46fSAndroid Build Coastguard Worker return TRUE;
751*3ac0a46fSAndroid Build Coastguard Worker
752*3ac0a46fSAndroid Build Coastguard Worker default:;
753*3ac0a46fSAndroid Build Coastguard Worker }
754*3ac0a46fSAndroid Build Coastguard Worker
755*3ac0a46fSAndroid Build Coastguard Worker return FALSE;
756*3ac0a46fSAndroid Build Coastguard Worker }
757*3ac0a46fSAndroid Build Coastguard Worker
758*3ac0a46fSAndroid Build Coastguard Worker
759*3ac0a46fSAndroid Build Coastguard Worker
760*3ac0a46fSAndroid Build Coastguard Worker // Several utilities -------------------------------------------------------
761*3ac0a46fSAndroid Build Coastguard Worker
762*3ac0a46fSAndroid Build Coastguard Worker // Translate from our colorspace to ICC representation
763*3ac0a46fSAndroid Build Coastguard Worker
_cmsICCcolorSpace(int OurNotation)764*3ac0a46fSAndroid Build Coastguard Worker cmsColorSpaceSignature CMSEXPORT _cmsICCcolorSpace(int OurNotation)
765*3ac0a46fSAndroid Build Coastguard Worker {
766*3ac0a46fSAndroid Build Coastguard Worker switch (OurNotation) {
767*3ac0a46fSAndroid Build Coastguard Worker
768*3ac0a46fSAndroid Build Coastguard Worker case 1:
769*3ac0a46fSAndroid Build Coastguard Worker case PT_GRAY: return cmsSigGrayData;
770*3ac0a46fSAndroid Build Coastguard Worker
771*3ac0a46fSAndroid Build Coastguard Worker case 2:
772*3ac0a46fSAndroid Build Coastguard Worker case PT_RGB: return cmsSigRgbData;
773*3ac0a46fSAndroid Build Coastguard Worker
774*3ac0a46fSAndroid Build Coastguard Worker case PT_CMY: return cmsSigCmyData;
775*3ac0a46fSAndroid Build Coastguard Worker case PT_CMYK: return cmsSigCmykData;
776*3ac0a46fSAndroid Build Coastguard Worker case PT_YCbCr:return cmsSigYCbCrData;
777*3ac0a46fSAndroid Build Coastguard Worker case PT_YUV: return cmsSigLuvData;
778*3ac0a46fSAndroid Build Coastguard Worker case PT_XYZ: return cmsSigXYZData;
779*3ac0a46fSAndroid Build Coastguard Worker
780*3ac0a46fSAndroid Build Coastguard Worker case PT_LabV2:
781*3ac0a46fSAndroid Build Coastguard Worker case PT_Lab: return cmsSigLabData;
782*3ac0a46fSAndroid Build Coastguard Worker
783*3ac0a46fSAndroid Build Coastguard Worker case PT_YUVK: return cmsSigLuvKData;
784*3ac0a46fSAndroid Build Coastguard Worker case PT_HSV: return cmsSigHsvData;
785*3ac0a46fSAndroid Build Coastguard Worker case PT_HLS: return cmsSigHlsData;
786*3ac0a46fSAndroid Build Coastguard Worker case PT_Yxy: return cmsSigYxyData;
787*3ac0a46fSAndroid Build Coastguard Worker
788*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH1: return cmsSigMCH1Data;
789*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH2: return cmsSigMCH2Data;
790*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH3: return cmsSigMCH3Data;
791*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH4: return cmsSigMCH4Data;
792*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH5: return cmsSigMCH5Data;
793*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH6: return cmsSigMCH6Data;
794*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH7: return cmsSigMCH7Data;
795*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH8: return cmsSigMCH8Data;
796*3ac0a46fSAndroid Build Coastguard Worker
797*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH9: return cmsSigMCH9Data;
798*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH10: return cmsSigMCHAData;
799*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH11: return cmsSigMCHBData;
800*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH12: return cmsSigMCHCData;
801*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH13: return cmsSigMCHDData;
802*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH14: return cmsSigMCHEData;
803*3ac0a46fSAndroid Build Coastguard Worker case PT_MCH15: return cmsSigMCHFData;
804*3ac0a46fSAndroid Build Coastguard Worker
805*3ac0a46fSAndroid Build Coastguard Worker default: return (cmsColorSpaceSignature) 0;
806*3ac0a46fSAndroid Build Coastguard Worker }
807*3ac0a46fSAndroid Build Coastguard Worker }
808*3ac0a46fSAndroid Build Coastguard Worker
809*3ac0a46fSAndroid Build Coastguard Worker
_cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace)810*3ac0a46fSAndroid Build Coastguard Worker int CMSEXPORT _cmsLCMScolorSpace(cmsColorSpaceSignature ProfileSpace)
811*3ac0a46fSAndroid Build Coastguard Worker {
812*3ac0a46fSAndroid Build Coastguard Worker switch (ProfileSpace) {
813*3ac0a46fSAndroid Build Coastguard Worker
814*3ac0a46fSAndroid Build Coastguard Worker case cmsSigGrayData: return PT_GRAY;
815*3ac0a46fSAndroid Build Coastguard Worker case cmsSigRgbData: return PT_RGB;
816*3ac0a46fSAndroid Build Coastguard Worker case cmsSigCmyData: return PT_CMY;
817*3ac0a46fSAndroid Build Coastguard Worker case cmsSigCmykData: return PT_CMYK;
818*3ac0a46fSAndroid Build Coastguard Worker case cmsSigYCbCrData:return PT_YCbCr;
819*3ac0a46fSAndroid Build Coastguard Worker case cmsSigLuvData: return PT_YUV;
820*3ac0a46fSAndroid Build Coastguard Worker case cmsSigXYZData: return PT_XYZ;
821*3ac0a46fSAndroid Build Coastguard Worker case cmsSigLabData: return PT_Lab;
822*3ac0a46fSAndroid Build Coastguard Worker case cmsSigLuvKData: return PT_YUVK;
823*3ac0a46fSAndroid Build Coastguard Worker case cmsSigHsvData: return PT_HSV;
824*3ac0a46fSAndroid Build Coastguard Worker case cmsSigHlsData: return PT_HLS;
825*3ac0a46fSAndroid Build Coastguard Worker case cmsSigYxyData: return PT_Yxy;
826*3ac0a46fSAndroid Build Coastguard Worker
827*3ac0a46fSAndroid Build Coastguard Worker case cmsSig1colorData:
828*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH1Data: return PT_MCH1;
829*3ac0a46fSAndroid Build Coastguard Worker
830*3ac0a46fSAndroid Build Coastguard Worker case cmsSig2colorData:
831*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH2Data: return PT_MCH2;
832*3ac0a46fSAndroid Build Coastguard Worker
833*3ac0a46fSAndroid Build Coastguard Worker case cmsSig3colorData:
834*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH3Data: return PT_MCH3;
835*3ac0a46fSAndroid Build Coastguard Worker
836*3ac0a46fSAndroid Build Coastguard Worker case cmsSig4colorData:
837*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH4Data: return PT_MCH4;
838*3ac0a46fSAndroid Build Coastguard Worker
839*3ac0a46fSAndroid Build Coastguard Worker case cmsSig5colorData:
840*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH5Data: return PT_MCH5;
841*3ac0a46fSAndroid Build Coastguard Worker
842*3ac0a46fSAndroid Build Coastguard Worker case cmsSig6colorData:
843*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH6Data: return PT_MCH6;
844*3ac0a46fSAndroid Build Coastguard Worker
845*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH7Data:
846*3ac0a46fSAndroid Build Coastguard Worker case cmsSig7colorData:return PT_MCH7;
847*3ac0a46fSAndroid Build Coastguard Worker
848*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH8Data:
849*3ac0a46fSAndroid Build Coastguard Worker case cmsSig8colorData:return PT_MCH8;
850*3ac0a46fSAndroid Build Coastguard Worker
851*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH9Data:
852*3ac0a46fSAndroid Build Coastguard Worker case cmsSig9colorData:return PT_MCH9;
853*3ac0a46fSAndroid Build Coastguard Worker
854*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCHAData:
855*3ac0a46fSAndroid Build Coastguard Worker case cmsSig10colorData:return PT_MCH10;
856*3ac0a46fSAndroid Build Coastguard Worker
857*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCHBData:
858*3ac0a46fSAndroid Build Coastguard Worker case cmsSig11colorData:return PT_MCH11;
859*3ac0a46fSAndroid Build Coastguard Worker
860*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCHCData:
861*3ac0a46fSAndroid Build Coastguard Worker case cmsSig12colorData:return PT_MCH12;
862*3ac0a46fSAndroid Build Coastguard Worker
863*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCHDData:
864*3ac0a46fSAndroid Build Coastguard Worker case cmsSig13colorData:return PT_MCH13;
865*3ac0a46fSAndroid Build Coastguard Worker
866*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCHEData:
867*3ac0a46fSAndroid Build Coastguard Worker case cmsSig14colorData:return PT_MCH14;
868*3ac0a46fSAndroid Build Coastguard Worker
869*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCHFData:
870*3ac0a46fSAndroid Build Coastguard Worker case cmsSig15colorData:return PT_MCH15;
871*3ac0a46fSAndroid Build Coastguard Worker
872*3ac0a46fSAndroid Build Coastguard Worker default: return (cmsColorSpaceSignature) 0;
873*3ac0a46fSAndroid Build Coastguard Worker }
874*3ac0a46fSAndroid Build Coastguard Worker }
875*3ac0a46fSAndroid Build Coastguard Worker
876*3ac0a46fSAndroid Build Coastguard Worker
cmsChannelsOfColorSpace(cmsColorSpaceSignature ColorSpace)877*3ac0a46fSAndroid Build Coastguard Worker cmsInt32Number CMSEXPORT cmsChannelsOfColorSpace(cmsColorSpaceSignature ColorSpace)
878*3ac0a46fSAndroid Build Coastguard Worker {
879*3ac0a46fSAndroid Build Coastguard Worker switch (ColorSpace) {
880*3ac0a46fSAndroid Build Coastguard Worker
881*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH1Data:
882*3ac0a46fSAndroid Build Coastguard Worker case cmsSig1colorData:
883*3ac0a46fSAndroid Build Coastguard Worker case cmsSigGrayData: return 1;
884*3ac0a46fSAndroid Build Coastguard Worker
885*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH2Data:
886*3ac0a46fSAndroid Build Coastguard Worker case cmsSig2colorData: return 2;
887*3ac0a46fSAndroid Build Coastguard Worker
888*3ac0a46fSAndroid Build Coastguard Worker case cmsSigXYZData:
889*3ac0a46fSAndroid Build Coastguard Worker case cmsSigLabData:
890*3ac0a46fSAndroid Build Coastguard Worker case cmsSigLuvData:
891*3ac0a46fSAndroid Build Coastguard Worker case cmsSigYCbCrData:
892*3ac0a46fSAndroid Build Coastguard Worker case cmsSigYxyData:
893*3ac0a46fSAndroid Build Coastguard Worker case cmsSigRgbData:
894*3ac0a46fSAndroid Build Coastguard Worker case cmsSigHsvData:
895*3ac0a46fSAndroid Build Coastguard Worker case cmsSigHlsData:
896*3ac0a46fSAndroid Build Coastguard Worker case cmsSigCmyData:
897*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH3Data:
898*3ac0a46fSAndroid Build Coastguard Worker case cmsSig3colorData: return 3;
899*3ac0a46fSAndroid Build Coastguard Worker
900*3ac0a46fSAndroid Build Coastguard Worker case cmsSigLuvKData:
901*3ac0a46fSAndroid Build Coastguard Worker case cmsSigCmykData:
902*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH4Data:
903*3ac0a46fSAndroid Build Coastguard Worker case cmsSig4colorData: return 4;
904*3ac0a46fSAndroid Build Coastguard Worker
905*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH5Data:
906*3ac0a46fSAndroid Build Coastguard Worker case cmsSig5colorData: return 5;
907*3ac0a46fSAndroid Build Coastguard Worker
908*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH6Data:
909*3ac0a46fSAndroid Build Coastguard Worker case cmsSig6colorData: return 6;
910*3ac0a46fSAndroid Build Coastguard Worker
911*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH7Data:
912*3ac0a46fSAndroid Build Coastguard Worker case cmsSig7colorData: return 7;
913*3ac0a46fSAndroid Build Coastguard Worker
914*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH8Data:
915*3ac0a46fSAndroid Build Coastguard Worker case cmsSig8colorData: return 8;
916*3ac0a46fSAndroid Build Coastguard Worker
917*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCH9Data:
918*3ac0a46fSAndroid Build Coastguard Worker case cmsSig9colorData: return 9;
919*3ac0a46fSAndroid Build Coastguard Worker
920*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCHAData:
921*3ac0a46fSAndroid Build Coastguard Worker case cmsSig10colorData: return 10;
922*3ac0a46fSAndroid Build Coastguard Worker
923*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCHBData:
924*3ac0a46fSAndroid Build Coastguard Worker case cmsSig11colorData: return 11;
925*3ac0a46fSAndroid Build Coastguard Worker
926*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCHCData:
927*3ac0a46fSAndroid Build Coastguard Worker case cmsSig12colorData: return 12;
928*3ac0a46fSAndroid Build Coastguard Worker
929*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCHDData:
930*3ac0a46fSAndroid Build Coastguard Worker case cmsSig13colorData: return 13;
931*3ac0a46fSAndroid Build Coastguard Worker
932*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCHEData:
933*3ac0a46fSAndroid Build Coastguard Worker case cmsSig14colorData: return 14;
934*3ac0a46fSAndroid Build Coastguard Worker
935*3ac0a46fSAndroid Build Coastguard Worker case cmsSigMCHFData:
936*3ac0a46fSAndroid Build Coastguard Worker case cmsSig15colorData: return 15;
937*3ac0a46fSAndroid Build Coastguard Worker
938*3ac0a46fSAndroid Build Coastguard Worker default: return -1;
939*3ac0a46fSAndroid Build Coastguard Worker }
940*3ac0a46fSAndroid Build Coastguard Worker }
941*3ac0a46fSAndroid Build Coastguard Worker
942*3ac0a46fSAndroid Build Coastguard Worker /**
943*3ac0a46fSAndroid Build Coastguard Worker * DEPRECATED: Provided for compatibility only
944*3ac0a46fSAndroid Build Coastguard Worker */
cmsChannelsOf(cmsColorSpaceSignature ColorSpace)945*3ac0a46fSAndroid Build Coastguard Worker cmsUInt32Number CMSEXPORT cmsChannelsOf(cmsColorSpaceSignature ColorSpace)
946*3ac0a46fSAndroid Build Coastguard Worker {
947*3ac0a46fSAndroid Build Coastguard Worker int n = cmsChannelsOfColorSpace(ColorSpace);
948*3ac0a46fSAndroid Build Coastguard Worker if (n < 0) return 3;
949*3ac0a46fSAndroid Build Coastguard Worker return (cmsUInt32Number)n;
950*3ac0a46fSAndroid Build Coastguard Worker }