Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
IccPcc.cpp
Go to the documentation of this file.
1/** @file
2 File: IccPcc.cpp
3
4 Contains: Implementation of the IIccProfileConnectionConditions interface class.
5
6 Version: V1
7
8 Copyright: (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#ifdef WIN32
72 #pragma warning( disable: 4786) //disable warning in <list.h>
73#endif
74#include "IccPcc.h"
75#include "IccProfile.h"
76#include "IccTag.h"
77#include "IccCmm.h"
78
80{
83
84 if (illum!=IPCC.getPccIlluminant() || obs!= IPCC.getPccObserver())
85 return false;
86
87 if ((illum==icIlluminantDaylight || illum==icIlluminantBlackBody) && getPccCCT()!=IPCC.getPccCCT())
88 return false;
89
90 if (illum==icIlluminantUnknown)
91 return false;
92
93 if (obs==icStdObsCustom) {
94 if (!hasIlluminantSPD() && !IPCC.hasIlluminantSPD()) {
95 icFloatNumber XYZ1[3], XYZ2[3];
96 getNormIlluminantXYZ(&XYZ1[0]);
97 IPCC.getNormIlluminantXYZ(&XYZ2[0]);
98
99 if (XYZ1[0]!=XYZ2[0] ||
100 XYZ1[1]!=XYZ2[1] ||
101 XYZ1[2]!=XYZ2[2])
102 return false;
103 }
104 else {
105 return false;
106 }
107 }
108
109 return true;
110}
111
120
122{
124 if (!pCond)
125 return 0.0f;
126
127 return pCond->getIlluminantCCT();
128}
129
138
140{
142 return true;
143
144 return false;
145}
146
148{
150 if (!pCond)
151 return false;
152
153 icSpectralRange illumRange;
154 const icFloatNumber *illum = pCond->getIlluminant(illumRange);
155
156 if (!illumRange.steps || !illum)
157 return false;
158
159 return true;
160}
161
163{
165 if (!pView)
166 return 1.0;
167
168 icSpectralRange illumRange;
169 const icFloatNumber *illum = pView->getIlluminant(illumRange);
170
171 icSpectralRange obsRange;
172 const icFloatNumber *obs = pView->getObserver(obsRange);
173
174 int i, n = illumRange.steps;
175 CIccMatrixMath *mapRange=CIccMatrixMath::rangeMap(obsRange, illumRange);
176 icFloatNumber rv=0;
177
178 if (mapRange) {
179 icFloatNumber *Ycmf = new icFloatNumber[illumRange.steps];
180 mapRange->VectorMult(Ycmf, &obs[obsRange.steps]);
181 delete mapRange;
182
183 for (i=0; i<n; i++) {
184 rv += Ycmf[i]*illum[i];
185 }
186 delete [] Ycmf;
187 }
188 else {
189 const icFloatNumber *Ycmf = &obs[obsRange.steps];
190
191 for (i=0; i<n; i++) {
192 rv += Ycmf[i]*illum[i];
193 }
194 }
195 return rv;
196}
197
199{
201 if (!pView)
202 return 1.0;
203
204 icSpectralRange obsRange;
205 const icFloatNumber *obs = pView->getObserver(obsRange);
206
207 int i, n = whiteRange.steps;
208 CIccMatrixMath *mapRange=CIccMatrixMath::rangeMap(obsRange, whiteRange);
209 icFloatNumber rv=0;
210
211 if (mapRange) {
212 icFloatNumber *Ycmf = new icFloatNumber[whiteRange.steps];
213 mapRange->VectorMult(Ycmf, &obs[obsRange.steps]);
214 delete mapRange;
215
216 for (i=0; i<n; i++) {
217 rv += Ycmf[i]*pWhite[i];
218 }
219 delete [] Ycmf;
220 }
221 else {
222 const icFloatNumber *Ycmf = &obs[obsRange.steps];
223
224 for (i=0; i<n; i++) {
225 rv += Ycmf[i]*pWhite[i];
226 }
227 }
228 return rv;
229}
230
232{
234 if (!pView || !pWhite)
235 return NULL;
236
237 int i, n = range.steps, size = 3*n;
238 const icFloatNumber *fptr;
239 icFloatNumber *tptr;
240
241 icSpectralRange observerRange;
242 const icFloatNumber *observer = pView->getObserver(observerRange);
243
244 if (!obs)
245 obs = (icFloatNumber*)malloc(size*sizeof(icFloatNumber));
246
247 if (obs) {
248 CIccMatrixMath *mapRange=CIccMatrixMath::rangeMap(observerRange, range);
249
250 //Copy observer while adjusting to range
251 if (mapRange) {
252 fptr = &observer[0];
253 tptr = obs;
254 for (i = 0; i < 3; i++) {
255 mapRange->VectorMult(tptr, fptr);
256 fptr += observerRange.steps;
257 tptr += range.steps;
258 }
259 delete mapRange;
260 }
261 else {
262 memcpy(obs, observer, size*sizeof(icFloatNumber));
263 }
264
265 //Calculate scale constant
266 icFloatNumber k=0.0f;
267 fptr = &obs[range.steps]; //Using second color matching function
268 for (i=0; i<(int)range.steps; i++) {
269 k += fptr[i]*pWhite[i];
270 }
271
272 //Scale observer so application of observer against white results in 1.0.
273 for (i=0; i<size; i++) {
274 obs[i] = obs[i] / k;
275 }
276
277 CIccMatrixMath observerMtx(3,range.steps);
278 memcpy(observerMtx.entry(0), obs, size*sizeof(icFloatNumber));
279
280 icFloatNumber xyz[3];
281 observerMtx.VectorMult(xyz, pWhite);
282 }
283
284 return obs;
285}
286
288{
289 CIccMatrixMath *pAdjust=NULL, *pMtx;
291
292 icSpectralRange illumRange;
293 const icFloatNumber *illum = pView->getIlluminant(illumRange);
294
295 pMtx = CIccMatrixMath::rangeMap(rangeRef, illumRange);
296 if (pMtx)
297 pAdjust = pMtx;
298
299 pMtx = pView->getObserverMatrix(illumRange);
300
301 if (pAdjust) {
302 pMtx = pAdjust->Mult(pMtx);
303 delete pAdjust;
304 }
305 pAdjust = pMtx;
306
307 pAdjust->VectorScale(illum);
308 pAdjust->Scale(1.0f / pAdjust->RowSum(1));
309
310 return pAdjust;
311}
312
315 bool bReflectance/*=false*/)
316{
317 if (pAppliedPCC) {
318 const CIccTagSpectralViewingConditions *pView = pAppliedPCC->getPccViewingConditions();
319 if (bReflectance) {
320 m_pPCC = pAppliedPCC;
322
329 m_bValidMediaXYZ = pProfile->calcMediaWhiteXYZ(m_mediaXYZ, pAppliedPCC);
330 }
331 else {
332 m_pPCC = NULL;
334
335 icSpectralRange illumRange;
336 const icFloatNumber *illum = pView->getIlluminant(illumRange);
337
338 m_pViewingConditions->setIlluminant(pView->getStdIllumiant(), illumRange, illum, pView->getIlluminantCCT());
339
340 pProfile->calcNormIlluminantXYZ(m_illuminantXYZ, this);
341 pProfile->calcLumIlluminantXYZ(m_illuminantXYZLum, this);
342 m_bValidMediaXYZ = pProfile->calcMediaWhiteXYZ(m_mediaXYZ, this);
343 }
344 }
345 else {
346 m_pPCC = NULL;
348 m_bValidMediaXYZ = false;
349 }
350}
351
357
366
373
380
385
390
392{
394 memcpy(pXYZ, m_mediaXYZ, 3*sizeof(icFloatNumber));
395 return m_bValidMediaXYZ;
396 }
397 return false;
398}
File: IccCmm.h.
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
Definition IccDefs.h:100
File: IccPcc.h.
File: IccProfile.h.
File: IccTag.h.
CIccCombinedConnectionConditions(CIccProfile *pProfile, IIccProfileConnectionConditions *pAppliedPCC, bool bReflectance=false)
Definition IccPcc.cpp:313
virtual void getLumIlluminantXYZ(icFloatNumber *pXYZLum)
Definition IccPcc.cpp:386
virtual ~CIccCombinedConnectionConditions()
Definition IccPcc.cpp:352
virtual CIccTagMultiProcessElement * getStandardToCustomPcc()
Definition IccPcc.cpp:374
CIccTagSpectralViewingConditions * m_pViewingConditions
Definition IccPcc.h:149
icFloatNumber m_illuminantXYZLum[3]
Definition IccPcc.h:151
IIccProfileConnectionConditions * m_pPCC
Definition IccPcc.h:153
icFloatNumber m_mediaXYZ[3]
Definition IccPcc.h:152
icFloatNumber m_illuminantXYZ[3]
Definition IccPcc.h:150
virtual const CIccTagSpectralViewingConditions * getPccViewingConditions()
Definition IccPcc.cpp:358
virtual CIccTagMultiProcessElement * getCustomToStandardPcc()
Definition IccPcc.cpp:367
virtual void getNormIlluminantXYZ(icFloatNumber *pXYZ)
Definition IccPcc.cpp:381
virtual bool getMediaWhiteXYZ(icFloatNumber *pXYZ)
Definition IccPcc.cpp:391
Type: Class.
icFloatNumber * entry(icUInt16Number nRow, icUInt16Number nCol=0)
icFloatNumber RowSum(icUInt16Number nRow) const
Name: CIccMatrixMath::RowSum.
void VectorScale(const icFloatNumber *vec)
Name: CIccMatrixMath::VectorScale.
CIccMatrixMath * Mult(const CIccMatrixMath *matrix) const
Name: CIccMatrixMath::Mult.
static CIccMatrixMath * rangeMap(const icSpectralRange &from, const icSpectralRange &to)
Name: CIccMatrixMath::rangeMap.
virtual void VectorMult(icFloatNumber *pDst, const icFloatNumber *pSrc) const
Name: CIccMatrixMath::VectorMult.
void Scale(icFloatNumber v)
Name: CIccMatrixMath::Scale.
Class: CIccTagMultiProcessElement.
Definition IccTagMPE.h:358
Class: CIccTagSpectralViewingConditions.
CIccMatrixMath * getObserverMatrix(const icSpectralRange &newRange) const
const icFloatNumber * getObserver(icSpectralRange &observerRange) const
icFloatNumber getIlluminantCCT() const
virtual CIccTag * NewCopy() const
Function: NewCopy(sDescription) Each derived tag will implement it's own NewCopy() function.
icIlluminant getStdIllumiant() const
const icFloatNumber * getIlluminant(icSpectralRange &illumRange) const
bool setIlluminant(icIlluminant illumId, const icSpectralRange &illumRange, const icFloatNumber *illum, icFloatNumber illumCCT=0.0f)
icStandardObserver getStdObserver() const
virtual CIccTagMultiProcessElement * getStandardToCustomPcc()=0
icFloatNumber getObserverIlluminantScaleFactor()
Definition IccPcc.cpp:162
icFloatNumber * getEmissiveObserver(const icSpectralRange &range, const icFloatNumber *pWhite, icFloatNumber *obsMatrix=NULL)
Definition IccPcc.cpp:231
virtual const CIccTagSpectralViewingConditions * getPccViewingConditions()=0
icIlluminant getPccIlluminant()
Definition IccPcc.cpp:112
virtual CIccTagMultiProcessElement * getCustomToStandardPcc()=0
icFloatNumber getObserverWhiteScaleFactor(const icFloatNumber *pWhite, const icSpectralRange &whiteRange)
Definition IccPcc.cpp:198
CIccMatrixMath * getReflectanceObserver(const icSpectralRange &rangeRef)
Definition IccPcc.cpp:287
virtual void getNormIlluminantXYZ(icFloatNumber *pXYZ)=0
bool isEquivalentPcc(IIccProfileConnectionConditions &IPCC)
Definition IccPcc.cpp:79
icStandardObserver getPccObserver()
Definition IccPcc.cpp:130
icIlluminant
Pre-defined illuminants, used in measurement and viewing conditions type.
@ icIlluminantDaylight
@ icIlluminantBlackBody
@ icIlluminantUnknown
@ icIlluminantD50
#define icStdObsCustom
icStandardObserver
Standard Observer, used in the measurmentType tag.
@ icStdObs1931TwoDegrees
icFloat32Number Z
icFloat32Number Y
icFloat32Number X
spectral range
icUInt16Number steps