Bug Summary

File:IccProfLib/IccTagComposite.cpp
Warning:line 1126, column 14
Value stored to 'pArrayObj' during its initialization 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 IccTagComposite.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/IccTagComposite.cpp
1/** @file
2 File: IccTagComposite.cpp
3
4 Contains: Implementation of Struct and Array Tags
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 Oct-21-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 "IccTagComposite.h"
80#include "IccStructBasic.h"
81#include "IccUtil.h"
82#include "IccIO.h"
83#include "IccStructFactory.h"
84#include "IccArrayFactory.h"
85
86bool IIccStruct::Describe(std::string &sDescription) const
87{
88 if (!m_pTagStruct) {
89 return false;
90 }
91 else {
92 char buf[256];
93 CIccInfo info;
94
95 sprintf(buf, "BEGIN UNKNOWN_TAG_STRUCT ");
96 sDescription += buf;
97 sDescription += info.GetStructSigName(m_pTagStruct->GetTagStructType());
98 sDescription += "\r\n\r\n";
99
100 TagEntryList::iterator i;
101 TagEntryList *pList = m_pTagStruct->GetElemList();
102 for (i=pList->begin(); i!=pList->end(); i++) {
103 i->pTag->Describe(sDescription);
104 }
105
106 sDescription += "\r\n";
107 sprintf(buf, "END TAG_STRUCT\r\n");
108 sDescription += buf;
109 sDescription += "\r\n";
110 }
111
112 return true;
113}
114
115TagEntryList* IIccStruct::getTagEntries() const
116{
117 if (m_pTagStruct)
118 return m_pTagStruct->m_ElemEntries;
119
120 return NULL__null;
121}
122
123
124/**
125 ******************************************************************************
126 * Name: CIccTagStruct::CIccTagStruct
127 *
128 * Purpose:
129 *
130 * Args:
131 *
132 * Return:
133 ******************************************************************************/
134CIccTagStruct::CIccTagStruct()
135{
136 m_ElemEntries = new(TagEntryList);
137 m_ElemVals = new(TagPtrList);
138 m_pStruct = NULL__null;
139}
140
141/**
142 ******************************************************************************
143 * Name: CIccTagStruct::CIccTagStruct
144 *
145 * Purpose:
146 *
147 * Args:
148 *
149 * Return:
150 ******************************************************************************/
151CIccTagStruct::CIccTagStruct(const CIccTagStruct &subTags)
152{
153 m_sigStructType = subTags.m_sigStructType;
154 m_ElemEntries = new(TagEntryList);
155 m_ElemVals = new(TagPtrList);
156
157 if (!subTags.m_ElemEntries->empty()) {
158 TagEntryList::const_iterator i;
159 IccTagEntry entry;
160 for (i=subTags.m_ElemEntries->begin(); i!=subTags.m_ElemEntries->end(); i++) {
161 entry.pTag = i->pTag->NewCopy();
162 memcpy(&entry.TagInfo, &i->TagInfo, sizeof(icTag));
163 m_ElemEntries->push_back(entry);
164 }
165 }
166
167 if (!subTags.m_ElemVals->empty()) {
168 TagPtrList::const_iterator i;
169 IccTagPtr tagptr;
170 for (i=subTags.m_ElemVals->begin(); i!=subTags.m_ElemVals->end(); i++) {
171 tagptr.ptr = i->ptr->NewCopy();
172 m_ElemVals->push_back(tagptr);
173 }
174 }
175
176 if (subTags.m_pStruct) {
177 m_pStruct = subTags.m_pStruct->NewCopy(this);
178 }
179 else {
180 m_pStruct = NULL__null;
181 }
182}
183
184/**
185 ******************************************************************************
186 * Name: &operator=
187 *
188 * Purpose:
189 *
190 * Args:
191 *
192 * Return:
193 ******************************************************************************/
194CIccTagStruct &CIccTagStruct::operator=(const CIccTagStruct &subTags)
195{
196 if (&subTags == this)
197 return *this;
198
199 Cleanup();
200
201 m_sigStructType = subTags.m_sigStructType;
202
203 if (!subTags.m_ElemEntries->empty()) {
204 m_ElemEntries->clear();
205 TagEntryList::const_iterator i;
206 IccTagEntry entry;
207 for (i=subTags.m_ElemEntries->begin(); i!=subTags.m_ElemEntries->end(); i++) {
208 entry.pTag = i->pTag->NewCopy();
209 memcpy(&entry.TagInfo, &i->TagInfo, sizeof(icTag));
210 m_ElemEntries->push_back(entry);
211 }
212 }
213
214 if (!subTags.m_ElemVals->empty()) {
215 m_ElemVals->clear();
216 TagPtrList::const_iterator i;
217 IccTagPtr tagptr;
218 for (i=subTags.m_ElemVals->begin(); i!=subTags.m_ElemVals->end(); i++) {
219 tagptr.ptr = i->ptr->NewCopy();
220 m_ElemVals->push_back(tagptr);
221 }
222 }
223
224 if (subTags.m_pStruct)
225 m_pStruct = subTags.m_pStruct->NewCopy(this);
226 else
227 m_pStruct = NULL__null;
228
229 return *this;
230}
231
232/**
233 ******************************************************************************
234 * Name: CIccTagStruct::~CIccTagStruct
235 *
236 * Purpose:
237 *
238 * Args:
239 *
240 * Return:
241 ******************************************************************************/
242CIccTagStruct::~CIccTagStruct()
243{
244 Cleanup();
245
246 delete m_ElemEntries;
247 delete m_ElemVals;
248
249 if (m_pStruct)
250 delete m_pStruct;
251}
252
253
254/**
255 ******************************************************************************
256 * Name: CIccTagStruct::ParseMem
257 *
258 * Purpose:
259 *
260 * Args:
261 *
262 * Return:
263 ******************************************************************************/
264CIccTagStruct* CIccTagStruct::ParseMem(icUInt8Number *pMem, icUInt32Number size)
265{
266 CIccMemIO IO;
267
268 if (!IO.Attach(pMem, size))
269 return NULL__null;
270
271 CIccTagStruct *pTags = new CIccTagStruct;
272
273 if (!pTags->Read(size, &IO)) {
274 delete pTags;
275 return NULL__null;
276 }
277
278 return pTags;
279}
280
281
282/**
283 ******************************************************************************
284 * Name: CIccTagStruct::Describe
285 *
286 * Purpose:
287 *
288 * Args:
289 *
290 * Return:
291 ******************************************************************************/
292void CIccTagStruct::Describe(std::string &sDescription)
293{
294 std::string name;
295 CIccStructCreator::GetStructSigName(name, m_sigStructType);
296
297 sDescription += "BEGIN STRUCT \"";
298 sDescription += name + "\"\r\n";
299
300 if (m_pStruct) {
301 m_pStruct->Describe(sDescription);
302 }
303 else {
304 IIccStruct *pStruct = CIccStructCreator::CreateStruct(m_sigStructType, this);
305 if (pStruct) {
306 pStruct->Describe(sDescription);
307 delete pStruct;
308 }
309 else {
310 CIccStructUnknown structHandler(this);
311
312 structHandler.Describe(sDescription);
313 }
314 }
315 sDescription += "END STRUCT \"";
316 sDescription += name + "\"\r\n";
317}
318
319
320/**
321 ******************************************************************************
322 * Name: CIccTagStruct::Read
323 *
324 * Purpose:
325 *
326 * Args:
327 *
328 * Return:
329 ******************************************************************************/
330bool CIccTagStruct::Read(icUInt32Number size, CIccIO *pIO)
331{
332 icTagTypeSignature sig;
333
334 m_tagSize = size;
335
336 icUInt32Number headerSize = sizeof(icTagTypeSignature) +
337 sizeof(icUInt32Number) +
338 sizeof(icStructSignature) +
339 sizeof(icUInt32Number);
340
341 if (headerSize > size)
342 return false;
343
344 if (!pIO) {
345 return false;
346 }
347
348 Cleanup();
349
350 m_tagStart = pIO->Tell();
351
352 if (!pIO->Read32(&sig))
353 return false;
354
355 if (!pIO->Read32(&m_nReserved))
356 return false;
357
358 if (!pIO->Read32(&m_sigStructType))
359 return false;
360
361 icUInt32Number count, i;
362 IccTagEntry TagEntry;
363
364 TagEntry.pTag = NULL__null;
365
366 if (!pIO->Read32(&count))
367 return false;
368
369 if (headerSize + (icUInt64Number)count*sizeof(icUInt32Number)*3 > size)
370 return false;
371
372 //Read TagDir
373 for (i=0; i<count; i++) {
374 if (!pIO->Read32(&TagEntry.TagInfo.sig) ||
375 !pIO->Read32(&TagEntry.TagInfo.offset) ||
376 !pIO->Read32(&TagEntry.TagInfo.size)) {
377 return false;
378 }
379 m_ElemEntries->push_back(TagEntry);
380 }
381
382 TagEntryList::iterator entry;
383
384 for (entry=m_ElemEntries->begin(); entry!=m_ElemEntries->end(); entry++) {
385 if (!LoadElem((IccTagEntry*)&(entry->TagInfo), pIO)) {
386 Cleanup();
387 return false;
388 }
389 }
390
391
392 return true;
393}
394
395/**
396 ******************************************************************************
397 * Name: CIccTagStruct::Write
398 *
399 * Purpose:
400 *
401 * Args:
402 *
403 * Return:
404 ******************************************************************************/
405bool CIccTagStruct::Write(CIccIO *pIO)
406{
407 icTagTypeSignature sig = GetType();
408
409 if (!pIO)
410 return false;
411
412 m_tagStart = pIO->Tell();
413
414 if (!pIO->Write32(&sig))
415 return false;
416
417 if (!pIO->Write32(&m_nReserved))
418 return false;
419
420 if (!pIO->Write32(&m_sigStructType))
421 return false;
422
423 TagEntryList::iterator i, j;
424 icUInt32Number count;
425
426 for (count=0, i=m_ElemEntries->begin(); i!= m_ElemEntries->end(); i++) {
427 if (i->pTag)
428 count++;
429 }
430
431 pIO->Write32(&count);
432
433 icUInt32Number dirpos = pIO->Tell();
434
435 //Write Unintialized TagDir
436 for (i=m_ElemEntries->begin(); i!= m_ElemEntries->end(); i++) {
437 if (i->pTag) {
438 i->TagInfo.offset = 0;
439 i->TagInfo.size = 0;
440
441 pIO->Write32(&i->TagInfo.sig);
442 pIO->Write32(&i->TagInfo.offset);
443 pIO->Write32(&i->TagInfo.size);
444 }
445 }
446
447 //Write Tags
448 for (i=m_ElemEntries->begin(); i!= m_ElemEntries->end(); i++) {
449 if (i->pTag) {
450 for (j=m_ElemEntries->begin(); j!=i; j++) {
451 if (i->pTag == j->pTag)
452 break;
453 }
454
455 if (i==j) {
456 i->TagInfo.offset = pIO->GetLength();
457 i->pTag->Write(pIO);
458 i->TagInfo.size = pIO->GetLength() - i->TagInfo.offset;
459 i->TagInfo.offset -= m_tagStart;
460
461 pIO->Align32();
462 }
463 else {
464 i->TagInfo.offset = j->TagInfo.offset;
465 i->TagInfo.size = j->TagInfo.size;
466 }
467 }
468 }
469 icUInt32Number epos = pIO->Tell();
470
471 pIO->Seek(dirpos, icSeekSet);
472
473 //Write TagDir with offsets and sizes
474 for (i=m_ElemEntries->begin(); i!= m_ElemEntries->end(); i++) {
475 if (i->pTag) {
476 pIO->Write32(&i->TagInfo.sig);
477 pIO->Write32(&i->TagInfo.offset);
478 pIO->Write32(&i->TagInfo.size);
479 }
480 }
481
482 pIO->Seek(epos, icSeekSet);
483
484
485 return true;
486}
487
488
489/**
490 ******************************************************************************
491 * Name: CIccTagStruct::Validate
492 *
493 * Purpose:
494 *
495 * Args:
496 *
497 * Return:
498 ******************************************************************************/
499icValidateStatus CIccTagStruct::Validate(std::string sigPath, std::string &sReport,
500 const CIccProfile* pProfile /*=NULL*/) const
501{
502 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
503
504 CIccInfo Info;
505 std::string sSigPathName = Info.GetSigPathName(sigPath);
506
507 // Check for duplicate tags
508 if (!AreElemsUnique()) {
509 sReport += icMsgValidateWarning;
510 sReport += sSigPathName;
511 sReport += " - There are duplicate tags.\r\n";
512 rv =icMaxStatus(rv, icValidateWarning);
513 }
514
515 if (m_pStruct) { //Should call GetStructHandler before validate to get
516 rv = icMaxStatus(rv, m_pStruct->Validate(sigPath, sReport, pProfile));
517 }
518 else {
519 sReport += "Unknown tag struct type - Validating struct sub-tags\n";
520 rv = icMaxStatus(rv, icValidateWarning);
521
522 // Per Tag tests
523 TagEntryList::iterator i;
524 for (i = m_ElemEntries->begin(); i != m_ElemEntries->end(); i++) {
525 rv = icMaxStatus(rv, i->pTag->Validate(sigPath + icGetSigPath(i->TagInfo.sig), sReport, pProfile));
526 }
527 }
528
529 return rv;
530}
531
532/**
533 ***************************************************************************
534 * Name: CIccTagStruct::Cleanup
535 *
536 * Purpose: Detach from a pending IO object
537 ***************************************************************************
538 */
539void CIccTagStruct::Cleanup()
540{
541 TagPtrList::iterator i;
542
543 for (i=m_ElemVals->begin(); i!=m_ElemVals->end(); i++) {
544 if (i->ptr)
545 delete i->ptr;
546 }
547 m_ElemEntries->clear();
548 m_ElemVals->clear();
549
550 if (m_pStruct)
551 delete m_pStruct;
552 m_pStruct = NULL__null;
553}
554
555/**
556 ****************************************************************************
557 * Name: CIccTagStruct::GetElem
558 *
559 * Purpose: Get a tag entry with a given signature
560 *
561 * Args:
562 * sig - signature id to find in tag structure
563 *
564 * Return:
565 * Pointer to desired tag struct entry, or NULL if not found.
566 *****************************************************************************
567 */
568IccTagEntry* CIccTagStruct::GetElem(icSignature sig) const
569{
570 TagEntryList::const_iterator i;
571
572 for (i=m_ElemEntries->begin(); i!=m_ElemEntries->end(); i++) {
573 if (i->TagInfo.sig==sig)
574 return (IccTagEntry*)&(i->TagInfo);
575 }
576
577 return NULL__null;
578}
579
580
581/**
582 ******************************************************************************
583 * Name: CIccTagStruct::AreElemsUnique
584 *
585 * Purpose: For each tag it checks to see if any other tags have the same
586 * signature.
587 *
588 *
589 * Return:
590 * true if all tags have unique signatures, or false if there are duplicate
591 * tag signatures.
592 *******************************************************************************
593 */
594bool CIccTagStruct::AreElemsUnique() const
595{
596 TagEntryList::const_iterator i, j;
597
598 for (i=m_ElemEntries->begin(); i!=m_ElemEntries->end(); i++) {
599 j=i;
600 for (j++; j!= m_ElemEntries->end(); j++) {
601 if (i->TagInfo.sig == j->TagInfo.sig)
602 return false;
603 }
604 }
605
606 return true;
607}
608
609
610/**
611******************************************************************************
612* Name: CIccTagStruct::GetElem
613*
614* Purpose: Finds the first tag entry that points to the indicated tag object
615*
616* Args:
617* pTag - pointer to tag object desired to be found
618*
619* Return:
620* pointer to first tag struct entry that points to the desired tag object,
621* or NULL if tag object is not pointed to by any tag struct entries.
622*******************************************************************************
623*/
624IccTagEntry* CIccTagStruct::GetElem(CIccTag *pTag) const
625{
626 TagEntryList::const_iterator i;
627
628 for (i=m_ElemEntries->begin(); i!=m_ElemEntries->end(); i++) {
629 if (i->pTag==pTag)
630 return (IccTagEntry*)&(i->TagInfo);
631 }
632
633 return NULL__null;
634}
635
636
637/**
638 ******************************************************************************
639 * Name: CIccTagStruct::FindElem
640 *
641 * Purpose: Finds the tag object associated with the struct entry with the
642 * given signature.
643 *
644 * Args:
645 * sig - element signature to find
646 *
647 * Return:
648 * The desired tag object, or NULL if unable to find in the struct
649 *******************************************************************************
650 */
651CIccTag* CIccTagStruct::FindElem(icSignature sig)
652{
653 IccTagEntry *pEntry = GetElem(sig);
654
655 if (pEntry) {
656 return pEntry->pTag;
657 }
658
659 return NULL__null;
660}
661
662/**
663******************************************************************************
664* Name: CIccTagStruct::FindElemOfType
665*
666* Purpose: Finds the tag object associated with the struct entry with the
667* given signature that has a specific tag type.
668*
669* Args:
670* sig - element signature to find
671* sigType - signature of desired tag type
672*
673* Return:
674* The desired tag object, or NULL if unable to find in the struct
675*******************************************************************************
676*/
677CIccTag* CIccTagStruct::FindElemOfType(icSignature sig, icTagTypeSignature sigType)
678{
679 IccTagEntry *pEntry = GetElem(sig);
680
681 if (pEntry && pEntry->pTag && pEntry->pTag->GetType()==sigType) {
682 return pEntry->pTag;
683 }
684
685 return NULL__null;
686}
687
688
689/**
690******************************************************************************
691* Name: CIccTagStruct::GetElemNumberValue
692*
693* Purpose: Returns the number value associated with the first entry of a
694* CIccTagNumberArray based tag with the given signature.
695*
696* Args:
697* sig - subtag signature to find
698* defaultValue - value to use if the tag cannot be found, or is not a number tag
699*
700* Return:
701* The tags value or defaultValue if unable to find subtag in the struct or if the
702* subtag is not a CIccTagNumberArray based tag.
703*******************************************************************************
704*/
705icFloatNumber CIccTagStruct::GetElemNumberValue(icSignature sig, icFloatNumber defaultValue/* =0 */)
706{
707 CIccTag *pTag = FindElem(sig);
708
709 if (!pTag || !pTag->IsNumArrayType())
710 return defaultValue;
711
712 CIccTagNumArray *pNumArray = (CIccTagNumArray*)pTag;
713 icFloatNumber rv = defaultValue;
714
715 pNumArray->GetValues(&rv, 0, 1);
716
717 return rv;
718}
719
720/**
721 ******************************************************************************
722 * Name: CIccTagStruct::AttachTag
723 *
724 * Purpose: Assign a tag object to a directory entry in the profile. This
725 * will assume ownership of the tag object.
726 *
727 * Args:
728 * sig - signature of tag 'name' to use to assign tag object with,
729 * pTag - pointer to tag object to attach to profile.
730 *
731 * Return:
732 * true = tag assigned to profile,
733 * false - tag not assigned to profile (tag already exists).
734 *******************************************************************************
735 */
736bool CIccTagStruct::AttachElem(icSignature sig, CIccTag *pTag)
737{
738 IccTagEntry *pEntry = GetElem(sig);
739
740 if (pEntry) {
741 if (pEntry->pTag == pTag)
742 return true;
743
744 return false;
745 }
746
747 IccTagEntry Entry;
748 Entry.TagInfo.sig = (icTagSignature)sig;
749 Entry.TagInfo.offset = 0;
750 Entry.TagInfo.size = 0;
751 Entry.pTag = pTag;
752
753 m_ElemEntries->push_back(Entry);
754
755 TagPtrList::iterator i;
756
757 for (i=m_ElemVals->begin(); i!=m_ElemVals->end(); i++)
758 if (i->ptr == pTag)
759 break;
760
761 if (i==m_ElemVals->end()) {
762 IccTagPtr TagPtr;
763 TagPtr.ptr = pTag;
764 m_ElemVals->push_back(TagPtr);
765 }
766
767 return true;
768}
769
770
771/**
772 ******************************************************************************
773 * Name: CIccTagStruct::DeleteSubTag
774 *
775 * Purpose: Delete tag directory entry with given signature. If no other tag
776 * directory entries use the tag object, the tag object will also be deleted.
777 *
778 * Args:
779 * sig - signature of tag directory entry to remove
780 *
781 * Return:
782 * true - desired tag directory entry was found and deleted,
783 * false - desired tag directory entry was not found
784 *******************************************************************************
785 */
786bool CIccTagStruct::DeleteElem(icSignature sig)
787{
788 TagEntryList::iterator i;
789
790 for (i=m_ElemEntries->begin(); i!=m_ElemEntries->end(); i++) {
791 if (i->TagInfo.sig==sig)
792 break;
793 }
794 if (i!=m_ElemEntries->end()) {
795 CIccTag *pTag = i->pTag;
796 m_ElemEntries->erase(i);
797
798 if (!GetElem(pTag)) {
799 DetachElem(pTag);
800 delete pTag;
801 }
802 return true;
803 }
804
805 return false;
806}
807
808
809/**
810 ******************************************************************************
811 * Name: CIccTagStruct::LoadSubTag
812 *
813 * Purpose: This will load from the indicated IO object and associate a tag
814 * object to a tag directory entry. Nothing happens if tag directory entry
815 * is associated with a tag object.
816 *
817 * Args:
818 * pTagEntry - pointer to tag directory entry,
819 * pIO - pointer to IO object to read tag object data from
820 *
821 * Return:
822 * true - tag directory object associated with tag directory entry,
823 * false - failure
824 *******************************************************************************
825 */
826bool CIccTagStruct::LoadElem(IccTagEntry *pTagEntry, CIccIO *pIO)
827{
828 if (!pTagEntry)
829 return false;
830
831 if (pTagEntry->pTag)
832 return true;
833
834 icUInt32Number headerSize = sizeof(icTagTypeSignature) +
835 sizeof(icUInt32Number) +
836 sizeof(icUInt32Number);
837
838 if (pTagEntry->TagInfo.offset<headerSize ||
839 !pTagEntry->TagInfo.size ||
840 pTagEntry->TagInfo.offset+pTagEntry->TagInfo.size > m_tagSize) {
841 return false;
842 }
843
844 icTagTypeSignature sigType;
845
846 icUInt32Number offset = pTagEntry->TagInfo.offset + m_tagStart;
847
848 //First we need to get the tag type to create the right kind of tag
849 if (pIO->Seek(offset, icSeekSet)!=offset)
850 return false;
851
852 if (!pIO->Read32(&sigType))
853 return false;
854
855 CIccTag *pTag = CIccTag::Create(sigType);
856
857 if (!pTag)
858 return false;
859
860 //Now seek back to where the tag starts so the created tag object can read
861 //in its data.
862 //First we need to get the tag type to create the right kind of tag
863 if (pIO->Seek(offset, icSeekSet)!=offset) {
864 delete pTag;
865 return false;
866 }
867
868 if (!pTag->Read(pTagEntry->TagInfo.size, pIO)) {
869 delete pTag;
870 return false;
871 }
872
873 pTagEntry->pTag = pTag;
874
875 IccTagPtr TagPtr;
876
877 TagPtr.ptr = pTag;
878
879 m_ElemVals->push_back(TagPtr);
880
881 TagEntryList::iterator i;
882
883 for (i=m_ElemEntries->begin(); i!= m_ElemEntries->end(); i++) {
884 if (i->TagInfo.offset == pTagEntry->TagInfo.offset &&
885 i->pTag != pTag)
886 i->pTag = pTag;
887 }
888
889 return true;
890}
891
892
893/**
894 ******************************************************************************
895 * Name: CIccTagStruct::DetachSubTag
896 *
897 * Purpose: Remove association of a tag object from all tag directory entries.
898 * Associated tag directory entries will be removed from the tag directory.
899 * The tag object is NOT deleted from memory, but is considered to be
900 * no longer associated with the CIccTagStruct object. The caller assumes
901 * ownership of the tag object.
902 *
903 * Args:
904 * pTag - pointer to tag object unassociated with the profile object
905 *
906 * Return:
907 * true - tag object found and unassociated with profile object,
908 * false - tag object not found
909 *******************************************************************************
910 */
911bool CIccTagStruct::DetachElem(CIccTag *pTag)
912{
913 if (!pTag)
914 return false;
915
916 TagPtrList::iterator i;
917
918 for (i=m_ElemVals->begin(); i!=m_ElemVals->end(); i++) {
919 if (i->ptr == pTag)
920 break;
921 }
922
923 if (i==m_ElemVals->end())
924 return false;
925
926 m_ElemVals->erase(i);
927
928 TagEntryList::iterator j;
929 for (j=m_ElemEntries->begin(); j!=m_ElemEntries->end();) {
930 if (j->pTag == pTag) {
931 j=m_ElemEntries->erase(j);
932 }
933 else
934 j++;
935 }
936 return true;
937}
938
939
940/**
941****************************************************************************
942* Name: CIccTagStruct::GetStructHandler
943*
944* Purpose: Get struct object handler
945*
946* Args:
947*
948* Return:
949* Pointer to a IIccStruct object handler for the associated struct type
950*****************************************************************************
951*/
952IIccStruct* CIccTagStruct::GetStructHandler()
953{
954 if (!m_pStruct) {
955
956 m_pStruct = CIccStructCreator::CreateStruct(m_sigStructType, this);
957 }
958 return m_pStruct;
959}
960
961
962/**
963******************************************************************************
964* Name: CIccTagArray::CIccTagArray
965*
966* Purpose:
967*
968* Args:
969*
970* Return:
971******************************************************************************/
972CIccTagArray::CIccTagArray()
973{
974 m_TagVals = NULL__null;
975 m_nSize = 0;
976 m_sigArrayType = icSigUnknownArray((icArraySignature) 0x3f3f3f3f);
977 m_pArray = NULL__null;
978}
979
980/**
981******************************************************************************
982* Name: CIccTagArray::CIccTagArray
983*
984* Purpose:
985*
986* Args:
987*
988* Return:
989******************************************************************************/
990CIccTagArray::CIccTagArray(icArraySignature sigArrayType/* =icSigUndefinedArray */)
991{
992 m_TagVals = NULL__null;
993 m_nSize = 0;
994 m_sigArrayType = sigArrayType;
995 m_pArray = NULL__null;
996}
997
998/**
999******************************************************************************
1000* Name: CIccTagArray::CIccTagArray
1001*
1002* Purpose:
1003*
1004* Args:
1005*
1006* Return:
1007******************************************************************************/
1008CIccTagArray::CIccTagArray(const CIccTagArray &tagAry)
1009{
1010 if (tagAry.m_nSize) {
1011 m_TagVals = new IccTagPtr[tagAry.m_nSize];
1012
1013 icUInt32Number i;
1014 for (i=0; i<tagAry.m_nSize; i++) {
1015 if (tagAry.m_TagVals[i].ptr)
1016 m_TagVals[i].ptr = tagAry.m_TagVals[i].ptr->NewCopy();
1017 else
1018 m_TagVals[i].ptr = NULL__null;
1019 }
1020 m_nSize = tagAry.m_nSize;
1021 }
1022 m_sigArrayType = tagAry.m_sigArrayType;
1023
1024 if (tagAry.m_pArray)
1025 m_pArray = tagAry.m_pArray->NewCopy(this);
1026 else
1027 m_pArray = NULL__null;
1028}
1029
1030/**
1031******************************************************************************
1032* Name: &operator=
1033*
1034* Purpose:
1035*
1036* Args:
1037*
1038* Return:
1039******************************************************************************/
1040CIccTagArray &CIccTagArray::operator=(const CIccTagArray &tagAry)
1041{
1042 if (&tagAry == this)
1043 return *this;
1044
1045 Cleanup();
1046
1047 if (tagAry.m_nSize) {
1048 m_TagVals = new IccTagPtr[tagAry.m_nSize];
1049
1050 icUInt32Number i;
1051 for (i=0; i<m_nSize; i++) {
1052 if (tagAry.m_TagVals[i].ptr)
1053 m_TagVals[i].ptr = tagAry.m_TagVals[i].ptr->NewCopy();
1054 else
1055 m_TagVals[i].ptr = NULL__null;
1056 }
1057 m_nSize = tagAry.m_nSize;
1058 }
1059 m_sigArrayType = tagAry.m_sigArrayType;
1060
1061 if (tagAry.m_pArray)
1062 m_pArray = tagAry.m_pArray->NewCopy(this);
1063 else
1064 m_pArray = NULL__null;
1065
1066 return *this;
1067}
1068
1069/**
1070******************************************************************************
1071* Name: CIccTagArray::~CIccTagArray
1072*
1073* Purpose:
1074*
1075* Args:
1076*
1077* Return:
1078******************************************************************************/
1079CIccTagArray::~CIccTagArray()
1080{
1081 Cleanup();
1082}
1083
1084
1085
1086/**
1087******************************************************************************
1088* Name: CIccTagArray::AreAllOftype
1089*
1090* Purpose:
1091* checks if all array elements have type signature sigTagType
1092* Args:
1093* sigTagType
1094* Return:
1095* true if all elements are of type sigTagType, false otherwise
1096******************************************************************************/
1097bool CIccTagArray::AreAllOfType(icTagTypeSignature sigTagType)
1098{
1099 icUInt32Number i;
1100 for (i=0; i<m_nSize; i++) {
1101 CIccTag *pTag = GetIndex(i);
1102 if (!pTag || pTag->GetType()!=sigTagType)
1103 return false;
1104 }
1105
1106 return true;
1107}
1108
1109
1110/**
1111******************************************************************************
1112* Name: CIccTagArray::Describe
1113*
1114* Purpose:
1115*
1116* Args:
1117*
1118* Return:
1119******************************************************************************/
1120void CIccTagArray::Describe(std::string &sDescription)
1121{
1122 std::string name;
1123 icChar buf[128];
1124 CIccInfo info;
1125
1126 IIccArray *pArrayObj = GetArrayHandler();
Value stored to 'pArrayObj' during its initialization is never read
1127 CIccArrayCreator::GetArraySigName(name, m_sigArrayType);
1128
1129 sDescription += "BEGIN TAG_ARRAY \"";
1130 sDescription += name;
1131 sDescription += "\"\r\n\r\n";
1132
1133 icUInt32Number i;
1134
1135 for (i=0; i<m_nSize; i++) {
1136 if (i)
1137 sDescription += "\r\n";
1138 sprintf(buf, "BEGIN INDEX[%d]\r\n", i);
1139 sDescription += buf;
1140
1141 if (m_TagVals[i].ptr) {
1142 m_TagVals[i].ptr->Describe(sDescription);
1143 }
1144 sprintf(buf, "END INDEX[%d]\r\n", i);
1145 sDescription += buf;
1146 }
1147
1148 sDescription += "\r\n";
1149 sDescription += "END TAG_ARRAY \"";
1150 sDescription += name;
1151 sDescription += "\"\r\n";
1152}
1153
1154
1155/**
1156******************************************************************************
1157* Name: CIccTagArray::Read
1158*
1159* Purpose:
1160*
1161* Args:
1162*
1163* Return:
1164******************************************************************************/
1165bool CIccTagArray::Read(icUInt32Number size, CIccIO *pIO)
1166{
1167 icTagTypeSignature sig;
1168
1169 icUInt32Number headerSize = sizeof(icTagTypeSignature) +
1170 sizeof(icUInt32Number) +
1171 sizeof(icTagTypeSignature) +
1172 sizeof(icStructSignature) +
1173 sizeof(icUInt32Number);
1174
1175 if (headerSize > size)
1176 return false;
1177
1178 if (!pIO) {
1179 return false;
1180 }
1181
1182 Cleanup();
1183
1184 icUInt32Number nTagStart = pIO->Tell();
1185
1186 if (!pIO->Read32(&sig))
1187 return false;
1188
1189 if (!pIO->Read32(&m_nReserved) ||
1190 !pIO->Read32(&m_sigArrayType))
1191 return false;
1192
1193 icUInt32Number count, i, j;
1194 IccTagEntry TagEntry;
1195
1196 TagEntry.pTag = NULL__null;
1197
1198 if (!pIO->Read32(&count))
1199 return false;
1200
1201 if (headerSize + count*sizeof(icPositionNumber) > size)
1202 return false;
1203
1204 if (count) {
1205 icPositionNumber *tagPos = new icPositionNumber[count];
1206
1207 if (!SetSize(count)) {
1208 delete[] tagPos;
1209 return false;
1210 }
1211
1212 for (i=0; i<count; i++) {
1213 if (!pIO->Read32(&tagPos[i].offset) ||
1214 !pIO->Read32(&tagPos[i].size)) {
1215 delete [] tagPos;
1216 return false;
1217 }
1218 }
1219
1220 for (i=0; i<count; i++) {
1221 if (!tagPos[i].offset || !tagPos[i].size) {
1222 m_TagVals[i].ptr = NULL__null;
1223 continue;
1224 }
1225
1226 for (j=0; j<i; j++) {
1227 if (tagPos[i].offset == tagPos[j].offset)
1228 break;
1229 }
1230
1231 if (j<i) {
1232 m_TagVals[i].ptr = m_TagVals[j].ptr;
1233 }
1234 else {
1235 if (tagPos[i].offset + tagPos[i].size > size) {
1236 delete [] tagPos;
1237 return false;
1238 }
1239 pIO->Seek(nTagStart + tagPos[i].offset, icSeekSet);
1240
1241 icTagTypeSignature tagSig;
1242 pIO->Read32(&tagSig);
1243 pIO->Seek(nTagStart + tagPos[i].offset, icSeekSet);
1244
1245 CIccTag *pTag = CIccTagCreator::CreateTag(tagSig);
1246 if (pTag) {
1247 if (!pTag->Read(tagPos[i].size, pIO)) {
1248 delete [] tagPos;
1249 return false;
1250 }
1251 m_TagVals[i].ptr = pTag;
1252 }
1253 else {
1254 delete [] tagPos;
1255 return false;
1256 }
1257 }
1258 }
1259
1260 delete [] tagPos;
1261 }
1262
1263 return true;
1264}
1265
1266/**
1267******************************************************************************
1268* Name: CIccTagArray::Write
1269*
1270* Purpose:
1271*
1272* Args:
1273*
1274* Return:
1275******************************************************************************/
1276bool CIccTagArray::Write(CIccIO *pIO)
1277{
1278 icTagTypeSignature sig = GetType();
1279
1280 if (!pIO)
1281 return false;
1282
1283 icUInt32Number nTagStart = pIO->Tell();
1284
1285 if (!pIO->Write32(&sig))
1286 return false;
1287
1288 if (!pIO->Write32(&m_nReserved))
1289 return false;
1290
1291 if (!pIO->Write32(&m_sigArrayType))
1292 return false;
1293
1294 if (!pIO->Write32(&m_nSize))
1295 return false;
1296
1297 if (m_nSize) {
1298 icUInt32Number i, j;
1299
1300 icUInt32Number pos = pIO->Tell();
1301
1302 //Write Unintialized TagPosition block
1303 icUInt32Number zero = 0;
1304 for (i=0; i<m_nSize; i++) {
1305 if (!pIO->Write32(&zero) || !pIO->Write32(&zero))
1306 return false;
1307 }
1308 icPositionNumber *tagPos = new icPositionNumber[m_nSize];
1309 if (!tagPos)
1310 return false;
1311
1312 //Write Tags
1313 for (i=0; i<m_nSize; i++) {
1314 if (m_TagVals[i].ptr) {
1315 for (j=0; j<i; j++) {
1316 if (m_TagVals[i].ptr==m_TagVals[j].ptr)
1317 break;
1318 }
1319
1320 if (j<i) {
1321 tagPos[i].offset = tagPos[j].offset;
1322 tagPos[i].size = tagPos[j].offset;
1323 }
1324 else {
1325 tagPos[i].offset = pIO->Tell() - nTagStart;
1326 if (!m_TagVals[i].ptr->Write(pIO)) {
1327 delete [] tagPos;
1328 return false;
1329 }
1330 tagPos[i].size = pIO->Tell() - nTagStart - tagPos[i].offset;
1331 pIO->Align32();
1332 }
1333 }
1334 else {
1335 tagPos[i].offset = 0;
1336 tagPos[i].size = 0;
1337 }
1338 }
1339 icUInt32Number endPos = pIO->Tell();
1340
1341 //Update TagPosition block
1342 pIO->Seek(pos, icSeekSet);
1343 for (i=0; i<m_nSize; i++) {
1344 if (!pIO->Write32(&tagPos[i].offset) ||
1345 !pIO->Write32(&tagPos[i].size)) {
1346 delete [] tagPos;
1347 return false;
1348 }
1349 }
1350 pIO->Seek(endPos, icSeekSet);
1351 }
1352
1353 return true;
1354}
1355
1356
1357/**
1358 ****************************************************************************
1359 * Name: CIccTagArray::SetSize
1360 *
1361 * Purpose: Sets the size of the tag array.
1362 *
1363 * Args:
1364 * nSize - number of tag entries,
1365 *****************************************************************************
1366 */
1367bool CIccTagArray::SetSize(icUInt32Number nSize)
1368{
1369 if (!m_nSize) {
1370 m_TagVals = (IccTagPtr*)calloc(nSize, sizeof(IccTagPtr));
1371 if (!m_TagVals) {
1372 m_nSize =0;
1373 return false;
1374 }
1375 }
1376 else {
1377 if (nSize<=m_nSize)
1378 return true;
1379
1380 m_TagVals = (IccTagPtr*)icRealloc(m_TagVals, nSize*sizeof(IccTagPtr));
1381 if (!m_TagVals) {
1382 m_nSize = 0;
1383 return false;
1384 }
1385 memset(&m_TagVals[m_nSize], 0, (nSize-m_nSize)*sizeof(IccTagPtr));
1386 }
1387 m_nSize = nSize;
1388 return true;
1389}
1390
1391
1392/**
1393******************************************************************************
1394* Name: CIccTagArray::Validate
1395*
1396* Purpose:
1397*
1398* Args:
1399*
1400* Return:
1401******************************************************************************/
1402icValidateStatus CIccTagArray::Validate(std::string sigPath, std::string &sReport,
1403 const CIccProfile* pProfile /*=NULL*/) const
1404{
1405 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
1406
1407 CIccInfo Info;
1408 std::string sigAryPath = sigPath + icGetSigPath(m_sigArrayType);
1409
1410 if (m_pArray) { //Should call GetArrayHandler before validate to get
1411 rv = icMaxStatus(rv, m_pArray->Validate(sigPath, sReport, pProfile));
1412 }
1413 else if (m_sigArrayType==icSigUtf8TextTypeArray) { //UTF8 text arrays are known
1414 //Check # of channels
1415 if (icGetFirstSigPathSig(sigPath) == icSigMaterialTypeArrayTag &&
1416 pProfile &&
1417 m_nSize != icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs)) {
1418 std::string sSigPathName = Info.GetSigPathName(sigPath);
1419
1420 sReport += icMsgValidateCriticalError;
1421 sReport += sSigPathName;
1422 sReport += " - Number of material channel names does not match MCS in header.\r\n";
1423 rv = icMaxStatus(rv, icValidateCriticalError);
1424 }
1425 icUInt32Number i;
1426 for (i=0; i<m_nSize; i++) {
1427 rv = icMaxStatus(rv, m_TagVals[i].ptr->Validate(sigAryPath, sReport, pProfile));
1428 }
1429 }
1430 else {
1431 icUInt32Number i;
1432 sReport += "Unknown tag array type - Validating array sub-tags\n";
1433 rv = icMaxStatus(rv, icValidateWarning);
1434
1435 for (i=0; i<m_nSize; i++) {
1436 rv = icMaxStatus(rv, m_TagVals[i].ptr->Validate(sigAryPath, sReport, pProfile));
1437 }
1438 }
1439
1440 return rv;
1441}
1442
1443/**
1444***************************************************************************
1445* Name: CIccTagArray::Cleanup
1446*
1447* Purpose: Detach from a pending IO object
1448***************************************************************************
1449*/
1450void CIccTagArray::Cleanup()
1451{
1452 icUInt32Number i, j;
1453 CIccTag* pTag;
1454
1455 for (i=0; i<m_nSize; i++) {
1456 pTag = m_TagVals[i].ptr;
1457 if (pTag) {
1458 for (j=i+1; j<m_nSize; j++) {
1459 if (m_TagVals[i].ptr==pTag)
1460 m_TagVals[i].ptr = NULL__null;
1461 }
1462 delete pTag;
1463 m_TagVals[i].ptr = NULL__null;
1464 }
1465 }
1466
1467 delete [] m_TagVals;
1468
1469 if (m_pArray)
1470 delete m_pArray;
1471
1472 m_pArray = NULL__null;
1473}
1474
1475/**
1476****************************************************************************
1477* Name: CIccTagArray::GetIndex
1478*
1479* Purpose: Get a tag entry with a given index
1480*
1481* Args:
1482* nIndex - index of tag in array
1483*
1484* Return:
1485* Pointer to desired tag entry, or NULL if not found.
1486*****************************************************************************
1487*/
1488CIccTag* CIccTagArray::GetIndex(icUInt32Number nIndex) const
1489{
1490 if (nIndex>m_nSize)
1491 return NULL__null;
1492
1493 return m_TagVals[nIndex].ptr;
1494}
1495
1496
1497/**
1498****************************************************************************
1499* Name: CIccTagArray::AttachTag
1500*
1501* Purpose: Get a tag entry with a given signature
1502*
1503* Args:
1504* nIndex - index of tag in array
1505*
1506* Return:
1507* Pointer to desired tag struct entry, or NULL if not found.
1508*****************************************************************************
1509*/
1510bool CIccTagArray::AttachTag(icUInt32Number nIndex, CIccTag *pTag)
1511{
1512 if (nIndex>m_nSize || !pTag) {
1513 return false;
1514 }
1515
1516 if (m_TagVals[nIndex].ptr && m_TagVals[nIndex].ptr != pTag) {
1517 return false;
1518 }
1519
1520 m_TagVals[nIndex].ptr = pTag;
1521 return true;
1522}
1523
1524
1525/**
1526****************************************************************************
1527* Name: CIccTagArray::DetachTag
1528*
1529* Purpose: Detach tag value at given index
1530*
1531* Args:
1532* nIndex - index of tag in array
1533* bDeleteFlag - flag indicating detached tag should be deleted
1534*
1535* Return:
1536* Pointer to Detached tag struct entry, or NULL if not found or deleted.
1537*****************************************************************************
1538*/
1539CIccTag * CIccTagArray::DetachTag(icUInt32Number nIndex, bool bDeleteFlag)
1540{
1541 if (nIndex>m_nSize)
1542 return NULL__null;
1543
1544 CIccTag *rv = m_TagVals[nIndex].ptr;
1545 m_TagVals[nIndex].ptr = NULL__null;
1546
1547 if (bDeleteFlag) {
1548 delete rv;
1549 rv = NULL__null;
1550 }
1551
1552 return rv;
1553}
1554
1555
1556/**
1557****************************************************************************
1558* Name: CIccTagArray::GetArrayHandler
1559*
1560* Purpose: Get Array object handler
1561*
1562* Args:
1563*
1564* Return:
1565* Pointer to an Array object handler for the associated array type
1566*****************************************************************************
1567*/
1568IIccArray *CIccTagArray::GetArrayHandler()
1569{
1570 if (!m_pArray) {
1571 m_pArray = CIccArrayCreator::CreateArray(m_sigArrayType, this);
1572 }
1573
1574 return m_pArray;
1575}
1576
1577
1578IIccStruct *icGetTagStructHandler(CIccTag *pTag)
1579{
1580 if (!pTag)
1581 return NULL__null;
1582 if (pTag->GetType()!=icSigTagStructType)
1583 return NULL__null;
1584
1585 CIccTagStruct *pStruct = (CIccTagStruct*)pTag;
1586
1587 return pStruct->GetStructHandler();
1588}
1589
1590IIccStruct *icGetTagStructHandlerOfType(CIccTag* pTag, icStructSignature sig)
1591{
1592 if (pTag->GetTagStructType()==sig)
1593 return icGetTagStructHandler(pTag);
1594
1595 return NULL__null;
1596}
1597
1598IIccArray *icGetTagArrayHandler(CIccTag *pTag)
1599{
1600 if (!pTag)
1601 return NULL__null;
1602 if (pTag->GetType()!=icSigTagArrayType)
1603 return NULL__null;
1604
1605 CIccTagArray *pArray = (CIccTagArray*)pTag;
1606
1607 return pArray->GetArrayHandler();
1608}
1609
1610IIccArray *icGetTagArrayHandlerOfType(CIccTag* pTag, icArraySignature sig)
1611{
1612 if (pTag->GetTagArrayType()==sig)
1613 return icGetTagArrayHandler(pTag);
1614
1615 return NULL__null;
1616}
1617