Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
IccTagMPE.cpp
Go to the documentation of this file.
1/** @file
2 File: IccTagMpe.cpp
3
4 Contains: Implementation of MultiProcessElementType Tag
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 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 "IccTagMPE.h"
80#include "IccIO.h"
81#include "IccMpeFactory.h"
82#include <map>
83#include "IccUtil.h"
84
85#ifdef USEREFICCMAXNAMESPACE
86namespace refIccMAX {
87#endif
88
89/**
90 ******************************************************************************
91 * Name: CIccApplyMpe::CIccApplyMpe
92 *
93 * Purpose:
94 *
95 * Args:
96 *
97 * Return:
98 ******************************************************************************/
100{
101 m_pElem = pElem;
102 m_pApplyTag = NULL;
103}
104
105
106/**
107 ******************************************************************************
108 * Name: CIccApplyMpe::~CIccApplyMpe
109 *
110 * Purpose:
111 *
112 * Args:
113 *
114 * Return:
115 ******************************************************************************/
119
120
121/**
122 ******************************************************************************
123 * Name: CIccMultiProcessElement::Create
124 *
125 * Purpose:
126 *
127 * Args:
128 *
129 * Return:
130 ******************************************************************************/
135
136/**
137 ******************************************************************************
138 * Name: CIccMultiProcessElement::GetNewApply()
139 *
140 * Purpose:
141 *
142 * Args:
143 *
144 * Return:
145******************************************************************************/
150
151
152/**
153 ******************************************************************************
154 * Name: CIccMpeUnknown::CIccMpeUnknown
155 *
156 * Purpose:
157 *
158 * Args:
159 *
160 * Return:
161 ******************************************************************************/
163{
164 m_sig = icSigUnknownElemType;
165 m_nReserved = 0;
166 m_nInputChannels = 0;
167 m_nOutputChannels = 0;
168 m_nSize = 0;
169 m_pData = 0;
170}
171
172/**
173 ******************************************************************************
174 * Name: CIccMpeUnknown::CIccMpeUnknown
175 *
176 * Purpose:
177 *
178 * Args:
179 *
180 * Return:
181 ******************************************************************************/
183{
184 m_sig = elem.m_sig;
185 m_nReserved = elem.m_nReserved;
186 m_nInputChannels = elem.m_nInputChannels;
187 m_nOutputChannels = elem.m_nOutputChannels;
188 m_nSize = elem.m_nSize;
189 if (m_nSize) {
190 m_pData = (icUInt8Number*)malloc(m_nSize);
191 if (m_pData)
192 memcpy(m_pData, elem.m_pData, m_nSize);
193 }
194 else
195 m_pData = NULL;
196}
197
198/**
199 ******************************************************************************
200 * Name: CIccMpeUnknown::operator=
201 *
202 * Purpose:
203 *
204 * Args:
205 *
206 * Return:
207 ******************************************************************************/
209{
210 if (m_pData)
211 free(m_pData);
212
213 m_sig = elem.m_sig;
214 m_nReserved = elem.m_nReserved;
215 m_nInputChannels = elem.m_nInputChannels;
216 m_nOutputChannels = elem.m_nOutputChannels;
217 m_nSize = elem.m_nSize;
218 if (m_nSize) {
219 m_pData = (icUInt8Number*)malloc(m_nSize);
220 if (m_pData)
221 memcpy(m_pData, elem.m_pData, m_nSize);
222 }
223 else
224 m_pData = NULL;
225
226 return (*this);
227}
228
229/**
230 ******************************************************************************
231 * Name: CIccMpeUnknown::~CIccMpeUnknown
232 *
233 * Purpose:
234 *
235 * Args:
236 *
237 * Return:
238 ******************************************************************************/
240{
241 if (m_pData)
242 free(m_pData);
243}
244
245/**
246******************************************************************************
247* Name: CIccMpeUnknown::SetType
248*
249* Purpose:
250*
251* Args:
252*
253* Return:
254******************************************************************************/
259
260/**
261******************************************************************************
262* Name: CIccMpeUnknown::Describe
263*
264* Purpose:
265*
266* Args:
267*
268* Return:
269******************************************************************************/
270void CIccMpeUnknown::SetChannels(icUInt16Number nInputChannels, icUInt16Number nOutputChannels)
271{
272 m_nInputChannels = nInputChannels;
273 m_nOutputChannels = nOutputChannels;
274}
275
276/**
277 ******************************************************************************
278 * Name: CIccMpeUnknown::Describe
279 *
280 * Purpose:
281 *
282 * Args:
283 *
284 * Return:
285 ******************************************************************************/
286void CIccMpeUnknown::Describe(std::string &sDescription, int nVerboseness)
287{
288 icChar buf[128], sigbuf[40];
289
290 sprintf(buf, "Unknown Element(%s) Type of %u Bytes.",
291 icGetSig(sigbuf, m_sig), m_nSize);
292 sDescription += buf;
293
294 if (nVerboseness > 50) {
295 sDescription += "\n\nData Follows:\n";
296
297 icMemDump(sDescription, m_pData, m_nSize);
298 }
299}
300
301/**
302 ******************************************************************************
303 * Name: CIccMpeUnknown::SetDataSize
304 *
305 * Purpose:
306 *
307 * Args:
308 *
309 * Return:
310 ******************************************************************************/
311bool CIccMpeUnknown::SetDataSize(icUInt32Number nSize, bool bZeroData/*=true*/)
312{
313 bool rv = true;
314 if (m_pData)
315 free(m_pData);
316
317 m_nSize = nSize;
318 if (m_nSize) {
319 m_pData = (icUInt8Number*)malloc(m_nSize);
320 if (!m_pData) {
321 rv = false;
322 m_nSize = 0;
323 }
324 }
325 else
326 m_pData = NULL;
327
328 return rv;
329}
330
331/**
332 ******************************************************************************
333 * Name: CIccMpeUnknown::Read
334 *
335 * Purpose:
336 *
337 * Args:
338 *
339 * Return:
340 ******************************************************************************/
342{
343 icUInt32Number nHeaderSize = sizeof(icTagTypeSignature) +
344 sizeof(icUInt32Number) +
345 sizeof(icUInt16Number) +
346 sizeof(icUInt16Number);
347
348 if (nHeaderSize > nSize)
349 return false;
350
351 if (!pIO) {
352 return false;
353 }
354
355 if (!pIO->Read32(&m_sig))
356 return false;
357
358 if (!pIO->Read32(&m_nReserved))
359 return false;
360
361 if (!pIO->Read16(&m_nInputChannels))
362 return false;
363
364 if (!pIO->Read16(&m_nOutputChannels))
365 return false;
366
367 icUInt32Number nDataSize = nSize - nHeaderSize;
368
369 if (nDataSize) {
370 if (!SetDataSize(nDataSize, false))
371 return false;
372
373 if (pIO->Read8(m_pData, nDataSize)!=(icInt32Number)nDataSize)
374 return false;
375 }
376
377 return true;
378}
379
380/**
381 ******************************************************************************
382 * Name: CIccMpeUnknown::Write
383 *
384 * Purpose:
385 *
386 * Args:
387 *
388 * Return:
389 ******************************************************************************/
391{
392 if (!pIO)
393 return false;
394
395 //icUInt32Number elemStart = pIO->Tell();
396
397 if (!pIO->Write32(&m_sig))
398 return false;
399
400 if (!pIO->Write32(&m_nReserved))
401 return false;
402
403 if (!pIO->Write16(&m_nInputChannels))
404 return false;
405
406 if (!pIO->Write16(&m_nOutputChannels))
407 return false;
408
409 if (m_nSize) {
410 if (pIO->Write8(m_pData, m_nSize)!=(icInt32Number)m_nSize)
411 return false;
412 }
413
414 return true;
415}
416
417/**
418 ******************************************************************************
419 * Name: CIccMpeUnknown::Validate
420 *
421 * Purpose:
422 *
423 * Args:
424 *
425 * Return:
426 ******************************************************************************/
427icValidateStatus CIccMpeUnknown::Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement* pMPE/*=NULL*/, const CIccProfile *pProfile/*=NULL*/) const
428{
429 CIccInfo Info;
430 icChar buf[40];
431 std::string sSigPathName = Info.GetSigPathName(sigPath);
432
434 sReport += sSigPathName;
435 sReport += " - Contains unknown processing element type (";
436 icGetSig(buf, m_sig, true);
437 sReport += buf;
438 sReport += ").\n";
439
441}
442
443
444/**
445 ******************************************************************************
446 * Name: CIccProcessElement::Validate
447 *
448 * Purpose:
449 *
450 * Args:
451 *
452 * Return:
453 ******************************************************************************/
454icValidateStatus CIccMultiProcessElement::Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement* pMPE/*=NULL*/, const CIccProfile *pProfile/*=NULL*/) const
455{
457
458 CIccInfo Info;
459 std::string sSigPathName = Info.GetSigPathName(sigPath+icGetSigPath(GetType()));
460 if (m_nReserved!=0) {
461 sReport += icMsgValidateNonCompliant;
462 sReport += sSigPathName;
463 sReport += " - Reserved Value must be zero.\n";
464
466 }
467
468 return rv;
469}
470
471
472/**
473 ******************************************************************************
474 * Name: CIccDblPixelBuffer::CIccDblPixelBuffer
475 *
476 * Purpose:
477 *
478 * Args:
479 *
480 * Return:
481 ******************************************************************************/
483{
484 m_nMaxChannels = 0;
485 m_nLastNumChannels = 0;
486 m_pixelBuf1 = NULL;
487 m_pixelBuf2 = NULL;
488}
489
490
491/**
492 ******************************************************************************
493 * Name: CIccDblPixelBuffer::CIccDblPixelBuffer
494 *
495 * Purpose:
496 *
497 * Args:
498 *
499 * Return:
500 ******************************************************************************/
502{
503 m_nLastNumChannels = 0;
504 m_nMaxChannels = buf.m_nMaxChannels;
505 if (m_nMaxChannels) {
506 m_pixelBuf1 = (icFloatNumber*)malloc(m_nMaxChannels*sizeof(icFloatNumber));
507 if (m_pixelBuf1)
508 memcpy(m_pixelBuf1, buf.m_pixelBuf1, m_nMaxChannels*sizeof(icFloatNumber));
509
510 m_pixelBuf2 = (icFloatNumber*)malloc(m_nMaxChannels*sizeof(icFloatNumber));
511 if (m_pixelBuf2)
512 memcpy(m_pixelBuf2, buf.m_pixelBuf2, m_nMaxChannels*sizeof(icFloatNumber));
513 }
514 else {
515 m_pixelBuf1 = NULL;;
516 m_pixelBuf2 = NULL;
517 }
518}
519
520
521/**
522 ******************************************************************************
523 * Name: CIccDblPixelBuffer::CIccDblPixelBuffer
524 *
525 * Purpose:
526 *
527 * Args:
528 *
529 * Return:
530 ******************************************************************************/
532{
533 Clean();
534
535 m_nMaxChannels = buf.m_nMaxChannels;
536 if (m_nMaxChannels) {
537 m_pixelBuf1 = (icFloatNumber*)malloc(m_nMaxChannels*sizeof(icFloatNumber));
538 if (m_pixelBuf1)
539 memcpy(m_pixelBuf1, buf.m_pixelBuf1, m_nMaxChannels*sizeof(icFloatNumber));
540
541 m_pixelBuf2 = (icFloatNumber*)malloc(m_nMaxChannels*sizeof(icFloatNumber));
542 if (m_pixelBuf2)
543 memcpy(m_pixelBuf2, buf.m_pixelBuf2, m_nMaxChannels*sizeof(icFloatNumber));
544 }
545 else {
546 m_pixelBuf1 = NULL;;
547 m_pixelBuf2 = NULL;
548 }
549
550 return *this;
551}
552
553/**
554 ******************************************************************************
555 * Name: CIccDblPixelBuffer::~CIccDblPixelBuffer
556 *
557 * Purpose:
558 *
559 * Args:
560 *
561 * Return:
562 ******************************************************************************/
567
568
569/**
570 ******************************************************************************
571 * Name: CIccDblPixelBuffer::CIccDblPixelBuffer
572 *
573 * Purpose:
574 *
575 * Args:
576 *
577 * Return:
578 ******************************************************************************/
580{
581 if (m_pixelBuf1) {
582 free(m_pixelBuf1);
583 m_pixelBuf1 = NULL;
584 }
585 if (m_pixelBuf2) {
586 free(m_pixelBuf2);
587 m_pixelBuf2 = NULL;
588 }
589 m_nMaxChannels = 0;
590 m_nLastNumChannels = 0;
591}
592
593/**
594 ******************************************************************************
595 * Name: CIccDblPixelBuffer::CIccDblPixelBuffer
596 *
597 * Purpose:
598 *
599 * Args:
600 *
601 * Return:
602 ******************************************************************************/
604{
605 m_pixelBuf1 = (icFloatNumber*)calloc(m_nMaxChannels, sizeof(icFloatNumber));
606 m_pixelBuf2 = (icFloatNumber*)calloc(m_nMaxChannels, sizeof(icFloatNumber));
607
608 return (!m_nMaxChannels || (m_pixelBuf1!=NULL && m_pixelBuf2!=NULL));
609}
610
611
612/**
613******************************************************************************
614* Name: CIccApplyTagMpe::CIccApplyTagMpe
615*
616* Purpose:
617*
618* Args:
619*
620* Return:
621******************************************************************************/
623{
624 m_pTag = pTag;
625 m_list = NULL;
626}
627
628
629/**
630******************************************************************************
631* Name: CIccApplyTagMpe::~CIccApplyTagMpe
632*
633* Purpose:
634*
635* Args:
636*
637* Return:
638******************************************************************************/
640{
641 if (m_list) {
642 CIccApplyMpeList::iterator i;
643
644 for (i=m_list->begin(); i!=m_list->end(); i++) {
645 delete i->ptr;
646 }
647
648 delete m_list;
649 }
650}
651
652
653/**
654******************************************************************************
655* Name: CIccApplyTagMpe::CIccApplyTagMpe
656*
657* Purpose:
658*
659* Args:
660*
661* Return:
662******************************************************************************/
664{
665 if (!m_list)
666 m_list = new CIccApplyMpeList();
667
668 if (!m_list)
669 return false;
670
671 CIccApplyMpe *pApply = pElem->GetNewApply(this);
672
673 if (!pApply)
674 return false;
675
676 CIccApplyMpePtr ptr;
677
678 ptr.ptr = pApply;
679 m_list->push_back(ptr);
680
681 return true;
682}
683
684
685/**
686 ******************************************************************************
687 * Name: CIccTagMultiProcessElement::CIccTagMultiProcessElement
688 *
689 * Purpose:
690 *
691 * Args:
692 *
693 * Return:
694 ******************************************************************************/
696{
697 m_nReserved = 0;
698 m_list = NULL;
699 m_nProcElements = 0;
700 m_position = NULL;
701 m_nBufChannels = 0;
702
703 m_nInputChannels = nInputChannels;
704 m_nOutputChannels = nOutputChannels;
705
706 m_pAppliedPCC = NULL;
707 m_pProfilePCC = NULL;
708
709 m_pCmmEnvVarLookup = NULL;
710}
711
712/**
713 ******************************************************************************
714 * Name: CIccTagMultiProcessElement::CIccTagMultiProcessElement
715 *
716 * Purpose:
717 *
718 * Args:
719 *
720 * Return:
721 ******************************************************************************/
723{
724 m_position = NULL;
725 m_list = NULL;
726 m_nProcElements = 0;
727
728 m_nReserved = lut.m_nReserved;
729
730 if (lut.m_list) {
731 m_list = new CIccMultiProcessElementList();
732
733 CIccMultiProcessElementList::iterator i;
735
736 for (i=lut.m_list->begin(); i!= lut.m_list->end(); i++) {
737 ptr.ptr = (CIccMultiProcessElement*)i->ptr->NewCopy();
738 m_list->push_back(ptr);
739 }
740 }
741 m_nInputChannels = lut.m_nInputChannels;
742 m_nOutputChannels = lut.m_nOutputChannels;
743
744 if (lut.m_nProcElements && lut.m_position) {
745 m_position = (icPositionNumber*)malloc(lut.m_nProcElements*sizeof(icPositionNumber));
746 if (m_position) {
747 memcpy(m_position, lut.m_position, lut.m_nProcElements*sizeof(icPositionNumber));
748 }
749 m_nProcElements = lut.m_nProcElements;
750 }
751
752 m_pAppliedPCC = lut.m_pAppliedPCC;
753 m_pProfilePCC = lut.m_pProfilePCC;
754
755 m_pCmmEnvVarLookup = lut.m_pCmmEnvVarLookup;
756}
757
758/**
759 ******************************************************************************
760 * Name: &operator=
761 *
762 * Purpose:
763 *
764 * Args:
765 *
766 * Return:
767 ******************************************************************************/
769{
770 Clean();
771
772 m_nReserved = lut.m_nReserved;
773
774 if (lut.m_list) {
775 m_list = new CIccMultiProcessElementList();
776
777 CIccMultiProcessElementList::iterator i;
779
780 for (i=lut.m_list->begin(); i!= lut.m_list->end(); i++) {
781 ptr.ptr = (CIccMultiProcessElement*)i->ptr->NewCopy();
782 m_list->push_back(ptr);
783 }
784 }
785 m_nInputChannels = lut.m_nInputChannels;
786 m_nOutputChannels = lut.m_nOutputChannels;
787
788 if (lut.m_nProcElements && lut.m_position) {
789 m_position = (icPositionNumber*)malloc(lut.m_nProcElements*sizeof(icPositionNumber));
790 if (m_position) {
791 memcpy(m_position, lut.m_position, lut.m_nProcElements*sizeof(icPositionNumber));
792 }
793 m_nProcElements = lut.m_nProcElements;
794 }
795
796 m_pAppliedPCC = lut.m_pAppliedPCC;
797 m_pProfilePCC = lut.m_pProfilePCC;
798
799 m_pCmmEnvVarLookup = lut.m_pCmmEnvVarLookup;
800
801 return *this;
802}
803
804/**
805 ******************************************************************************
806 * Name: CIccTagMultiProcessElement::~CIccTagMultiProcessElement
807 *
808 * Purpose:
809 *
810 * Args:
811 *
812 * Return:
813 ******************************************************************************/
818
819typedef std::map<CIccMultiProcessElement*, icPositionNumber> CIccLutPtrMap;
820typedef std::map<icUInt32Number, CIccMultiProcessElement*> CIccLutOffsetMap;
821/**
822 ******************************************************************************
823 * Name: CIccTagMultiProcessElement::Clean
824 *
825 * Purpose:
826 *
827 * Args:
828 *
829 * Return:
830 ******************************************************************************/
832{
833 if (m_list) {
834 CIccLutPtrMap map;
835 CIccMultiProcessElementList::iterator i;
836
837 for (i=m_list->begin(); i!=m_list->end(); i++) {
838 if (!map[i->ptr].offset) {
839 map[i->ptr].offset = 1;
840 delete i->ptr;
841 }
842 }
843
844 delete m_list;
845 m_list = NULL;
846 }
847
848 if (m_position) {
849 free(m_position);
850 m_position = NULL;
851 }
852
853 m_nProcElements = 0;
854}
855
856/**
857 ******************************************************************************
858 * Name: CIccTagMultiProcessElement::IsSupported
859 *
860 * Purpose:
861 *
862 * Args:
863 *
864 * Return:
865 ******************************************************************************/
867{
868 if (m_list) {
869 CIccMultiProcessElementList::iterator i;
870
871 for (i=m_list->begin(); i!=m_list->end(); i++) {
872 if (!i->ptr->IsSupported())
873 return false;
874 }
875 }
876
877 return true;
878}
879
880
881
882/**
883 ******************************************************************************
884 * Name: CIccTagMultiProcessElement::Describe
885 *
886 * Purpose:
887 *
888 * Args:
889 *
890 * Return:
891 ******************************************************************************/
892void CIccTagMultiProcessElement::Describe(std::string &sDescription, int nVerboseness)
893{
894 icChar buf[128];
895
896 sprintf(buf, "BEGIN MULTI_PROCESS_ELEMENT_TAG %d %d\n", m_nInputChannels, m_nOutputChannels);
897 sDescription += buf;
898 sDescription += "\n";
899
900 CIccMultiProcessElementList::iterator i;
901 int j;
902
903 for (j=0, i=m_list->begin(); i!=m_list->end(); j++, i++) {
904 sprintf(buf, "PROCESS_ELEMENT #%d\n", j+1);
905 sDescription += buf;
906 i->ptr->Describe(sDescription, nVerboseness);
907 sDescription += "\n";
908 }
909 sDescription += "END MULTI_PROCESS_ELEMENT_TAG\n";
910}
911
912/**
913 ******************************************************************************
914 * Name: CIccTagMultiProcessElement::Attach
915 *
916 * Purpose:
917 *
918 * Args:
919 *
920 * Return:
921 ******************************************************************************/
923{
924 if (!m_list) {
925 m_list = new CIccMultiProcessElementList();
926 }
927
929
930 ptr.ptr = pElement;
931
932 m_list->push_back(ptr);
933}
934
935/**
936******************************************************************************
937* Name: CIccTagMultiProcessElement::Insert
938*
939* Purpose:
940*
941* Args:
942*
943* Return:
944******************************************************************************/
946{
947 if (!m_list) {
948 m_list = new CIccMultiProcessElementList();
949 }
950
952
953 ptr.ptr = pElement;
954
955 m_list->push_front(ptr);
956}
957
958
959/**
960 ******************************************************************************
961 * Name: CIccTagMultiProcessElement::Read
962 *
963 * Purpose:
964 *
965 * Args:
966 *
967 * Return:
968 ******************************************************************************/
970{
972
973 icUInt32Number headerSize = sizeof(icTagTypeSignature) +
974 sizeof(icUInt32Number) +
975 sizeof(icUInt8Number) +
976 sizeof(icUInt8Number) +
977 sizeof(icUInt16Number);
978
979 if (headerSize > size)
980 return false;
981
982 if (!pIO) {
983 return false;
984 }
985
986 Clean();
987
988 icUInt32Number tagStart = pIO->Tell();
989
990 if (!pIO->Read32(&sig))
991 return false;
992
993 if (!pIO->Read32(&m_nReserved))
994 return false;
995
996 if (!pIO->Read16(&m_nInputChannels))
997 return false;
998
999 if (!pIO->Read16(&m_nOutputChannels))
1000 return false;
1001
1002 if (!pIO->Read32(&m_nProcElements))
1003 return false;
1004
1005 if (headerSize + (icUInt64Number)m_nProcElements*sizeof(icUInt32Number) > size)
1006 return false;
1007
1008 m_list = new CIccMultiProcessElementList();
1009
1010 if (!m_list)
1011 return false;
1012
1014
1015 m_position = (icPositionNumber*)calloc(m_nProcElements, sizeof(icPositionNumber));
1016
1017 if (!m_position)
1018 return false;
1019
1020 CIccLutOffsetMap loadedElements;
1021
1022 for (i=0; i<m_nProcElements; i++) {
1023 if (!pIO->Read32(&m_position[i].offset))
1024 return false;
1025 if (!pIO->Read32(&m_position[i].size))
1026 return false;
1027 }
1028
1030 icElemTypeSignature sigElem;
1031
1032 for (i=0; i<m_nProcElements; i++) {
1033 if (m_position[i].offset+m_position[i].size > size) {
1034 return false;
1035 }
1036
1037 //Use hash to cache offset duplication
1038 CIccMultiProcessElement *element = loadedElements[m_position[i].offset];
1039 if (!element) {
1040 icUInt32Number pos = tagStart + m_position[i].offset;
1041
1042 if (pIO->Seek(pos, icSeekSet)!=(icInt32Number)pos) {
1043 return false;
1044 }
1045
1046 if (!pIO->Read32(&sigElem)) {
1047 return false;
1048 }
1049
1050 if (pIO->Seek(pos, icSeekSet)!=(icInt32Number)pos) {
1051 return false;
1052 }
1053
1054 element = CIccMultiProcessElement::Create(sigElem);
1055 if (!element) {
1056 return false;
1057 }
1058
1059 if (!element->Read(m_position[i].size, pIO)) {
1060 delete element;
1061 return false;
1062 }
1063
1064 loadedElements[m_position[i].offset] = element;
1065 }
1066 ptr.ptr = element;
1067
1068 m_list->push_back(ptr);
1069 }
1070
1071 return true;
1072}
1073
1074/**
1075 ******************************************************************************
1076 * Name: CIccTagMultiProcessElement::Write
1077 *
1078 * Purpose:
1079 *
1080 * Args:
1081 *
1082 * Return:
1083 ******************************************************************************/
1085{
1086 icTagTypeSignature sig = GetType();
1087
1088 if (!pIO)
1089 return false;
1090
1091 icUInt32Number tagStart = pIO->Tell();
1092
1093 if (!pIO->Write32(&sig))
1094 return false;
1095
1096 if (!pIO->Write32(&m_nReserved))
1097 return false;
1098
1099 if (!pIO->Write16(&m_nInputChannels))
1100 return false;
1101
1102 if (!pIO->Write16(&m_nOutputChannels))
1103 return false;
1104
1105 if (m_list) {
1106 m_nProcElements = (icUInt32Number)m_list->size();
1107 }
1108 else {
1109 m_nProcElements = 0;
1110 }
1111
1112 if (!pIO->Write32(&m_nProcElements))
1113 return false;
1114
1115 if (m_nProcElements) {
1116 icUInt32Number offsetPos = pIO->Tell();
1117
1118 if (m_position) {
1119 delete [] m_position;
1120 }
1121
1122 m_position = (icPositionNumber*)calloc(m_nProcElements, sizeof(icPositionNumber));
1123
1124 if (!m_position)
1125 return false;
1126
1127 //Write an empty position table
1128 icUInt32Number j, zeros[2] = { 0, 0 };
1129 for (j=0; j<m_nProcElements; j++) {
1130 if (pIO->Write32(zeros, 2)!=2)
1131 return false;
1132 }
1133
1134 CIccLutPtrMap map;
1135 CIccMultiProcessElementList::iterator i;
1136 icUInt32Number start, end;
1137 icPositionNumber position;
1138
1139 //Write out each process element
1140 for (j=0, i=m_list->begin(); i!=m_list->end(); i++, j++) {
1141 if (map.find(i->ptr)==map.end()) {
1142 start = pIO->Tell();
1143
1144 if (!i->ptr->Write(pIO))
1145 return false;
1146
1147 end = pIO->Tell();
1148
1149 if (!pIO->Align32())
1150 return false;
1151
1152 position.offset = start - tagStart;
1153 position.size = end - start;
1154
1155 map[i->ptr] = position;
1156 }
1157 m_position[j] = map[i->ptr];
1158 }
1159
1160 icUInt32Number endPos = pIO->Tell();
1161
1162 if (pIO->Seek(offsetPos, icSeekSet)<0)
1163 return false;
1164
1165 for (j=0; j<m_nProcElements; j++) {
1166 if (!pIO->Write32(&m_position[j].offset))
1167 return false;
1168 if (!pIO->Write32(&m_position[j].size))
1169 return false;
1170 }
1171
1172 if (pIO->Seek(endPos, icSeekSet)<0)
1173 return false;
1174 }
1175
1176 return true;
1177}
1178
1179/**
1180******************************************************************************
1181* Name: CIccTagMultiProcessElement::GetElement
1182*
1183* Purpose:
1184*
1185* Args:
1186*
1187* Return:
1188******************************************************************************/
1190{
1191 if (!m_list)
1192 return NULL;
1193
1194 CIccMultiProcessElementList::iterator i;
1195 int j;
1196
1197 for(i=m_list->begin(), j=0; j<nIndex && i!=m_list->end(); i++, j++);
1198
1199 if (i!=m_list->end())
1200 return i->ptr;
1201
1202 return NULL;
1203}
1204
1205/**
1206******************************************************************************
1207* Name: CIccTagMultiProcessElement::GetNextElemIterator
1208*
1209* Purpose:
1210*
1211* Args:
1212*
1213* Return:
1214******************************************************************************/
1215void CIccTagMultiProcessElement::GetNextElemIterator(CIccMultiProcessElementList::iterator &itr)
1216{
1217 itr++;
1218}
1219
1220/**
1221******************************************************************************
1222* Name: CIccTagMultiProcessElement::IsLateBinding
1223*
1224* Purpose:
1225*
1226* Args:
1227*
1228* Return:
1229******************************************************************************/
1231{
1232 if (!m_list)
1233 return false;
1234
1235 CIccMultiProcessElementList::const_iterator i;
1236
1237 for (i = m_list->begin(); i!= m_list->end(); i++) {
1238 if (i->ptr->IsLateBinding()) {
1239 return true;
1240 }
1241 }
1242
1243 return false;
1244}
1245
1246/**
1247******************************************************************************
1248* Name: CIccTagMultiProcessElement::IsLateBindingReflectance
1249*
1250* Purpose:
1251*
1252* Args:
1253*
1254* Return:
1255******************************************************************************/
1257{
1258 if (!m_list)
1259 return false;
1260
1261 CIccMultiProcessElementList::const_iterator i;
1262
1263 for (i = m_list->begin(); i!= m_list->end(); i++) {
1264 if (i->ptr->IsLateBindingReflectance()) {
1265 return true;
1266 }
1267 }
1268
1269 return false;
1270}
1271
1272/**
1273 ******************************************************************************
1274 * Name: CIccTagMultiProcessElement::Begin
1275 *
1276 * Purpose:
1277 * Initialize for application of processing element
1278 *
1279 * Args:
1280 * nInterp defines interpolation to use for N-Dimensional LUTs
1281 * pPCC provides Profile Connection Conditions (only expected to be valid during call to Begin)
1282 *
1283 * Return:
1284 * true if initialization successful, false if not
1285 ******************************************************************************/
1286bool CIccTagMultiProcessElement::Begin(icElemInterp nInterp /*=icElemInterpLinear*/,
1287 IIccProfileConnectionConditions *pProfilePCC /*= NULL*/,
1288 IIccProfileConnectionConditions *pAppliedPCC /*= NULL*/,
1289 IIccCmmEnvVarLookup *pCmmEnvVarLookup /*= NULL*/)
1290{
1291 if (!m_list || !m_list->size()) {
1292 if (m_nInputChannels != m_nOutputChannels)
1293 return false;
1294 else
1295 return true;
1296 }
1297
1298 m_pProfilePCC = pProfilePCC;
1299 m_pAppliedPCC = pAppliedPCC;
1300 m_pCmmEnvVarLookup = pCmmEnvVarLookup;
1301
1302 CIccMultiProcessElementList::iterator i;
1303
1304 m_nBufChannels=0;
1305
1306 //Now we initialize each processing element checking channel matching as we go
1307 CIccMultiProcessElement *last=NULL;
1308 i = m_list->begin();
1309 if (i->ptr->NumInputChannels() != m_nInputChannels)
1310 return false;
1311
1312 for (; i!= m_list->end(); i++) {
1313 if (last) {
1314 if (i->ptr->NumInputChannels() != last->NumOutputChannels())
1315 return false;
1316 }
1317 last = i->ptr;
1318
1319 if (last) {
1320 if (m_nBufChannels < last->NumOutputChannels())
1321 m_nBufChannels = last->NumOutputChannels();
1322
1323 if (!last->Begin(nInterp, this))
1324 return false;
1325 }
1326 }
1327
1328 //The output channels must match
1329 if (last && last->NumOutputChannels() != m_nOutputChannels)
1330 return false;
1331
1332 m_pAppliedPCC = NULL;
1333 m_pProfilePCC = NULL;
1334
1335 return true;
1336}
1337
1338
1339
1340
1341/**
1342******************************************************************************
1343* Name: CIccTagMultiProcessElement::ElementIndex
1344*
1345* Purpose:
1346*
1347* Args:
1348*
1349* Return:
1350******************************************************************************/
1352{
1353 CIccMultiProcessElementList::iterator i;
1354 icInt32Number n;
1355
1356 for (n=0, i=m_list->begin(); i!= m_list->end(); i++, n++) {
1357 if (i->ptr == pElem)
1358 break;
1359 }
1360 if (i==m_list->end())
1361 n=-1;
1362
1363 return n;
1364}
1365
1366CIccMultiProcessElementList::iterator CIccTagMultiProcessElement::GetFirstElem()
1367{
1368 return m_list->begin();
1369}
1370
1371CIccMultiProcessElementList::iterator CIccTagMultiProcessElement::GetLastElem()
1372{
1373 return m_list->end();
1374}
1375
1376
1377/**
1378******************************************************************************
1379* Name: CIccTagMultiProcessElement::GetNewApply
1380*
1381* Purpose:
1382*
1383* Args:
1384*
1385* Return:
1386******************************************************************************/
1388{
1389 CIccApplyTagMpe *pApply = new CIccApplyTagMpe(this);
1390
1391 if (!pApply)
1392 return NULL;
1393
1394 CIccDblPixelBuffer *pApplyBuf = pApply->GetBuf();
1395 pApplyBuf->UpdateChannels(m_nBufChannels);
1396 if (!pApplyBuf->Begin()) {
1397 delete pApply;
1398 return NULL;
1399 }
1400
1401 if (!m_list || !m_list->size())
1402 return pApply;
1403
1404 CIccMultiProcessElementList::iterator i, last;
1405 last = GetLastElem();
1406 for (i=GetFirstElem(); i!=last;) {
1407 pApply->AppendElem(i->ptr);
1408
1409 GetNextElemIterator(i);
1410 }
1411
1412 return pApply;
1413}
1414
1415//#define DEBUG_MPE_APPLY
1416
1417#ifdef DEBUG_MPE_APPLY
1418static void DumpMpeApplyPixe(int nCount, const icFloatNumber* pPixel, icUInt16Number nSamples)
1419{
1420 printf("Mpe%d:", nCount);
1421 for (icUInt16Number i = 0; i < nSamples; i++) {
1422 if (i)
1423 printf(",");
1424 printf(" %.3f", pPixel[i]);
1425 }
1426 printf("\n");
1427}
1428#endif
1429
1430/**
1431 ******************************************************************************
1432 * Name: CIccTagMultiProcessElement::Apply
1433 *
1434 * Purpose:
1435 *
1436 * Args:
1437 *
1438 * Return:
1439 ******************************************************************************/
1440void CIccTagMultiProcessElement::Apply(CIccApplyTagMpe *pApply, icFloatNumber *pDestPixel, const icFloatNumber *pSrcPixel) const
1441{
1442 if (!pApply || !pApply->GetList() || !pApply->GetList()->size()) {
1443 memcpy(pDestPixel, pSrcPixel, m_nInputChannels*sizeof(icFloatNumber));
1444 return;
1445 }
1446
1447#ifdef DEBUG_MPE_APPLY
1448 int nCount = 0;
1449 printf("Start of MPE APPLY\n");
1450 DumpMpeApplyPixe(nCount++, pSrcPixel, m_nInputChannels);
1451#endif
1452
1453 CIccDblPixelBuffer *pApplyBuf = pApply->GetBuf();
1454 CIccApplyMpeIter i = pApply->begin();
1455 CIccApplyMpeIter next;
1456
1457 next = i;
1458 next++;
1459
1460 if (next==pApply->end()) {
1461 //Elements rely on pDestPixel != pSrcPixel
1462 if (pSrcPixel==pDestPixel) {
1463 i->ptr->Apply(pApplyBuf->GetDstBuf(), pSrcPixel);
1464 memcpy(pDestPixel, pApplyBuf->GetDstBuf(), m_nOutputChannels*sizeof(icFloatNumber));
1465 }
1466 else {
1467 i->ptr->Apply(pDestPixel, pSrcPixel);
1468 }
1469#ifdef DEBUG_MPE_APPLY
1470 DumpMpeApplyPixe(nCount++, pSrcPixel, m_nInputChannels);
1471#endif
1472 }
1473 else {
1474 i->ptr->Apply(pApplyBuf->GetDstBuf(), pSrcPixel);
1475
1476#ifdef DEBUG_MPE_APPLY
1477 DumpMpeApplyPixe(nCount++, pApplyBuf->GetDstBuf(), m_nInputChannels);
1478#endif
1479
1480 i++;
1481 next++;
1482 pApplyBuf->Switch();
1483
1484 while (next != pApply->end()) {
1485 CIccMultiProcessElement *pElem = i->ptr->GetElem();
1486
1487 if (!pElem->IsAcs()) {
1488 i->ptr->Apply(pApplyBuf->GetDstBuf(), pApplyBuf->GetSrcBuf());
1489
1490#ifdef DEBUG_MPE_APPLY
1491 DumpMpeApplyPixe(nCount++, pApplyBuf->GetDstBuf(), m_nInputChannels);
1492#endif
1493
1494 pApplyBuf->Switch();
1495 }
1496
1497 i++;
1498 next++;
1499 }
1500
1501 i->ptr->Apply(pDestPixel, pApplyBuf->GetSrcBuf());
1502
1503#ifdef DEBUG_MPE_APPLY
1504 DumpMpeApplyPixe(nCount++, pDestPixel, m_nInputChannels);
1505#endif
1506
1507 }
1508
1509#ifdef DEBUG_MPE_APPLY
1510 printf("End MPE Apply\n\n");
1511#endif
1512
1513}
1514
1515
1516/**
1517 ******************************************************************************
1518 * Name: CIccTagMultiProcessElement::Validate
1519 *
1520 * Purpose:
1521 *
1522 * Args:
1523 *
1524 * Return:
1525 ******************************************************************************/
1526icValidateStatus CIccTagMultiProcessElement::Validate(std::string sigPath, std::string &sReport,
1527 const CIccProfile* pProfile /*=NULL*/) const
1528{
1530
1531 CIccInfo Info;
1532 std::string sSigPathName = Info.GetSigPathName(sigPath);
1533 bool bMatchChannels = true;
1534
1535 if (!m_list || !m_list->size()) {
1536 if (m_nInputChannels != m_nOutputChannels) {
1537 sReport += icMsgValidateCriticalError;
1538 sReport += sSigPathName;
1539 sReport += " No processing elements and input and output channels do not match!\n";
1541 }
1542 else {
1543 sReport += icMsgValidateWarning;
1544 sReport += sSigPathName;
1545 sReport += " No processing elements.\n";
1547 }
1548 }
1549
1550 if (!pProfile) {
1551 sReport += icMsgValidateWarning;
1552 sReport += sSigPathName;
1553 sReport += " - Tag validation incomplete: Pointer to profile unavailable.\n";
1555 return rv;
1556 }
1557 icUInt32Number nInput, nOutput;
1558
1559 //Check # of channels
1560 switch(icGetFirstSigPathSig(sigPath)) {
1561 case icSigAToB0Tag:
1562 case icSigAToB1Tag:
1563 case icSigAToB2Tag:
1564 case icSigAToB3Tag:
1565 {
1566 nInput = icGetSpaceSamples(pProfile->m_Header.colorSpace);
1567 if (m_nInputChannels != nInput) {
1568 sReport += icMsgValidateCriticalError;
1569 sReport += sSigPathName;
1570 sReport += " - Incorrect number of input channels.\n";
1572 }
1573
1574 nOutput = icGetSpaceSamples(pProfile->m_Header.pcs);
1575 if (m_nOutputChannels != nOutput) {
1576 sReport += icMsgValidateCriticalError;
1577 sReport += sSigPathName;
1578 sReport += " - Incorrect number of output channels.\n";
1580 }
1581
1582 break;
1583 }
1584 case icSigBToA0Tag:
1585 case icSigBToA1Tag:
1586 case icSigBToA2Tag:
1587 case icSigBToA3Tag:
1588 {
1589 nInput = icGetSpaceSamples(pProfile->m_Header.pcs);
1590 if (m_nInputChannels!=nInput) {
1591 sReport += icMsgValidateCriticalError;
1592 sReport += sSigPathName;
1593 sReport += " - Incorrect number of input channels.\n";
1595 }
1596
1597 nOutput = icGetSpaceSamples(pProfile->m_Header.colorSpace);
1598 if (m_nOutputChannels!=nOutput) {
1599 sReport += icMsgValidateCriticalError;
1600 sReport += sSigPathName;
1601 sReport += " - Incorrect number of output channels.\n";
1603 }
1604
1605 break;
1606 }
1607 case icSigDToB0Tag:
1608 case icSigDToB1Tag:
1609 case icSigDToB2Tag:
1610 case icSigDToB3Tag:
1611 {
1612 nInput = icGetSpaceSamples(pProfile->m_Header.colorSpace);
1613 if (m_nInputChannels != nInput) {
1614 sReport += icMsgValidateCriticalError;
1615 sReport += sSigPathName;
1616 sReport += " - Incorrect number of input channels.\n";
1618 }
1619
1620 nOutput = icGetSpectralSpaceSamples(&pProfile->m_Header);
1621 if (m_nOutputChannels != nOutput) {
1622 sReport += icMsgValidateCriticalError;
1623 sReport += sSigPathName;
1624 sReport += " - Incorrect number of output channels.\n";
1626 }
1627
1628 break;
1629 }
1630 case icSigBToD0Tag:
1631 case icSigBToD1Tag:
1632 case icSigBToD2Tag:
1633 case icSigBToD3Tag:
1634 {
1635 nInput = icGetSpectralSpaceSamples(&pProfile->m_Header);
1636 if (m_nInputChannels!=nInput) {
1637 sReport += icMsgValidateCriticalError;
1638 sReport += sSigPathName;
1639 sReport += " - Incorrect number of input channels.\n";
1641 }
1642
1643 nOutput = icGetSpaceSamples(pProfile->m_Header.colorSpace);
1644 if (m_nOutputChannels!=nOutput) {
1645 sReport += icMsgValidateCriticalError;
1646 sReport += sSigPathName;
1647 sReport += " - Incorrect number of output channels.\n";
1649 }
1650
1651 break;
1652 }
1653 case icSigHToS0Tag:
1654 case icSigHToS1Tag:
1655 case icSigHToS2Tag:
1656 case icSigHToS3Tag:
1657 {
1658 nInput = icGetSpaceSamples(pProfile->m_Header.pcs);
1659 if (m_nInputChannels != nInput) {
1660 sReport += icMsgValidateCriticalError;
1661 sReport += sSigPathName;
1662 sReport += " - Incorrect number of input channels.\n";
1664 }
1665
1666 nOutput = icGetSpaceSamples(pProfile->m_Header.pcs);
1667 if (m_nOutputChannels != nOutput) {
1668 sReport += icMsgValidateCriticalError;
1669 sReport += sSigPathName;
1670 sReport += " - Incorrect number of output channels.\n";
1672 }
1673
1674 break;
1675 }
1678 {
1679 if (m_nInputChannels != 3) {
1680 sReport += icMsgValidateCriticalError;
1681 sReport += sSigPathName;
1682 sReport += " - Incorrect number of input channels.\n";
1684 }
1685
1686 if (m_nOutputChannels != 3) {
1687 sReport += icMsgValidateCriticalError;
1688 sReport += sSigPathName;
1689 sReport += " - Incorrect number of output channels.\n";
1691 }
1692
1693 break;
1694 }
1695 case icSigBRDFAToB0Tag:
1696 case icSigBRDFAToB1Tag:
1697 case icSigBRDFAToB2Tag:
1698 case icSigBRDFAToB3Tag:
1699 {
1700 switch(icGetFirstSigPathSig(sigPath)) {
1702 //TODO: Initialize input and output
1703 nInput = nOutput = 0;
1704 break;
1705
1707 //TODO: Initialize input and output
1708 nInput = nOutput = 0;
1709 break;
1710
1712 //TODO: Initialize input and output
1713 nInput = nOutput = 0;
1714 break;
1715
1716 default:
1717 break;
1718 }
1719 break;
1720 }
1721 case icSigBRDFDToB0Tag:
1722 case icSigBRDFDToB1Tag:
1723 case icSigBRDFDToB2Tag:
1724 case icSigBRDFDToB3Tag:
1725 {
1726 switch(icGetFirstSigPathSig(sigPath)) {
1728 //TODO: Initialize input and output
1729 nInput = nOutput = 0;
1730 break;
1731
1733 //TODO: Initialize input and output
1734 nInput = nOutput = 0;
1735 break;
1736
1738 //TODO: Initialize input and output
1739 nInput = nOutput = 0;
1740 break;
1741
1742 default:
1743 break;
1744 }
1745 break;
1746 }
1747
1748 case icSigMToA0Tag:
1749 {
1750 nInput = icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs);
1751 if (m_nInputChannels != nInput) {
1752 sReport += icMsgValidateCriticalError;
1753 sReport += sSigPathName;
1754 sReport += " - Incorrect number of input channels.\n";
1756 }
1757
1758 nOutput = icGetSpaceSamples(pProfile->m_Header.colorSpace);
1759 if (m_nOutputChannels != nOutput) {
1760 sReport += icMsgValidateCriticalError;
1761 sReport += sSigPathName;
1762 sReport += " - Incorrect number of output channels.\n";
1764 }
1765
1766 break;
1767 }
1768
1769 case icSigAToM0Tag:
1770 {
1771 nInput = icGetSpaceSamples(pProfile->m_Header.colorSpace);
1772 if (m_nInputChannels != nInput) {
1773 sReport += icMsgValidateCriticalError;
1774 sReport += sSigPathName;
1775 sReport += " - Incorrect number of input channels.\n";
1777 }
1778
1779 nOutput = icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs);
1780 if (m_nOutputChannels != nOutput) {
1781 sReport += icMsgValidateCriticalError;
1782 sReport += sSigPathName;
1783 sReport += " - Incorrect number of output channels.\n";
1785 }
1786
1787 break;
1788 }
1789
1790 case icSigMToB0Tag:
1791 case icSigMToB1Tag:
1792 case icSigMToB2Tag:
1793 case icSigMToB3Tag:
1794 {
1795 nInput = icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs);
1796 if (m_nInputChannels != nInput) {
1797 sReport += icMsgValidateCriticalError;
1798 sReport += sSigPathName;
1799 sReport += " - Incorrect number of input channels.\n";
1801 }
1802
1803 nOutput = icGetSpaceSamples(pProfile->m_Header.pcs);
1804 if (m_nOutputChannels != nOutput) {
1805 sReport += icMsgValidateCriticalError;
1806 sReport += sSigPathName;
1807 sReport += " - Incorrect number of output channels.\n";
1809 }
1810
1811 break;
1812 }
1813
1814 case icSigMToS0Tag:
1815 case icSigMToS1Tag:
1816 case icSigMToS2Tag:
1817 case icSigMToS3Tag:
1818 {
1819 nInput = icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs);
1820 if (m_nInputChannels != nInput) {
1821 sReport += icMsgValidateCriticalError;
1822 sReport += sSigPathName;
1823 sReport += " - Incorrect number of input channels.\n";
1825 }
1826
1827 nOutput = icGetSpectralSpaceSamples(&pProfile->m_Header);
1828 if (m_nOutputChannels != nOutput) {
1829 sReport += icMsgValidateCriticalError;
1830 sReport += sSigPathName;
1831 sReport += " - Incorrect number of output channels.\n";
1833 }
1834
1835 break;
1836 }
1837
1838 default:
1839 sReport += icMsgValidateWarning;
1840 sReport += sSigPathName;
1841 sReport += " - Unknown tag - Cannot validate input and output channels!\n";
1843 bMatchChannels = false;
1844 break;
1845 }
1846
1847 if (!m_list || !m_list->size()) {
1848 return rv;
1849 }
1850
1851 CIccMultiProcessElementList::iterator i = m_list->begin();
1852 CIccMultiProcessElement *last=NULL;
1853
1854 if (bMatchChannels && i->ptr->NumInputChannels() != m_nInputChannels) {
1855 sReport += icMsgValidateCriticalError;
1856 sReport += sSigPathName;
1857 sReport += "Mis-matching number of input channels in first process element!\n";
1859 }
1860
1861 for (; i!= m_list->end(); i++) {
1862 if (last) {
1863 if (i->ptr->NumInputChannels() != last->NumOutputChannels()) {
1864 sReport += icMsgValidateCriticalError;
1865 sReport += sSigPathName;
1866
1867 sReport += "(";
1868 sReport += last->GetClassName();
1869 sReport += "->";
1870 sReport += i->ptr->GetClassName();
1871
1872 sReport += " Mis-matching number of channels in last process element!\n";
1874 }
1875 }
1876 last = i->ptr;
1877
1878 if (last)
1879 rv = icMaxStatus(rv, last->Validate(sigPath+icGetSigPath(GetType()), sReport, this));
1880 }
1881
1882 if (bMatchChannels && last && last->NumOutputChannels() != m_nOutputChannels) {
1883 sReport += icMsgValidateCriticalError;
1884 sReport += sSigPathName;
1885 sReport += " Mis-matching number of output channels!\n";
1887 }
1888
1889 return rv;
1890}
1891
1892#ifdef USEREFICCMAXNAMESPACE
1893} //namespace refIccMAX
1894#endif
icArraySignature sig
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
@ icValidateNonCompliant
Definition IccDefs.h:121
File: IccIO.h.
@ icSeekSet
Definition IccIO.h:83
File: IccMpeFactory.h.
std::map< icUInt32Number, CIccMultiProcessElement * > CIccLutOffsetMap
std::map< CIccMultiProcessElement *, icPositionNumber > CIccLutPtrMap
File: IccTagMPE.h.
std::list< CIccMultiProcessElementPtr > CIccMultiProcessElementList
Definition IccTagMPE.h:120
CIccApplyMpeList::iterator CIccApplyMpeIter
Definition IccTagMPE.h:130
icElemInterp
Definition IccTagMPE.h:93
std::list< CIccApplyMpePtr > CIccApplyMpeList
Definition IccTagMPE.h:129
icValidateStatus icMaxStatus(icValidateStatus s1, icValidateStatus s2)
Name: icMaxStatus.
Definition IccUtil.cpp:244
std::string icGetSigPath(icUInt32Number nSig)
Definition IccUtil.cpp:1191
const char * icMsgValidateWarning
Definition IccUtil.cpp:90
icUInt32Number icGetSpaceSamples(icColorSpaceSignature sig)
Definition IccUtil.cpp:1303
icUInt32Number icGetSpectralSpaceSamples(const icHeader *pHdr)
Definition IccUtil.cpp:1367
icUInt32Number icGetMaterialColorSpaceSamples(icMaterialColorSignature sig)
Definition IccUtil.cpp:1391
void icMemDump(std::string &sDump, void *pBuf, icUInt32Number nNum)
Definition IccUtil.cpp:951
const char * icMsgValidateNonCompliant
Definition IccUtil.cpp:91
const char * icMsgValidateCriticalError
Definition IccUtil.cpp:92
icSignature icGetFirstSigPathSig(std::string sigPath)
Definition IccUtil.cpp:1201
const icChar * icGetSig(icChar *pBuf, icUInt32Number nSig, bool bGetHexVal)
Definition IccUtil.cpp:1028
File: IccUtil.h.
icTagTypeSignature
unsigned int icUInt32Number
Class: CIccApplyMpe.
Definition IccTagMPE.h:203
CIccApplyMpe(CIccMultiProcessElement *pElem)
Name: CIccApplyMpe::CIccApplyMpe.
Definition IccTagMPE.cpp:99
virtual ~CIccApplyMpe()
Name: CIccApplyMpe::~CIccApplyMpe.
CIccApplyMpe * ptr
Definition IccTagMPE.h:126
Class: CIccTagMultiProcessElement.
Definition IccTagMPE.h:321
CIccDblPixelBuffer * GetBuf()
Definition IccTagMPE.h:330
CIccApplyTagMpe(CIccTagMultiProcessElement *pTag)
Name: CIccApplyTagMpe::CIccApplyTagMpe.
virtual ~CIccApplyTagMpe()
Name: CIccApplyTagMpe::~CIccApplyTagMpe.
virtual bool AppendElem(CIccMultiProcessElement *pElem)
Name: CIccApplyTagMpe::CIccApplyTagMpe.
CIccApplyMpeIter end()
Definition IccTagMPE.h:334
CIccApplyMpeList * GetList()
Definition IccTagMPE.h:331
CIccApplyMpeIter begin()
Definition IccTagMPE.h:333
Class: CIccDblPixelBuffer.
Definition IccTagMPE.h:278
CIccDblPixelBuffer & operator=(const CIccDblPixelBuffer &buf)
Name: CIccDblPixelBuffer::CIccDblPixelBuffer.
void UpdateChannels(icUInt16Number nNumChannels)
Definition IccTagMPE.h:288
icFloatNumber * GetSrcBuf()
Definition IccTagMPE.h:297
icUInt16Number m_nMaxChannels
Definition IccTagMPE.h:306
icFloatNumber * m_pixelBuf2
Definition IccTagMPE.h:309
icFloatNumber * m_pixelBuf1
Definition IccTagMPE.h:308
bool Begin()
Name: CIccDblPixelBuffer::CIccDblPixelBuffer.
void Clean()
Name: CIccDblPixelBuffer::CIccDblPixelBuffer.
virtual ~CIccDblPixelBuffer()
Name: CIccDblPixelBuffer::~CIccDblPixelBuffer.
CIccDblPixelBuffer()
Name: CIccDblPixelBuffer::CIccDblPixelBuffer.
icFloatNumber * GetDstBuf()
Definition IccTagMPE.h:298
Type: Class.
Definition IccIO.h:97
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
virtual icInt32Number Tell()
Definition IccIO.h:133
bool Align32()
Write operation to make sure that filelength is evenly divisible by 4.
Definition IccIO.cpp:341
icInt32Number Write32(void *pBuf32, icInt32Number nNum=1)
Definition IccIO.cpp:152
virtual icInt32Number Seek(icInt32Number nOffset, icSeekVal pos)
Definition IccIO.h:132
icInt32Number Read32(void *pBuf32, icInt32Number nNum=1)
Definition IccIO.cpp:143
Type: Class.
Definition IccUtil.h:303
std::string GetSigPathName(std::string sigPath)
Definition IccUtil.cpp:1614
static CIccMultiProcessElement * CreateElement(icElemTypeSignature elemTypeSig)
Function: CreateElement(elemTypeSig) Create a element of type elemTypeSig.
Class: CIccMpeUnknown.
Definition IccTagMPE.h:230
void SetType(icElemTypeSignature sig)
Name: CIccMpeUnknown::SetType.
virtual bool Write(CIccIO *pIO)
Name: CIccMpeUnknown::Write.
virtual ~CIccMpeUnknown()
Name: CIccMpeUnknown::~CIccMpeUnknown.
icUInt16Number m_nOutputChannels
Definition IccTagMPE.h:264
CIccMpeUnknown & operator=(const CIccMpeUnknown &elem)
Name: CIccMpeUnknown::operator=.
icUInt32Number m_nReserved
Definition IccTagMPE.h:262
icElemTypeSignature m_sig
Definition IccTagMPE.h:261
bool SetDataSize(icUInt32Number nSize, bool bZeroData=true)
Name: CIccMpeUnknown::SetDataSize.
virtual bool Read(icUInt32Number nSize, CIccIO *pIO)
Name: CIccMpeUnknown::Read.
icUInt16Number m_nInputChannels
Definition IccTagMPE.h:263
void SetChannels(icUInt16Number nInputChannels, icUInt16Number nOutputChannels)
Name: CIccMpeUnknown::Describe.
icUInt32Number m_nSize
Definition IccTagMPE.h:265
CIccMpeUnknown()
Name: CIccMpeUnknown::CIccMpeUnknown.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement *pMPE=NULL, const CIccProfile *pProfile=NULL) const
Name: CIccMpeUnknown::Validate.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccMpeUnknown::Describe.
icUInt8Number * m_pData
Definition IccTagMPE.h:266
Class: CIccMultiProcessElement.
Definition IccTagMPE.h:146
virtual void Apply(CIccApplyMpe *pApply, icFloatNumber *pDestPixel, const icFloatNumber *pSrcPixel) const =0
virtual icUInt16Number NumOutputChannels() const
Definition IccTagMPE.h:160
virtual CIccMultiProcessElement * NewCopy() const =0
virtual bool Begin(icElemInterp nIterp=icElemInterpLinear, CIccTagMultiProcessElement *pMPE=NULL)=0
virtual bool Read(icUInt32Number size, CIccIO *pIO)=0
virtual bool IsAcs()
Definition IccTagMPE.h:177
static CIccMultiProcessElement * Create(icElemTypeSignature sig)
Name: CIccMultiProcessElement::Create.
virtual CIccApplyMpe * GetNewApply(CIccApplyTagMpe *pApplyTag)
Name: CIccMultiProcessElement::GetNewApply()
virtual const icChar * GetClassName() const =0
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement *pMPE=NULL, const CIccProfile *pProfile=NULL) const =0
Name: CIccProcessElement::Validate.
Class: CIccProcessElementPtr.
Definition IccTagMPE.h:115
CIccMultiProcessElement * ptr
Definition IccTagMPE.h:117
icUInt32Number m_nReserved
Class: CIccTagMultiProcessElement.
Definition IccTagMPE.h:358
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagMultiProcessElement::Read.
virtual bool IsSupported()
Name: CIccTagMultiProcessElement::IsSupported.
virtual void Attach(CIccMultiProcessElement *pElement)
Name: CIccTagMultiProcessElement::Attach.
virtual bool Begin(icElemInterp nInterp=icElemInterpLinear, IIccProfileConnectionConditions *pProfilePCC=NULL, IIccProfileConnectionConditions *pAppliedPCC=NULL, IIccCmmEnvVarLookup *pCmmEnvVarLookup=NULL)
Name: CIccTagMultiProcessElement::Begin.
icUInt16Number m_nInputChannels
Definition IccTagMPE.h:415
IIccCmmEnvVarLookup * m_pCmmEnvVarLookup
Definition IccTagMPE.h:431
virtual CIccMultiProcessElementList::iterator GetLastElem()
virtual ~CIccTagMultiProcessElement()
Name: CIccTagMultiProcessElement::~CIccTagMultiProcessElement.
icUInt16Number m_nOutputChannels
Definition IccTagMPE.h:416
CIccMultiProcessElementList * m_list
Definition IccTagMPE.h:419
virtual CIccMultiProcessElementList::iterator GetFirstElem()
virtual CIccApplyTagMpe * GetNewApply()
Name: CIccTagMultiProcessElement::GetNewApply.
virtual void Apply(CIccApplyTagMpe *pApply, icFloatNumber *pDestPixel, const icFloatNumber *pSrcPixel) const
Name: CIccTagMultiProcessElement::Apply.
IIccProfileConnectionConditions * m_pAppliedPCC
Definition IccTagMPE.h:429
icUInt32Number m_nProcElements
Definition IccTagMPE.h:422
virtual bool Write(CIccIO *pIO)
Name: CIccTagMultiProcessElement::Write.
virtual void Clean()
Name: CIccTagMultiProcessElement::Clean.
CIccTagMultiProcessElement & operator=(const CIccTagMultiProcessElement &lut)
Name: &operator=.
virtual void Insert(CIccMultiProcessElement *pElement)
Name: CIccTagMultiProcessElement::Insert.
bool IsLateBinding() const
Name: CIccTagMultiProcessElement::IsLateBinding.
icPositionNumber * m_position
Definition IccTagMPE.h:423
CIccTagMultiProcessElement(icUInt16Number nInputChannels=0, icUInt16Number nOutputChannels=0)
Name: CIccTagMultiProcessElement::CIccTagMultiProcessElement.
bool IsLateBindingReflectance() const
Name: CIccTagMultiProcessElement::IsLateBindingReflectance.
CIccMultiProcessElement * GetElement(int nIndex)
Name: CIccTagMultiProcessElement::GetElement.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagMultiProcessElement::Validate.
virtual void GetNextElemIterator(CIccMultiProcessElementList::iterator &itr)
Name: CIccTagMultiProcessElement::GetNextElemIterator.
virtual icInt32Number ElementIndex(CIccMultiProcessElement *pElem)
Name: CIccTagMultiProcessElement::ElementIndex.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagMultiProcessElement::Describe.
IIccProfileConnectionConditions * m_pProfilePCC
Definition IccTagMPE.h:428
Type: Class.
Definition IccUtil.h:401
unsigned char icUInt8Number
Number definitions.
unsigned short icUInt16Number
long icInt32Number
icElemTypeSignature
Multi-Processing Element type signatures.
#define icSigUnknownElemType
Convenience Enum Definitions - Not defined in proposal.
icUInt32Number icUInt64Number[2]
@ icSigBToD0Tag
@ icSigBToA2Tag
@ icSigBRDFDToB0Tag
@ icSigAToB3Tag
@ icSigHToS3Tag
@ icSigMToS3Tag
@ icSigBToD2Tag
@ icSigAToM0Tag
@ icSigHToS2Tag
@ icSigMToB0Tag
@ icSigAToB0Tag
@ icSigMToB3Tag
@ icSigBToA1Tag
@ icSigDToB3Tag
@ icSigAToB2Tag
@ icSigBRDFAToB1Tag
@ icSigBRDFAToB2Tag
@ icSigCustomToStandardPccTag
@ icSigBRDFAToB0Tag
@ icSigDToB0Tag
@ icSigBToD3Tag
@ icSigBToA0Tag
@ icSigMToS0Tag
@ icSigMToS2Tag
@ icSigHToS1Tag
@ icSigBToD1Tag
@ icSigMToB1Tag
@ icSigHToS0Tag
@ icSigBRDFAToB3Tag
@ icSigAToB1Tag
@ icSigBToA3Tag
@ icSigDToB2Tag
@ icSigStandardToCustomPccTag
@ icSigMToA0Tag
@ icSigMToS1Tag
@ icSigDToB1Tag
@ icSigBRDFDToB1Tag
@ icSigBRDFDToB2Tag
@ icSigMToB2Tag
@ icSigBRDFDToB3Tag
@ icSigBrdfLightTransformMbr
@ icSigBrdfOutputTransformMbr
@ icSigBrdfTransformMbr
icUInt32Number offset
icUInt32Number size