Bug Summary

File:IccProfLib/IccTagMPE.cpp
Warning:line 1628, column 22
Although the value stored to 'nOutput' is used in the enclosing expression, the value is never actually read from 'nOutput'

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;
Although the value stored to 'nOutput' is used in the enclosing expression, the value is never actually read from 'nOutput'
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