Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
IccEval.cpp
Go to the documentation of this file.
1/** @file
2File: IccEval.cpp
3
4Contains: Implementation of the CIccProfile Evaluation utilites.
5
6Version: V1
7
8Copyright: (c) see ICC Software License
9*/
10
11/*
12* The ICC Software License, Version 0.2
13*
14*
15* Copyright (c) 2003-2012 The International Color Consortium. All rights
16* reserved.
17*
18* Redistribution and use in source and binary forms, with or without
19* modification, are permitted provided that the following conditions
20* are met:
21*
22* 1. Redistributions of source code must retain the above copyright
23* notice, this list of conditions and the following disclaimer.
24*
25* 2. Redistributions in binary form must reproduce the above copyright
26* notice, this list of conditions and the following disclaimer in
27* the documentation and/or other materials provided with the
28* distribution.
29*
30* 3. In the absence of prior written permission, the names "ICC" and "The
31* International Color Consortium" must not be used to imply that the
32* ICC organization endorses or promotes products derived from this
33* software.
34*
35*
36* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39* DISCLAIMED. IN NO EVENT SHALL THE INTERNATIONAL COLOR CONSORTIUM OR
40* ITS CONTRIBUTING MEMBERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47* SUCH DAMAGE.
48* ====================================================================
49*
50* This software consists of voluntary contributions made by many
51* individuals on behalf of the The International Color Consortium.
52*
53*
54* Membership in the ICC is encouraged when this software is used for
55* commercial purposes.
56*
57*
58* For more information on The International Color Consortium, please
59* see <http://www.color.org/>.
60*
61*
62*/
63
64//////////////////////////////////////////////////////////////////////
65// HISTORY:
66//
67// -Initial implementation by Max Derhak 5-15-2003
68//
69//////////////////////////////////////////////////////////////////////
70
71#include <math.h>
72#include "IccEval.h"
73#include "IccTag.h"
74
75#ifdef USEREFICCMAXNAMESPACE
76namespace refIccMAX {
77#endif
78
79static const icFloatNumber SMALLNUM = (icFloatNumber)0.0001;
81
82icStatusCMM CIccEvalCompare::EvaluateProfile(CIccProfile *pProfile, icUInt8Number nGran/* =0 */,
83 icRenderingIntent nIntent/* =icUnknownIntent */, icXformInterp nInterp/* =icInterpLinear */,
84 bool buseMpeTags/* =true */)
85{
86 if (!pProfile)
87 {
89 }
90
91 if (pProfile->m_Header.deviceClass!=icSigInputClass &&
92 pProfile->m_Header.deviceClass!=icSigDisplayClass &&
93 pProfile->m_Header.deviceClass!=icSigOutputClass &&
94 pProfile->m_Header.deviceClass!=icSigColorSpaceClass)
95 {
97 }
98
99 CIccCmm dev2Lab(icSigUnknownData, icSigLabData);
100 CIccCmm Lab2Dev2Lab(icSigLabData, icSigLabData, false);
101
102 icStatusCMM result;
103
104 result = dev2Lab.AddXform(*pProfile, nIntent, nInterp, NULL, icXformLutColorimetric, buseMpeTags);
105
106 if (result!=icCmmStatOk) {
107 return result;
108 }
109
110 result = dev2Lab.Begin();
111 if (result != icCmmStatOk) {
112 return result;
113 }
114
115 result = Lab2Dev2Lab.AddXform(*pProfile, nIntent, nInterp, NULL, icXformLutColorimetric, buseMpeTags);
116 if (result != icCmmStatOk) {
117 return result;
118 }
119
120 result = Lab2Dev2Lab.AddXform(*pProfile, nIntent, nInterp, NULL, icXformLutColorimetric, buseMpeTags);
121 if (result != icCmmStatOk) {
122 return result;
123 }
124
125 result = Lab2Dev2Lab.Begin();
126 if (result != icCmmStatOk) {
127 return result;
128 }
129
130 icFloatNumber sPixel[15];
131 icFloatNumber devPcs[15], roundPcs1[15], roundPcs2[15];
132
133 int ndim = icGetSpaceSamples(pProfile->m_Header.colorSpace);
134 int ndim1 = ndim+1;
135
136 // determine granularity
137 if (!nGran)
138 {
139 CIccTagLutAtoB* pTag = (CIccTagLutAtoB*)pProfile->FindTag(icSigAToB0Tag+(nIntent==icAbsoluteColorimetric ? icRelativeColorimetric : nIntent));
140 if (!pTag || ndim==3)
141 {
142 nGran = 33;
143 }
144 else {
145 CIccCLUT* pClut = pTag->GetCLUT();
146 if (pClut)
147 nGran = pClut->GridPoints()+2;
148 else
149 nGran = 33;
150 }
151 }
152
153 int i, j;
154 icFloatNumber stepsize = (icFloatNumber)(1.0/(icFloatNumber)(nGran-1));
155 icFloatNumber* steps = new icFloatNumber[ndim1];
156 icFloatNumber nstart = 0.0;
157 icFloatNumber nEnd = (icFloatNumber)(1.0+stepsize/2.0);
158 for(j=0; j<ndim1; j++) {
159 steps[j] = nstart;
160 }
161
162 while(steps[0]==nstart) {
163 for(j=0; j<ndim; j++) {
164 sPixel[j] = icMin(steps[j+1],1.0);
165 }
166 steps[ndim] = (steps[ndim]+stepsize);
167 for(i=ndim; i>=0; i--) {
168 if(steps[i]>nEnd) {
169 steps[i] = nstart;
170 steps[i-1] = (steps[i-1]+stepsize);
171 }
172 else break;
173 }
174
175 dev2Lab.Apply(devPcs, sPixel); //Convert device value to pcs from input table
176 Lab2Dev2Lab.Apply(roundPcs1, devPcs); //First round trip gets color into output gamut
177 Lab2Dev2Lab.Apply(roundPcs2, roundPcs1); //Second round trip find reproducibility error
178
179 icLabFromPcs(devPcs);
180 icLabFromPcs(roundPcs1);
181 icLabFromPcs(roundPcs2);
182
183 Compare(sPixel, devPcs, roundPcs1, roundPcs2);
184 }
185
186 return icCmmStatOk;
187}
188
189icStatusCMM CIccEvalCompare::EvaluateProfile(const icChar *szProfilePath, icUInt8Number nGrid/* =0 */, icRenderingIntent nIntent/* =icUnknownIntent */,
190 icXformInterp nInterp/* =icInterpLinear */, bool buseMpeTags/* =true */)
191{
192 CIccProfile *pProfile = ReadIccProfile(szProfilePath);
193
194 if (!pProfile)
196
197 icStatusCMM result = EvaluateProfile(pProfile, nGrid, nIntent, nInterp, buseMpeTags);
198
199 delete pProfile;
200
201 return result;
202}
203
204#ifdef USEREFICCMAXNAMESPACE
205} //namespace refIccMAX
206#endif
@ icXformLutColorimetric
Definition IccCmm.h:135
icXformInterp
CMM Interpolation types.
Definition IccCmm.h:113
icStatusCMM
CMM return status values.
Definition IccCmm.h:90
@ icCmmStatInvalidProfile
Definition IccCmm.h:95
@ icCmmStatCantOpenProfile
Definition IccCmm.h:93
@ icCmmStatOk
Definition IccCmm.h:92
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
Definition IccDefs.h:100
char icChar
Definition IccDefs.h:109
static const icFloatNumber SMALLNUM
Definition IccEval.cpp:79
static const icFloatNumber LESSTHANONE
Definition IccEval.cpp:80
File: IccEval.h.
CIccProfile * ReadIccProfile(const icChar *szFilename, bool bUseSubProfile)
Name: ReadIccProfile.
File: IccTag.h.
icUInt32Number icGetSpaceSamples(icColorSpaceSignature sig)
Definition IccUtil.cpp:1303
void icLabFromPcs(icFloatNumber *Lab)
Floating point encoding of Lab in PCS is in range 0.0 to 1.0.
Definition IccUtil.cpp:919
icFloatNumber icMin(icFloatNumber v1, icFloatNumber v2)
Definition IccUtil.cpp:898
Class: CIccCLUT.
Definition IccTagLut.h:326
icUInt8Number GridPoints() const
Definition IccTagLut.h:349
icStatusCMM EvaluateProfile(CIccProfile *pProfile, icUInt8Number nGran=0, icRenderingIntent nIntent=((icRenderingIntent) 0x3f3f3f3f), icXformInterp nInterp=icInterpLinear, bool buseMpeTags=true)
Definition IccEval.cpp:82
CIccCLUT * GetCLUT() const
Definition IccTagLut.h:469
Class: CIccTagLutAtoB.
Definition IccTagLut.h:502
unsigned char icUInt8Number
Number definitions.
@ icSigDisplayClass
@ icSigOutputClass
@ icSigInputClass
@ icSigColorSpaceClass
@ icSigLabData
#define icSigUnknownData
@ icSigAToB0Tag
icRenderingIntent
Rendering Intents, used in the profile header.
@ icRelativeColorimetric
@ icAbsoluteColorimetric