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