Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
IccArrayBasic.cpp
Go to the documentation of this file.
1/** @file
2 File: IccArrayBasic.cpp
3
4 Contains: Implementation of the IIccArray class and basic inherited classes
5
6 Version: V1
7
8 Copyright: � 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 #include <windows.h>
74#endif
75#include <stdio.h>
76#include <math.h>
77#include <string.h>
78#include <stdlib.h>
79#include "IccArrayBasic.h"
80#include "IccStructBasic.h"
81#include "IccUtil.h"
82#include "IccArrayFactory.h"
83
84#ifndef __min
85#include <algorithm>
86using std::min;
87#define __min min
88#endif
89
90#ifdef USEREFICCMAXNAMESPACE
91namespace refIccMAX {
92#endif
93
94
96{
97 m_pTag = pTagArray;
98 m_sig = sigArray;
99}
100
101
106
107
109{
110 CIccArrayUnknown *rv = new CIccArrayUnknown(pTagArray);
111
112 return rv;
113}
114
115
116void CIccArrayUnknown::Describe(std::string &sDescription, int nVerboseness) const
117{
118 sDescription += "\nCIccArrayUnknown::Describe()\n";
119}
120
121
122icValidateStatus CIccArrayUnknown::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile) const
123{
125
126 if (m_pTag) {
128
129 sReport += "Unknown tag array type!\n";
130 for (i=0; i<m_pTag->GetSize(); i++) {
131 CIccTag *pTag = m_pTag->GetIndex(i);
132 if (!pTag) {
134 char buf[80];
135 sprintf(buf, "Tag at index %d is NULL\n", i);
136 sReport += buf;
137 }
138 else {
139 rv = icMaxStatus(rv, pTag->Validate(sigPath+icGetSigPath(pTag->GetType()), sReport, pProfile));
140 }
141 }
142 }
143 else {
144 sReport += "Array Handler not connected to CIccTagArray object!";
145
147 }
148
149 return rv;
150}
151
152
154{
155 m_pTag = pTagArray;
157}
158
159
164
165
167{
168 CIccArrayColorantInfo *rv = new CIccArrayColorantInfo(pTagArray);
169
170 return rv;
171}
172
173
174void CIccArrayColorantInfo::Describe(std::string &sDescription, int nVerboseness) const
175{
176 sDescription += "\nCIccArrayColorantInfo::Describe()\n";
177}
178
179
180icValidateStatus CIccArrayColorantInfo::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile) const
181{
183
184 if (m_pTag) {
186
187 for (i = 0; i < m_pTag->GetSize(); i++) {
188 CIccTag *pTag = m_pTag->GetIndex(i);
189 if (!pTag) {
191 char buf[80];
192 sprintf(buf, "Tag at index %d is NULL\n", i);
193 sReport += buf;
194 }
195 else {
198 char buf[80];
199 sprintf(buf, "Tag at index %d is not a colorantInfoStruct\n", i);
200 sReport += buf;
201 }
202 rv = icMaxStatus(rv, pTag->Validate(sigPath + icGetSigPath(pTag->GetType()), sReport, pProfile));
203 }
204 }
205 }
206 else {
207 sReport += "Array Handler not connected to CIccTagArray object!";
208
210 }
211
212 return rv;
213}
214
215
217{
218 m_pTag = pTagArray;
219 m_sig = icSigNamedColorArray;
220
221 m_list = new icNamedColorStructList;
222
223 m_nDeviceSamples = 0;
224 m_nPcsSamples = 0;
225 m_nSpectralSamples = 0;
226 m_spectralRange = m_biSpectralRange = {};
227 m_csDevice = icSigUnknownData;
228 m_pZeroTint = NULL;
229 m_csSpectralPcs = icSigNoSpectralData;
230}
231
232
234{
235 delete m_list;
236}
237
238
240{
241 CIccArrayNamedColor *rv = new CIccArrayNamedColor(pTagArray);
242
243 if (rv) {
244 rv->m_csPcs = m_csPcs;
245 rv->m_csDevice = m_csDevice;
246 rv->m_csSpectralPcs = m_csSpectralPcs;
247 rv->m_spectralRange = m_spectralRange;
248 rv->m_biSpectralRange = m_biSpectralRange;
249 }
250
251 return rv;
252}
253
254
255void CIccArrayNamedColor::Describe(std::string &sDescription, int nVerboseness) const
256{
257 sDescription += "\nCIccArrayNamedColor::Describe()\n";
258}
259
260
262 icSpectralColorSignature csSpectralPcs/* =icSigNoSpectralData */,
263 const icSpectralRange *pSpectralRange /* = NULL */,
264 const icSpectralRange *pBiSpectralRange /* = NULL */)
265{
266 m_csPcs = csPcs;
267 m_csDevice = csDevice;
268 m_csSpectralPcs = csSpectralPcs;
269 if (pSpectralRange)
270 m_spectralRange = *pSpectralRange;
271 else
272 memset(&m_spectralRange, 0, sizeof(m_spectralRange));
273
274 if (pBiSpectralRange)
275 m_biSpectralRange = *pBiSpectralRange;
276 else
277 memset(&m_biSpectralRange, 0, sizeof(m_biSpectralRange));
278
279 m_nDeviceSamples = icGetSpaceSamples(m_csDevice);
280 m_nPcsSamples = icGetSpaceSamples(m_csPcs);
281 m_nSpectralSamples = icGetSpaceSamples((icColorSpaceSignature)m_csSpectralPcs);
282}
283
285{
286 m_pZeroTint = (CIccStructNamedColor*)icGetTagStructHandlerOfType(m_pTag->GetIndex(0), icSigTintZeroStruct);
287
288 m_list->clear();
289
290 int i, n=m_pTag->GetSize();
291 for (i=1; i<n; i++) {
293 if (pNamedColor) {
294 std::string name = pNamedColor->getName();
295 if (!name.empty())
296 (*m_list)[name] = pNamedColor;
297 }
298 }
299
300 return true;
301}
302
304{
305 std::string name(szColor);
306
307 icNamedColorStructList::const_iterator i;
308 i=m_list->find(name);
309 if (i!=m_list->end())
310 return i->second;
311
312 return NULL;
313}
314
316{
317 icFloatNumber *temp = new icFloatNumber[m_nDeviceSamples];
318
319 if (!temp)
320 return NULL;
321
322 icUInt32Number i, j, n=m_pTag->GetSize();
323 for (i=1; i<n; i++) {
325 if (pNamedColor) {
326 CIccTag *pTag = pNamedColor->GetElem(icSigNmclDeviceDataMbr);
327 if (pTag && pTag->IsNumArrayType()) {
329 icUInt32Number n = v->GetNumValues()/m_nDeviceSamples;
330 if (n) {
331 v->GetValues(temp, (n-1)*m_nDeviceSamples, m_nDeviceSamples);
332
333 for (j=0; j<m_nDeviceSamples; j++) {
334 if (temp[j]!=pDevColor[j])
335 break;
336 }
337 if (n==m_nDeviceSamples) {
338 delete [] temp;
339 return pNamedColor;
340 }
341 }
342 }
343 }
344 }
345 return NULL;
346}
347
349{
350 icFloatNumber dCalcDE, dLeastDE=dMinDE;
351 icFloatNumber pLabIn[3], pLab[3];
352 CIccStructNamedColor* leastDEindex = NULL;
353
354 if (m_csPcs != icSigLabData) {
355 icXYZtoLab(pLabIn,pPCS);
356 }
357 else {
358 memcpy(pLabIn, pPCS, 3*sizeof(icFloatNumber));
359 }
360
361 icUInt32Number i, n=m_pTag->GetSize();
362 for (i=1; i<n; i++) {
364 if (pNamedColor) {
365 CIccTag *pTag = pNamedColor->GetElem(icSigNmclDeviceDataMbr);
366 if (pTag && pTag->IsNumArrayType()) {
368 icUInt32Number n = v->GetNumValues()/m_nDeviceSamples;
369 if (n) {
370 v->GetValues(pLab, (n-1)*m_nDeviceSamples, 3);
371
372 dCalcDE = icDeltaE(pLabIn, pLab);
373
374 if (dCalcDE<dMinDE && dCalcDE<dLeastDE) {
375 dLeastDE = dCalcDE;
376 leastDEindex = pNamedColor;
377 }
378 }
379 }
380 }
381 }
382
383 return leastDEindex;
384}
385
387{
388 icFloatNumber dCalcRMS, dLeastRMS=dMinRMS;
389 CIccStructNamedColor* leastRMSindex = NULL;
390
391 icFloatNumber *temp = new icFloatNumber[m_nSpectralSamples];
392
393 if (!temp)
394 return NULL;
395
396 icUInt32Number i, n=m_pTag->GetSize();
397 for (i=1; i<n; i++) {
399 if (pNamedColor) {
400 CIccTag *pTag = pNamedColor->GetElem(icSigNmclDeviceDataMbr);
401 if (pTag && pTag->IsNumArrayType()) {
403 icUInt32Number n = v->GetNumValues()/m_nDeviceSamples;
404 if (n) {
405 v->GetValues(temp, (n-1)*m_nSpectralSamples, m_nSpectralSamples);
406
407 dCalcRMS = icRmsDif(pSpec, temp, m_nSpectralSamples);
408
409 if (dCalcRMS<dMinRMS && dCalcRMS<dLeastRMS) {
410 dLeastRMS = dCalcRMS;
411 leastRMSindex = pNamedColor;
412 }
413 }
414 }
415 }
416 }
417
418 return leastRMSindex;
419}
420
422 const CIccStructNamedColor *pColor,
423 icFloatNumber tint/*=1.0f*/,
424 icNamedColorlMemberSignature sig/*=icSigDeviceNmClrMember*/) const
425{
426 CIccTagNumArray *pZero;
427
428 if (m_pZeroTint)
429 pZero = m_pZeroTint->GetNumArray(sig);
430 else
431 pZero = NULL;
432
433 if (!pColor)
434 return false;
435
436 return pColor->GetTint(dstColor, tint, pZero, sig, m_nDeviceSamples);
437}
438
439
441 const CIccStructNamedColor *pColor,
442 icFloatNumber tint/*=1.0f*/,
443 icNamedColorlMemberSignature sig/*=icSigPcsNmClrMember*/) const
444{
445 CIccTagNumArray *pZero;
446
447 if (m_pZeroTint)
448 pZero = m_pZeroTint->GetNumArray(sig);
449 else
450 pZero = NULL;
451
452 if (!pColor)
453 return false;
454
455 return pColor->GetTint(dstColor, tint, pZero, sig, m_nPcsSamples);
456}
457
459 const CIccStructNamedColor *pColor,
460 icFloatNumber tint/*=1.0f*/,
461 icNamedColorlMemberSignature sig/*=icSigSpectralNmClrMember*/) const
462{
463 CIccTagNumArray *pZero;
464
465 if (m_pZeroTint)
466 pZero = m_pZeroTint->GetNumArray(sig);
467 else
468 pZero = NULL;
469
470 if (!pColor)
471 return false;
472
473 return pColor->GetTint(dstColor, tint, pZero, sig, m_nSpectralSamples);
474}
475
476
477icValidateStatus CIccArrayNamedColor::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile) const
478{
480
481 if (m_pTag) {
482 icUInt32Number i, n = m_pTag->GetSize();
483 CIccTag *pSubTag;
484 int nBad = 0;
485
486 if (n<1) {
487 sReport += "Named Color array must have at least 1 entry\n";
489 }
490
491 for (i=0; i<n; i++) {
492 pSubTag = m_pTag->GetIndex(i);
493 if (pSubTag) {
495 if (!((i && sig==icSigNamedColorStruct) || (!i && sig==icSigTintZeroStruct))) {
496 nBad++;
497 }
498 else {
499 CIccTagStruct *pTag = (CIccTagStruct*)pSubTag;
501
502 if (pColor) {
503 CIccTagNumArray *pArray, *pTint;
504 char str[256];
505
506 pTint = pColor->GetNumArray(icSigNmclTintMbr);
507
508 pArray = pColor->GetNumArray(icSigNmclDeviceDataMbr);
509 if (pArray && m_nDeviceSamples) {
510 icUInt32Number n = pArray->GetNumValues()/m_nDeviceSamples;
511
512 if (n<1) {
513 sprintf(str, "Insufficient device samples in NamedColor[%d]\n", i);
514 sReport += str;
516 }
517 else if (pArray->GetNumValues() != n*m_nDeviceSamples) {
518 sprintf(str, "Number of Device samples isn't an even multiple of Device samples in NamedColor[%d]!\n", i);
519 sReport += str;
521 }
522 if (pTint && pTint->GetNumValues()!=n) {
523 sprintf(str, "Number of device samples doesn't match tint values in NamedColor[%d]\n", i);
524 sReport += str;
526 }
527 }
528
529 pArray = pColor->GetNumArray(icSigNmclPcsDataMbr);
530 if (pArray && m_nPcsSamples) {
531 icUInt32Number n = pArray->GetNumValues()/m_nPcsSamples;
532
533 if (n<1) {
534 sprintf(str, "Insufficient PCS samples in NamedColor[%d]\n", i);
535 sReport += str;
537 }
538 else if (pArray->GetNumValues() != n*m_nPcsSamples) {
539 sprintf(str, "Number of PCS samples isn't an even multiple of PCS samples in NamedColor[%d]!\n", i);
540 sReport += str;
542 }
543 if (pTint && pTint->GetNumValues()!=n) {
544 sprintf(str, "Number of PCS samples doesn't match tint values in NamedColor[%d]\n", i);
545 sReport += str;
547 }
548 }
549
550 pArray = pColor->GetNumArray(icSigNmclSpectralDataMbr);
551 if (pArray) {
552 if (pArray->IsMatrixArray()) {
554
555 if (pArrayTag->GetChannelsPerMatrix()!= m_nSpectralSamples) {
556 sprintf(str, "Incompatible SpectralPcs samples in NamedColor[%d]\n", i);
557 sReport += str;
559 }
560 }
561 else if (m_nSpectralSamples) {
562 icUInt32Number n = pArray->GetNumValues()/m_nSpectralSamples;
563
564 if (n<1) {
565 sprintf(str, "Insufficient SpectralPcs samples in NamedColor[%d]\n", i);
566 sReport += str;
568 }
569 else if (pArray->GetNumValues() != n*m_nSpectralSamples) {
570 sprintf(str, "Number of spectral samples isn't an even multiple of spectral PCS samples in Namedcolor[%d]!\n", i);
571 sReport += str;
573 }
574 if (pTint && pTint->GetNumValues()!=n) {
575 sprintf(str, "Number of SpectralPCS samples doesn't match tint values in NamedColor[%d]\n", i);
576 sReport += str;
578 }
579 }
580 }
581 }
582
583 }
584 rv = icMaxStatus(rv, pSubTag->Validate(sigPath, sReport, pProfile));
585 }
586 else {
587 nBad++;
588 }
589 }
590 if (nBad) {
591 sReport += "Named Color array has invalid tag struct entries!\n";
593 }
594 }
595
596 return rv;
597}
598
599
600#ifdef USEREFICCMAXNAMESPACE
601} //namespace refIccMAX
602#endif
File: IccArrayBasic.h.
std::map< std::string, CIccStructNamedColor * > icNamedColorStructList
icArraySignature sig
File: IccArrayFactory.h.
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
Definition IccDefs.h:100
char icChar
Definition IccDefs.h:109
icValidateStatus
Definition IccDefs.h:118
@ icValidateOK
Definition IccDefs.h:119
@ icValidateWarning
Definition IccDefs.h:120
@ icValidateCriticalError
Definition IccDefs.h:122
File: IccStructBasic.h.
IIccStruct * icGetTagStructHandlerOfType(CIccTag *pTag, icStructSignature sig)
icValidateStatus icMaxStatus(icValidateStatus s1, icValidateStatus s2)
Name: icMaxStatus.
Definition IccUtil.cpp:244
std::string icGetSigPath(icUInt32Number nSig)
Definition IccUtil.cpp:1191
icUInt32Number icGetSpaceSamples(icColorSpaceSignature sig)
Definition IccUtil.cpp:1303
icFloatNumber icRmsDif(const icFloatNumber *v1, const icFloatNumber *v2, icUInt32Number nSample)
Definition IccUtil.cpp:532
icFloatNumber icDeltaE(const icFloatNumber *lab1, const icFloatNumber *lab2)
Definition IccUtil.cpp:527
void icXYZtoLab(icFloatNumber *Lab, const icFloatNumber *XYZ, const icFloatNumber *WhiteXYZ)
Definition IccUtil.cpp:846
File: IccUtil.h.
unsigned int icUInt32Number
Class: CIccArrayColorantInfo.
virtual void Describe(std::string &sDescription, int nVerboseness) const
CIccArrayColorantInfo(CIccTagArray *pTagArray=NULL)
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
virtual IIccArray * NewCopy(CIccTagArray *pTagArray) const
Class: CIccArrayNamedColor.
icColorSpaceSignature m_csDevice
icSpectralColorSignature m_csSpectralPcs
icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
CIccStructNamedColor * FindColor(const icChar *szColor) const
bool GetSpectralTint(icFloatNumber *dstColor, const CIccStructNamedColor *pColor, icFloatNumber tint=1.0f, icNamedColorlMemberSignature sig=icSigNmclSpectralDataMbr) const
CIccArrayNamedColor(CIccTagArray *pTagArray=NULL)
virtual IIccArray * NewCopy(CIccTagArray *pTagArray) const
icSpectralRange m_spectralRange
CIccStructNamedColor * FindSpectralColor(const icFloatNumber *pSpec, icFloatNumber dMinRms=1000.0) const
void SetColorSpaces(icColorSpaceSignature csPcs, icColorSpaceSignature csDevice, icSpectralColorSignature csSpectralPCS=icSigNoSpectralData, const icSpectralRange *pSpectralRange=NULL, const icSpectralRange *pBiSPectralRange=NULL)
CIccStructNamedColor * FindDeviceColor(const icFloatNumber *pDevColor) const
CIccStructNamedColor * FindPcsColor(const icFloatNumber *pPCS, icFloatNumber dMinDE=1000.0) const
icColorSpaceSignature m_csPcs
icSpectralRange m_biSpectralRange
virtual void Describe(std::string &sDescription, int nVerboseness) const
bool GetDeviceTint(icFloatNumber *dstColor, const CIccStructNamedColor *pColor, icFloatNumber tint=1.0f, icNamedColorlMemberSignature sig=icSigNmclDeviceDataMbr) const
bool GetPcsTint(icFloatNumber *dstColor, const CIccStructNamedColor *pColor, icFloatNumber tint=1.0f, icNamedColorlMemberSignature sig=icSigNmclPcsDataMbr) const
Class: CIccArrayUnknown.
virtual void Describe(std::string &sDescription, int nVerboseness) const
CIccArrayUnknown(CIccTagArray *pTagArray=NULL, icArraySignature sigArray=(icArraySignature) 0)
virtual ~CIccArrayUnknown()
virtual IIccArray * NewCopy(CIccTagArray *pTagArray) const
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Class: CIccStructNamedColor.
CIccTagNumArray * GetNumArray(icSignature sigElem) const
bool GetTint(icFloatNumber *dstColor, icFloatNumber tint, CIccTagNumArray *pZero, icSignature sigElem, icUInt32Number nSamples) const
std::string getName() const
CIccTag * GetElem(icSignature sigElem) const
Class: CIccTagArray.
Class: CIccTag.
virtual icTagTypeSignature GetType() const
Function: GetType()
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Function: Validate Each derived tag will implement it's own IsValid() function.
virtual bool IsNumArrayType() const
virtual icStructSignature GetTagStructType() const
Class: CIccTagNumArray.
virtual bool GetValues(icFloatNumber *DstVector, icUInt32Number nStart=0, icUInt32Number nVectorSize=1) const =0
virtual icUInt32Number GetNumValues() const =0
virtual bool IsMatrixArray() const =0
Class: CIccTagSparseMatrixArray.
icUInt32Number GetChannelsPerMatrix() const
Class: CIccTagStruct.
IIccStruct * GetStructHandler()
Name: CIccTagStruct::GetStructHandler.
Class: IIccArray.
icColorSpaceSignature
Color Space Signatures.
@ icSigLabData
icNamedColorlMemberSignature
NamedColorStructure (icSigNamedColorStruct) Member Tag signatures.
@ icSigNmclPcsDataMbr
@ icSigNmclTintMbr
@ icSigNmclDeviceDataMbr
@ icSigNmclSpectralDataMbr
icStructSignature
Tag Structure type signatures.
@ icSigColorantInfoStruct
@ icSigTintZeroStruct
@ icSigNamedColorStruct
#define icSigUnknownData
icSpectralColorSignature
icSpectralColorSignature enumerations
@ icSigNoSpectralData
icArraySignature
Tag Array type signatures.
@ icSigColorantInfoArray
@ icSigNamedColorArray
spectral range