Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
IccMpeSpectral.cpp
Go to the documentation of this file.
1/** @file
2 File: IccMpeSpectral.cpp
3
4 Contains: Implementation of Basic Multi Processing Elements
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-2014 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 1-30-2006
68//
69//////////////////////////////////////////////////////////////////////
70
71#ifdef WIN32
72#pragma warning( disable: 4786) //disable warning in <list.h>
73#endif
74
75#include <stdio.h>
76#include <math.h>
77#include <string.h>
78#include <stdlib.h>
79#include "IccMpeBasic.h"
80#include "IccMpeSpectral.h"
81#include "IccIO.h"
82#include <map>
83#include "IccMatrixMath.h"
84#include "IccUtil.h"
85#include "IccCAM.h"
86
87#ifdef USEREFICCMAXNAMESPACE
88namespace refIccMAX {
89#endif
90
91/**
92 ******************************************************************************
93 * Name: CIccMpeSpectralMatrix::CIccMpeSpectralMatrix
94 *
95 * Purpose:
96 *
97 * Args:
98 *
99 * Return:
100 ******************************************************************************/
102{
103 m_nReserved = 0;
104 m_nReserved2 = 0;
105 m_nInputChannels = m_nOutputChannels = 0;
106 m_size = 0;
107 m_pMatrix = NULL;
108 m_pOffset = NULL;
109 m_pWhite = NULL;
110
111 m_Range.start=0;
112 m_Range.end=0;
113 m_Range.steps=0;
114
115 m_pApplyMtx = NULL;
116}
117
118
119/**
120 ******************************************************************************
121 * Name: CIccMpeSpectralMatrix::CIccMpeSpectralMatrix
122 *
123 * Purpose:
124 *
125 * Args:
126 *
127 * Return:
128 ******************************************************************************/
130{
131 m_nReserved = matrix.m_nReserved;
132 m_nReserved2 = matrix.m_nReserved2;
133
134 m_nInputChannels = matrix.m_nInputChannels;
135 m_nOutputChannels = matrix.m_nOutputChannels;
136
137 m_Range = matrix.m_Range;
138
139 m_size = matrix.m_size;
140 if(matrix.m_pMatrix) {
141 int num = m_size * sizeof(icFloatNumber);
142 m_pMatrix = (icFloatNumber*)malloc(num);
143 memcpy(m_pMatrix, matrix.m_pMatrix, num);
144 }
145 else
146 m_pMatrix = NULL;
147
148 if (matrix.m_pOffset) {
149 int num = m_Range.steps * sizeof(icFloatNumber);
150 m_pOffset = (icFloatNumber*)malloc(num);
151 memcpy(m_pOffset, matrix.m_pOffset, num);
152 }
153 else
154 m_pOffset = NULL;
155
156 if (matrix.m_pWhite) {
157 int num = m_Range.steps * sizeof(icFloatNumber);
158 m_pWhite = (icFloatNumber*)malloc(num);
159 memcpy(m_pWhite, matrix.m_pWhite, num);
160 }
161 else
162 m_pWhite = NULL;
163
164 m_pApplyMtx = NULL;
165}
166
167/**
168 ******************************************************************************
169 * Name: &CIccMpeSpectralMatrix::operator=
170 *
171 * Purpose:
172 *
173 * Args:
174 *
175 * Return:
176 ******************************************************************************/
178{
179 m_nReserved = matrix.m_nReserved;
180 m_nReserved2 = matrix.m_nReserved2;
181
182 m_nInputChannels = matrix.m_nInputChannels;
183 m_nOutputChannels = matrix.m_nOutputChannels;
184
185 m_Range = m_Range;
186
187 if (m_pMatrix)
188 free(m_pMatrix);
189
190 m_size = matrix.m_size;
191 if (matrix.m_pMatrix) {
192 int num = m_size * sizeof(icFloatNumber);
193 m_pMatrix = (icFloatNumber*)malloc(num);
194 memcpy(m_pMatrix, matrix.m_pMatrix, num);
195 }
196 else
197 m_pMatrix = NULL;
198
199 if (m_pOffset)
200 free(m_pOffset);
201
202 if (matrix.m_pOffset) {
203 int num = m_Range.steps * sizeof(icFloatNumber);
204 m_pOffset = (icFloatNumber*)malloc(num);
205 memcpy(m_pOffset, matrix.m_pOffset, num);
206 }
207 else
208 m_pOffset = NULL;
209
210 if (m_pWhite)
211 free(m_pWhite);
212
213 if (matrix.m_pWhite) {
214 int num = m_Range.steps * sizeof(icFloatNumber);
215 m_pWhite = (icFloatNumber*)malloc(num);
216 memcpy(m_pWhite, matrix.m_pWhite, num);
217 }
218 else
219 m_pWhite = NULL;
220
221 m_pApplyMtx = NULL;
222}
223
224/**
225 ******************************************************************************
226 * Name: CIccMpeSpectralMatrix::~CIccMpeSpectralMatrix
227 *
228 * Purpose:
229 *
230 * Args:
231 *
232 * Return:
233 ******************************************************************************/
235{
236 if (m_pMatrix)
237 free(m_pMatrix);
238
239 if (m_pOffset)
240 free(m_pOffset);
241
242 if (m_pWhite)
243 free(m_pWhite);
244
245 if (m_pApplyMtx)
246 delete m_pApplyMtx;
247}
248
249
250/**
251 ******************************************************************************
252 * Name: CIccMpeSpectralMatrix::SetSize
253 *
254 * Purpose:
255 *
256 * Args:
257 *
258 * Return:
259 ******************************************************************************/
260bool CIccMpeSpectralMatrix::SetSize(icUInt16Number nInputChannels, icUInt16Number nOutputChannels, const icSpectralRange &range)
261{
262 if (m_pMatrix) {
263 free(m_pMatrix);
264 m_pMatrix = NULL;
265 }
266
267 if (m_pWhite) {
268 free(m_pWhite);
269 m_pWhite = NULL;
270 }
271
272 if (m_pOffset) {
273 free(m_pOffset);
274 m_pOffset = NULL;
275 }
276
277 if (m_pApplyMtx) {
278 delete m_pApplyMtx;
279 m_pApplyMtx = NULL;
280 }
281
282 m_nInputChannels = nInputChannels;
283 m_nOutputChannels = nOutputChannels;
284 m_Range = range;
285
286 m_size = (icUInt32Number)numVectors() * range.steps;
287
288 m_pMatrix = (icFloatNumber*)calloc(m_size, sizeof(icFloatNumber));
289 m_pOffset = (icFloatNumber*)calloc(range.steps, sizeof(icFloatNumber));
290 m_pWhite = (icFloatNumber*)calloc(range.steps, sizeof(icFloatNumber));
291
292 if (!m_pMatrix || !m_pOffset || !m_pWhite) {
293 m_size = 0;
294 return false;
295 }
296
297 return true;
298}
299
300/**
301 ******************************************************************************
302 * Name: CIccMpeSpectralMatrix::Describe
303 *
304 * Purpose:
305 *
306 * Args:
307 *
308 * Return:
309 ******************************************************************************/
310void CIccMpeSpectralMatrix::Describe(std::string &sDescription, int nVerboseness)
311{
312 icChar buf[81];
313 int i, j;
314 icFloatNumber *data = m_pMatrix;
315
316 sprintf(buf, "BEGIN_%s %d %d \n", GetDescribeName(), m_nInputChannels, m_nOutputChannels);
317 sDescription += buf;
318
319 sprintf(buf, "RANGE %f %f %d\n", icF16toF(m_Range.start), icF16toF(m_Range.end), m_Range.steps);
320 sDescription += buf;
321
322 sDescription += "White\n";
323 for (j=0; j<(int)m_Range.steps; j++) {
324 if (j)
325 sDescription += " ";
326 sprintf(buf, "%12.8lf", m_pWhite[j]);
327 sDescription += buf;
328 }
329 sDescription += "\n";
330
331 sDescription += "BLACK_OFFSET\n";
332 for (j=0; j<(int)m_Range.steps; j++) {
333 if (j)
334 sDescription += " ";
335 sprintf(buf, "%12.8lf", m_pOffset[j]);
336 sDescription += buf;
337 }
338 sDescription += "\n";
339
340 if (data) {
341 sDescription += "CHANNEL_DATA\n";
342 for (j=0; j<m_nOutputChannels; j++) {
343 for (i=0; i<(int)m_Range.steps; i++) {
344 if (i)
345 sDescription += " ";
346 sprintf(buf, "%12.8lf", data[i]);
347 sDescription += buf;
348 }
349 sDescription += "\n";
350 data += m_nInputChannels;
351 }
352 }
353
354 sprintf(buf, "END_%s\n", GetDescribeName());
355 sDescription += buf;
356}
357
358/**
359 ******************************************************************************
360 * Name: CIccMpeSpectralMatrix::Read
361 *
362 * Purpose:
363 *
364 * Args:
365 *
366 * Return:
367 ******************************************************************************/
369{
371
372 icUInt32Number headerSize = sizeof(icElemTypeSignature) +
373 sizeof(icUInt32Number) +
374 sizeof(icUInt16Number) +
375 sizeof(icUInt16Number) +
376 sizeof(icUInt16Number) +
377 sizeof(icUInt16Number) +
378 sizeof(icUInt16Number) +
379 sizeof(icUInt16Number);
380
381 if (headerSize > size)
382 return false;
383
384 if (!pIO) {
385 return false;
386 }
387
388 icUInt16Number nInputChannels, nOutputChannels;
389 icSpectralRange range;
390
391 if (!pIO->Read32(&sig))
392 return false;
393
394 if (!pIO->Read32(&m_nReserved))
395 return false;
396
397 if (!pIO->Read16(&nInputChannels))
398 return false;
399
400 if (!pIO->Read16(&nOutputChannels))
401 return false;
402
403 if (!pIO->Read16(&range.start))
404 return false;
405
406 if (!pIO->Read16(&range.end))
407 return false;
408
409 if (!pIO->Read16(&range.steps))
410 return false;
411
412 if (!pIO->Read16(&m_nReserved2))
413 return false;
414
415 SetSize(nInputChannels, nOutputChannels, range);
416 if (!m_pWhite || !m_pMatrix || !m_pOffset)
417 return false;
418
419 if (size<headerSize + (int)range.steps*sizeof(icFloatNumber))
420 return false;
421
422 //Read White data
423 if (pIO->ReadFloat32Float(m_pWhite, range.steps)!=range.steps)
424 return false;
425
426 if (size<headerSize + (int)range.steps*sizeof(icFloatNumber) + m_size * sizeof(icFloatNumber))
427 return false;
428
429 //Read Matrix data
430 if (pIO->ReadFloat32Float(m_pMatrix, m_size)!=(icInt32Number)m_size)
431 return false;
432
433 if (size>=headerSize + 2*(int)range.steps*sizeof(icFloatNumber) + m_size * sizeof(icFloatNumber)) {
434 if (pIO->ReadFloat32Float(m_pOffset, range.steps)!=range.steps)
435 return false;
436 }
437 else {
438 memset(m_pOffset, 0, (int)range.steps*sizeof(icFloatNumber));
439 }
440
441 return true;
442}
443
444/**
445 ******************************************************************************
446 * Name: CIccMpeSpectralMatrix::Write
447 *
448 * Purpose:
449 *
450 * Args:
451 *
452 * Return:
453 ******************************************************************************/
455{
456 icElemTypeSignature sig = GetType();
457
458 if (!pIO)
459 return false;
460
461 if (!pIO->Write32(&sig))
462 return false;
463
464 if (!pIO->Write32(&m_nReserved))
465 return false;
466
467 if (!pIO->Write16(&m_nInputChannels))
468 return false;
469
470 if (!pIO->Write16(&m_nOutputChannels))
471 return false;
472
473 if (!pIO->Write16(&m_Range.start))
474 return false;
475
476 if (!pIO->Write16(&m_Range.end))
477 return false;
478
479 if (!pIO->Write16(&m_Range.steps))
480 return false;
481
482 if (!pIO->Write16(&m_nReserved2))
483 return false;
484
485 if (m_pWhite) {
486 if (pIO->WriteFloat32Float(m_pWhite, m_Range.steps)!=m_Range.steps)
487 return false;
488 }
489 else if (m_Range.steps) {
490 return false;
491 }
492
493 if (m_pMatrix) {
494 if (pIO->WriteFloat32Float(m_pMatrix, m_size)!=(icInt32Number)m_size)
495 return false;
496 }
497
498 //Write Constant data
499 if (m_pOffset) {
500 if (pIO->WriteFloat32Float(m_pOffset, m_Range.steps)!=m_Range.steps)
501 return false;
502 }
503
504 return true;
505}
506
507/**
508 ******************************************************************************
509 * Name: CIccMpeSpectralMatrix::Validate
510 *
511 * Purpose:
512 *
513 * Args:
514 *
515 * Return:
516 ******************************************************************************/
517icValidateStatus CIccMpeSpectralMatrix::Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement* pMPE/*=NULL*/, const CIccProfile *pProfile/*=NULL*/) const
518{
519 std::string mpeSigPath = sigPath + icGetSigPath(GetType());
520 icValidateStatus rv = CIccMultiProcessElement::Validate(sigPath, sReport, pMPE, pProfile);
521
522 if (!m_Range.steps) {
523 CIccInfo Info;
524 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
525
527 sReport += sSigPathName;
528 sReport += " - Cannot have zero spectral range steps!\n";
530 }
531
532 if (m_nOutputChannels != 3) {
533 CIccInfo Info;
534 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
535
537 sReport += sSigPathName;
538 sReport += " - Output Channels must be 3!\n";
540 }
541
542 if (!m_pWhite) {
543 CIccInfo Info;
544 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
545
547 sReport += sSigPathName;
548 sReport += " - Has Empty White data!\n";
550 }
551
552 if (!m_pMatrix) {
553 CIccInfo Info;
554 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
555
557 sReport += sSigPathName;
558 sReport += " - Has Empty Matrix data!\n";
560 }
561
562 if (!m_pOffset) {
563 CIccInfo Info;
564 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
565
567 sReport += sSigPathName;
568 sReport += " - Has Empty Matrix Constant data!\n";
570 }
571
572 if (m_Range.start>= m_Range.end || !m_Range.steps) {
573 CIccInfo Info;
574 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
575
577 sReport += sSigPathName;
578 sReport += " - Has an invalid spectral range!\n";
580 }
581
582 return rv;
583}
584
585/**
586 ******************************************************************************
587 * Name: CIccMpeEmissionMatrix::Begin
588 *
589 * Purpose:
590 *
591 * Args:
592 *
593 * Return:
594 ******************************************************************************/
596{
597 if (!m_pOffset ||!pMPE || !m_pMatrix || m_nOutputChannels != 3)
598 return false;
599
600 IIccProfileConnectionConditions *pAppliedPCC = pMPE->GetAppliedPCC();
601 if (!pAppliedPCC)
602 return false;
603
605 if (!pSVC)
606 return false;
607
608 CIccMatrixMath observer(3, m_Range.steps);
609 icFloat32Number *pSrc, *pMtx;
610
611 if (!pAppliedPCC->getEmissiveObserver(m_Range, m_pWhite, observer.entry(0)))
612 return false;
613
614 //convert m_Matrix emission values to a matrix of XYZ column vectors
615 m_pApplyMtx = new CIccMatrixMath(3,m_nInputChannels);
616
617 if (!m_pApplyMtx)
618 return false;
619
620 icFloatNumber xyz[3];
621 int i;
622
623 pSrc = m_pMatrix;
624 pMtx = m_pApplyMtx->entry(0);
625 for (i=0; i<m_nInputChannels; i++) {
626 observer.VectorMult(xyz, pSrc);
627 pSrc += m_Range.steps;
628
629 pMtx[0] = xyz[0];
630 pMtx[m_nInputChannels] = xyz[1];
631 pMtx[2*m_nInputChannels] = xyz[2];
632 pMtx++;
633 }
634
635 //Now convert offset emission to XYZ offset
636 observer.VectorMult(m_xyzOffset, m_pOffset);
637
638 return true;
639}
640
641/**
642 ******************************************************************************
643 * Name: CIccMpeEmissionMatrix::Apply
644 *
645 * Purpose:
646 *
647 * Args:
648 *
649 * Return:
650 ******************************************************************************/
651void CIccMpeEmissionMatrix::Apply(CIccApplyMpe *pApply, icFloatNumber *dstPixel, const icFloatNumber *srcPixel) const
652{
653 if (m_pApplyMtx) {
654 m_pApplyMtx->VectorMult(dstPixel, srcPixel);
655 dstPixel[0] += m_xyzOffset[0];
656 dstPixel[1] += m_xyzOffset[1];
657 dstPixel[2] += m_xyzOffset[2];
658 }
659 else {
660 dstPixel[0] = 0;
661 dstPixel[1] = 0;
662 dstPixel[2] = 0;
663 }
664}
665
666
667/**
668 ******************************************************************************
669 * Name: CIccMpeInvEmissionMatrix::Begin
670 *
671 * Purpose:
672 *
673 * Args:
674 *
675 * Return:
676 ******************************************************************************/
678{
679 if (!m_pOffset ||!pMPE || !m_pMatrix || m_nInputChannels != 3 || m_nOutputChannels != 3)
680 return false;
681
682 IIccProfileConnectionConditions *pAppliedPCC = pMPE->GetAppliedPCC();
683 if (!pAppliedPCC)
684 return false;
685
687 if (!pSVC)
688 return false;
689
690 CIccMatrixMath observer(3, m_Range.steps);
691 icFloat32Number *pSrc, *pMtx;
692
693 if (!pAppliedPCC->getEmissiveObserver(m_Range, m_pWhite, observer.entry(0)))
694 return false;
695
696 observer.VectorMult(m_xyzOffset, m_pOffset);
697
698 //convert m_Matrix emission values to a matrix of XYZ column vectors
699 m_pApplyMtx = new CIccMatrixMath(3,m_nInputChannels);
700
701 if (!m_pApplyMtx)
702 return false;
703
704 icFloatNumber xyz[3];
705 int i;
706
707 pSrc = m_pMatrix;
708 pMtx = m_pApplyMtx->entry(0);
709 for (i=0; i<m_nInputChannels; i++) {
710 observer.VectorMult(xyz, pSrc);
711 pSrc += m_Range.steps;
712
713 pMtx[0] = xyz[0];
714 pMtx[m_nInputChannels] = xyz[1];
715 pMtx[2*m_nInputChannels] = xyz[2];
716 pMtx++;
717 }
718
719 m_pApplyMtx->Invert();
720
721 return true;
722}
723
724/**
725 ******************************************************************************
726 * Name: CIccMpeInvEmissionMatrix::Apply
727 *
728 * Purpose:
729 *
730 * Args:
731 *
732 * Return:
733 ******************************************************************************/
734void CIccMpeInvEmissionMatrix::Apply(CIccApplyMpe *pApply, icFloatNumber *dstPixel, const icFloatNumber *srcPixel) const
735{
736 if (m_pApplyMtx) {
737 icFloatNumber xyz[3];
738 xyz[0] = srcPixel[0] - m_xyzOffset[0];
739 xyz[1] = srcPixel[1] - m_xyzOffset[1];
740 xyz[2] = srcPixel[2] - m_xyzOffset[2];
741 m_pApplyMtx->VectorMult(dstPixel, xyz);
742 }
743 else {
744 dstPixel[0] = 0;
745 dstPixel[1] = 0;
746 dstPixel[2] = 0;
747 }
748}
749
750/**
751 ******************************************************************************
752 * Name: CIccMpeInvEmissionMatrix::Validate
753 *
754 * Purpose:
755 *
756 * Args:
757 *
758 * Return:
759 ******************************************************************************/
760icValidateStatus CIccMpeInvEmissionMatrix::Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement* pMPE/*=NULL*/, const CIccProfile *pProfile/*=NULL*/) const
761{
762 std::string mpeSigPath = sigPath + icGetSigPath(GetType());
763 icValidateStatus rv = CIccMpeSpectralMatrix::Validate(sigPath, sReport, pMPE, pProfile);
764
765 if (m_nInputChannels != 3) {
766 CIccInfo Info;
767 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
768
770 sReport += sSigPathName;
771 sReport += " - Input Channels must be 3!\n";
773 }
774
775 return rv;
776}
777
779{
780 return v;
781}
782
783
784
785/**
786 ******************************************************************************
787 * Name: CIccMpeSpectralCLUT::CIccMpeSpectralCLUT
788 *
789 * Purpose:
790 *
791 * Args:
792 *
793 * Return:
794 ******************************************************************************/
796{
797 m_nInputChannels = 0;
798 m_nOutputChannels = 0;
799
800 m_nReserved = 0;
801
802 m_Range.start = 0;
803 m_Range.end = 0;
804 m_Range.steps = 0;
805
806 m_nStorageType = icValueTypeFloat32;
807 m_flags = 0;
808
809 m_pCLUT = NULL;
810 m_pApplyCLUT = NULL;
811 m_pWhite = NULL;
812}
813
814/**
815 ******************************************************************************
816 * Name: CIccMpeSpectralCLUT::CIccMpeSpectralCLUT
817 *
818 * Purpose:
819 *
820 * Args:
821 *
822 * Return:
823 ******************************************************************************/
825{
826 if (clut.m_pCLUT)
827 m_pCLUT = new CIccCLUT(*clut.m_pCLUT);
828 else
829 m_pCLUT = NULL;
830
831 if (clut.m_pApplyCLUT)
832 m_pApplyCLUT = new CIccCLUT(*clut.m_pApplyCLUT);
833 else
834 m_pApplyCLUT = NULL;
835
836 if (clut.m_pWhite) {
837 m_pWhite = (icFloatNumber *)malloc((int)clut.m_Range.steps*sizeof(icFloatNumber));
838 memcpy(m_pWhite, clut.m_pWhite, clut.m_Range.steps*sizeof(icFloatNumber));
839 }
840 else
841 m_pWhite = NULL;
842
843 m_nReserved = clut.m_nReserved;
844 m_nInputChannels = clut.m_nInputChannels;
845 m_nOutputChannels = clut.m_nOutputChannels;
846
847 m_Range = clut.m_Range;
848 m_nStorageType = clut.m_nStorageType;
849 m_flags = clut.m_flags;
850}
851
852/**
853 ******************************************************************************
854 * Name: &CIccMpeSpectralCLUT::operator=
855 *
856 * Purpose:
857 *
858 * Args:
859 *
860 * Return:
861 ******************************************************************************/
863{
864 if (m_pCLUT)
865 delete m_pCLUT;
866
867 if (m_pApplyCLUT)
868 delete m_pApplyCLUT;
869
870 if (m_pWhite)
871 free(m_pWhite);
872
873 if (clut.m_pCLUT)
874 m_pCLUT = new CIccCLUT(*clut.m_pCLUT);
875 else
876 m_pCLUT = NULL;
877
878 if (clut.m_pApplyCLUT)
879 m_pApplyCLUT = new CIccCLUT(*clut.m_pApplyCLUT);
880 else
881 m_pApplyCLUT = NULL;
882
883 if (clut.m_pWhite) {
884 m_pWhite = (icFloatNumber *)malloc((int)clut.m_Range.steps*sizeof(icFloatNumber));
885 memcpy(m_pWhite, clut.m_pWhite, clut.m_Range.steps*sizeof(icFloatNumber));
886 }
887 else
888 m_pWhite = NULL;
889
890 m_nReserved = clut.m_nReserved;
891 m_nInputChannels = clut.m_nInputChannels;
892 m_nOutputChannels = clut.m_nOutputChannels;
893
894 m_Range = clut.m_Range;
895 m_nStorageType = clut.m_nStorageType;
896 m_flags = clut.m_flags;
897}
898
899/**
900 ******************************************************************************
901 * Name: CIccMpeSpectralCLUT::~CIccMpeSpectralCLUT
902 *
903 * Purpose:
904 *
905 * Args:
906 *
907 * Return:
908 ******************************************************************************/
910{
911 if (m_pCLUT)
912 delete m_pCLUT;
913
914 if (m_pApplyCLUT)
915 delete m_pApplyCLUT;
916
917 if (m_pWhite)
918 free(m_pWhite);
919
920}
921
922/**
923 ******************************************************************************
924 * Name: CIccMpeSpectralCLUT::SetCLUT
925 *
926 * Purpose:
927 *
928 * Args:
929 *
930 * Return:
931 ******************************************************************************/
933 const icSpectralRange &range, icFloatNumber *pWhite,
934 icUInt16Number nOutputChannels)
935{
936 if (m_pCLUT)
937 delete m_pCLUT;
938
939 m_pCLUT = pCLUT;
940 if (pCLUT) {
941 pCLUT->SetClipFunc(NoClip);
942 m_nInputChannels = pCLUT->GetInputDim();
943 m_nOutputChannels = nOutputChannels;
944 }
945
946 m_nStorageType = nStorageType;
947
948 if (m_pApplyCLUT) {
949 delete m_pApplyCLUT;
950 m_pApplyCLUT = NULL;
951 }
952
953 m_Range = range;
954
955 if (m_pWhite)
956 free(m_pWhite);
957
958 m_pWhite = pWhite;
959}
960
961/**
962 ******************************************************************************
963 * Name: CIccMpeSpectralCLUT::Describe
964 *
965 * Purpose:
966 *
967 * Args:
968 *
969 * Return:
970 ******************************************************************************/
971void CIccMpeSpectralCLUT::Describe(std::string &sDescription, int nVerboseness)
972{
973 if (m_pCLUT) {
974 m_pCLUT->DumpLut(sDescription, GetDescribeName(), icSigUnknownData, icSigUnknownData, nVerboseness);
975 }
976}
977
978
979/**
980******************************************************************************
981* Name: CIccMpeSpectralCLUT::Read
982*
983* Purpose:
984*
985* Args:
986*
987* Return:
988******************************************************************************/
990{
992
993 icUInt32Number headerSize = sizeof(icTagTypeSignature) +
994 sizeof(icUInt32Number) +
995 sizeof(icUInt32Number) +
996 sizeof(icUInt16Number) +
997 sizeof(icUInt16Number) +
998 sizeof(icUInt16Number) +
999 sizeof(icUInt16Number) +
1000 sizeof(icUInt16Number) +
1001 sizeof(icUInt16Number) +
1002 16 * sizeof(icUInt8Number);
1003
1004 if (headerSize > size)
1005 return false;
1006
1007 if (!pIO) {
1008 return false;
1009 }
1010
1011 if (!pIO->Read32(&sig))
1012 return false;
1013
1014 if (!pIO->Read32(&m_nReserved))
1015 return false;
1016
1017 if (!pIO->Read16(&m_nInputChannels))
1018 return false;
1019
1020 if (!pIO->Read16(&m_nOutputChannels))
1021 return false;
1022
1023 if (!pIO->Read32(&m_flags))
1024 return false;
1025
1026 if (!pIO->Read16(&m_Range.start))
1027 return false;
1028
1029 if (!pIO->Read16(&m_Range.end))
1030 return false;
1031
1032 if (!pIO->Read16(&m_Range.steps))
1033 return false;
1034
1035 if (!pIO->Read16(&m_nStorageType))
1036 return false;
1037
1038 icUInt8Number gridPoints[16];
1039
1040 if (pIO->Read8(gridPoints, 16)!=16) {
1041 return false;
1042 }
1043
1044 m_pCLUT = new CIccCLUT((icUInt8Number)m_nInputChannels, (icUInt16Number)m_Range.steps, 4);
1045
1046 if (!m_pCLUT)
1047 return false;
1048
1049 m_pCLUT->SetClipFunc(NoClip);
1050 icUInt32Number nBytesPerPoint = icGetStorageTypeBytes(m_nStorageType) * m_Range.steps;
1051
1052 if (!nBytesPerPoint)
1053 return false;
1054
1055 m_pCLUT->Init(gridPoints, size - headerSize, (icUInt8Number)nBytesPerPoint);
1056
1057 icFloatNumber *pData = m_pCLUT->GetData(0);
1058
1059 if (!pData)
1060 return false;
1061
1062 icInt32Number nPoints = m_pCLUT->NumPoints()*(int)m_Range.steps;
1063
1064 switch(m_nStorageType) {
1065 case icValueTypeUInt8:
1066 if (pIO->ReadUInt8Float(pData,nPoints)!= nPoints)
1067 return false;
1068 break;
1069
1070 case icValueTypeUInt16:
1071 if (pIO->ReadUInt16Float(pData,nPoints)!= nPoints)
1072 return false;
1073 break;
1074
1075 case icValueTypeFloat16:
1076 if (pIO->ReadFloat16Float(pData,nPoints)!= nPoints)
1077 return false;
1078 break;
1079
1080 case icValueTypeFloat32:
1081 if (pIO->ReadFloat32Float(pData,nPoints)!= nPoints)
1082 return false;
1083 break;
1084
1085 default:
1086 return false;
1087 }
1088
1089 if (m_Range.steps *nBytesPerPoint > size - headerSize - nPoints*nBytesPerPoint)
1090 return false;
1091
1092 m_pWhite = (icFloatNumber *)malloc((int)m_Range.steps*sizeof(icFloatNumber));
1093 if (!m_pWhite)
1094 return false;
1095
1096 switch(m_nStorageType) {
1097 case icValueTypeUInt8:
1098 if (pIO->ReadUInt8Float(m_pWhite,m_Range.steps)!= m_Range.steps)
1099 return false;
1100 break;
1101
1102 case icValueTypeUInt16:
1103 if (pIO->ReadUInt16Float(m_pWhite,m_Range.steps)!= m_Range.steps)
1104 return false;
1105 break;
1106
1107 case icValueTypeFloat16:
1108 if (pIO->ReadFloat16Float(m_pWhite,m_Range.steps)!= m_Range.steps)
1109 return false;
1110 break;
1111
1112 case icValueTypeFloat32:
1113 if (pIO->ReadFloat32Float(m_pWhite,m_Range.steps)!= m_Range.steps)
1114 return false;
1115 break;
1116
1117 default:
1118 return false;
1119 }
1120
1121
1122 return true;
1123}
1124
1125/**
1126******************************************************************************
1127* Name: CIccMpeSpectralCLUT::Write
1128*
1129* Purpose:
1130*
1131* Args:
1132*
1133* Return:
1134******************************************************************************/
1136{
1137 icElemTypeSignature sig = GetType();
1138
1139 if (!pIO)
1140 return false;
1141
1142 if (!pIO->Write32(&sig))
1143 return false;
1144
1145 if (!pIO->Write32(&m_nReserved))
1146 return false;
1147
1148 if (!pIO->Write16(&m_nInputChannels))
1149 return false;
1150
1151 if (!pIO->Write16(&m_nOutputChannels))
1152 return false;
1153
1154 if (!pIO->Write32(&m_flags))
1155 return false;
1156
1157 if (!pIO->Write16(&m_Range.start))
1158 return false;
1159
1160 if (!pIO->Write16(&m_Range.end))
1161 return false;
1162
1163 if (!pIO->Write16(&m_Range.steps))
1164 return false;
1165
1166 if (!pIO->Write16(&m_nStorageType))
1167 return false;
1168
1169 if (m_pCLUT) {
1170 icUInt8Number gridPoints[16];
1171 int i;
1172
1173 for (i=0; i<16; i++)
1174 gridPoints[i] = m_pCLUT->GridPoint(i);
1175
1176 if (pIO->Write8(gridPoints, 16)!=16)
1177 return false;
1178
1179 icFloatNumber *pData = m_pCLUT->GetData(0);
1180 icInt32Number nPoints = m_pCLUT->NumPoints()*(int)m_Range.steps;
1181
1182 switch(m_nStorageType) {
1183 case icValueTypeUInt8:
1184 if (pIO->WriteUInt8Float(pData,nPoints)!= nPoints)
1185 return false;
1186 break;
1187
1188 case icValueTypeUInt16:
1189 if (pIO->WriteUInt16Float(pData,nPoints)!= nPoints)
1190 return false;
1191 break;
1192
1193 case icValueTypeFloat16:
1194 if (pIO->WriteFloat16Float(pData,nPoints)!= nPoints)
1195 return false;
1196 break;
1197
1198 case icValueTypeFloat32:
1199 if (pIO->WriteFloat32Float(pData,nPoints)!= nPoints)
1200 return false;
1201 break;
1202
1203 default:
1204 return false;
1205 }
1206 }
1207
1208 if (m_pWhite) {
1209 switch(m_nStorageType) {
1210 case icValueTypeUInt8:
1211 if (pIO->WriteUInt8Float(m_pWhite, m_Range.steps)!= m_Range.steps)
1212 return false;
1213 break;
1214
1215 case icValueTypeUInt16:
1216 if (pIO->WriteUInt16Float(m_pWhite, m_Range.steps)!= m_Range.steps)
1217 return false;
1218 break;
1219
1220 case icValueTypeFloat16:
1221 if (pIO->WriteFloat16Float(m_pWhite, m_Range.steps)!= m_Range.steps)
1222 return false;
1223 break;
1224
1225 case icValueTypeFloat32:
1226 if (pIO->WriteFloat32Float(m_pWhite, m_Range.steps)!= m_Range.steps)
1227 return false;
1228 break;
1229
1230 default:
1231 return false;
1232 }
1233 }
1234 else if (m_Range.steps) {
1235 return false;
1236 }
1237
1238 return true;
1239}
1240
1241/**
1242******************************************************************************
1243* Name: CIccMpeSpectralCLUT::GetNewApply
1244*
1245* Purpose:
1246*
1247* Args:
1248*
1249* Return:
1250******************************************************************************/
1252{
1253 if (!m_pCLUT) {
1254 return NULL;
1255 }
1256
1257 CIccApplyCLUT* pApply = m_pCLUT->GetNewApply();
1258 if (!pApply)
1259 return NULL;
1260
1261 CIccApplyMpeSpectralCLUT* rv = new CIccApplyMpeSpectralCLUT(this, pApply);
1262 if (!rv)
1263 delete pApply;
1264
1265 return rv;
1266}
1267
1268/**
1269 ******************************************************************************
1270 * Name: CIccMpeEmissionCLUT::Apply
1271 *
1272 * Purpose:
1273 *
1274 * Args:
1275 *
1276 * Return:
1277 ******************************************************************************/
1278void CIccMpeSpectralCLUT::Apply(CIccApplyMpe *pApply, icFloatNumber *dstPixel, const icFloatNumber *srcPixel) const
1279{
1280 const CIccCLUT *pCLUT = m_pApplyCLUT;
1281
1282 switch(m_interpType) {
1283 case ic1dInterp:
1284 pCLUT->Interp1d(dstPixel, srcPixel);
1285 break;
1286 case ic2dInterp:
1287 pCLUT->Interp2d(dstPixel, srcPixel);
1288 break;
1289 case ic3dInterpTetra:
1290 pCLUT->Interp3dTetra(dstPixel, srcPixel);
1291 break;
1292 case ic3dInterp:
1293 pCLUT->Interp3d(dstPixel, srcPixel);
1294 break;
1295 case ic4dInterp:
1296 pCLUT->Interp4d(dstPixel, srcPixel);
1297 break;
1298 case ic5dInterp:
1299 pCLUT->Interp5d(dstPixel, srcPixel);
1300 break;
1301 case ic6dInterp:
1302 pCLUT->Interp6d(dstPixel, srcPixel);
1303 break;
1304 case icNdInterp:
1306 pCLUT->InterpND(dstPixel, srcPixel, pClutApply->m_pApply);
1307 break;
1308 }
1309}
1310
1311
1312/**
1313 ******************************************************************************
1314 * Name: CIccMpeSpectralCLUT::Validate
1315 *
1316 * Purpose:
1317 *
1318 * Args:
1319 *
1320 * Return:
1321 ******************************************************************************/
1322icValidateStatus CIccMpeSpectralCLUT::Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement* pMPE/*=NULL*/, const CIccProfile *pProfile/*=NULL*/) const
1323{
1324 std::string mpeSigPath = sigPath + icGetSigPath(GetType());
1325 icValidateStatus rv = CIccMultiProcessElement::Validate(sigPath, sReport, pMPE, pProfile);
1326
1327 if (m_nStorageType>icMaxValueType) {
1328 CIccInfo Info;
1329 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
1330
1331 sReport += icMsgValidateCriticalError;
1332 sReport += sSigPathName;
1333 sReport += " - Invalid storageType value!\n";
1335 }
1336
1337 if (!m_pCLUT) {
1338 CIccInfo Info;
1339 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
1340
1341 sReport += icMsgValidateCriticalError;
1342 sReport += sSigPathName;
1343 sReport += " - Has No CLUT!\n";
1345 }
1346
1347 if (!m_pWhite) {
1348 CIccInfo Info;
1349 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
1350
1351 sReport += icMsgValidateCriticalError;
1352 sReport += sSigPathName;
1353 sReport += " - Has Empty White data!\n";
1355 }
1356
1357 if (!m_Range.steps) {
1358 CIccInfo Info;
1359 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
1360
1361 sReport += icMsgValidateCriticalError;
1362 sReport += sSigPathName;
1363 sReport += " - Cannot have zero spectral range steps!\n";
1365 }
1366
1367 if (m_Range.start>= m_Range.end || !m_Range.steps) {
1368 CIccInfo Info;
1369 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
1370
1371 sReport += icMsgValidateCriticalError;
1372 sReport += sSigPathName;
1373 sReport += " - Has an invalid spectral range!\n";
1375 }
1376
1377 return rv;
1378}
1379
1380/**
1381**************************************************************************
1382* Name: CIccApplyMpeSpectralCLUT::CIccApplyMpeSpectralCLUT
1383*
1384* Purpose:
1385* Constructor
1386**************************************************************************
1387*/
1392
1393
1394/**
1395**************************************************************************
1396* Name: CIccApplyMpeSpectralCLUT::~CIccApplyMpeSpectralCLUT
1397*
1398* Purpose:
1399* Destructor
1400**************************************************************************
1401*/
1407
1408
1409
1410
1411/**
1412 ******************************************************************************
1413 * Name: CIccMpeEmissionCLUT::Begin
1414 *
1415 * Purpose:
1416 *
1417 * Args:
1418 *
1419 * Return:
1420 ******************************************************************************/
1422{
1424 return false;
1425
1426 switch (m_nInputChannels) {
1427 case 1:
1429 break;
1430 case 2:
1432 break;
1433 case 3:
1434 if (nInterp==icElemInterpTetra)
1436 else
1438 break;
1439 case 4:
1441 break;
1442 case 5:
1444 break;
1445 case 6:
1447 break;
1448 default:
1450 break;
1451 }
1452
1453 IIccProfileConnectionConditions *pAppliedPCC = pMPE->GetAppliedPCC();
1454 if (!pAppliedPCC)
1455 return false;
1456
1457 const CIccTagSpectralViewingConditions *pSVC = pAppliedPCC->getPccViewingConditions();
1458 if (!pSVC)
1459 return false;
1460
1461 CIccMatrixMath observer(3, m_Range.steps);
1462
1463 if (!pAppliedPCC->getEmissiveObserver(m_Range, m_pWhite, observer.entry(0)))
1464 return false;
1465
1466 if (m_pApplyCLUT)
1467 delete m_pApplyCLUT;
1468
1470
1471 if (!m_pApplyCLUT) {
1472 return false;
1473 }
1474
1477
1478 icFloatNumber *pSrc = m_pCLUT->GetData(0);
1480
1481 icFloatNumber xyzW[3];
1483
1484 observer.VectorMult(xyzW, m_pWhite);
1485
1486 bool bUseAbsolute = (m_flags & icRelativeSpectralData)!=0;
1487 bool bLab = (m_flags & icLabSpectralData) != 0;
1488
1489 for (i=0; i<m_pCLUT->NumPoints(); i++) {
1490 observer.VectorMult(pDst, pSrc);
1491 if (bLab) {
1492 icXYZtoLab(pDst, pDst, xyzW);
1493// icLabToPcs(pDst);
1494 }
1495 else {
1496// icXyzToPcs(pDst);
1497 }
1498 pSrc += m_Range.steps;
1499 pDst += m_nOutputChannels;
1500 }
1501
1503
1504 return true;
1505}
1506
1507
1508/**
1509 ******************************************************************************
1510 * Name: CIccMpeReflectanceCLUT::Begin
1511 *
1512 * Purpose:
1513 *
1514 * Args:
1515 *
1516 * Return:
1517 ******************************************************************************/
1519{
1521 return false;
1522
1523 switch (m_nInputChannels) {
1524 case 1:
1526 break;
1527 case 2:
1529 break;
1530 case 3:
1531 if (nInterp==icElemInterpTetra)
1533 else
1535 break;
1536 case 4:
1538 break;
1539 case 5:
1541 break;
1542 case 6:
1544 break;
1545 default:
1547 break;
1548 }
1549
1550 IIccProfileConnectionConditions *pAppliedPCC = pMPE->GetAppliedPCC();
1551 if (!pAppliedPCC)
1552 return false;
1553
1554 const CIccTagSpectralViewingConditions *pSVC = pAppliedPCC->getPccViewingConditions();
1555 if (!pSVC)
1556 return false;
1557
1558 CIccMatrixMath observer(3, m_Range.steps);
1559 icSpectralRange illumRange;
1560 const icFloatNumber *illum = pSVC->getIlluminant(illumRange);
1561
1562 if (!pAppliedPCC->getEmissiveObserver(illumRange, illum, observer.entry(0)))
1563 return false;
1564
1565 //
1566 icFloatNumber xyzi[3];
1567
1568 //apply illuminant to observer and calculate XYZ of illuminant
1569 icFloatNumber *pObs = observer.entry(0);
1570 int i, j;
1571 for (i=0; i<3; i++) {
1572 xyzi[i] = 0.0;
1573 for (j=0; j<illumRange.steps; j++) {
1574 *pObs *= illum[j];
1575 xyzi[i] += *pObs;
1576 pObs++;
1577 }
1578 }
1579
1580 //concatenate reflectance range mapping to observer+illuminant
1581 CIccMatrixMath *rangeRef = CIccMatrixMath::rangeMap(m_Range, illumRange);
1582 CIccMatrixMath *pApplyMtx;
1583 if (!rangeRef)
1584 pApplyMtx = &observer;
1585 else
1586 pApplyMtx = rangeRef->Mult(&observer);
1587
1588 if (m_pApplyCLUT)
1589 delete m_pApplyCLUT;
1590
1592
1593 if (!m_pApplyCLUT) {
1594 if (pApplyMtx!=&observer)
1595 delete pApplyMtx;
1596 return false;
1597 }
1598
1601
1602 icFloatNumber *pSrc = m_pCLUT->GetData(0);
1604
1605 icFloatNumber xyzW[3];
1606
1607 pApplyMtx->VectorMult(xyzW, m_pWhite);
1608
1609 bool bUseAbsolute = (m_flags & icRelativeSpectralData)!=0;
1610 bool bLab = (m_flags & icLabSpectralData) != 0;
1611
1612 icFloatNumber xyzscale[3];
1613 if (!bUseAbsolute) {
1614 xyzscale[0] = xyzi[0] / xyzW[0];
1615 xyzscale[1] = xyzi[1] / xyzW[1];
1616 xyzscale[2] = xyzi[2] / xyzW[2];
1617 }
1618
1619 for (i=0; i<(int)m_pCLUT->NumPoints(); i++) {
1620 pApplyMtx->VectorMult(pDst, pSrc);
1621
1622 if (!bUseAbsolute) {
1623 pDst[0] *= xyzscale[0];
1624 pDst[1] *= xyzscale[1];
1625 pDst[2] *= xyzscale[2];
1626 }
1627
1628 if (bLab) {
1629 icXYZtoLab(pDst, pDst, xyzi);
1630 // icLabToPcs(pDst);
1631 }
1632 else {
1633 // icXyzToPcs(pDst);
1634 }
1635 pSrc += m_Range.steps;
1636 pDst += m_nOutputChannels;
1637 }
1638
1639 if (pApplyMtx!=&observer)
1640 delete pApplyMtx;
1641
1643
1644 return true;
1645}
1646
1647
1648/**
1649 ******************************************************************************
1650 * Name: CIccMpeSpectralObserver::CIccMpeSpectralObserver
1651 *
1652 * Purpose:
1653 *
1654 * Args:
1655 *
1656 * Return:
1657 ******************************************************************************/
1659{
1660 m_nReserved = 0;
1662 m_pWhite = NULL;
1663
1664 m_Range.start=0;
1665 m_Range.end=0;
1666 m_Range.steps=0;
1667
1668 m_pApplyMtx = NULL;
1669}
1670
1671
1672/**
1673 ******************************************************************************
1674 * Name: CIccMpeSpectralObserver::CIccMpeSpectralObserver
1675 *
1676 * Purpose:
1677 *
1678 * Args:
1679 *
1680 * Return:
1681 ******************************************************************************/
1683{
1684 m_nReserved = matrix.m_nReserved;
1685
1688
1689 m_Range = matrix.m_Range;
1690
1691 if (matrix.m_pWhite) {
1692 int num = m_Range.steps*sizeof(icFloatNumber);
1693 m_pWhite = (icFloatNumber*)malloc(num);
1694 memcpy(m_pWhite, matrix.m_pWhite, num);
1695 }
1696 else
1697 m_pWhite = NULL;
1698
1699 m_pApplyMtx = NULL;
1700}
1701
1702/**
1703 ******************************************************************************
1704 * Name: &CIccMpeSpectralObserver::operator=
1705 *
1706 * Purpose:
1707 *
1708 * Args:
1709 *
1710 * Return:
1711 ******************************************************************************/
1713{
1714 m_nReserved = matrix.m_nReserved;
1715
1718
1719 m_Range = m_Range;
1720
1721 if (m_pWhite)
1722 free(m_pWhite);
1723
1724 if (matrix.m_pWhite) {
1725 int num = m_Range.steps*sizeof(icFloatNumber);
1726 m_pWhite = (icFloatNumber*)malloc(num);
1727 memcpy(m_pWhite, matrix.m_pWhite, num);
1728 }
1729 else
1730 m_pWhite = NULL;
1731
1732 m_pApplyMtx = NULL;
1733}
1734
1735/**
1736 ******************************************************************************
1737 * Name: CIccMpeSpectralObserver::~CIccMpeSpectralObserver
1738 *
1739 * Purpose:
1740 *
1741 * Args:
1742 *
1743 * Return:
1744 ******************************************************************************/
1746{
1747 if (m_pWhite)
1748 free(m_pWhite);
1749
1750 if (m_pApplyMtx)
1751 delete m_pApplyMtx;
1752}
1753
1754
1755/**
1756 ******************************************************************************
1757 * Name: CIccMpeSpectralObserver::SetSize
1758 *
1759 * Purpose:
1760 *
1761 * Args:
1762 *
1763 * Return:
1764 ******************************************************************************/
1765bool CIccMpeSpectralObserver::SetSize(icUInt16Number nInputChannels, icUInt16Number nOutputChannels, const icSpectralRange &range)
1766{
1767 if (m_pWhite) {
1768 free(m_pWhite);
1769 m_pWhite = NULL;
1770 }
1771
1772 if (m_pApplyMtx) {
1773 delete m_pApplyMtx;
1774 m_pApplyMtx = NULL;
1775 }
1776
1777 m_nInputChannels = nInputChannels;
1778 m_nOutputChannels = nOutputChannels;
1779 m_Range = range;
1780
1781 m_pWhite = (icFloatNumber*)calloc(range.steps, sizeof(icFloatNumber));
1782
1783 if (!m_pWhite)
1784 return false;
1785
1786 return true;
1787}
1788
1789/**
1790 ******************************************************************************
1791 * Name: CIccMpeSpectralObserver::Describe
1792 *
1793 * Purpose:
1794 *
1795 * Args:
1796 *
1797 * Return:
1798 ******************************************************************************/
1799void CIccMpeSpectralObserver::Describe(std::string &sDescription, int nVerboseness)
1800{
1801 icChar buf[81];
1802 int j;
1803
1804 sprintf(buf, "BEGIN_%s %d %d \n", GetDescribeName(), m_nInputChannels, m_nOutputChannels);
1805 sDescription += buf;
1806
1807 sprintf(buf, "RANGE %f %f %d\n", icF16toF(m_Range.start), icF16toF(m_Range.end), m_Range.steps);
1808 sDescription += buf;
1809
1810 sDescription += "White\n";
1811 for (j=0; j<(int)m_Range.steps; j++) {
1812 if (j)
1813 sDescription += " ";
1814 sprintf(buf, "%12.8lf", m_pWhite[j]);
1815 sDescription += buf;
1816 }
1817 sDescription += "\n";
1818
1819 sprintf(buf, "END_%s\n", GetDescribeName());
1820 sDescription += buf;
1821}
1822
1823/**
1824 ******************************************************************************
1825 * Name: CIccMpeSpectralObserver::Read
1826 *
1827 * Purpose:
1828 *
1829 * Args:
1830 *
1831 * Return:
1832 ******************************************************************************/
1834{
1836
1837 icUInt32Number headerSize = sizeof(icElemTypeSignature) +
1838 sizeof(icUInt32Number) +
1839 sizeof(icUInt16Number) +
1840 sizeof(icUInt16Number) +
1841 sizeof(icUInt16Number) +
1842 sizeof(icUInt16Number) +
1843 sizeof(icUInt16Number) +
1844 sizeof(icUInt16Number);
1845
1846 if (headerSize > size)
1847 return false;
1848
1849 if (!pIO) {
1850 return false;
1851 }
1852
1853 icUInt16Number nInputChannels, nOutputChannels;
1854 icSpectralRange range;
1855
1856 if (!pIO->Read32(&sig))
1857 return false;
1858
1859 if (!pIO->Read32(&m_nReserved))
1860 return false;
1861
1862 if (!pIO->Read16(&nInputChannels))
1863 return false;
1864
1865 if (!pIO->Read16(&nOutputChannels))
1866 return false;
1867
1868 if (!pIO->Read16(&range.start))
1869 return false;
1870
1871 if (!pIO->Read16(&range.end))
1872 return false;
1873
1874 if (!pIO->Read16(&range.steps))
1875 return false;
1876
1877 if (!pIO->Read16(&m_flags))
1878 return false;
1879
1880 if (!SetSize(nInputChannels, nOutputChannels, range))
1881 return false;
1882
1883 if (!m_pWhite )
1884 return false;
1885
1886 if (size<headerSize + (int)range.steps*sizeof(icFloatNumber))
1887 return false;
1888
1889 //Read White data
1890 if (pIO->ReadFloat32Float(m_pWhite, range.steps)!=range.steps)
1891 return false;
1892
1893 return true;
1894}
1895
1896/**
1897 ******************************************************************************
1898 * Name: CIccMpeSpectralObserver::Write
1899 *
1900 * Purpose:
1901 *
1902 * Args:
1903 *
1904 * Return:
1905 ******************************************************************************/
1907{
1909
1910 if (!pIO)
1911 return false;
1912
1913 if (!pIO->Write32(&sig))
1914 return false;
1915
1916 if (!pIO->Write32(&m_nReserved))
1917 return false;
1918
1919 if (!pIO->Write16(&m_nInputChannels))
1920 return false;
1921
1922 if (!pIO->Write16(&m_nOutputChannels))
1923 return false;
1924
1925 if (!pIO->Write16(&m_Range.start))
1926 return false;
1927
1928 if (!pIO->Write16(&m_Range.end))
1929 return false;
1930
1931 if (!pIO->Write16(&m_Range.steps))
1932 return false;
1933
1934 if (!pIO->Write16(&m_flags))
1935 return false;
1936
1937 if (m_pWhite) {
1939 return false;
1940 }
1941 else if (m_Range.steps) {
1942 return false;
1943 }
1944
1945 return true;
1946}
1947
1948void CIccMpeSpectralObserver::Apply(CIccApplyMpe *pApply, icFloatNumber *dstPixel, const icFloatNumber *srcPixel) const
1949{
1950 if (m_pApplyMtx) {
1951 icFloatNumber xyz[3];
1952 m_pApplyMtx->VectorMult(xyz, srcPixel);
1953
1954 bool bUseAbsolute = (m_flags & icRelativeSpectralData)!=0;
1955 bool bLab = (m_flags & icLabSpectralData) != 0;
1956
1957 if (!bUseAbsolute) {
1958 xyz[0] *= m_xyzscale[0];
1959 xyz[1] *= m_xyzscale[1];
1960 xyz[2] *= m_xyzscale[2];
1961 }
1962
1963 if (bLab) {
1964 icXYZtoLab(dstPixel, xyz, m_xyzw);
1965 // icLabToPcs(dstPixel);
1966 }
1967 else {
1968 memcpy(dstPixel, xyz, 3*sizeof(icFloatNumber));
1969 // icXyzToPcs(dstPixel);
1970 }
1971 }
1972}
1973
1974/**
1975 ******************************************************************************
1976 * Name: CIccMpeSpectralObserver::Validate
1977 *
1978 * Purpose:
1979 *
1980 * Args:
1981 *
1982 * Return:
1983 ******************************************************************************/
1984icValidateStatus CIccMpeSpectralObserver::Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement* pMPE/*=NULL*/, const CIccProfile *pProfile/*=NULL*/) const
1985{
1986 std::string mpeSigPath = sigPath + icGetSigPath(GetType());
1987 icValidateStatus rv = CIccMultiProcessElement::Validate(sigPath, sReport, pMPE, pProfile);
1988
1989 if (!m_Range.steps) {
1990 CIccInfo Info;
1991 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
1992
1993 sReport += icMsgValidateCriticalError;
1994 sReport += sSigPathName;
1995 sReport += " - Cannot have zero spectral range steps!\n";
1997 }
1998
1999 if (m_nOutputChannels != 3) {
2000 CIccInfo Info;
2001 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
2002
2003 sReport += icMsgValidateCriticalError;
2004 sReport += sSigPathName;
2005 sReport += " - Output Channels must be 3!\n";
2007 }
2008
2009 if (!m_pWhite) {
2010 CIccInfo Info;
2011 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
2012
2013 sReport += icMsgValidateCriticalError;
2014 sReport += sSigPathName;
2015 sReport += " - Has Empty White data!\n";
2017 }
2018
2019
2020 if (m_Range.start>= m_Range.end || !m_Range.steps) {
2021 CIccInfo Info;
2022 std::string sSigPathName = Info.GetSigPathName(mpeSigPath);
2023
2024 sReport += icMsgValidateCriticalError;
2025 sReport += sSigPathName;
2026 sReport += " - Has an invalid spectral range!\n";
2028 }
2029
2030 return rv;
2031}
2032
2033
2034/**
2035 ******************************************************************************
2036 * Name: CIccMpeEmissionObserver::Begin
2037 *
2038 * Purpose:
2039 *
2040 * Args:
2041 *
2042 * Return:
2043 ******************************************************************************/
2045{
2047 return false;
2048
2049 IIccProfileConnectionConditions *pAppliedPCC = pMPE->GetAppliedPCC();
2050 if (!pAppliedPCC)
2051 return false;
2052
2053 const CIccTagSpectralViewingConditions *pSVC = pAppliedPCC->getPccViewingConditions();
2054 if (!pSVC)
2055 return false;
2056
2058
2059 if (!m_pApplyMtx)
2060 return false;
2061
2062 if (!pAppliedPCC->getEmissiveObserver(m_Range, m_pWhite, m_pApplyMtx->entry(0)))
2063 return false;
2064
2066
2067 m_xyzscale[0] = 1.0;
2068 m_xyzscale[0] = 1.0;
2069 m_xyzscale[0] = 1.0;
2070
2071 return true;
2072}
2073
2074
2075/**
2076 ******************************************************************************
2077 * Name: CIccMpeReflectanceObserver::Begin
2078 *
2079 * Purpose:
2080 *
2081 * Args:
2082 *
2083 * Return:
2084 ******************************************************************************/
2086{
2088 return false;
2089
2090 IIccProfileConnectionConditions *pAppliedPCC = pMPE->GetAppliedPCC();
2091 if (!pAppliedPCC)
2092 return false;
2093
2094 const CIccTagSpectralViewingConditions *pSVC = pAppliedPCC->getPccViewingConditions();
2095 if (!pSVC)
2096 return false;
2097
2098 CIccMatrixMath observer(3, m_Range.steps);
2099 icSpectralRange illumRange;
2100 const icFloatNumber *illum = pSVC->getIlluminant(illumRange);
2101
2102 if (!pAppliedPCC->getEmissiveObserver(illumRange, illum, observer.entry(0)))
2103 return false;
2104
2105 //
2106 //apply illuminant to observer and calculate XYZ of illuminant
2107 icFloatNumber *pObs = observer.entry(0);
2108 int i, j;
2109 for (i=0; i<3; i++) {
2110 m_xyzw[i] = 0.0;
2111 for (j=0; j<illumRange.steps; j++) {
2112 *pObs *= illum[j];
2113 m_xyzw[i] += *pObs;
2114 pObs++;
2115 }
2116 }
2117
2118 //concatenate reflectance range mapping to observer+illuminant
2119 CIccMatrixMath *rangeRef = CIccMatrixMath::rangeMap(m_Range, illumRange);
2120 if (!rangeRef)
2121 m_pApplyMtx = new CIccMatrixMath(observer);
2122 else
2123 m_pApplyMtx = rangeRef->Mult(&observer);
2124
2125 icFloatNumber xyzm[3];
2126
2128
2129 bool bUseAbsolute = (m_flags & icRelativeSpectralData)!=0;
2130 bool bLab = (m_flags & icLabSpectralData) != 0;
2131
2132 if (!bUseAbsolute) {
2133 m_xyzscale[0] = m_xyzw[0] / xyzm[0];
2134 m_xyzscale[1] = m_xyzw[1] / xyzm[1];
2135 m_xyzscale[2] = m_xyzw[2] / xyzm[2];
2136 }
2137
2138 return true;
2139}
2140
2141#ifdef USEREFICCMAXNAMESPACE
2142} //namespace refIccMAX
2143#endif
icArraySignature sig
File: IccCAM.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
@ icValidateCriticalError
Definition IccDefs.h:122
File: IccIO.h.
File: IccCmm.h.
static icFloatNumber NoClip(icFloatNumber v)
File: IccMpeBasic.h.
@ ic1dInterp
@ ic3dInterpTetra
@ ic6dInterp
@ icNdInterp
@ ic2dInterp
@ ic4dInterp
@ ic5dInterp
@ ic3dInterp
File: IccMpeSpectral.h.
icElemInterp
Definition IccTagMPE.h:93
@ icElemInterpTetra
Definition IccTagMPE.h:95
icValidateStatus icMaxStatus(icValidateStatus s1, icValidateStatus s2)
Name: icMaxStatus.
Definition IccUtil.cpp:244
std::string icGetSigPath(icUInt32Number nSig)
Definition IccUtil.cpp:1191
icUInt8Number icGetStorageTypeBytes(icUInt16Number nStorageType)
Definition IccUtil.cpp:1375
const char * icMsgValidateCriticalError
Definition IccUtil.cpp:92
void icXYZtoLab(icFloatNumber *Lab, const icFloatNumber *XYZ, const icFloatNumber *WhiteXYZ)
Definition IccUtil.cpp:846
icFloatNumber icF16toF(icFloat16Number num)
Definition IccUtil.cpp:629
File: IccUtil.h.
icTagTypeSignature
unsigned int icUInt32Number
Class: CIccApplyCLUT.
Definition IccTagLut.h:302
Class: CIccApplyMpe.
Definition IccTagMPE.h:203
Class: CIccApplyMpeSpectralCLUT.
virtual ~CIccApplyMpeSpectralCLUT()
Name: CIccApplyMpeSpectralCLUT::~CIccApplyMpeSpectralCLUT.
CIccApplyMpeSpectralCLUT(CIccMultiProcessElement *pElem, CIccApplyCLUT *pApply)
Name: CIccApplyMpeSpectralCLUT::CIccApplyMpeSpectralCLUT.
Class: CIccTagMultiProcessElement.
Definition IccTagMPE.h:321
Class: CIccCLUT.
Definition IccTagLut.h:326
void Interp4d(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const
Name: CIccCLUT::Interp4d.
icUInt8Number GetInputDim() const
Definition IccTagLut.h:356
icUInt16Number GetOutputChannels() const
Definition IccTagLut.h:357
void SetClipFunc(icCLUTCLIPFUNC ClipFunc)
Definition IccTagLut.h:379
void Begin()
Name: CIccCLUT::Begin.
void Interp2d(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const
Name: CIccCLUT::Interp2d.
void Interp6d(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const
Name: CIccCLUT::Interp6d.
void Interp3d(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const
Name: CIccCLUT::Interp3d.
void Interp5d(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const
Name: CIccCLUT::Interp5d.
icUInt32Number NumPoints() const
Definition IccTagLut.h:348
icFloatNumber * GetData(int index)
Definition IccTagLut.h:347
const icUInt8Number * GridPointArray() const
Definition IccTagLut.h:351
void Interp3dTetra(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const
Name: CIccCLUT::Interp3dTetra.
void Interp1d(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const
Name: CIccCLUT::Interp1d.
void InterpND(icFloatNumber *destPixel, const icFloatNumber *srcPixel, CIccApplyCLUT *pApply) const
Name: CIccCLUT::InterpND.
bool Init(icUInt8Number nGridPoints, icUInt32Number nMaxSize=0, icUInt8Number nBytesPerPoint=4)
Name: CIccCLUT::Init.
Type: Class.
Definition IccIO.h:97
icInt32Number ReadFloat16Float(void *pBufFloat, icInt32Number nNum=1)
Definition IccIO.cpp:269
icInt32Number ReadFloat32Float(void *pBufFloat, icInt32Number nNum=1)
Definition IccIO.cpp:302
virtual icInt32Number Write8(void *pBuf8, icInt32Number nNum=1)
Definition IccIO.h:105
icInt32Number Write16(void *pBuf16, icInt32Number nNum=1)
Definition IccIO.cpp:122
virtual icInt32Number Read8(void *pBuf8, icInt32Number nNum=1)
Definition IccIO.h:104
icInt32Number Read16(void *pBuf16, icInt32Number nNum=1)
Definition IccIO.cpp:114
icInt32Number WriteFloat16Float(void *pBuf16, icInt32Number nNum=1)
Definition IccIO.cpp:285
icInt32Number ReadUInt8Float(void *pBufFloat, icInt32Number nNum=1)
Definition IccIO.cpp:203
icInt32Number Write32(void *pBuf32, icInt32Number nNum=1)
Definition IccIO.cpp:152
icInt32Number WriteFloat32Float(void *pBufFloat, icInt32Number nNum=1)
Definition IccIO.cpp:321
icInt32Number WriteUInt8Float(void *pBuf16, icInt32Number nNum=1)
Definition IccIO.cpp:219
icInt32Number ReadUInt16Float(void *pBufFloat, icInt32Number nNum=1)
Definition IccIO.cpp:236
icInt32Number Read32(void *pBuf32, icInt32Number nNum=1)
Definition IccIO.cpp:143
icInt32Number WriteUInt16Float(void *pBuf16, icInt32Number nNum=1)
Definition IccIO.cpp:252
Type: Class.
Definition IccUtil.h:303
std::string GetSigPathName(std::string sigPath)
Definition IccUtil.cpp:1614
Type: Class.
icFloatNumber * entry(icUInt16Number nRow, icUInt16Number nCol=0)
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.
virtual bool Begin(icElemInterp nInterp, CIccTagMultiProcessElement *pMPE)
Name: CIccMpeEmissionCLUT::Begin.
virtual void Apply(CIccApplyMpe *pApply, icFloatNumber *dstPixel, const icFloatNumber *srcPixel) const
Name: CIccMpeEmissionMatrix::Apply.
virtual bool Begin(icElemInterp nInterp, CIccTagMultiProcessElement *pMPE)
Name: CIccMpeEmissionMatrix::Begin.
virtual bool Begin(icElemInterp nInterp, CIccTagMultiProcessElement *pMPE)
Name: CIccMpeEmissionObserver::Begin.
virtual void Apply(CIccApplyMpe *pApply, icFloatNumber *dstPixel, const icFloatNumber *srcPixel) const
Name: CIccMpeInvEmissionMatrix::Apply.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement *pMPE=NULL, const CIccProfile *pProfile=NULL) const
Name: CIccMpeInvEmissionMatrix::Validate.
virtual bool Begin(icElemInterp nInterp, CIccTagMultiProcessElement *pMPE)
Name: CIccMpeInvEmissionMatrix::Begin.
virtual bool Begin(icElemInterp nInterp, CIccTagMultiProcessElement *pMPE)
Name: CIccMpeReflectanceCLUT::Begin.
virtual bool Begin(icElemInterp nInterp, CIccTagMultiProcessElement *pMPE)
Name: CIccMpeReflectanceObserver::Begin.
Class: CIccMpeSpectralCLUT.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement *pMPE=NULL, const CIccProfile *pProfile=NULL) const
Name: CIccMpeSpectralCLUT::Validate.
CIccMpeSpectralCLUT()
Name: CIccMpeSpectralCLUT::CIccMpeSpectralCLUT.
virtual ~CIccMpeSpectralCLUT()
Name: CIccMpeSpectralCLUT::~CIccMpeSpectralCLUT.
icUInt32Number m_flags
icUInt16Number m_nStorageType
virtual void Apply(CIccApplyMpe *pApply, icFloatNumber *dstPixel, const icFloatNumber *srcPixel) const
Name: CIccMpeEmissionCLUT::Apply.
virtual bool Write(CIccIO *pIO)
Name: CIccMpeSpectralCLUT::Write.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccMpeSpectralCLUT::Read.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccMpeSpectralCLUT::Describe.
icSpectralRange m_Range
void SetData(CIccCLUT *pCLUT, icUInt16Number nStorageType, const icSpectralRange &range, icFloatNumber *pWhite, icUInt16Number nOutputChannels=3)
Name: CIccMpeSpectralCLUT::SetCLUT.
icCLUTElemType m_interpType
icFloatNumber * m_pWhite
void copyData(const CIccMpeSpectralCLUT &ITPC)
Name: &CIccMpeSpectralCLUT::operator=.
virtual CIccApplyMpe * GetNewApply(CIccApplyTagMpe *pApplyTag)
Name: CIccMpeSpectralCLUT::GetNewApply.
Class: CIccMpeSpectralMatrix.
virtual ~CIccMpeSpectralMatrix()
Name: CIccMpeSpectralMatrix::~CIccMpeSpectralMatrix.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccMpeSpectralMatrix::Read.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccMpeSpectralMatrix::Describe.
icUInt16Number m_nReserved2
CIccMpeSpectralMatrix()
Name: CIccMpeSpectralMatrix::CIccMpeSpectralMatrix.
void copyData(const CIccMpeSpectralMatrix &ITPC)
Name: &CIccMpeSpectralMatrix::operator=.
icFloatNumber * m_pOffset
icSpectralRange m_Range
icFloatNumber * m_pWhite
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement *pMPE=NULL, const CIccProfile *pProfile=NULL) const
Name: CIccMpeSpectralMatrix::Validate.
icFloatNumber * m_pMatrix
virtual bool Write(CIccIO *pIO)
Name: CIccMpeSpectralMatrix::Write.
bool SetSize(icUInt16Number nInputChannels, icUInt16Number nOutputChannels, const icSpectralRange &range)
Name: CIccMpeSpectralMatrix::SetSize.
Class: CIccMpeSpectralObserver.
virtual const char * GetDescribeName() const =0
virtual bool Write(CIccIO *pIO)
Name: CIccMpeSpectralObserver::Write.
void copyData(const CIccMpeSpectralObserver &ITPC)
Name: &CIccMpeSpectralObserver::operator=.
CIccMpeSpectralObserver()
Name: CIccMpeSpectralObserver::CIccMpeSpectralObserver.
virtual void Apply(CIccApplyMpe *pApply, icFloatNumber *dstPixel, const icFloatNumber *srcPixel) const
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccMpeSpectralObserver::Read.
virtual ~CIccMpeSpectralObserver()
Name: CIccMpeSpectralObserver::~CIccMpeSpectralObserver.
bool SetSize(icUInt16Number nInputChannels, icUInt16Number nOutputChannels, const icSpectralRange &range)
Name: CIccMpeSpectralObserver::SetSize.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement *pMPE=NULL, const CIccProfile *pProfile=NULL) const
Name: CIccMpeSpectralObserver::Validate.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccMpeSpectralObserver::Describe.
icFloatNumber m_xyzw[3]
CIccMatrixMath * m_pApplyMtx
icFloatNumber m_xyzscale[3]
Class: CIccMultiProcessElement.
Definition IccTagMPE.h:146
icUInt16Number m_nOutputChannels
Definition IccTagMPE.h:192
virtual icElemTypeSignature GetType() const =0
icUInt16Number m_nInputChannels
Definition IccTagMPE.h:191
icUInt32Number m_nReserved
Definition IccTagMPE.h:188
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement *pMPE=NULL, const CIccProfile *pProfile=NULL) const =0
Name: CIccProcessElement::Validate.
Class: CIccTagMultiProcessElement.
Definition IccTagMPE.h:358
IIccProfileConnectionConditions * GetAppliedPCC()
Definition IccTagMPE.h:403
Class: CIccTagSpectralViewingConditions.
const icFloatNumber * getIlluminant(icSpectralRange &illumRange) const
icFloatNumber * getEmissiveObserver(const icSpectralRange &range, const icFloatNumber *pWhite, icFloatNumber *obsMatrix=NULL)
Definition IccPcc.cpp:231
virtual const CIccTagSpectralViewingConditions * getPccViewingConditions()=0
unsigned char icUInt8Number
Number definitions.
float icFloat32Number
unsigned short icUInt16Number
long icInt32Number
#define icMaxValueType
#define icRelativeSpectralData
MPE Spectral Data Conversion flags.
icElemTypeSignature
Multi-Processing Element type signatures.
#define icSigUnknownData
@ icValueTypeFloat16
@ icValueTypeUInt8
@ icValueTypeUInt16
@ icValueTypeFloat32
#define icLabSpectralData
spectral range
icUInt16Number steps
icFloat16Number start
icFloat16Number end