Bug Summary

File:IccProfLib/IccTagMPE.cpp
Warning:line 1628, column 13
Value stored to 'nInput' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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