Bug Summary

File:IccProfLib/IccTagBasic.cpp
Warning:line 2138, column 38
Null pointer passed as 1st argument to string length function

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 IccTagBasic.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/IccTagBasic.cpp
1/** @file
2 File: IccTagBasic.cpp
3
4 Contains: Implementation of the CIccTag class and basic inherited classes
5
6 Version: V1
7
8 Copyright: � see ICC Software License
9*/
10
11/*
12 * The ICC Software License, Version 0.2
13 *
14 *
15 * Copyright (c) 2003-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 5-15-2003
68//
69//////////////////////////////////////////////////////////////////////
70
71#ifdef WIN32
72 #pragma warning( disable: 4786) //disable warning in <list.h>
73 #include <windows.h>
74#endif
75#include <stdio.h>
76#include <math.h>
77#include <string.h>
78#include <stdlib.h>
79#include "IccTag.h"
80#include "IccUtil.h"
81#include "IccProfile.h"
82#include "IccTagFactory.h"
83#include "IccConvertUTF.h"
84#include "IccSparseMatrix.h"
85#include "IccCmm.h"
86
87#ifdef ICC_USE_ZLIB
88#include "zlib.h"
89#endif
90
91
92#ifndef __minmin
93#include <algorithm>
94using std::min;
95#define __minmin min
96#endif
97
98#ifdef USEREFICCMAXNAMESPACE
99namespace refIccMAX {
100#endif
101
102
103/**
104 ****************************************************************************
105 * Name: CIccTag::CIccTag
106 *
107 * Purpose: Constructor
108 *
109 *****************************************************************************
110 */
111CIccTag::CIccTag()
112{
113 m_nReserved = 0;
114}
115
116/**
117 ****************************************************************************
118 * Name: CIccTag::CIccTag
119 *
120 * Purpose: Destructor
121 *
122 *****************************************************************************
123 */
124CIccTag::~CIccTag()
125{
126
127}
128
129/**
130 ****************************************************************************
131 * Name: CIccTag::Create
132 *
133 * Purpose: This is a static tag creator based upon tag signature type
134 *
135 * Args:
136 * sig = tag type signature
137 *
138 * Return: Pointer to Allocated tag
139 *****************************************************************************
140 */
141CIccTag* CIccTag::Create(icTagTypeSignature sig)
142{
143 return CIccTagCreator::CreateTag(sig);
144}
145
146
147/**
148 ******************************************************************************
149 * Name: CIccTag::Validate
150 *
151 * Purpose: Check tag data validity. In base class we only look at the
152 * tag's reserved data value
153 *
154 * Args:
155 * sig = signature of tag being validated,
156 * sReport = String to add report information to
157 *
158 * Return:
159 * icValidateStatusOK if valid, or other error status.
160 ******************************************************************************
161 */
162icValidateStatus CIccTag::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
163{
164 icValidateStatus rv = icValidateOK;
165
166 if (m_nReserved != 0) {
167 CIccInfo Info;
168 sReport += icMsgValidateNonCompliant;
169 sReport += Info.GetSigPathName(sigPath);
170 sReport += " - Reserved Value must be zero.\r\n";
171
172 rv = icValidateNonCompliant;
173 }
174
175 return rv;
176}
177
178
179/**
180 ****************************************************************************
181 * Name: CIccTagUnknown::CIccTagUnknown
182 *
183 * Purpose: Constructor
184 *
185 *****************************************************************************
186 */
187CIccTagUnknown::CIccTagUnknown()
188{
189 m_nType = icSigUnknownType((icTagTypeSignature) 0x3f3f3f3f);
190 m_pData = NULL__null;
191}
192
193/**
194 ****************************************************************************
195 * Name: CIccTagUnknown::CIccTagUnknown
196 *
197 * Purpose: Copy Constructor
198 *
199 * Args:
200 * ITU = The CIccTagUnknown object to be copied
201 *****************************************************************************
202 */
203CIccTagUnknown::CIccTagUnknown(const CIccTagUnknown &ITU)
204{
205 m_nSize = ITU.m_nSize;
206 m_nType = ITU.m_nType;
207
208 m_pData = new icUInt8Number[m_nSize];
209 memcpy(m_pData, ITU.m_pData, sizeof(icUInt8Number)*m_nSize);
210}
211
212/**
213 ****************************************************************************
214 * Name: CIccTagUnknown::operator=
215 *
216 * Purpose: Copy Operator
217 *
218 * Args:
219 * UnknownTag = The CIccTagUnknown object to be copied
220 *****************************************************************************
221 */
222CIccTagUnknown &CIccTagUnknown::operator=(const CIccTagUnknown &UnknownTag)
223{
224 if (&UnknownTag == this)
225 return *this;
226
227 m_nSize = UnknownTag.m_nSize;
228 m_nType = UnknownTag.m_nType;
229
230 if (m_pData)
231 delete [] m_pData;
232 m_pData = new icUInt8Number[m_nSize];
233 memcpy(m_pData, UnknownTag.m_pData, sizeof(icUInt8Number)*m_nSize);
234
235 return *this;
236}
237
238/**
239 ****************************************************************************
240 * Name: CIccTagUnknown::~CIccTagUnknown
241 *
242 * Purpose: Destructor
243 *****************************************************************************
244 */
245CIccTagUnknown::~CIccTagUnknown()
246{
247 if (m_pData)
248 delete [] m_pData;
249}
250
251
252/**
253 ****************************************************************************
254 * Name: CIccTagUnknown::Read
255 *
256 * Purpose: Read in an unknown tag type into a data block
257 *
258 * Args:
259 * size - # of bytes in tag,
260 * pIO - IO object to read tag from
261 *
262 * Return:
263 * true = successful, false = failure
264 *****************************************************************************
265 */
266bool CIccTagUnknown::Read(icUInt32Number size, CIccIO *pIO)
267{
268 if (m_pData) {
269 delete [] m_pData;
270 m_pData = NULL__null;
271 }
272
273 if (size<sizeof(icTagTypeSignature) || !pIO) {
274 return false;
275 }
276
277 if (!pIO->Read32(&m_nType))
278 return false;
279
280 m_nSize = size - sizeof(icTagTypeSignature);
281
282 if (m_nSize > 0) { // size could be stored as smaller than expected value, therefore the size check
283
284 m_pData = new icUInt8Number[m_nSize];
285
286 if (pIO->Read8(m_pData, m_nSize) != (icInt32Number)m_nSize) {
287 return false;
288 }
289 } else {
290 return false;
291 }
292
293 return true;
294}
295
296
297/**
298 ****************************************************************************
299 * Name: CIccTagUnknown::Write
300 *
301 * Purpose: Write an unknown tag to a file
302 *
303 * Args:
304 * pIO - The IO object to write tag to.
305 *
306 * Return:
307 * true = succesful, false = failure
308 *****************************************************************************
309 */
310bool CIccTagUnknown::Write(CIccIO *pIO)
311{
312 if (!pIO)
313 return false;
314
315 if (!pIO->Write32(&m_nType))
316 return false;
317
318 if (m_nSize && m_pData) {
319 if (pIO->Write8(m_pData, m_nSize) != (icInt32Number)m_nSize)
320 return false;
321 }
322
323 return true;
324}
325
326
327/**
328 ****************************************************************************
329 * Name: CIccTagUnknown::Describe
330 *
331 * Purpose: Dump data associated with unknown tag to a string
332 *
333 * Args:
334 * sDescription - string to concatenate tag dump to
335 *****************************************************************************
336 */
337void CIccTagUnknown::Describe(std::string &sDescription)
338{
339 icChar buf[128];
340
341 sDescription = "Unknown Tag Type of ";
342 sprintf(buf, "%u Bytes.", m_nSize-4);
343 sDescription += buf;
344
345 sDescription += "\r\n\r\nData Follows:\r\n";
346
347 icMemDump(sDescription, m_pData+4, m_nSize-4);
348}
349
350
351/**
352 ****************************************************************************
353 * Name: CIccTagText::CIccTagText
354 *
355 * Purpose: Constructor
356 *
357 *****************************************************************************
358 */
359CIccTagText::CIccTagText()
360{
361 m_szText = (icChar*)malloc(1);
362 m_szText[0] = '\0';
363 m_nBufSize = 1;
364}
365
366/**
367 ****************************************************************************
368 * Name: CIccTagText::CIccTagText
369 *
370 * Purpose: Copy Constructor
371 *
372 * Args:
373 * ITT = The CIccTagText object to be copied
374 *****************************************************************************
375 */
376CIccTagText::CIccTagText(const CIccTagText &ITT)
377{
378 m_szText = (icChar*)malloc(1);
379 m_szText[0] = '\0';
380 m_nBufSize = 1;
381 SetText(ITT.m_szText);
382}
383
384/**
385 ****************************************************************************
386 * Name: CIccTagText::operator=
387 *
388 * Purpose: Copy Operator
389 *
390 * Args:
391 * TextTag = The CIccTagText object to be copied
392 *****************************************************************************
393 */
394CIccTagText &CIccTagText::operator=(const CIccTagText &TextTag)
395{
396 if (&TextTag == this)
397 return *this;
398
399 m_szText = (icChar*)malloc(1);
400 m_szText[0] = '\0';
401 m_nBufSize = 1;
402 SetText(TextTag.m_szText);
403
404 return *this;
405}
406
407/**
408 ****************************************************************************
409 * Name: CIccTagText::~CIccTagText
410 *
411 * Purpose: Destructor
412 *
413 *****************************************************************************
414 */
415CIccTagText::~CIccTagText()
416{
417 free(m_szText);
418}
419
420/**
421 ****************************************************************************
422 * Name: CIccTagText::Read
423 *
424 * Purpose: Read in a text type tag into a data block
425 *
426 * Args:
427 * size - # of bytes in tag,
428 * pIO - IO object to read tag from
429 *
430 * Return:
431 * true = successful, false = failure
432 *****************************************************************************
433 */
434bool CIccTagText::Read(icUInt32Number size, CIccIO *pIO)
435{
436 icTagTypeSignature sig;
437
438 if (size<sizeof(icTagTypeSignature) || !pIO) {
439 m_szText[0] = '\0';
440 return false;
441 }
442
443 if (!pIO->Read32(&sig))
444 return false;
445
446 if (!pIO->Read32(&m_nReserved))
447 return false;
448
449 icUInt32Number nSize = size - sizeof(icTagTypeSignature) - sizeof(icUInt32Number);
450
451 icChar *pBuf = GetBuffer(nSize);
452
453 if (nSize) {
454 if (pIO->Read8(pBuf, nSize) != (icInt32Number)nSize) {
455 return false;
456 }
457 }
458
459 Release();
460
461 return true;
462}
463
464/**
465 ****************************************************************************
466 * Name: CIccTagText::Write
467 *
468 * Purpose: Write a text type tag to a file
469 *
470 * Args:
471 * pIO - The IO object to write tag to.
472 *
473 * Return:
474 * true = succesful, false = failure
475 *****************************************************************************
476 */
477bool CIccTagText::Write(CIccIO *pIO)
478{
479 icTagTypeSignature sig = GetType();
480
481 if (!pIO)
482 return false;
483
484 if (!pIO->Write32(&sig))
485 return false;
486
487 if (!pIO->Write32(&m_nReserved))
488 return false;
489
490 if (!m_szText)
491 return false;
492
493 icUInt32Number nSize = (icUInt32Number)strlen(m_szText)+1;
494
495 if (pIO->Write8(m_szText, nSize) != (icInt32Number)nSize)
496 return false;
497
498 return true;
499}
500
501/**
502 ****************************************************************************
503 * Name: CIccTagText::Describe
504 *
505 * Purpose: Dump data associated with the tag to a string
506 *
507 * Args:
508 * sDescription - string to concatenate tag dump to
509 *****************************************************************************
510 */
511void CIccTagText::Describe(std::string &sDescription)
512{
513 sDescription += "\"";
514 if (m_szText && *m_szText)
515 sDescription += m_szText;
516
517 sDescription += "\"\r\n";
518}
519
520
521/**
522 ****************************************************************************
523 * Name: CIccTagText::SetText
524 *
525 * Purpose: Allows text data associated with the tag to be set.
526 *
527 * Args:
528 * szText - zero terminated string to put in tag
529 *****************************************************************************
530 */
531void CIccTagText::SetText(const icChar *szText)
532{
533 if (!szText)
534 SetText("");
535
536 icUInt32Number len=(icUInt32Number)strlen(szText) + 1;
537 icChar *szBuf = GetBuffer(len);
538
539 strcpy(szBuf, szText);
540 Release();
541}
542
543/**
544 ****************************************************************************
545 * Name: *CIccTagText::operator=
546 *
547 * Purpose: Define assignment operator to associate text with tag.
548 *
549 * Args:
550 * szText - zero terminated string to put in the tag
551 *
552 * Return: A pointer to the string assigned to the tag.
553 *****************************************************************************
554 */
555const icChar *CIccTagText::operator=(const icChar *szText)
556{
557 SetText(szText);
558 return m_szText;
559}
560
561/**
562 ******************************************************************************
563 * Name: CIccTagText::GetBuffer
564 *
565 * Purpose: This function allocates room and returns pointer to data buffer to
566 * put string into
567 *
568 * Args:
569 * nSize = Requested size of data buffer.
570 *
571 * Return: The character buffer array
572 *******************************************************************************
573 */
574icChar *CIccTagText::GetBuffer(icUInt32Number nSize)
575{
576 if (m_nBufSize < nSize) {
577 m_szText = (icChar*)icRealloc(m_szText, nSize+1);
578
579 if (m_szText) {
580 m_szText[nSize] = '\0';
581 m_nBufSize = nSize;
582 }
583 else
584 m_nBufSize = 0;
585 }
586
587 return m_szText;
588}
589
590/**
591 ****************************************************************************
592 * Name: CIccTagText::Release
593 *
594 * Purpose: This will resize the buffer to fit the zero terminated string in
595 * the buffer.
596 *****************************************************************************
597 */
598void CIccTagText::Release()
599{
600 icUInt32Number nSize = (icUInt32Number)strlen(m_szText)+1;
601
602 if (nSize < m_nBufSize-1) {
603 m_szText=(icChar*)icRealloc(m_szText, nSize+1);
604 m_nBufSize = nSize+1;
605 }
606}
607
608
609/**
610******************************************************************************
611* Name: CIccTagText::Validate
612*
613* Purpose: Check tag data validity.
614*
615* Args:
616* sig = signature of tag being validated,
617* sReport = String to add report information to
618*
619* Return:
620* icValidateStatusOK if valid, or other error status.
621******************************************************************************
622*/
623icValidateStatus CIccTagText::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
624{
625 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
626
627 CIccInfo Info;
628 std::string sSigPathName = Info.GetSigPathName(sigPath);
629 icSignature sig = icGetFirstSigPathSig(sigPath);
630
631 if (m_nBufSize) {
632 switch(sig) {
633 case icSigCopyrightTag:
634 break;
635 case icSigCharTargetTag:
636 if (m_nBufSize<7) {
637 sReport += icMsgValidateNonCompliant;
638 sReport += sSigPathName;
639 sReport += " - Tag must have at least seven text characters.\r\n";
640 rv = icMaxStatus(rv, icValidateNonCompliant);
641 }
642 break;
643 default:
644 sReport += icMsgValidateWarning;
645 sReport += sSigPathName;
646 sReport += " - Unknown Tag.\r\n";
647 rv = icMaxStatus(rv, icValidateWarning);
648 }
649 int i;
650 for (i=0; m_szText[i] && i<(int)m_nBufSize; i++) {
651 if (m_szText[i]&0x80) {
652 sReport += icMsgValidateWarning;
653 sReport += sSigPathName;
654 sReport += " - Text does not contain just 7-bit data.\r\n";
655 rv = icMaxStatus(rv, icValidateWarning);
656 }
657 }
658 }
659 else {
660 sReport += icMsgValidateWarning;
661 sReport += sSigPathName;
662 sReport += " - Empty Tag.\r\n";
663 rv = icMaxStatus(rv, icValidateWarning);
664 }
665
666
667 return rv;
668}
669
670
671
672/**
673 ****************************************************************************
674 * Name: CIccTagUtf8Text::CIccTagUtf8Text
675 *
676 * Purpose: Constructor
677 *
678 *****************************************************************************
679 */
680CIccTagUtf8Text::CIccTagUtf8Text()
681{
682 m_szText = (icUChar*)malloc(1);
683 m_szText[0] = '\0';
684 m_nBufSize = 1;
685}
686
687/**
688 ****************************************************************************
689 * Name: CIccTagUtf8Text::CIccTagUtf8Text
690 *
691 * Purpose: Copy Constructor
692 *
693 * Args:
694 * ITT = The CIccTagText object to be copied
695 *****************************************************************************
696 */
697CIccTagUtf8Text::CIccTagUtf8Text(const CIccTagUtf8Text &ITT)
698{
699 m_szText = (icUChar*)malloc(1);
700 m_szText[0] = '\0';
701 m_nBufSize = 1;
702 SetText(ITT.m_szText);
703}
704
705/**
706 ****************************************************************************
707 * Name: CIccTagUtf8Text::operator=
708 *
709 * Purpose: Copy Operator
710 *
711 * Args:
712 * TextTag = The CIccTagText object to be copied
713 *****************************************************************************
714 */
715CIccTagUtf8Text &CIccTagUtf8Text::operator=(const CIccTagUtf8Text &TextTag)
716{
717 if (&TextTag == this)
718 return *this;
719
720 m_szText = (icUChar*)malloc(1);
721 m_szText[0] = '\0';
722 m_nBufSize = 1;
723 SetText(TextTag.m_szText);
724
725 return *this;
726}
727
728/**
729 ****************************************************************************
730 * Name: CIccTagUtf8Text::~CIccTagUtf8Text
731 *
732 * Purpose: Destructor
733 *
734 *****************************************************************************
735 */
736CIccTagUtf8Text::~CIccTagUtf8Text()
737{
738 free(m_szText);
739}
740
741/**
742 ****************************************************************************
743 * Name: CIccTagUtf8Text::Read
744 *
745 * Purpose: Read in a text type tag into a data block
746 *
747 * Args:
748 * size - # of bytes in tag,
749 * pIO - IO object to read tag from
750 *
751 * Return:
752 * true = successful, false = failure
753 *****************************************************************************
754 */
755bool CIccTagUtf8Text::Read(icUInt32Number size, CIccIO *pIO)
756{
757 icTagTypeSignature sig;
758
759 if (size<sizeof(icTagTypeSignature) || !pIO) {
760 m_szText[0] = '\0';
761 return false;
762 }
763
764 if (!pIO->Read32(&sig))
765 return false;
766
767 if (!pIO->Read32(&m_nReserved))
768 return false;
769
770 if (size < sizeof(icTagTypeSignature) + sizeof(icUInt32Number))
771 return false;
772
773 icUInt32Number nSize = size - sizeof(icTagTypeSignature) - sizeof(icUInt32Number);
774
775 icUChar *pBuf = GetBuffer(nSize);
776
777 if (nSize) {
778 if (pIO->Read8(pBuf, nSize) != (icInt32Number)nSize) {
779 return false;
780 }
781 }
782
783 Release();
784
785 return true;
786}
787
788/**
789 ****************************************************************************
790 * Name: CIccTagUtf8Text::Write
791 *
792 * Purpose: Write a text type tag to a file
793 *
794 * Args:
795 * pIO - The IO object to write tag to.
796 *
797 * Return:
798 * true = succesful, false = failure
799 *****************************************************************************
800 */
801bool CIccTagUtf8Text::Write(CIccIO *pIO)
802{
803 icTagTypeSignature sig = GetType();
804
805 if (!pIO)
806 return false;
807
808 if (!pIO->Write32(&sig))
809 return false;
810
811 if (!pIO->Write32(&m_nReserved))
812 return false;
813
814 if (!m_szText)
815 return false;
816
817 icUInt32Number nSize = (icUInt32Number)strlen((icChar*)m_szText)+1;
818
819 if (pIO->Write8(m_szText, nSize) != (icInt32Number)nSize)
820 return false;
821
822 return true;
823}
824
825/**
826 ****************************************************************************
827 * Name: CIccTagUtf8Text::Describe
828 *
829 * Purpose: Dump data associated with the tag to a string
830 *
831 * Args:
832 * sDescription - string to concatenate tag dump to
833 *****************************************************************************
834 */
835void CIccTagUtf8Text::Describe(std::string &sDescription)
836{
837 sDescription += "\"";
838 if (m_szText && *m_szText)
839 sDescription += (icChar*)m_szText;
840
841 sDescription += "\"\r\n";
842}
843
844
845/**
846 ****************************************************************************
847 * Name: CIccTagUtf8Text::SetText
848 *
849 * Purpose: Allows text data associated with the tag to be set.
850 *
851 * Args:
852 * szText - zero terminated string to put in tag
853 *****************************************************************************
854 */
855void CIccTagUtf8Text::SetText(const icUChar *szText)
856{
857 if (!szText)
858 SetText("");
859
860 icUInt32Number len=(icUInt32Number)strlen((icChar*)szText) + 1;
861 icUChar *szBuf = GetBuffer(len);
862
863 strcpy((icChar*)szBuf, (icChar*)szText);
864 Release();
865}
866
867
868/**
869 ****************************************************************************
870 * Name: CIccTagUtf8Text::SetText
871 *
872 * Purpose: Allows text data associated with the tag to be set.
873 *
874 * Args:
875 * szText - zero terminated string to put in tag
876 *****************************************************************************
877 */
878void CIccTagUtf8Text::SetText(const icUChar16 *szText)
879{
880 if (!szText)
881 SetText("");
882
883 icUtf8Vector text;
884 icUInt32Number len;
885 for (len=0; szText[len]; len++);
886
887 icConvertUTF16toUTF8(szText, &szText[len], text, lenientConversion);
888
889 SetText((const icUChar*)&text[0]);
890}
891
892/**
893 ****************************************************************************
894 * Name: *CIccTagUtf8Text::operator=
895 *
896 * Purpose: Define assignment operator to associate text with tag.
897 *
898 * Args:
899 * szText - zero terminated string to put in the tag
900 *
901 * Return: A pointer to the string assigned to the tag.
902 *****************************************************************************
903 */
904const icUChar *CIccTagUtf8Text::operator=(const icUChar *szText)
905{
906 SetText(szText);
907 return (icUChar*)m_szText;
908}
909
910/**
911 ******************************************************************************
912 * Name: CIccTagUtf8Text::GetBuffer
913 *
914 * Purpose: This function allocates room and returns pointer to data buffer to
915 * put string into
916 *
917 * Args:
918 * nSize = Requested size of data buffer.
919 *
920 * Return: The character buffer array
921 *******************************************************************************
922 */
923icUChar *CIccTagUtf8Text::GetBuffer(icUInt32Number nSize)
924{
925 if (m_nBufSize < nSize) {
926 m_szText = (icUChar*)icRealloc(m_szText, nSize+1);
927
928 if (m_szText) {
929 m_szText[nSize] = '\0';
930 m_nBufSize = nSize;
931 }
932 else {
933 m_nBufSize = 0;
934 }
935 }
936
937 return m_szText;
938}
939
940/**
941 ****************************************************************************
942 * Name: CIccTagUtf8Text::Release
943 *
944 * Purpose: This will resize the buffer to fit the zero terminated string in
945 * the buffer.
946 *****************************************************************************
947 */
948void CIccTagUtf8Text::Release()
949{
950 icUInt32Number nSize = (icUInt32Number)strlen((icChar*)m_szText)+1;
951
952 if (nSize < m_nBufSize-1) {
953 m_szText=(icUChar*)icRealloc(m_szText, nSize+1);
954 m_nBufSize = nSize+1;
955 }
956}
957
958
959/**
960******************************************************************************
961* Name: CIccTagUtf8Text::Validate
962*
963* Purpose: Check tag data validity.
964*
965* Args:
966* sig = signature of tag being validated,
967* sReport = String to add report information to
968*
969* Return:
970* icValidateStatusOK if valid, or other error status.
971******************************************************************************
972*/
973icValidateStatus CIccTagUtf8Text::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
974{
975 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
976
977 CIccInfo Info;
978 std::string sSigPathName = Info.GetSigPathName(sigPath);
979
980 if (!m_nBufSize) {
981 sReport += icMsgValidateWarning;
982 sReport += sSigPathName;
983 sReport += " - Empty Tag.\r\n";
984 rv = icMaxStatus(rv, icValidateWarning);
985 }
986
987
988 return rv;
989}
990
991
992static unsigned char icFaultyXmlZipData[4] = { 0,0,0,1 };
993
994/**
995 ****************************************************************************
996 * Name: CIccTagZipUtf8Text::CIccTagZipUtf8Text
997 *
998 * Purpose: Constructor
999 *
1000 *****************************************************************************
1001 */
1002CIccTagZipUtf8Text::CIccTagZipUtf8Text()
1003{
1004 m_pZipBuf = NULL__null;
1005 m_nBufSize = 0;
1006}
1007
1008/**
1009 ****************************************************************************
1010 * Name: CIccTagZipUtf8Text::CIccTagZipUtf8Text
1011 *
1012 * Purpose: Copy Constructor
1013 *
1014 * Args:
1015 * ITT = The CIccTagText object to be copied
1016 *****************************************************************************
1017 */
1018CIccTagZipUtf8Text::CIccTagZipUtf8Text(const CIccTagZipUtf8Text &ITT)
1019{
1020 m_pZipBuf = NULL__null;
1021 m_nBufSize = 0;
1022 AllocBuffer(ITT.BufferSize());
1023 if (m_pZipBuf) {
1024 memcpy(m_pZipBuf, ITT.GetBuffer(), m_nBufSize);
1025 }
1026}
1027
1028/**
1029 ****************************************************************************
1030 * Name: CIccTagZipUtf8Text::operator=
1031 *
1032 * Purpose: Copy Operator
1033 *
1034 * Args:
1035 * TextTag = The CIccTagText object to be copied
1036 *****************************************************************************
1037 */
1038CIccTagZipUtf8Text &CIccTagZipUtf8Text::operator=(const CIccTagZipUtf8Text &ITT)
1039{
1040 if (&ITT == this)
1041 return *this;
1042
1043 AllocBuffer(ITT.BufferSize());
1044 if (m_pZipBuf) {
1045 memcpy(m_pZipBuf, ITT.GetBuffer(), m_nBufSize);
1046 }
1047
1048 return *this;
1049}
1050
1051/**
1052 ****************************************************************************
1053 * Name: CIccTagZipUtf8Text::~CIccTagZipUtf8Text
1054 *
1055 * Purpose: Destructor
1056 *
1057 *****************************************************************************
1058 */
1059CIccTagZipUtf8Text::~CIccTagZipUtf8Text()
1060{
1061 if (m_pZipBuf)
1062 free(m_pZipBuf);
1063}
1064
1065/**
1066 ****************************************************************************
1067 * Name: CIccTagZipUtf8Text::Read
1068 *
1069 * Purpose: Read in a text type tag into a data block
1070 *
1071 * Args:
1072 * size - # of bytes in tag,
1073 * pIO - IO object to read tag from
1074 *
1075 * Return:
1076 * true = successful, false = failure
1077 *****************************************************************************
1078 */
1079bool CIccTagZipUtf8Text::Read(icUInt32Number size, CIccIO *pIO)
1080{
1081 icTagTypeSignature sig;
1082
1083 if (size<sizeof(icTagTypeSignature) || !pIO) {
1084 AllocBuffer(0);
1085 return false;
1086 }
1087
1088 if (!pIO->Read32(&sig))
1089 return false;
1090
1091 if (!pIO->Read32(&m_nReserved))
1092 return false;
1093
1094 icUInt32Number nSize = size - sizeof(icTagTypeSignature) - sizeof(icUInt32Number);
1095
1096 icUChar *pBuf = AllocBuffer(nSize);
1097
1098 if (m_nBufSize && pBuf) {
1099 if (pIO->Read8(pBuf, m_nBufSize) != (icInt32Number)m_nBufSize) {
1100 return false;
1101 }
1102 }
1103
1104 return true;
1105}
1106
1107/**
1108 ****************************************************************************
1109 * Name: CIccTagZipUtf8Text::Write
1110 *
1111 * Purpose: Write a text type tag to a file
1112 *
1113 * Args:
1114 * pIO - The IO object to write tag to.
1115 *
1116 * Return:
1117 * true = succesful, false = failure
1118 *****************************************************************************
1119 */
1120bool CIccTagZipUtf8Text::Write(CIccIO *pIO)
1121{
1122 icTagTypeSignature sig = GetType();
1123
1124 if (!pIO)
1125 return false;
1126
1127 if (!pIO->Write32(&sig))
1128 return false;
1129
1130 if (!pIO->Write32(&m_nReserved))
1131 return false;
1132
1133 if (m_pZipBuf) {
1134 if (pIO->Write8(m_pZipBuf, m_nBufSize) != (icInt32Number)m_nBufSize)
1135 return false;
1136 }
1137 return true;
1138}
1139
1140/**
1141 ****************************************************************************
1142 * Name: CIccTagZipUtf8Text::Describe
1143 *
1144 * Purpose: Dump data associated with the tag to a string
1145 *
1146 * Args:
1147 * sDescription - string to concatenate tag dump to
1148 *****************************************************************************
1149 */
1150void CIccTagZipUtf8Text::Describe(std::string &sDescription)
1151{
1152 std::string str;
1153#ifdef ICC_USE_ZLIB
1154 if (!GetText(str)) {
1155 sDescription += "Error! - Unable to decompress text data.\r\n";
1156 }
1157 else if (m_nBufSize > 4 && !memcmp(m_pZipBuf, icFaultyXmlZipData, 4)) {
1158 sDescription += "Warning! - Correcting for improperly encoded ";
1159 sDescription += CIccTagCreator::GetTagTypeSigName(GetType());
1160 sDescription += " tag.\r\n\r\n";
1161 }
1162
1163 sDescription += "ZLib Compressed String=\"";
1164 sDescription += str;
1165 sDescription += "\"\r\n";
1166#else
1167 char size[30];
1168 sprintf(size, "%d", m_nBufSize);
1169 sDescription += "BEGIN_COMPESSED_DATA[\"";
1170 sDescription += size;
1171 sDescription += "]\r\n";
1172 if (m_nBufSize) {
1173 icMemDump(str, m_pZipBuf, m_nBufSize);
1174 sDescription += str;
1175 sDescription += "\r\n";
1176 }
1177 sDescription += "END_COMPRESSED_DATA\r\n";
1178#endif
1179}
1180
1181/**
1182 ****************************************************************************
1183 * Name: CIccTagZipUtf8Text::GetText
1184 *
1185 * Purpose: Allows text data associated with the tag to be set.
1186 *
1187 * Args:
1188 * text - string to put uncompressed text into
1189 *****************************************************************************
1190 */
1191bool CIccTagZipUtf8Text::GetText(std::string &str) const
1192{
1193#ifndef ICC_USE_ZLIB
1194 str="";
1195 return false;
1196#else
1197 int zstat;
1198 z_stream zstr;
1199 memset(&zstr, 0, sizeof(zstr));
1200 unsigned char buf[32767] = { 0 };
1201
1202 zstat = inflateInit(&zstr);
1203
1204 if (zstat != Z_OK) {
1205 return false;
1206 }
1207
1208 zstat = inflateReset(&zstr);
1209
1210 if (zstat != Z_OK) {
1211 return false;
1212 }
1213
1214 if (m_nBufSize > 4 && !memcmp(m_pZipBuf, icFaultyXmlZipData, 4)) {
1215 //xrite creates invalid zipXMLType tags
1216 zstr.next_in = m_pZipBuf+4;
1217 zstr.avail_in = m_nBufSize-4;
1218 }
1219 else {
1220 zstr.next_in = m_pZipBuf;
1221 zstr.avail_in = m_nBufSize;
1222 }
1223
1224 do {
1225 unsigned int i, n;
1226
1227 zstr.next_out = buf;
1228 zstr.avail_out = sizeof(buf);
1229
1230 zstat = inflate(&zstr, Z_SYNC_FLUSH);
1231
1232 if (zstat != Z_OK && zstat != Z_STREAM_END) {
1233 inflateEnd(&zstr);
1234 return false;
1235 }
1236
1237 n = sizeof(buf) - zstr.avail_out;
1238
1239 for (i = 0; i < n; i++) {
1240 str += buf[i];
1241 }
1242 } while (zstat != Z_STREAM_END);
1243
1244 inflateEnd(&zstr);
1245
1246 return true;
1247#endif
1248}
1249
1250
1251/**
1252 ****************************************************************************
1253 * Name: CIccTagZipUtf8Text::SetText
1254 *
1255 * Purpose: Allows text data associated with the tag to be set.
1256 *
1257 * Args:
1258 * szText - zero terminated string to put in tag
1259 *****************************************************************************
1260 */
1261bool CIccTagZipUtf8Text::SetText(const icUChar *szText)
1262{
1263#ifndef ICC_USE_ZLIB
1264 return false;
1265#else
1266 icUInt32Number nSize = (icUInt32Number)strlen((const char*)szText) + 1;
1267 icUtf8Vector compress;
1268 int i;
1269
1270 int zstat;
1271 z_stream zstr;
1272 unsigned char buf[32767];
1273 memset(&zstr, 0, sizeof(zstr));
1274
1275 zstat = deflateInit(&zstr, Z_DEFAULT_COMPRESSION);
1276
1277 if (zstat != Z_OK) {
1278 return false;
1279 }
1280
1281 zstat = deflateReset(&zstr);
1282 zstr.next_in = (Bytef*)szText;
1283 zstr.avail_in = nSize;
1284
1285 if (zstat != Z_OK) {
1286 return false;
1287 }
1288
1289
1290 do {
1291 int n;
1292 zstr.next_out = buf;
1293 zstr.avail_out = sizeof(buf);
1294
1295 zstat = deflate(&zstr, Z_FINISH);
1296
1297 if (zstat != Z_OK && zstat != Z_STREAM_END) {
1298 deflateEnd(&zstr);
1299 return false;
1300 }
1301
1302 n = sizeof(buf) - zstr.avail_out;
1303
1304 for (i = 0; i < n; i++) {
1305 compress.push_back(buf[i]);
1306 }
1307 } while (zstat != Z_STREAM_END);
1308
1309 deflateEnd(&zstr);
1310
1311 icUChar *pBuf = AllocBuffer(compress.size());
1312
1313 if (pBuf) {
1314 for (i = 0; i < m_nBufSize; i++) {
1315 pBuf[i] = compress[i];
1316}
1317 }
1318
1319 return true;
1320#endif
1321}
1322
1323/**
1324 ****************************************************************************
1325 * Name: CIccTagZipUtf8Text::SetText
1326 *
1327 * Purpose: Allows text data associated with the tag to be set.
1328 *
1329 * Args:
1330 * szText - zero terminated string to put in tag
1331 *****************************************************************************
1332 */
1333bool CIccTagZipUtf8Text::SetText(const icUChar16 *szText)
1334{
1335 if (!szText)
1336 return SetText("");
1337
1338 icUtf8Vector text;
1339 icUInt32Number len;
1340 for (len=0; szText[len]; len++);
1341
1342 icConvertUTF16toUTF8(szText, &szText[len], text, lenientConversion);
1343
1344 return SetText((const icUChar*)&text[0]);
1345}
1346
1347
1348
1349/**
1350 ******************************************************************************
1351 * Name: CIccTagZipUtf8Text::AllocBuffer
1352 *
1353 * Purpose: This function allocates room and returns pointer to data buffer to
1354 * put string into
1355 *
1356 * Args:
1357 * nSize = Requested size of data buffer.
1358 *
1359 * Return: The character buffer array
1360 *******************************************************************************
1361 */
1362icUChar *CIccTagZipUtf8Text::AllocBuffer(icUInt32Number nSize)
1363{
1364 if (m_nBufSize != nSize) {
1365 if (!nSize) {
1366 if (m_pZipBuf)
1367 free(m_pZipBuf);
1368
1369 m_nBufSize = nSize;
1370 return NULL__null;
1371 }
1372
1373 if (!m_nBufSize)
1374 m_pZipBuf = (icUChar*)malloc(nSize);
1375 else
1376 m_pZipBuf = (icUChar*)icRealloc(m_pZipBuf, nSize);
1377
1378 m_nBufSize = nSize;
1379
1380 }
1381
1382 return m_pZipBuf;
1383}
1384
1385
1386/**
1387******************************************************************************
1388* Name: CIccTagZipUtf8Text::Validate
1389*
1390* Purpose: Check tag data validity.
1391*
1392* Args:
1393* sig = signature of tag being validated,
1394* sReport = String to add report information to
1395*
1396* Return:
1397* icValidateStatusOK if valid, or other error status.
1398******************************************************************************
1399*/
1400icValidateStatus CIccTagZipUtf8Text::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
1401{
1402 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
1403
1404 CIccInfo Info;
1405 std::string sSigPathName = Info.GetSigPathName(sigPath);
1406
1407 if (!m_nBufSize) {
1408 sReport += icMsgValidateWarning;
1409 sReport += sSigPathName;
1410 sReport += " - Empty Tag.\r\n";
1411 rv = icMaxStatus(rv, icValidateWarning);
1412 }
1413 else {
1414#ifdef ICC_USE_ZLIB
1415 std::string sText;
1416 if (!GetText(sText)) {
1417 sReport += icMsgValidateNonCompliant;
1418 sReport += sSigPathName;
1419 sReport += " - Unable to get text for tag (possibly corrupt compressed data).\r\n";
1420 rv = icMaxStatus(rv, icValidateNonCompliant);
1421 }
1422 else if (m_nBufSize > 4 && !memcmp(m_pZipBuf, icFaultyXmlZipData, 4)) {
1423 sReport += icMsgValidateNonCompliant;
1424 sReport += sSigPathName;
1425 sReport += " - Improperly encoded ";
1426 sReport += CIccTagCreator::GetTagTypeSigName(GetType());
1427 sReport += " tag.\r\n";
1428 rv = icMaxStatus(rv, icValidateNonCompliant);
1429 }
1430#else
1431 sReport += icMsgValidateWarning;
1432 sReport += sSigPathName;
1433 sReport += " - Zip compression not supported by CMM - unable to validate text compression.\r\n";
1434 rv = icMaxStatus(rv, icValidateWarning);
1435#endif
1436 }
1437
1438 return rv;
1439}
1440
1441
1442
1443/**
1444 ****************************************************************************
1445 * Name: CIccTagUtf16Text::CIccTagUtf16Text
1446 *
1447 * Purpose: Constructor
1448 *
1449 *****************************************************************************
1450 */
1451CIccTagUtf16Text::CIccTagUtf16Text()
1452{
1453 m_szText = (icUChar16*)malloc(1*sizeof(icUChar16));
1454 m_szText[0] = 0;
1455 m_nBufSize = 1;
1456}
1457
1458/**
1459 ****************************************************************************
1460 * Name: CIccTagUtf16Text::CIccTagUtf16Text
1461 *
1462 * Purpose: Copy Constructor
1463 *
1464 * Args:
1465 * ITT = The CIccTagText object to be copied
1466 *****************************************************************************
1467 */
1468CIccTagUtf16Text::CIccTagUtf16Text(const CIccTagUtf16Text &ITT)
1469{
1470 m_szText = (icUChar16*)malloc(1*sizeof(icUChar16));
1471 m_szText[0] = 0;
1472 m_nBufSize = 1;
1473 SetText(ITT.m_szText);
1474}
1475
1476/**
1477 ****************************************************************************
1478 * Name: CIccTagUtf16Text::operator=
1479 *
1480 * Purpose: Copy Operator
1481 *
1482 * Args:
1483 * TextTag = The CIccTagText object to be copied
1484 *****************************************************************************
1485 */
1486CIccTagUtf16Text &CIccTagUtf16Text::operator=(const CIccTagUtf16Text &TextTag)
1487{
1488 if (&TextTag == this)
1489 return *this;
1490
1491 m_szText = (icUChar16*)malloc(1*sizeof(icUChar16));
1492 m_szText[0] = '\0';
1493 m_nBufSize = 1;
1494 SetText(TextTag.m_szText);
1495
1496 return *this;
1497}
1498
1499/**
1500 ****************************************************************************
1501 * Name: CIccTagUtf16Text::~CIccTagUtf16Text
1502 *
1503 * Purpose: Destructor
1504 *
1505 *****************************************************************************
1506 */
1507CIccTagUtf16Text::~CIccTagUtf16Text()
1508{
1509 free(m_szText);
1510}
1511
1512/**
1513 ****************************************************************************
1514 * Name: CIccTagUtf16Text::GetLength
1515 *
1516 * Purpose: Get length of utf16 string
1517 *
1518 *****************************************************************************
1519 */
1520icUInt32Number CIccTagUtf16Text::GetLength() const
1521{
1522 icUInt32Number n;
1523 if (!m_szText || !m_nBufSize)
1524 return 0;
1525
1526 for (n=0; n<m_nBufSize && m_szText[n]; n++);
1527
1528 return n;
1529}
1530
1531/**
1532 ****************************************************************************
1533 * Name: CIccTagUtf16Text::Read
1534 *
1535 * Purpose: Read in a text type tag into a data block
1536 *
1537 * Args:
1538 * size - # of bytes in tag,
1539 * pIO - IO object to read tag from
1540 *
1541 * Return:
1542 * true = successful, false = failure
1543 *****************************************************************************
1544 */
1545bool CIccTagUtf16Text::Read(icUInt32Number size, CIccIO *pIO)
1546{
1547 icTagTypeSignature sig;
1548
1549 if (size<sizeof(icTagTypeSignature) || !pIO) {
1550 m_szText[0] = '\0';
1551 return false;
1552 }
1553
1554 if (!pIO->Read32(&sig))
1555 return false;
1556
1557 if (!pIO->Read32(&m_nReserved))
1558 return false;
1559
1560 icUInt32Number nSize = (size - sizeof(icTagTypeSignature) - sizeof(icUInt32Number))/sizeof(icUChar16);
1561
1562 icUChar16 *pBuf = GetBuffer(nSize);
1563
1564 if (nSize) {
1565 if (pIO->Read16(pBuf, nSize) != (icInt32Number)nSize) {
1566 return false;
1567 }
1568 }
1569
1570 Release();
1571
1572 return true;
1573}
1574
1575/**
1576 ****************************************************************************
1577 * Name: CIccTagUtf16Text::Write
1578 *
1579 * Purpose: Write a text type tag to a file
1580 *
1581 * Args:
1582 * pIO - The IO object to write tag to.
1583 *
1584 * Return:
1585 * true = succesful, false = failure
1586 *****************************************************************************
1587 */
1588bool CIccTagUtf16Text::Write(CIccIO *pIO)
1589{
1590 icTagTypeSignature sig = GetType();
1591
1592 if (!pIO)
1593 return false;
1594
1595 if (!pIO->Write32(&sig))
1596 return false;
1597
1598 if (!pIO->Write32(&m_nReserved))
1599 return false;
1600
1601 if (!m_szText)
1602 return false;
1603
1604 icUInt32Number nSize = GetLength();
1605
1606 if (nSize) {
1607 if (pIO->Write16(m_szText, nSize) != (icInt32Number)nSize)
1608 return false;
1609 }
1610
1611 return true;
1612}
1613
1614/**
1615 ****************************************************************************
1616 * Name: CIccTagUtf16Text::Describe
1617 *
1618 * Purpose: Dump data associated with the tag to a string
1619 *
1620 * Args:
1621 * sDescription - string to concatenate tag dump to
1622 *****************************************************************************
1623 */
1624void CIccTagUtf16Text::Describe(std::string &sDescription)
1625{
1626 sDescription += "\"";
1627 if (m_szText && *m_szText) {
1628 std::string buf;
1629 sDescription += GetText(buf);
1630 }
1631
1632 sDescription += "\"\r\n";
1633}
1634
1635/**
1636 ****************************************************************************
1637 * Name: CIccTagUtf16Text::GetText
1638 *
1639 * Purpose: Allows text data associated with the tag to be set.
1640 *
1641 * Args:
1642 * szText - zero terminated string to put in tag
1643 *****************************************************************************
1644 */
1645const icChar *CIccTagUtf16Text::GetText(std::string &buf) const
1646{
1647 icUtf8Vector str;
1648
1649 icConvertUTF16toUTF8(m_szText, &m_szText[GetLength()], str, lenientConversion);
1650
1651 buf.clear();
1652 icUtf8Vector::iterator c;
1653 c=str.begin();
1654 if (str.size()>2 && (str[0]==0xff && str[1]==0xfe)) {
1655 c++; c++;
1656 }
1657 for (; c!=str.end(); c++)
1658 buf.push_back(*c);
1659
1660 return buf.c_str();
1661}
1662
1663
1664/**
1665 ****************************************************************************
1666 * Name: CIccTagUtf16Text::SetText
1667 *
1668 * Purpose: Allows text data associated with the tag to be set.
1669 *
1670 * Args:
1671 * szText - zero terminated string to put in tag
1672 *****************************************************************************
1673 */
1674void CIccTagUtf16Text::SetText(const icUChar16 *szText)
1675{
1676 if (!szText) {
1677 icUChar16 c=0;
1678 SetText(&c);
1679 }
1680
1681 icUInt32Number n;
1682 for (n=0; szText[n]; n++);
1683
1684 icUInt32Number len=n + 1;
1685 icUChar16 *szBuf = GetBuffer(len);
1686
1687 memcpy(szBuf, szText, len*sizeof(icUChar16));
1688 Release();
1689}
1690
1691/**
1692 ****************************************************************************
1693 * Name: CIccTagUtf16Text::SetText
1694 *
1695 * Purpose: Allows text data associated with the tag to be set.
1696 *
1697 * Args:
1698 * szText - zero terminated string to put in tag
1699 *****************************************************************************
1700 */
1701void CIccTagUtf16Text::SetText(const icUChar *szText)
1702{
1703 if (!szText) {
1704 icUChar16 c=0;
1705 SetText(&c);
1706 }
1707
1708 icUtf16Vector str;
1709 icConvertUTF8toUTF16(szText, szText+strlen((icChar*)szText)+1, str, lenientConversion);
1710
1711 int pos = 0;
1712 if (str[0]==0xfeff) {
1713 pos = 1;
1714 }
1715
1716 icUInt32Number nSize = (icUInt32Number)(str.size()-pos);
1717 icUChar16 *szBuf = GetBuffer(nSize);
1718
1719 if (nSize)
1720 memcpy(m_szText, &str[pos], nSize*sizeof(icUChar));
1721 Release();
1722}
1723
1724/**
1725 ****************************************************************************
1726 * Name: *CIccTagUtf16Text::operator=
1727 *
1728 * Purpose: Define assignment operator to associate text with tag.
1729 *
1730 * Args:
1731 * szText - zero terminated string to put in the tag
1732 *
1733 * Return: A pointer to the string assigned to the tag.
1734 *****************************************************************************
1735 */
1736const icUChar16 *CIccTagUtf16Text::operator=(const icUChar16 *szText)
1737{
1738 SetText(szText);
1739 return (icUChar16*)m_szText;
1740}
1741
1742/**
1743 ******************************************************************************
1744 * Name: CIccTagUtf16Text::GetBuffer
1745 *
1746 * Purpose: This function allocates room and returns pointer to data buffer to
1747 * put string into
1748 *
1749 * Args:
1750 * nSize = Requested size of data buffer.
1751 *
1752 * Return: The utf16 character buffer array
1753 *******************************************************************************
1754 */
1755icUChar16 *CIccTagUtf16Text::GetBuffer(icUInt32Number nSize)
1756{
1757 if (m_nBufSize < nSize) {
1758 m_szText = (icUChar16*)icRealloc(m_szText, (nSize+1)*sizeof(icUChar16));
1759
1760 m_szText[nSize] = 0;
1761
1762 m_nBufSize = nSize;
1763 }
1764
1765 return m_szText;
1766}
1767
1768/**
1769 ****************************************************************************
1770 * Name: CIccTagUtf16Text::Release
1771 *
1772 * Purpose: This will resize the buffer to fit the zero terminated string in
1773 * the buffer.
1774 *****************************************************************************
1775 */
1776void CIccTagUtf16Text::Release()
1777{
1778 icUInt32Number nSize = GetLength()+1;
1779
1780 if (nSize < m_nBufSize-1) {
1781 m_szText=(icUChar16*)icRealloc(m_szText, (nSize+1)*sizeof(icUChar16));
1782 m_nBufSize = nSize+1;
1783 }
1784}
1785
1786
1787/**
1788******************************************************************************
1789* Name: CIccTagUtf16Text::Validate
1790*
1791* Purpose: Check tag data validity.
1792*
1793* Args:
1794* sig = signature of tag being validated,
1795* sReport = String to add report information to
1796*
1797* Return:
1798* icValidateStatusOK if valid, or other error status.
1799******************************************************************************
1800*/
1801icValidateStatus CIccTagUtf16Text::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
1802{
1803 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
1804
1805 CIccInfo Info;
1806 std::string sSigPathName = Info.GetSigPathName(sigPath);
1807
1808 if (!m_nBufSize) {
1809 sReport += icMsgValidateWarning;
1810 sReport += sSigPathName;
1811 sReport += " - Empty Tag.\r\n";
1812 rv = icMaxStatus(rv, icValidateWarning);
1813 }
1814
1815 return rv;
1816}
1817
1818
1819
1820/**
1821 ****************************************************************************
1822 * Name: CIccTagTextDescription::CIccTagTextDescription
1823 *
1824 * Purpose: Constructor
1825 *
1826 *****************************************************************************
1827 */
1828CIccTagTextDescription::CIccTagTextDescription()
1829{
1830 m_szText = (icChar*)malloc(1);
1831 m_szText[0] = '\0';
1832 m_nASCIISize = 1;
1833
1834 m_uzUnicodeText = (icUInt16Number*)malloc(sizeof(icUInt16Number));
1835 m_uzUnicodeText[0] = 0;
1836 m_nUnicodeSize = 1;
1837 m_nUnicodeLanguageCode = 0;
1838
1839 m_nScriptSize = 0;
1840 m_nScriptCode = 0;
1841 memset(m_szScriptText, 0, sizeof(m_szScriptText));
1842
1843 m_bInvalidScript = false;
1844}
1845
1846/**
1847 ****************************************************************************
1848 * Name: CIccTagTextDescription::CIccTagTextDescription
1849 *
1850 * Purpose: Copy Constructor
1851 *
1852 * Args:
1853 * ITTD = The CIccTagTextDescription object to be copied
1854 *****************************************************************************
1855 */
1856CIccTagTextDescription::CIccTagTextDescription(const CIccTagTextDescription &ITTD)
1857{
1858 m_nASCIISize = ITTD.m_nASCIISize;
1859 m_nUnicodeSize = ITTD.m_nUnicodeSize;
1860 m_nUnicodeLanguageCode = ITTD.m_nUnicodeLanguageCode;
1861 m_nScriptSize = ITTD.m_nScriptSize;
1862 m_nScriptCode = ITTD.m_nScriptCode;
1863
1864 if (m_nASCIISize) {
1865 m_szText = (icChar*)malloc(m_nASCIISize * sizeof(icChar));
1866 memcpy(m_szText, ITTD.m_szText, m_nASCIISize*sizeof(icChar));
1867 }
1868 else {
1869 m_nASCIISize = 1;
1870 m_szText = (icChar*)calloc(m_nASCIISize, sizeof(icChar));
1871 m_szText[0] = '\0';
1872 }
1873
1874 if (m_nUnicodeSize) {
1875 m_uzUnicodeText = (icUInt16Number*)malloc((m_nUnicodeSize) * sizeof(icUInt16Number));
1876 memcpy(m_uzUnicodeText, ITTD.m_uzUnicodeText, m_nUnicodeSize*sizeof(icUInt16Number));
1877 }
1878 else {
1879 m_nUnicodeSize = 1;
1880 m_uzUnicodeText = (icUInt16Number*)calloc(m_nUnicodeSize, sizeof(icUInt16Number));
1881 m_uzUnicodeText[0] = 0;
1882 }
1883
1884 memcpy(m_szScriptText, ITTD.m_szScriptText, sizeof(m_szScriptText));
1885
1886 m_bInvalidScript = ITTD.m_bInvalidScript;
1887}
1888
1889
1890/**
1891 ****************************************************************************
1892 * Name: CIccTagTextDescription::operator=
1893 *
1894 * Purpose: Copy Operator
1895 *
1896 * Args:
1897 * TextDescTag = The CIccTagTextDescription object to be copied
1898 *****************************************************************************
1899 */
1900CIccTagTextDescription &CIccTagTextDescription::operator=(const CIccTagTextDescription& TextDescTag)
1901{
1902 if (&TextDescTag == this)
1903 return *this;
1904
1905 m_nASCIISize = TextDescTag.m_nASCIISize;
1906 m_nUnicodeSize = TextDescTag.m_nUnicodeSize;
1907 m_nUnicodeLanguageCode = TextDescTag.m_nUnicodeLanguageCode;
1908 m_nScriptSize = TextDescTag.m_nScriptSize;
1909 m_nScriptCode = TextDescTag.m_nScriptCode;
1910
1911 if (m_szText)
1912 free(m_szText);
1913 if (m_nASCIISize) {
1914 m_szText = (icChar*)calloc(m_nASCIISize, sizeof(icChar));
1915 memcpy(m_szText, TextDescTag.m_szText, m_nASCIISize*sizeof(icChar));
1916 }
1917 else {
1918 m_nASCIISize = 1;
1919 m_szText = (icChar*)calloc(m_nASCIISize, sizeof(icChar));
1920 m_szText[0] = '\0';
1921 }
1922
1923 if (m_uzUnicodeText)
1924 free(m_uzUnicodeText);
1925 if (m_nUnicodeSize) {
1926 m_uzUnicodeText = (icUInt16Number*)calloc(m_nUnicodeSize, sizeof(icUInt16Number));
1927 memcpy(m_uzUnicodeText, TextDescTag.m_uzUnicodeText, m_nUnicodeSize*sizeof(icUInt16Number));
1928 }
1929 else {
1930 m_nUnicodeSize = 1;
1931 m_uzUnicodeText = (icUInt16Number*)calloc(m_nUnicodeSize, sizeof(icUInt16Number));
1932 m_uzUnicodeText[0] = 0;
1933 }
1934
1935 memcpy(m_szScriptText, TextDescTag.m_szScriptText, sizeof(m_szScriptText));
1936
1937 m_bInvalidScript = TextDescTag.m_bInvalidScript;
1938
1939 return *this;
1940}
1941
1942/**
1943 ****************************************************************************
1944 * Name: CIccTagTextDescription::~CIccTagTextDescription
1945 *
1946 * Purpose: Destructor
1947 *
1948 *****************************************************************************
1949 */
1950CIccTagTextDescription::~CIccTagTextDescription()
1951{
1952 free(m_szText);
1953 free(m_uzUnicodeText);
1954}
1955
1956/**
1957 ****************************************************************************
1958 * Name: CIccTagTextDescription::Read
1959 *
1960 * Purpose: Read in the tag contents into a data block
1961 *
1962 * Args:
1963 * size - # of bytes in tag,
1964 * pIO - IO object to read tag from
1965 *
1966 * Return:
1967 * true = successful, false = failure
1968 *****************************************************************************
1969 */
1970bool CIccTagTextDescription::Read(icUInt32Number size, CIccIO *pIO)
1971{
1972 icTagTypeSignature sig;
1973 icUInt32Number nEnd;
1974
1975 nEnd = pIO->Tell() + size;
1976
1977 if (size<3*sizeof(icUInt32Number) || !pIO) {
1978 m_szText[0] = '\0';
1979 return false;
1980 }
1981
1982 icUInt32Number nSize;
1983
1984 if (!pIO->Read32(&sig) ||
1985 !pIO->Read32(&m_nReserved) ||
1986 !pIO->Read32(&nSize))
1987 return false;
1988
1989 if (3*sizeof(icUInt32Number) + nSize > size)
1990 return false;
1991
1992 icChar *pBuf = GetBuffer(nSize);
1993
1994 if (nSize) {
1995 if (pIO->Read8(pBuf, nSize) != (icInt32Number)nSize) {
1996 return false;
1997 }
1998 }
1999 else
2000 m_szText[0] = '\0';
2001
2002 Release();
2003
2004 if (pIO->Tell() + 2 * sizeof(icUInt32Number) > nEnd)
2005 return false;
2006
2007 if (!pIO->Read32(&m_nUnicodeLanguageCode) ||
2008 !pIO->Read32(&nSize))
2009 return false;
2010
2011 icUInt16Number *pBuf16 = GetUnicodeBuffer(nSize);
2012
2013 if (nSize) {
2014 if (pIO->Read16(pBuf16, nSize) != (icInt32Number)nSize) {
2015 return false;
2016 }
2017 }
2018 else
2019 pBuf16[0] = 0;
2020
2021 ReleaseUnicode();
2022
2023 if (pIO->Tell()+3 > (icInt32Number)nEnd)
2024 return false;
2025
2026 if (!pIO->Read16(&m_nScriptCode) ||
2027 !pIO->Read8(&m_nScriptSize))
2028 return false;
2029
2030 if (pIO->Tell() + m_nScriptSize> (icInt32Number)nEnd ||
2031 m_nScriptSize > sizeof(m_szScriptText))
2032 return false;
2033
2034 int nScriptLen = pIO->Read8(m_szScriptText, 67);
2035
2036 if (!nScriptLen)
2037 return false;
2038
2039 if (nScriptLen<67) {
2040 memset(&m_szScriptText[0], 0, 67-nScriptLen);
2041 m_bInvalidScript = true;
2042 }
2043
2044 return true;
2045}
2046
2047/**
2048 ****************************************************************************
2049 * Name: CIccTagTextDescription::Write
2050 *
2051 * Purpose: Write the tag to a file
2052 *
2053 * Args:
2054 * pIO - The IO object to write tag to.
2055 *
2056 * Return:
2057 * true = succesful, false = failure
2058 *****************************************************************************
2059 */
2060bool CIccTagTextDescription::Write(CIccIO *pIO)
2061{
2062 icTagTypeSignature sig = GetType();
2063 icUInt32Number zero = 0;
2064
2065 if (!pIO)
2066 return false;
2067
2068 if (!pIO->Write32(&sig) ||
2069 !pIO->Write32(&m_nReserved) ||
2070 !pIO->Write32(&m_nASCIISize))
2071 return false;
2072
2073 if (m_nASCIISize) {
2074 if (pIO->Write8(m_szText, m_nASCIISize) != (icInt32Number)m_nASCIISize)
2075 return false;
2076 }
2077
2078 if (!pIO->Write32(&m_nUnicodeLanguageCode))
2079 return false;
2080
2081 if (m_nUnicodeSize > 1) {
2082 if (!pIO->Write32(&m_nUnicodeSize) ||
2083 pIO->Write16(m_uzUnicodeText, m_nUnicodeSize) != (icInt32Number)m_nUnicodeSize)
2084 return false;
2085 }
2086 else {
2087 if (!pIO->Write32(&zero))
2088 return false;
2089 }
2090
2091 if (!pIO->Write16(&m_nScriptCode) ||
2092 !pIO->Write8(&m_nScriptSize) ||
2093 pIO->Write8(m_szScriptText, 67)!= 67)
2094 return false;
2095
2096 m_bInvalidScript = false;
2097
2098 return true;
2099}
2100
2101/**
2102 ****************************************************************************
2103 * Name: CIccTagTextDescription::Describe
2104 *
2105 * Purpose: Dump data associated with the tag to a string
2106 *
2107 * Args:
2108 * sDescription - string to concatenate tag dump to
2109 *****************************************************************************
2110 */
2111void CIccTagTextDescription::Describe(std::string &sDescription)
2112{
2113 sDescription += "\"";
2114 if (m_szText && *m_szText)
2115 sDescription += m_szText;
2116
2117 sDescription += "\"\r\n";
2118}
2119
2120
2121/**
2122 ****************************************************************************
2123 * Name: CIccTagTextDescription::SetText
2124 *
2125 * Purpose: Allows text data associated with the tag to be set.
2126 *
2127 * Args:
2128 * szText - zero terminated string to put in tag
2129 *****************************************************************************
2130 */
2131void CIccTagTextDescription::SetText(const icChar *szText)
2132{
2133 m_bInvalidScript = false;
2134
2135 if (!szText)
3
Assuming 'szText' is null
4
Taking true branch
2136 SetText("");
2137
2138 icUInt32Number len=(icUInt32Number)strlen(szText) + 1;
5
Null pointer passed as 1st argument to string length function
2139 icChar *szBuf = GetBuffer(len);
2140
2141 strcpy(szBuf, szText);
2142 Release();
2143}
2144
2145/**
2146 ****************************************************************************
2147 * Name: CIccTagTextDescription::operator=
2148 *
2149 * Purpose: Define assignment operator to associate text with tag.
2150 *
2151 * Args:
2152 * szText - zero terminated string to put in the tag
2153 *
2154 * Return: A pointer to the string assigned to the tag.
2155 *****************************************************************************
2156 */
2157const icChar *CIccTagTextDescription::operator=(const icChar *szText)
2158{
2159 SetText(szText);
1
Passing value via 1st parameter 'szText'
2
Calling 'CIccTagTextDescription::SetText'
2160 return m_szText;
2161}
2162
2163/**
2164 ****************************************************************************
2165 * Name: CIccTagTextDescription::GetBuffer
2166 *
2167 * Purpose: This function allocates room and returns pointer to data buffer to
2168 * put string into
2169 *
2170 * Args:
2171 * nSize = Requested size of data buffer.
2172 *
2173 * Return:
2174 *****************************************************************************
2175 */
2176icChar *CIccTagTextDescription::GetBuffer(icUInt32Number nSize)
2177{
2178 if (m_nASCIISize < nSize) {
2179 m_szText = (icChar*)icRealloc(m_szText, nSize+1);
2180
2181 m_szText[nSize] = '\0';
2182
2183 m_nASCIISize = nSize;
2184 }
2185
2186 return m_szText;
2187}
2188
2189/**
2190 ****************************************************************************
2191 * Name: CIccTagTextDescription::Release
2192 *
2193 * Purpose: This will resize the buffer to fit the zero terminated string in
2194 * the buffer.
2195 *****************************************************************************
2196 */
2197void CIccTagTextDescription::Release()
2198{
2199 icUInt32Number nSize = (icUInt32Number)strlen(m_szText);
2200
2201 if (nSize < m_nASCIISize-1) {
2202 m_szText=(icChar*)icRealloc(m_szText, nSize+1);
2203 m_nASCIISize = nSize+1;
2204 }
2205}
2206
2207/**
2208 ****************************************************************************
2209 * Name: CIccTagTextDescription::GetUnicodeBuffer
2210 *
2211 * Purpose: This function allocates room and returns pointer to data buffer to
2212 * put string into
2213 *
2214 * Args:
2215 * nSize = Requested size of data buffer.
2216 *
2217 * Return:
2218 *****************************************************************************
2219 */
2220icUInt16Number *CIccTagTextDescription::GetUnicodeBuffer(icUInt32Number nSize)
2221{
2222 if (m_nUnicodeSize < nSize) {
2223 m_uzUnicodeText = (icUInt16Number*)icRealloc(m_uzUnicodeText, (nSize+1)*sizeof(icUInt16Number));
2224
2225 m_uzUnicodeText[nSize] = 0;
2226
2227 m_nUnicodeSize = nSize;
2228 }
2229
2230 return m_uzUnicodeText;
2231}
2232
2233/**
2234 ****************************************************************************
2235 * Name: CIccTagTextDescription::ReleaseUnicode
2236 *
2237 * Purpose: This will resize the buffer to fit the zero terminated string in
2238 * the buffer.
2239 *****************************************************************************
2240 */
2241void CIccTagTextDescription::ReleaseUnicode()
2242{
2243 int i;
2244 for (i=0; m_uzUnicodeText[i]; i++);
2245
2246 icUInt32Number nSize = i+1;
2247
2248 if (nSize < m_nUnicodeSize-1) {
2249 m_uzUnicodeText=(icUInt16Number*)icRealloc(m_uzUnicodeText, (nSize+1)*sizeof(icUInt16Number));
2250 m_nUnicodeSize = nSize+1;
2251 }
2252}
2253
2254
2255/**
2256******************************************************************************
2257* Name: CIccTagTextDescription::Validate
2258*
2259* Purpose: Check tag data validity.
2260*
2261* Args:
2262* sig = signature of tag being validated,
2263* sReport = String to add report information to
2264*
2265* Return:
2266* icValidateStatusOK if valid, or other error status.
2267******************************************************************************
2268*/
2269icValidateStatus CIccTagTextDescription::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
2270{
2271 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
2272
2273 CIccInfo Info;
2274 std::string sSigPathName = Info.GetSigPathName(sigPath);
2275
2276 if (m_nScriptSize>67) {
2277 sReport += icMsgValidateNonCompliant;
2278 sReport += sSigPathName;
2279 sReport += " - ScriptCode count must not be greater than 67.\r\n";
2280
2281 rv =icMaxStatus(rv, icValidateNonCompliant);
2282 }
2283
2284 if (m_bInvalidScript) {
2285 sReport += icMsgValidateNonCompliant;
2286 sReport += sSigPathName;
2287 sReport += " - ScriptCode must contain 67 bytes.\r\n";
2288
2289 rv =icMaxStatus(rv, icValidateNonCompliant);
2290 }
2291
2292 return rv;
2293}
2294
2295/**
2296 ****************************************************************************
2297 * Name: CIccTagSignature::CIccTagSignature
2298 *
2299 * Purpose: Constructor
2300 *
2301 *****************************************************************************
2302 */
2303CIccTagSignature::CIccTagSignature()
2304{
2305 m_nSig = 0x3f3f3f3f; //'????';
2306}
2307
2308
2309
2310/**
2311 ****************************************************************************
2312 * Name: CIccTagSignature::CIccTagSignature
2313 *
2314 * Purpose: Copy Constructor
2315 *
2316 * Args:
2317 * ITS = The CIccTagSignature object to be copied
2318 *****************************************************************************
2319 */
2320CIccTagSignature::CIccTagSignature(const CIccTagSignature &ITS)
2321{
2322 m_nSig = ITS.m_nSig;
2323}
2324
2325
2326
2327/**
2328 ****************************************************************************
2329 * Name: CIccTagSignature::operator=
2330 *
2331 * Purpose: Copy Operator
2332 *
2333 * Args:
2334 * SignatureTag = The CIccTagSignature object to be copied
2335 *****************************************************************************
2336 */
2337CIccTagSignature &CIccTagSignature::operator=(const CIccTagSignature &SignatureTag)
2338{
2339 if (&SignatureTag == this)
2340 return *this;
2341
2342 m_nSig = SignatureTag.m_nSig;
2343
2344 return *this;
2345}
2346
2347
2348/**
2349 ****************************************************************************
2350 * Name: CIccTagSignature::~CIccTagSignature
2351 *
2352 * Purpose: Destructor
2353 *
2354 *****************************************************************************
2355 */
2356CIccTagSignature::~CIccTagSignature()
2357{
2358}
2359
2360/**
2361 ****************************************************************************
2362 * Name: CIccTagSignature::Read
2363 *
2364 * Purpose: Read in the tag contents into a data block
2365 *
2366 * Args:
2367 * size - # of bytes in tag,
2368 * pIO - IO object to read tag from
2369 *
2370 * Return:
2371 * true = successful, false = failure
2372 *****************************************************************************
2373 */
2374bool CIccTagSignature::Read(icUInt32Number size, CIccIO *pIO)
2375{
2376 icTagTypeSignature sig;
2377
2378 if (sizeof(icTagTypeSignature) + 2*sizeof(icUInt32Number) > size)
2379 return false;
2380
2381 if (!pIO) {
2382 m_nSig = 0x3f3f3f3f; //'????';
2383 return false;
2384 }
2385
2386 if (!pIO->Read32(&sig))
2387 return false;
2388
2389 if (!pIO->Read32(&m_nReserved))
2390 return false;
2391
2392 if (!pIO->Read32(&m_nSig))
2393 return false;
2394
2395 return true;
2396}
2397
2398/**
2399 ****************************************************************************
2400 * Name: CIccTagSignature::Write
2401 *
2402 * Purpose: Write the tag to a file
2403 *
2404 * Args:
2405 * pIO - The IO object to write tag to.
2406 *
2407 * Return:
2408 * true = succesful, false = failure
2409 *****************************************************************************
2410 */
2411bool CIccTagSignature::Write(CIccIO *pIO)
2412{
2413 icTagTypeSignature sig = GetType();
2414
2415 if (!pIO)
2416 return false;
2417
2418 if (!pIO->Write32(&sig))
2419 return false;
2420
2421 if (!pIO->Write32(&m_nReserved))
2422 return false;
2423
2424 if (!pIO->Write32(&m_nSig))
2425 return false;
2426
2427 return true;
2428}
2429
2430
2431/**
2432 ****************************************************************************
2433 * Name: CIccTagSignature::Describe
2434 *
2435 * Purpose: Dump data associated with the tag to a string
2436 *
2437 * Args:
2438 * sDescription - string to concatenate tag dump to
2439 *****************************************************************************
2440 */
2441void CIccTagSignature::Describe(std::string &sDescription)
2442{
2443 CIccInfo Fmt;
2444
2445 sDescription += Fmt.GetSigName(m_nSig);
2446 sDescription += "\r\n";
2447}
2448
2449
2450/**
2451******************************************************************************
2452* Name: CIccTagSignature::Validate
2453*
2454* Purpose: Check tag data validity.
2455*
2456* Args:
2457* sig = signature of tag being validated,
2458* sReport = String to add report information to
2459*
2460* Return:
2461* icValidateStatusOK if valid, or other error status.
2462******************************************************************************
2463*/
2464icValidateStatus CIccTagSignature::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
2465{
2466 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
2467
2468 CIccInfo Info;
2469 std::string sSigPathName = Info.GetSigPathName(sigPath);
2470 icSignature sig = icGetFirstSigPathSig(sigPath);
2471 char buf[128];
2472
2473 if (sig==icSigTechnologyTag) {
2474 switch(m_nSig) {
2475 case icSigFilmScanner:
2476 case icSigDigitalCamera:
2477 case icSigReflectiveScanner:
2478 case icSigInkJetPrinter:
2479 case icSigThermalWaxPrinter:
2480 case icSigElectrophotographicPrinter:
2481 case icSigElectrostaticPrinter:
2482 case icSigDyeSublimationPrinter:
2483 case icSigPhotographicPaperPrinter:
2484 case icSigFilmWriter:
2485 case icSigVideoMonitor:
2486 case icSigVideoCamera:
2487 case icSigProjectionTelevision:
2488 case icSigCRTDisplay:
2489 case icSigPMDisplay:
2490 case icSigAMDisplay:
2491 case icSigPhotoCD:
2492 case icSigPhotoImageSetter:
2493 case icSigGravure:
2494 case icSigOffsetLithography:
2495 case icSigSilkscreen:
2496 case icSigFlexography:
2497 case icSigMotionPictureFilmScanner:
2498 case icSigMotionPictureFilmRecorder:
2499 case icSigDigitalMotionPictureCamera:
2500 case icSigDigitalCinemaProjector:
2501 break;
2502
2503 default:
2504 {
2505 sReport += icMsgValidateNonCompliant;
2506 sReport += sSigPathName;
2507 sprintf(buf, " - %s: Unknown Technology.\r\n", Info.GetSigName(m_nSig));
2508 sReport += buf;
2509 rv = icMaxStatus(rv, icValidateNonCompliant);
2510 }
2511 }
2512 }
2513 else if (sig==icSigPerceptualRenderingIntentGamutTag ||
2514 sig==icSigSaturationRenderingIntentGamutTag) {
2515 switch(m_nSig) {
2516 case icSigPerceptualReferenceMediumGamut:
2517 break;
2518
2519 default:
2520 {
2521 sReport += icMsgValidateNonCompliant;
2522 sReport += sSigPathName;
2523 sprintf(buf, " - %s: Unknown Reference Medium Gamut.\r\n", Info.GetSigName(m_nSig));
2524 sReport += buf;
2525 rv = icMaxStatus(rv, icValidateNonCompliant);
2526 }
2527 }
2528 }
2529 else if (sig==icSigColorimetricIntentImageStateTag) {
2530 switch(m_nSig) {
2531 case icSigSceneColorimetryEstimates:
2532 case icSigSceneAppearanceEstimates:
2533 case icSigFocalPlaneColorimetryEstimates:
2534 case icSigReflectionHardcopyOriginalColorimetry:
2535 case icSigReflectionPrintOutputColorimetry:
2536 break;
2537
2538 default:
2539 {
2540 sReport += icMsgValidateNonCompliant;
2541 sReport += sSigPathName;
2542 sprintf(buf, " - %s: Unknown Colorimetric Intent Image State.\r\n", Info.GetSigName(m_nSig));
2543 sReport += buf;
2544 rv = icMaxStatus(rv, icValidateNonCompliant);
2545 }
2546 }
2547 }
2548
2549
2550 return rv;
2551}
2552
2553/**
2554 ****************************************************************************
2555 * Name: CIccTagNamedColor2::CIccTagNamedColor2
2556 *
2557 * Purpose: Constructor
2558 *
2559 * Args:
2560 * nSize = number of named color entries,
2561 * nDeviceCoords = number of device channels
2562 *****************************************************************************
2563 */
2564CIccTagNamedColor2::CIccTagNamedColor2(int nSize/*=1*/, int nDeviceCoords/*=0*/)
2565{
2566 m_nSize = nSize <1 ? 1 : nSize;
2567 m_nVendorFlags = 0;
2568 m_nDeviceCoords = nDeviceCoords;
2569 if (nDeviceCoords<0)
2570 m_nDeviceCoords = nDeviceCoords = 0;
2571
2572 if (nDeviceCoords>0)
2573 nDeviceCoords--;
2574
2575 m_szPrefix[0] = '\0';
2576 m_szSufix[0] = '\0';
2577 m_csPCS = icSigUnknownData((icColorSpaceSignature) 0x3f3f3f3f);
2578 m_csDevice = icSigUnknownData((icColorSpaceSignature) 0x3f3f3f3f);
2579
2580 m_nColorEntrySize = 32/*rootName*/ + (3/*PCS*/ + 1/*iAny*/ + nDeviceCoords)*sizeof(icFloatNumber);
2581
2582 m_NamedColor = (SIccNamedColorEntry*)calloc(nSize, m_nColorEntrySize);
2583
2584 m_NamedLab = NULL__null;
2585}
2586
2587
2588/**
2589 ****************************************************************************
2590 * Name: CIccTagNamedColor2::CIccTagNamedColor2
2591 *
2592 * Purpose: Copy Constructor
2593 *
2594 * Args:
2595 * ITNC = The CIccTagNamedColor2 object to be copied
2596 *****************************************************************************
2597 */
2598CIccTagNamedColor2::CIccTagNamedColor2(const CIccTagNamedColor2 &ITNC)
2599{
2600 m_nColorEntrySize = ITNC.m_nColorEntrySize;
2601 m_nVendorFlags = ITNC.m_nVendorFlags;
2602 m_nDeviceCoords = ITNC.m_nDeviceCoords;
2603 m_nSize = ITNC.m_nSize;
2604
2605 m_csPCS = ITNC.m_csPCS;
2606 m_csDevice = ITNC.m_csDevice;
2607
2608 memcpy(m_szPrefix, ITNC.m_szPrefix, sizeof(m_szPrefix));
2609 memcpy(m_szSufix, ITNC.m_szSufix, sizeof(m_szSufix));
2610
2611 m_NamedColor = (SIccNamedColorEntry*)calloc(m_nSize, m_nColorEntrySize);
2612 memcpy(m_NamedColor, ITNC.m_NamedColor, m_nColorEntrySize*m_nSize);
2613
2614 m_NamedLab = NULL__null;
2615}
2616
2617
2618/**
2619 ****************************************************************************
2620 * Name: CIccTagNamedColor2::operator=
2621 *
2622 * Purpose: Copy Operator
2623 *
2624 * Args:
2625 * NamedColor2Tag = The CIccTagNamedColor2 object to be copied
2626 *****************************************************************************
2627 */
2628CIccTagNamedColor2 &CIccTagNamedColor2::operator=(const CIccTagNamedColor2 &NamedColor2Tag)
2629{
2630 if (&NamedColor2Tag == this)
2631 return *this;
2632
2633 m_nColorEntrySize = NamedColor2Tag.m_nColorEntrySize;
2634 m_nVendorFlags = NamedColor2Tag.m_nVendorFlags;
2635 m_nDeviceCoords = NamedColor2Tag.m_nDeviceCoords;
2636 m_nSize = NamedColor2Tag.m_nSize;
2637
2638 m_csPCS = NamedColor2Tag.m_csPCS;
2639 m_csDevice = NamedColor2Tag.m_csDevice;
2640
2641 memcpy(m_szPrefix, NamedColor2Tag.m_szPrefix, sizeof(m_szPrefix));
2642 memcpy(m_szSufix, NamedColor2Tag.m_szSufix, sizeof(m_szSufix));
2643
2644 if (m_NamedColor)
2645 free(m_NamedColor);
2646 m_NamedColor = (SIccNamedColorEntry*)calloc(m_nSize, m_nColorEntrySize);
2647 memcpy(m_NamedColor, NamedColor2Tag.m_NamedColor, m_nColorEntrySize*m_nSize);
2648
2649 m_NamedLab = NULL__null;
2650
2651 return *this;
2652}
2653
2654
2655/**
2656 ****************************************************************************
2657 * Name: CIccTagNamedColor2::~CIccTagNamedColor2
2658 *
2659 * Purpose: Destructor
2660 *
2661 *****************************************************************************
2662 */
2663CIccTagNamedColor2::~CIccTagNamedColor2()
2664{
2665 if (m_NamedColor)
2666 free(m_NamedColor);
2667
2668 if (m_NamedLab)
2669 delete [] m_NamedLab;
2670}
2671
2672/**
2673 ****************************************************************************
2674 * Name: CIccTagNamedColor2::SetSize
2675 *
2676 * Purpose: Sets the size of the named color array.
2677 *
2678 * Args:
2679 * nSize - number of named color entries,
2680 * nDeviceCoords - number of device channels
2681 *****************************************************************************
2682 */
2683bool CIccTagNamedColor2::SetSize(icUInt32Number nSize, icInt32Number nDeviceCoords/*=-1*/)
2684{
2685 if (nSize <1)
2686 nSize = 1;
2687 if (nDeviceCoords<0)
2688 nDeviceCoords = m_nDeviceCoords;
2689
2690 icInt32Number nNewCoords=nDeviceCoords;
2691
2692 if (nDeviceCoords>0)
2693 nDeviceCoords--;
2694
2695 icUInt32Number nColorEntrySize = 32/*rootName*/ + (3/*PCS*/ + 1/*iAny*/ + nDeviceCoords)*sizeof(icFloatNumber);
2696
2697 SIccNamedColorEntry* pNamedColor = (SIccNamedColorEntry*)calloc(nSize, nColorEntrySize);
2698
2699 if (!pNamedColor)
2700 return false;
2701
2702 icUInt32Number i, nCopy = __minmin(nSize, m_nSize);
2703 icUInt32Number j, nCoords = __minmin(nNewCoords, (icInt32Number)m_nDeviceCoords);
2704
2705 for (i=0; i<nCopy; i++) {
2706 SIccNamedColorEntry *pFrom = (SIccNamedColorEntry*)((icChar*)m_NamedColor + i*m_nColorEntrySize);
2707 SIccNamedColorEntry *pTo = (SIccNamedColorEntry*)((icChar*)pNamedColor + i*nColorEntrySize);
2708
2709 strcpy(pTo->rootName, pFrom->rootName);
2710 for (j=0; j<3; j++)
2711 pTo->pcsCoords[j] = pFrom->pcsCoords[j];
2712
2713 for (j=0; j<nCoords; j++) {
2714 pTo->deviceCoords[j] = pFrom->deviceCoords[j];
2715 }
2716 }
2717 free(m_NamedColor);
2718
2719 m_nColorEntrySize = nColorEntrySize;
2720
2721 m_NamedColor = pNamedColor;
2722 m_nSize = nSize;
2723 m_nDeviceCoords = nNewCoords;
2724
2725 ResetPCSCache();
2726
2727 return true;
2728}
2729
2730
2731/**
2732****************************************************************************
2733* Name: CIccTagNamedColor2::SetPrefix
2734*
2735* Purpose: Set contents of suffix member field
2736*
2737* Args:
2738* szPrefix - string to set prefix to
2739*****************************************************************************
2740*/
2741void CIccTagNamedColor2::SetPrefix(const icChar *szPrefix)
2742{
2743 strncpy(m_szPrefix, szPrefix, sizeof(m_szPrefix));
2744 m_szPrefix[sizeof(m_szPrefix)-1]='\0';
2745}
2746
2747
2748/**
2749****************************************************************************
2750* Name: CIccTagNamedColor2::SetSufix
2751*
2752* Purpose: Set contents of suffix member field
2753*
2754* Args:
2755* szPrefix - string to set prefix to
2756*****************************************************************************
2757*/
2758void CIccTagNamedColor2::SetSufix(const icChar *szSufix)
2759{
2760 strncpy(m_szSufix, szSufix, sizeof(m_szSufix));
2761 m_szSufix[sizeof(m_szSufix)-1]='\0';
2762}
2763
2764
2765/**
2766 ****************************************************************************
2767 * Name: CIccTagNamedColor2::Read
2768 *
2769 * Purpose: Read in the tag contents into a data block
2770 *
2771 * Args:
2772 * size - # of bytes in tag,
2773 * pIO - IO object to read tag from
2774 *
2775 * Return:
2776 * true = successful, false = failure
2777 *****************************************************************************
2778 */
2779bool CIccTagNamedColor2::Read(icUInt32Number size, CIccIO *pIO)
2780{
2781 icTagTypeSignature sig;
2782 icUInt32Number nNum, nCoords;
2783
2784 icUInt32Number nTagHdrSize = sizeof(icTagTypeSignature) +
2785 sizeof(icUInt32Number) + //m_nReserved=0
2786 sizeof(icUInt32Number) + //VendorFlags
2787 sizeof(icUInt32Number) + //Num Colors
2788 sizeof(icUInt32Number) + //Num Device Coords
2789 sizeof(m_szPrefix) +
2790 sizeof(m_szSufix);
2791 if (nTagHdrSize > size)
2792 return false;
2793
2794 if (!pIO) {
2795 return false;
2796 }
2797
2798 if (!pIO->Read32(&sig) ||
2799 !pIO->Read32(&m_nReserved) ||
2800 !pIO->Read32(&m_nVendorFlags) ||
2801 !pIO->Read32(&nNum) ||
2802 !pIO->Read32(&nCoords) ||
2803 pIO->Read8(m_szPrefix, sizeof(m_szPrefix))!=sizeof(m_szPrefix) ||
2804 pIO->Read8(m_szSufix, sizeof(m_szSufix))!=sizeof(m_szSufix)) {
2805 return false;
2806 }
2807
2808 size -= nTagHdrSize;
2809
2810 icUInt32Number nCount = size / (32+(3+nCoords)*sizeof(icUInt16Number));
2811
2812 if (nCount < nNum)
2813 return false;
2814
2815 if (!SetSize(nNum, nCoords))
2816 return false;
2817
2818 icUInt32Number i;
2819 SIccNamedColorEntry *pNamedColor=m_NamedColor;
2820
2821 for (i=0; i<nNum; i++) {
2822 if (pIO->Read8(&pNamedColor->rootName, sizeof(pNamedColor->rootName))!=sizeof(pNamedColor->rootName) ||
2823 pIO->ReadUInt16Float(&pNamedColor->pcsCoords, 3)!=3)
2824 return false;
2825 if (nCoords) {
2826 if (pIO->ReadUInt16Float(&pNamedColor->deviceCoords, nCoords)!=(icInt32Number)nCoords)
2827 return false;
2828 }
2829 pNamedColor = (SIccNamedColorEntry*)((icChar*)pNamedColor + m_nColorEntrySize);
2830 }
2831
2832 return true;
2833}
2834
2835
2836/**
2837 ****************************************************************************
2838 * Name: CIccTagNamedColor2::Write
2839 *
2840 * Purpose: Write the tag to a file
2841 *
2842 * Args:
2843 * pIO - The IO object to write tag to.
2844 *
2845 * Return:
2846 * true = succesful, false = failure
2847 *****************************************************************************
2848 */
2849bool CIccTagNamedColor2::Write(CIccIO *pIO)
2850{
2851 icTagTypeSignature sig = GetType();
2852
2853 if (!pIO)
2854 return false;
2855
2856 if (!pIO->Write32(&sig))
2857 return false;
2858
2859 if (!pIO->Write32(&m_nReserved))
2860 return false;
2861
2862 if (!pIO->Write32(&m_nVendorFlags))
2863 return false;
2864
2865 if (!pIO->Write32(&m_nSize))
2866 return false;
2867
2868 if (!pIO->Write32(&m_nDeviceCoords))
2869 return false;
2870
2871 if (!pIO->Write8(m_szPrefix, sizeof(m_szPrefix)))
2872 return false;
2873
2874 if (!pIO->Write8(m_szSufix, sizeof(m_szSufix)))
2875 return false;
2876
2877 icUInt32Number i;
2878 SIccNamedColorEntry *pNamedColor=m_NamedColor;
2879
2880 for (i=0; i<m_nSize; i++) {
2881 if (pIO->Write8(&pNamedColor->rootName, sizeof(pNamedColor->rootName))!=sizeof(pNamedColor->rootName) ||
2882 pIO->WriteUInt16Float(&pNamedColor->pcsCoords, 3)!=3)
2883 return false;
2884 if (m_nDeviceCoords) {
2885 if (pIO->WriteUInt16Float(&pNamedColor->deviceCoords, m_nDeviceCoords) != (icInt32Number)m_nDeviceCoords)
2886 return false;
2887 }
2888 pNamedColor = (SIccNamedColorEntry*)((icChar*)pNamedColor + m_nColorEntrySize);
2889 }
2890
2891 return true;
2892}
2893
2894
2895/**
2896 ****************************************************************************
2897 * Name: CIccTagNamedColor2::Describe
2898 *
2899 * Purpose: Dump data associated with the tag to a string
2900 *
2901 * Args:
2902 * sDescription - string to concatenate tag dump to
2903 *****************************************************************************
2904 */
2905void CIccTagNamedColor2::Describe(std::string &sDescription)
2906{
2907 icChar buf[128], szColorVal[40], szColor[40];
2908
2909 icUInt32Number i, j;
2910 SIccNamedColorEntry *pNamedColor=m_NamedColor;
2911
2912 sDescription.reserve(sDescription.size() + m_nSize*79);
2913
2914 sprintf(buf, "BEGIN_NAMED_COLORS flags=%08x %u %u\r\n", m_nVendorFlags, m_nSize, m_nDeviceCoords);
2915 sDescription += buf;
2916
2917 sprintf(buf, "Prefix=\"%s\"\r\n", m_szPrefix);
2918 sDescription += buf;
2919
2920 sprintf(buf, "Sufix= \"%s\"\r\n", m_szSufix);
2921 sDescription += buf;
2922
2923 for (i=0; i<m_nSize; i++) {
2924 sprintf(buf, "Color[%u]: %s :", i, pNamedColor->rootName);
2925 sDescription += buf;
2926
2927 icFloatNumber pcsCoord[3];
2928 for (j=0; j<3; j++)
2929 pcsCoord[j] = pNamedColor->pcsCoords[j];
2930
2931 if (m_csPCS==icSigLabData) {
2932 for (j=0; j<3; j++)
2933 pcsCoord[j] = (icFloatNumber)(pcsCoord[j] * 65535.0 / 65280.0);
2934 }
2935
2936 for (j=0; j<3; j++) {
2937 icColorIndexName(szColor, m_csPCS, j, 3, "P");
2938 icColorValue(szColorVal, pcsCoord[j], m_csPCS, j);
2939 sprintf(buf, " %s=%s", szColor, szColorVal);
2940 sDescription += buf;
2941 }
2942 if (m_nDeviceCoords) {
2943 sDescription += " :";
2944 for (j=0; j<m_nDeviceCoords; j++) {
2945 icColorIndexName(szColor, m_csDevice, j, m_nDeviceCoords, "D");
2946 icColorValue(szColorVal, pNamedColor->deviceCoords[j], m_csDevice, j);
2947 sprintf(buf, " %s=%s", szColor, szColorVal);
2948 sDescription += buf;
2949 }
2950 }
2951 sDescription += "\r\n";
2952
2953 pNamedColor = (SIccNamedColorEntry*)((icChar*)pNamedColor + m_nColorEntrySize);
2954 }
2955}
2956
2957/**
2958 ****************************************************************************
2959 * Name: CIccTagNamedColor2::SetColorSpaces
2960 *
2961 * Purpose: Set the device and PCS color space of the tag
2962 *
2963 * Args:
2964 * csPCS = PCS color space signature,
2965 * csDevice = Device color space signature
2966 *
2967 *****************************************************************************
2968 */
2969void CIccTagNamedColor2::SetColorSpaces(icColorSpaceSignature csPCS, icColorSpaceSignature csDevice)
2970{
2971 m_csPCS = csPCS;
2972 m_csDevice = csDevice;
2973}
2974
2975/**
2976 ****************************************************************************
2977 * Name: CIccTagNamedColor2::FindRootColor
2978 *
2979 * Purpose: Find the root color name
2980 *
2981 * Args:
2982 * szRootColor = string containing the root color name to be found
2983 *
2984 * Return: Index of the named color array where the root color name was found,
2985 * if the color was not found -1 is returned
2986 *****************************************************************************
2987 */
2988icInt32Number CIccTagNamedColor2::FindRootColor(const icChar *szRootColor) const
2989{
2990 for (icUInt32Number i=0; i<m_nSize; i++) {
2991 if (stricmpstrcasecmp(m_NamedColor[i].rootName,szRootColor) == 0)
2992 return i;
2993 }
2994
2995 return -1;
2996}
2997
2998/**
2999 ****************************************************************************
3000 * Name: CIccTagNamedColor2::ResetPCSCache
3001 *
3002 * Purpose: This function is called if entry values change between calls
3003 * to FindPCSColor()
3004 *
3005 *****************************************************************************
3006 */
3007void CIccTagNamedColor2::ResetPCSCache()
3008{
3009 if (m_NamedLab) {
3010 delete [] m_NamedLab;
3011 m_NamedLab = NULL__null;
3012 }
3013}
3014
3015/**
3016****************************************************************************
3017* Name: CIccTagNamedColor2::InitFindPCSColor
3018*
3019* Purpose: Initialization needed for using FindPCSColor
3020*
3021* Return:
3022* true if successfull, false if failure
3023*****************************************************************************
3024*/
3025bool CIccTagNamedColor2::InitFindCachedPCSColor()
3026{
3027 icFloatNumber *pXYZ, *pLab;
3028
3029 if (!m_NamedLab) {
3030 m_NamedLab = new SIccNamedLabEntry[m_nSize];
3031 if (!m_NamedLab)
3032 return false;
3033
3034 if (m_csPCS != icSigLabData) {
3035 for (icUInt32Number i=0; i<m_nSize; i++) {
3036 pLab = m_NamedLab[i].lab;
3037 pXYZ = m_NamedColor[i].pcsCoords;
3038 icXyzFromPcs(pXYZ);
3039 icXYZtoLab(pLab, pXYZ);
3040 }
3041 }
3042 else {
3043 for (icUInt32Number i=0; i<m_nSize; i++) {
3044 pLab = m_NamedLab[i].lab;
3045 Lab2ToLab4(pLab, m_NamedColor[i].pcsCoords);
3046 icLabFromPcs(pLab);
3047 }
3048 }
3049 }
3050
3051 return true;
3052}
3053
3054/**
3055 ****************************************************************************
3056 * Name: CIccTagNamedColor2::FindPCSColor
3057 *
3058 * Purpose: Find the PCS color within the specified deltaE
3059 *
3060 * Args:
3061 * pPCS = PCS co-ordinates,
3062 * dMinDE = the minimum deltaE (tolerance)
3063 *
3064 * Return: Index of the named color array where the PCS color was found,
3065 * if the color was not found within the tolerance -1 is returned
3066 *****************************************************************************
3067 */
3068icInt32Number CIccTagNamedColor2::FindCachedPCSColor(icFloatNumber *pPCS, icFloatNumber dMinDE/*=1000.0*/) const
3069{
3070 icFloatNumber dCalcDE, dLeastDE=0.0;
3071 icFloatNumber pLabIn[3];
3072 icFloatNumber *pXYZ, *pLab;
3073 icInt32Number leastDEindex = -1;
3074 if (m_csPCS != icSigLabData) {
3075 pXYZ = pPCS;
3076 icXyzFromPcs(pXYZ);
3077 icXYZtoLab(pLabIn,pXYZ);
3078 }
3079 else {
3080 Lab2ToLab4(pLabIn, pPCS);
3081 icLabFromPcs(pLabIn);
3082 }
3083
3084 if (!m_NamedLab)
3085 return -1;
3086
3087 for (icUInt32Number i=0; i<m_nSize; i++) {
3088 pLab = m_NamedLab[i].lab;
3089
3090 dCalcDE = icDeltaE(pLabIn, pLab);
3091
3092 if (i==0) {
3093 dLeastDE = dCalcDE;
3094 leastDEindex = i;
3095 }
3096
3097 if (dCalcDE<dMinDE) {
3098 if (dCalcDE<dLeastDE) {
3099 dLeastDE = dCalcDE;
3100 leastDEindex = i;
3101 }
3102 }
3103 }
3104
3105 return leastDEindex;
3106}
3107
3108/**
3109****************************************************************************
3110* Name: CIccTagNamedColor2::FindPCSColor
3111*
3112* Purpose: Find the PCS color within the specified deltaE
3113*
3114* Args:
3115* pPCS = PCS co-ordinates,
3116* dMinDE = the minimum deltaE (tolerance)
3117*
3118* Return: Index of the named color array where the PCS color was found,
3119* if the color was not found within the tolerance -1 is returned
3120*****************************************************************************
3121*/
3122icInt32Number CIccTagNamedColor2::FindPCSColor(icFloatNumber *pPCS, icFloatNumber dMinDE/*=1000.0*/)
3123{
3124 if (!m_NamedLab)
3125 InitFindCachedPCSColor();
3126
3127 return FindCachedPCSColor(pPCS, dMinDE);
3128}
3129
3130/**
3131 ****************************************************************************
3132 * Name: CIccTagNamedColor2::FindColor
3133 *
3134 * Purpose: Find the color with given name
3135 *
3136 * Args:
3137 * szColor = the color name
3138 *
3139 * Return: Index of the named color array where the color name was found,
3140 * if the color was not found -1 is returned
3141 *****************************************************************************
3142 */
3143icInt32Number CIccTagNamedColor2::FindColor(const icChar *szColor) const
3144{
3145 std::string sColorName;
3146 icInt32Number i, j;
3147
3148 j = (icInt32Number)strlen(m_szPrefix);
3149 if (j != 0) {
3150 if (strncmp(szColor, m_szPrefix, j))
3151 return -1;
3152 }
3153
3154 j = (icInt32Number)strlen(m_szSufix);
3155 i = (icInt32Number)strlen(szColor);
3156 if (j != 0) {
3157 if (strncmp(szColor+(i-j), m_szSufix, j))
3158 return -1;
3159 }
3160
3161
3162 for ( i=0; i<(icInt32Number)m_nSize; i++) {
3163 sColorName = m_szPrefix;
3164 sColorName += m_NamedColor[i].rootName;
3165 sColorName += m_szSufix;
3166
3167 if (strcmp(sColorName.c_str(),szColor) == 0)
3168 return i;
3169 }
3170
3171 return -1;
3172}
3173
3174/**
3175 ****************************************************************************
3176 * Name: CIccTagNamedColor2::FindDeviceColor
3177 *
3178 * Purpose: Find the device color
3179 *
3180 * Args:
3181 * pDevColor = device color co-ordinates
3182 *
3183 * Return: Index of the named color array where the closest device color
3184 * was found, if device representation is absent -1 is returned.
3185 *****************************************************************************
3186 */
3187icInt32Number CIccTagNamedColor2::FindDeviceColor(icFloatNumber *pDevColor) const
3188{
3189 if (!m_nDeviceCoords)
3190 return -1;
3191
3192 icFloatNumber dCalcDiff=0.0, dLeastDiff=0.0;
3193 icFloatNumber *pDevOut;
3194 icInt32Number leastDiffindex = -1;
3195
3196
3197 for (icUInt32Number i=0; i<m_nSize; i++) {
3198 pDevOut = m_NamedColor[i].deviceCoords;
3199
3200 for (icUInt32Number j=0; j<m_nDeviceCoords; j++) {
3201 dCalcDiff += (pDevColor[j]-pDevOut[j])*(pDevColor[j]-pDevOut[j]);
3202 }
3203 dCalcDiff = (icFloatNumber)sqrt(dCalcDiff);
3204
3205 if (i==0) {
3206 dLeastDiff = dCalcDiff;
3207 leastDiffindex = i;
3208 }
3209
3210 if (dCalcDiff<dLeastDiff) {
3211 dLeastDiff = dCalcDiff;
3212 leastDiffindex = i;
3213 }
3214
3215 dCalcDiff = 0.0;
3216 }
3217
3218 return leastDiffindex;
3219}
3220
3221/**
3222 ****************************************************************************
3223 * Name: CIccTagNamedColor2::GetColorName
3224 *
3225 * Purpose: Extracts the color name from the named color array
3226 *
3227 * Args:
3228 * sColorName = string where color name will be stored,
3229 * index = array index of the color name
3230 *
3231 * Return:
3232 * true = if the index is within range,
3233 * false = index out of range
3234 *****************************************************************************
3235 */
3236bool CIccTagNamedColor2::GetColorName(std::string &sColorName, icInt32Number index) const
3237{
3238 if (index > (icInt32Number)m_nSize-1)
3239 return false;
3240
3241 sColorName += m_szPrefix;
3242 SIccNamedColorEntry * pNamedColor = (SIccNamedColorEntry*)((icChar*)m_NamedColor + m_nColorEntrySize * index);
3243 sColorName += pNamedColor->rootName;
3244 sColorName += m_szSufix;
3245
3246 return true;
3247}
3248
3249/**
3250 ****************************************************************************
3251 * Name: CIccTagNamedColor2::UnitClip
3252 *
3253 * Purpose: Clip number so that its between 0-1
3254 *
3255 * Args:
3256 * v = number to be clipped
3257 *
3258 * Return: Clipped number
3259 *
3260 *****************************************************************************
3261 */
3262icFloatNumber CIccTagNamedColor2::UnitClip(icFloatNumber v) const
3263{
3264 if (v<0)
3265 v = 0;
3266 if (v>1.0)
3267 v = 1.0;
3268
3269 return v;
3270}
3271
3272/**
3273 ****************************************************************************
3274 * Name: CIccTagNamedColor2::NegClip
3275 *
3276 * Purpose: Negative numbers are clipped to zero
3277 *
3278 * Args:
3279 * v = number to be clipped
3280 *
3281 * Return: Clipped number
3282 *
3283 *****************************************************************************
3284 */
3285icFloatNumber CIccTagNamedColor2::NegClip(icFloatNumber v) const
3286{
3287 if (v<0)
3288 v=0;
3289
3290 return v;
3291}
3292
3293
3294/**
3295 ****************************************************************************
3296 * Name: CIccTagNamedColor2::Lab2ToLab4
3297 *
3298 * Purpose: Convert version 2 Lab to version 4 Lab
3299 *
3300 * Args:
3301 * Dst = array to store version 4 Lab coordinates,
3302 * Src = array containing version 2 Lab coordinates
3303 *
3304 *****************************************************************************
3305 */
3306void CIccTagNamedColor2::Lab2ToLab4(icFloatNumber *Dst, const icFloatNumber *Src) const
3307{
3308 Dst[0] = UnitClip((icFloatNumber)(Src[0] * 65535.0 / 65280.0));
3309 Dst[1] = UnitClip((icFloatNumber)(Src[1] * 65535.0 / 65280.0));
3310 Dst[2] = UnitClip((icFloatNumber)(Src[2] * 65535.0 / 65280.0));
3311}
3312
3313/**
3314 ****************************************************************************
3315 * Name: CIccTagNamedColor2::Lab4ToLab2
3316 *
3317 * Purpose: Convert version 4 Lab to version 2 Lab
3318 *
3319 * Args:
3320 * Dst = array to store version 2 Lab coordinates,
3321 * Src = array containing version 4 Lab coordinates
3322 *
3323 *****************************************************************************
3324 */
3325void CIccTagNamedColor2::Lab4ToLab2(icFloatNumber *Dst, const icFloatNumber *Src) const
3326{
3327 Dst[0] = (icFloatNumber)(Src[0] * 65280.0 / 65535.0);
3328 Dst[1] = (icFloatNumber)(Src[1] * 65280.0 / 65535.0);
3329 Dst[2] = (icFloatNumber)(Src[2] * 65280.0 / 65535.0);
3330}
3331
3332
3333/**
3334******************************************************************************
3335* Name: CIccTagNamedColor2::Validate
3336*
3337* Purpose: Check tag data validity.
3338*
3339* Args:
3340* sig = signature of tag being validated,
3341* sReport = String to add report information to
3342*
3343* Return:
3344* icValidateStatusOK if valid, or other error status.
3345******************************************************************************
3346*/
3347icValidateStatus CIccTagNamedColor2::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
3348{
3349 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
3350
3351 CIccInfo Info;
3352 std::string sSigPathName = Info.GetSigPathName(sigPath);
3353
3354 if (!m_nSize) {
3355 sReport += icMsgValidateWarning;
3356 sReport += sSigPathName;
3357 sReport += " - Empty tag!\r\n";
3358 rv = icMaxStatus(rv, icValidateWarning);
3359 }
3360
3361 if (m_nDeviceCoords) {
3362 if (pProfile) {
3363 icUInt32Number nCoords = icGetSpaceSamples(pProfile->m_Header.colorSpace);
3364 if (m_nDeviceCoords != nCoords) {
3365 sReport += icMsgValidateNonCompliant;
3366 sReport += sSigPathName;
3367 sReport += " - Incorrect number of device co-ordinates.\r\n";
3368 rv = icMaxStatus(rv, icValidateNonCompliant);
3369 }
3370 }
3371 else {
3372 sReport += icMsgValidateWarning;
3373 sReport += sSigPathName;
3374 sReport += " - Tag validation incomplete: Pointer to profile unavailable.\r\n";
3375 rv = icMaxStatus(rv, icValidateWarning);
3376 }
3377 }
3378
3379
3380 return rv;
3381}
3382
3383
3384/**
3385 ****************************************************************************
3386 * Name: CIccTagXYZ::CIccTagXYZ
3387 *
3388 * Purpose: Constructor
3389 *
3390 * Args:
3391 * nSize = number of XYZ entries
3392 *
3393 *****************************************************************************
3394 */
3395CIccTagXYZ::CIccTagXYZ(int nSize/*=1*/)
3396{
3397 m_nSize = nSize;
3398 if (m_nSize <1)
3399 m_nSize = 1;
3400 m_XYZ = (icXYZNumber*)calloc(nSize, sizeof(icXYZNumber));
3401}
3402
3403
3404/**
3405 ****************************************************************************
3406 * Name: CIccTagXYZ::CIccTagXYZ
3407 *
3408 * Purpose: Copy Constructor
3409 *
3410 * Args:
3411 * ITXYZ = The CIccTagXYZ object to be copied
3412 *****************************************************************************
3413 */
3414CIccTagXYZ::CIccTagXYZ(const CIccTagXYZ &ITXYZ)
3415{
3416 m_nSize = ITXYZ.m_nSize;
3417
3418 m_XYZ = (icXYZNumber*)calloc(m_nSize, sizeof(icXYZNumber));
3419 memcpy(m_XYZ, ITXYZ.m_XYZ, sizeof(icXYZNumber)*m_nSize);
3420}
3421
3422
3423
3424/**
3425 ****************************************************************************
3426 * Name: CIccTagXYZ::operator=
3427 *
3428 * Purpose: Copy Operator
3429 *
3430 * Args:
3431 * XYZTag = The CIccTagXYZ object to be copied
3432 *****************************************************************************
3433 */
3434CIccTagXYZ &CIccTagXYZ::operator=(const CIccTagXYZ &XYZTag)
3435{
3436 if (&XYZTag == this)
3437 return *this;
3438
3439 m_nSize = XYZTag.m_nSize;
3440
3441 if (m_XYZ)
3442 free(m_XYZ);
3443 m_XYZ = (icXYZNumber*)calloc(m_nSize, sizeof(icXYZNumber));
3444 memcpy(m_XYZ, XYZTag.m_XYZ, sizeof(icXYZNumber)*m_nSize);
3445
3446 return *this;
3447}
3448
3449
3450/**
3451 ****************************************************************************
3452 * Name: CIccTagXYZ::~CIccTagXYZ
3453 *
3454 * Purpose: Destructor
3455 *
3456 *****************************************************************************
3457 */
3458CIccTagXYZ::~CIccTagXYZ()
3459{
3460 if (m_XYZ)
3461 free(m_XYZ);
3462}
3463
3464
3465/**
3466 ****************************************************************************
3467 * Name: CIccTagXYZ::Read
3468 *
3469 * Purpose: Read in the tag contents into a data block
3470 *
3471 * Args:
3472 * size - # of bytes in tag,
3473 * pIO - IO object to read tag from
3474 *
3475 * Return:
3476 * true = successful, false = failure
3477 *****************************************************************************
3478 */
3479bool CIccTagXYZ::Read(icUInt32Number size, CIccIO *pIO)
3480{
3481 icTagTypeSignature sig;
3482
3483 if (sizeof(icTagTypeSignature) +
3484 sizeof(icUInt32Number) +
3485 sizeof(icXYZNumber) > size)
3486 return false;
3487
3488 if (!pIO) {
3489 return false;
3490 }
3491
3492 if (!pIO->Read32(&sig))
3493 return false;
3494
3495 if (!pIO->Read32(&m_nReserved))
3496 return false;
3497
3498 icUInt32Number nNum=((size-2*sizeof(icUInt32Number)) / sizeof(icXYZNumber));
3499 icUInt32Number nNum32 = nNum*sizeof(icXYZNumber)/sizeof(icUInt32Number);
3500
3501 if (!SetSize(nNum))
3502 return false;
3503
3504 if (pIO->Read32(m_XYZ, nNum32) != (icInt32Number)nNum32 )
3505 return false;
3506
3507 return true;
3508}
3509
3510
3511/**
3512 ****************************************************************************
3513 * Name: CIccTagXYZ::Write
3514 *
3515 * Purpose: Write the tag to a file
3516 *
3517 * Args:
3518 * pIO - The IO object to write tag to.
3519 *
3520 * Return:
3521 * true = succesful, false = failure
3522 *****************************************************************************
3523 */
3524bool CIccTagXYZ::Write(CIccIO *pIO)
3525{
3526 icTagTypeSignature sig = GetType();
3527
3528 if (!pIO)
3529 return false;
3530
3531 if (!pIO->Write32(&sig))
3532 return false;
3533
3534 if (!pIO->Write32(&m_nReserved))
3535 return false;
3536
3537 icUInt32Number nNum32 = m_nSize * sizeof(icXYZNumber)/sizeof(icUInt32Number);
3538
3539 if (
3540 pIO->Write32(m_XYZ, nNum32) != (icInt32Number)nNum32)
3541 return false;
3542
3543 return true;
3544}
3545
3546
3547/**
3548 ****************************************************************************
3549 * Name: CIccTagXYZ::Describe
3550 *
3551 * Purpose: Dump data associated with the tag to a string
3552 *
3553 * Args:
3554 * sDescription - string to concatenate tag dump to
3555 *****************************************************************************
3556 */
3557void CIccTagXYZ::Describe(std::string &sDescription)
3558{
3559 icChar buf[128];
3560
3561 if (m_nSize == 1 ) {
3562 sprintf(buf, "X=%.4lf, Y=%.4lf, Z=%.4lf\r\n", icFtoD(m_XYZ[0].X), icFtoD(m_XYZ[0].Y), icFtoD(m_XYZ[0].Z));
3563 sDescription += buf;
3564 }
3565 else {
3566 icUInt32Number i;
3567 sDescription.reserve(sDescription.size() + m_nSize*79);
3568
3569 for (i=0; i<m_nSize; i++) {
3570 sprintf(buf, "value[%u]: X=%.4lf, Y=%.4lf, Z=%.4lf\r\n", i, icFtoD(m_XYZ[i].X), icFtoD(m_XYZ[i].Y), icFtoD(m_XYZ[i].Z));
3571 sDescription += buf;
3572 }
3573 }
3574}
3575
3576/**
3577 ****************************************************************************
3578 * Name: CIccTagXYZ::SetSize
3579 *
3580 * Purpose: Sets the size of the XYZ array.
3581 *
3582 * Args:
3583 * nSize - number of XYZ entries,
3584 * bZeroNew - flag to zero newly formed values
3585 *****************************************************************************
3586 */
3587bool CIccTagXYZ::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
3588{
3589 if (nSize==m_nSize)
3590 return true;
3591
3592 m_XYZ = (icXYZNumber*)icRealloc(m_XYZ, nSize*sizeof(icXYZNumber));
3593
3594 if (!m_XYZ) {
3595 m_nSize = 0;
3596 return false;
3597 }
3598
3599 if (bZeroNew && m_nSize < nSize) {
3600 memset(&m_XYZ[m_nSize], 0, (nSize-m_nSize)*sizeof(icXYZNumber));
3601 }
3602 m_nSize = nSize;
3603
3604 return true;
3605}
3606
3607
3608/**
3609******************************************************************************
3610* Name: CIccTagXYZ::Validate
3611*
3612* Purpose: Check tag data validity.
3613*
3614* Args:
3615* sig = signature of tag being validated,
3616* sReport = String to add report information to
3617*
3618* Return:
3619* icValidateStatusOK if valid, or other error status.
3620******************************************************************************
3621*/
3622icValidateStatus CIccTagXYZ::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
3623{
3624 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
3625
3626 CIccInfo Info;
3627 std::string sSigPathName = Info.GetSigPathName(sigPath);
3628
3629 if (!m_nSize) {
3630 sReport += icMsgValidateWarning;
3631 sReport += sSigPathName;
3632 sReport += " - Empty tag.\r\n";
3633
3634 rv = icMaxStatus(rv, icValidateWarning);
3635 return rv;
3636 }
3637
3638 for (int i=0; i<(int)m_nSize; i++) {
3639 rv = icMaxStatus(rv, Info.CheckData(sReport, m_XYZ[i], sSigPathName + ":XYZ"));
3640 }
3641
3642 return rv;
3643}
3644
3645
3646/**
3647 ****************************************************************************
3648 * Name: CIccTagChromaticity::CIccTagChromaticity
3649 *
3650 * Purpose: Constructor
3651 *
3652 * Args:
3653 * nSize = number of xy entries
3654 *
3655 *****************************************************************************
3656 */
3657CIccTagChromaticity::CIccTagChromaticity(int nSize/*=3*/)
3658{
3659 m_nChannels = nSize;
3660 if (m_nChannels <3)
3661 m_nChannels = 3;
3662 m_xy = (icChromaticityNumber*)calloc(nSize, sizeof(icChromaticityNumber));
3663}
3664
3665
3666/**
3667 ****************************************************************************
3668 * Name: CIccTagChromaticity::CIccTagChromaticity
3669 *
3670 * Purpose: Copy Constructor
3671 *
3672 * Args:
3673 * ITCh = The CIccTagChromaticity object to be copied
3674 *****************************************************************************
3675 */
3676CIccTagChromaticity::CIccTagChromaticity(const CIccTagChromaticity &ITCh)
3677{
3678 m_nChannels = ITCh.m_nChannels;
3679
3680 m_xy = (icChromaticityNumber*)calloc(m_nChannels, sizeof(icChromaticityNumber));
3681 memcpy(m_xy, ITCh.m_xy, sizeof(icChromaticityNumber)*m_nChannels);
3682}
3683
3684
3685/**
3686 ****************************************************************************
3687 * Name: CIccTagChromaticity::operator=
3688 *
3689 * Purpose: Copy Operator
3690 *
3691 * Args:
3692 * ChromTag = The CIccTagChromaticity object to be copied
3693 *****************************************************************************
3694 */
3695CIccTagChromaticity &CIccTagChromaticity::operator=(const CIccTagChromaticity &ChromTag)
3696{
3697 if (&ChromTag == this)
3698 return *this;
3699
3700 m_nChannels = ChromTag.m_nChannels;
3701
3702 if (m_xy)
3703 free(m_xy);
3704 m_xy = (icChromaticityNumber*)calloc(m_nChannels, sizeof(icChromaticityNumber));
3705 memcpy(m_xy, ChromTag.m_xy, sizeof(icChromaticityNumber)*m_nChannels);
3706
3707 return *this;
3708}
3709
3710
3711/**
3712 ****************************************************************************
3713 * Name: CIccTagChromaticity::~CIccTagChromaticity
3714 *
3715 * Purpose: Destructor
3716 *
3717 *****************************************************************************
3718 */
3719CIccTagChromaticity::~CIccTagChromaticity()
3720{
3721 if (m_xy)
3722 free(m_xy);
3723}
3724
3725
3726/**
3727 ****************************************************************************
3728 * Name: CIccTagChromaticity::Read
3729 *
3730 * Purpose: Read in the tag contents into a data block
3731 *
3732 * Args:
3733 * size - # of bytes in tag,
3734 * pIO - IO object to read tag from
3735 *
3736 * Return:
3737 * true = successful, false = failure
3738 *****************************************************************************
3739 */
3740bool CIccTagChromaticity::Read(icUInt32Number size, CIccIO *pIO)
3741{
3742 icTagTypeSignature sig;
3743 icUInt16Number nChannels;
3744
3745 if (sizeof(icTagTypeSignature) +
3746 sizeof(icUInt32Number) +
3747 sizeof(icUInt32Number) +
3748 sizeof(icChromaticityNumber) > size)
3749 return false;
3750
3751 if (!pIO) {
3752 return false;
3753 }
3754
3755 if (!pIO->Read32(&sig))
3756 return false;
3757
3758 if (!pIO->Read32(&m_nReserved))
3759 return false;
3760
3761 if (!pIO->Read16(&nChannels) ||
3762 !pIO->Read16(&m_nColorantType))
3763 return false;
3764
3765 icUInt32Number nNum = (size-3*sizeof(icUInt32Number)) / sizeof(icChromaticityNumber);
3766 icUInt32Number nNum32 = nNum*sizeof(icChromaticityNumber)/sizeof(icU16Fixed16Number);
3767
3768 if (nNum < nChannels)
3769 return false;
3770
3771 if (!SetSize((icUInt16Number)nNum))
3772 return false;
3773
3774 if (pIO->Read32(&m_xy[0], nNum32) != (icInt32Number)nNum32 )
3775 return false;
3776
3777 return true;
3778}
3779
3780
3781/**
3782 ****************************************************************************
3783 * Name: CIccTagChromaticity::Write
3784 *
3785 * Purpose: Write the tag to a file
3786 *
3787 * Args:
3788 * pIO - The IO object to write tag to.
3789 *
3790 * Return:
3791 * true = succesful, false = failure
3792 *****************************************************************************
3793 */
3794bool CIccTagChromaticity::Write(CIccIO *pIO)
3795{
3796 icTagTypeSignature sig = GetType();
3797
3798 if (!pIO)
3799 return false;
3800
3801 if (!pIO->Write32(&sig))
3802 return false;
3803
3804 if (!pIO->Write32(&m_nReserved))
3805 return false;
3806
3807 if (!pIO->Write16(&m_nChannels))
3808 return false;
3809
3810 if (!pIO->Write16(&m_nColorantType))
3811 return false;
3812
3813 icUInt32Number nNum32 = m_nChannels*sizeof(icChromaticityNumber)/sizeof(icU16Fixed16Number);
3814
3815 if (pIO->Write32(&m_xy[0], nNum32) != (icInt32Number)nNum32)
3816 return false;
3817
3818 return true;
3819}
3820
3821
3822/**
3823 ****************************************************************************
3824 * Name: CIccTagChromaticity::Describe
3825 *
3826 * Purpose: Dump data associated with the tag to a string
3827 *
3828 * Args:
3829 * sDescription - string to concatenate tag dump to
3830 *****************************************************************************
3831 */
3832void CIccTagChromaticity::Describe(std::string &sDescription)
3833{
3834 icChar buf[128];
3835 CIccInfo Fmt;
3836
3837 icUInt32Number i;
3838 //sDescription.reserve(sDescription.size() + m_nChannels*79);
3839 sprintf(buf, "Number of Channels : %u\r\n", m_nChannels);
3840 sDescription += buf;
3841
3842 sprintf(buf, "Colorant Encoding : %s\r\n", Fmt.GetColorantEncoding((icColorantEncoding)m_nColorantType));
3843 sDescription += buf;
3844
3845 for (i=0; i<m_nChannels; i++) {
3846 sprintf(buf, "value[%u]: x=%.3lf, y=%.3lf\r\n", i, icUFtoD(m_xy[i].x), icUFtoD(m_xy[i].y));
3847 sDescription += buf;
3848 }
3849
3850}
3851
3852/**
3853 ****************************************************************************
3854 * Name: CIccTagChromaticity::SetSize
3855 *
3856 * Purpose: Sets the size of the xy chromaticity array.
3857 *
3858 * Args:
3859 * nSize - number of xy entries,
3860 * bZeroNew - flag to zero newly formed values
3861 *****************************************************************************
3862 */
3863bool CIccTagChromaticity::SetSize(icUInt16Number nSize, bool bZeroNew/*=true*/)
3864{
3865 if (m_nChannels == nSize)
3866 return true;
3867
3868 m_xy = (icChromaticityNumber*)icRealloc(m_xy, nSize*sizeof(icChromaticityNumber));
3869
3870 if (!m_xy) {
3871 m_nChannels = 0;
3872 return false;
3873 }
3874
3875 if (bZeroNew && nSize > m_nChannels) {
3876 memset(&m_xy[m_nChannels], 0, (nSize - m_nChannels)*sizeof(icChromaticityNumber));
3877 }
3878
3879 m_nChannels = nSize;
3880 return true;
3881}
3882
3883
3884/**
3885******************************************************************************
3886* Name: CIccTagChromaticity::Validate
3887*
3888* Purpose: Check tag data validity.
3889*
3890* Args:
3891* sig = signature of tag being validated,
3892* sReport = String to add report information to
3893*
3894* Return:
3895* icValidateStatusOK if valid, or other error status.
3896******************************************************************************
3897*/
3898icValidateStatus CIccTagChromaticity::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
3899{
3900 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
3901
3902 CIccInfo Info;
3903 std::string sSigPathName = Info.GetSigPathName(sigPath);
3904
3905 if (m_nColorantType) {
3906
3907 if (m_nChannels!=3) {
3908 sReport += icMsgValidateCriticalError;
3909 sReport += sSigPathName;
3910 sReport += " - Number of device channels must be three.\r\n";
3911 rv = icMaxStatus(rv, icValidateCriticalError);
3912 }
3913
3914 switch(m_nColorantType) {
3915 case icColorantITU:
3916 {
3917 if ( (m_xy[0].x != icDtoUF((icFloatNumber)0.640)) || (m_xy[0].y != icDtoUF((icFloatNumber)0.330)) ||
3918 (m_xy[1].x != icDtoUF((icFloatNumber)0.300)) || (m_xy[1].y != icDtoUF((icFloatNumber)0.600)) ||
3919 (m_xy[2].x != icDtoUF((icFloatNumber)0.150)) || (m_xy[2].y != icDtoUF((icFloatNumber)0.060)) ) {
3920 sReport += icMsgValidateNonCompliant;
3921 sReport += sSigPathName;
3922 sReport += " - Chromaticity data does not match specification.\r\n";
3923 rv = icMaxStatus(rv, icValidateNonCompliant);
3924 }
3925 break;
3926 }
3927
3928 case icColorantSMPTE:
3929 {
3930 if ( (m_xy[0].x != icDtoUF((icFloatNumber)0.630)) || (m_xy[0].y != icDtoUF((icFloatNumber)0.340)) ||
3931 (m_xy[1].x != icDtoUF((icFloatNumber)0.310)) || (m_xy[1].y != icDtoUF((icFloatNumber)0.595)) ||
3932 (m_xy[2].x != icDtoUF((icFloatNumber)0.155)) || (m_xy[2].y != icDtoUF((icFloatNumber)0.070)) ) {
3933 sReport += icMsgValidateNonCompliant;
3934 sReport += sSigPathName;
3935 sReport += " - Chromaticity data does not match specification.\r\n";
3936 rv = icMaxStatus(rv, icValidateNonCompliant);
3937 }
3938 break;
3939 }
3940
3941 case icColorantEBU:
3942 {
3943 if ( (m_xy[0].x != icDtoUF((icFloatNumber)0.64)) || (m_xy[0].y != icDtoUF((icFloatNumber)0.33)) ||
3944 (m_xy[1].x != icDtoUF((icFloatNumber)0.29)) || (m_xy[1].y != icDtoUF((icFloatNumber)0.60)) ||
3945 (m_xy[2].x != icDtoUF((icFloatNumber)0.15)) || (m_xy[2].y != icDtoUF((icFloatNumber)0.06)) ) {
3946 sReport += icMsgValidateNonCompliant;
3947 sReport += sSigPathName;
3948 sReport += " - Chromaticity data does not match specification.\r\n";
3949 rv = icMaxStatus(rv, icValidateNonCompliant);
3950 }
3951 break;
3952 }
3953
3954 case icColorantP22:
3955 {
3956 if ( (m_xy[0].x != icDtoUF((icFloatNumber)0.625)) || (m_xy[0].y != icDtoUF((icFloatNumber)0.340)) ||
3957 (m_xy[1].x != icDtoUF((icFloatNumber)0.280)) || (m_xy[1].y != icDtoUF((icFloatNumber)0.605)) ||
3958 (m_xy[2].x != icDtoUF((icFloatNumber)0.155)) || (m_xy[2].y != icDtoUF((icFloatNumber)0.070)) ) {
3959 sReport += icMsgValidateNonCompliant;
3960 sReport += sSigPathName;
3961 sReport += " - Chromaticity data does not match specification.\r\n";
3962 rv = icMaxStatus(rv, icValidateNonCompliant);
3963 }
3964 break;
3965 }
3966
3967 default:
3968 {
3969 sReport += icMsgValidateNonCompliant;
3970 sReport += sSigPathName;
3971 sReport += " - Invalid colorant type encoding.\r\n";
3972 rv = icMaxStatus(rv, icValidateNonCompliant);
3973 }
3974 }
3975 }
3976
3977 return rv;
3978}
3979
3980
3981/**
3982 ****************************************************************************
3983 * Name: CIccTagSparseMatrixArray::CIccTagSparseMatrixArray
3984 *
3985 * Purpose: CIccTagSparseMatrixArray Constructor
3986 *
3987 * Args:
3988 * nSize = number of data entries
3989 *
3990 *****************************************************************************
3991 */
3992CIccTagSparseMatrixArray::CIccTagSparseMatrixArray(int nNumMatrices/* =1 */, int nChannelsPerMatrix/* =4 */)
3993{
3994 m_nSize = nNumMatrices;
3995 m_nChannelsPerMatrix = nChannelsPerMatrix;
3996 m_nMatrixType = icSparseMatrixFloat32;
3997
3998 if (m_nSize <1)
3999 m_nSize = 1;
4000 if (nChannelsPerMatrix<4)
4001 m_nChannelsPerMatrix = 4;
4002
4003 m_RawData = (icUInt8Number*)calloc(m_nSize, GetBytesPerMatrix());
4004
4005 m_bNonZeroPadding = false;
4006}
4007
4008
4009/**
4010 ****************************************************************************
4011 * Name: CIccTagSparseMatrixArray::CIccTagSparseMatrixArray
4012 *
4013 * Purpose: Copy Constructor
4014 *
4015 * Args:
4016 * ITFN = The CIccTagFixedNum object to be copied
4017 *****************************************************************************
4018 */
4019CIccTagSparseMatrixArray::CIccTagSparseMatrixArray(const CIccTagSparseMatrixArray &ITSMA)
4020{
4021 m_nSize = ITSMA.m_nSize;
4022 m_nChannelsPerMatrix = ITSMA.m_nChannelsPerMatrix;
4023 m_nMatrixType = ITSMA.m_nMatrixType;
4024
4025 m_RawData = (icUInt8Number*)calloc(m_nSize, GetBytesPerMatrix());
4026 memcpy(m_RawData, ITSMA.m_RawData, m_nSize*GetBytesPerMatrix());
4027
4028 m_bNonZeroPadding = ITSMA.m_bNonZeroPadding;
4029}
4030
4031
4032/**
4033 ****************************************************************************
4034 * Name: CIccTagSparseMatrixArray::operator=
4035 *
4036 * Purpose: Copy Operator
4037 *
4038 * Args:
4039 * ITFN = The CIccTagSparseMatrixArray object to be copied
4040 *****************************************************************************
4041 */
4042CIccTagSparseMatrixArray &CIccTagSparseMatrixArray::operator=(const CIccTagSparseMatrixArray &ITSMA)
4043{
4044 if (&ITSMA == this)
4045 return *this;
4046
4047 m_nSize = ITSMA.m_nSize;
4048 m_nChannelsPerMatrix = ITSMA.m_nChannelsPerMatrix;
4049
4050 if (m_RawData)
4051 free(m_RawData);
4052 m_RawData = (icUInt8Number*)calloc(m_nSize, m_nChannelsPerMatrix);
4053 memcpy(m_RawData, ITSMA.m_RawData, m_nSize*GetBytesPerMatrix());
4054
4055 m_bNonZeroPadding = ITSMA.m_bNonZeroPadding;
4056
4057 return *this;
4058}
4059
4060
4061
4062/**
4063 ****************************************************************************
4064 * Name: CIccTagSparseMatrixArray::~CIccTagSparseMatrixArray
4065 *
4066 * Purpose: Destructor
4067 *
4068 *****************************************************************************
4069 */
4070CIccTagSparseMatrixArray::~CIccTagSparseMatrixArray()
4071{
4072 if (m_RawData)
4073 free(m_RawData);
4074}
4075
4076
4077/**
4078 ****************************************************************************
4079 * Name: CIccTagSparseMatrixArray::Read
4080 *
4081 * Purpose: Read in the tag contents into a data block
4082 *
4083 * Args:
4084 * size - # of bytes in tag,
4085 * pIO - IO object to read tag from
4086 *
4087 * Return:
4088 * true = successful, false = failure
4089 *****************************************************************************
4090 */
4091bool CIccTagSparseMatrixArray::Read(icUInt32Number size, CIccIO *pIO)
4092{
4093 icTagTypeSignature sig;
4094 icUInt16Number nChannels;
4095 icUInt16Number nMatrixType;
4096 icUInt32Number nBytesPerMatrix;
4097 icUInt32Number nNumMatrices;
4098
4099 icUInt32Number nHdrSize = sizeof(icTagTypeSignature) +
4100 sizeof(icUInt32Number) +
4101 2*sizeof(icUInt16Number) +
4102 sizeof(icUInt32Number);
4103
4104 if (nHdrSize +sizeof(icUInt16Number) > size)
4105 return false;
4106
4107 if (!pIO) {
4108 return false;
4109 }
4110
4111 if (!pIO->Read32(&sig) ||
4112 !pIO->Read32(&m_nReserved) ||
4113 !pIO->Read16(&nChannels) ||
4114 !pIO->Read16(&nMatrixType) ||
4115 !pIO->Read32(&nNumMatrices))
4116 return false;
4117
4118 m_nMatrixType = (icSparseMatrixType)nMatrixType;
4119
4120 icUInt32Number nSizeLeft = size - nHdrSize;
4121
4122 Reset(nNumMatrices, nChannels);
4123 nBytesPerMatrix = GetBytesPerMatrix();
4124
4125 if (m_nSize) {
4126 icUInt32Number pos;
4127 icUInt16Number nRows;
4128
4129 int i, j;
4130 icUInt32Number n, nAligned;
4131 CIccSparseMatrix mtx;
4132
4133 m_bNonZeroPadding = false;
4134
4135 pos = nHdrSize;
4136 for (i=0; i<(int)m_nSize; i++) {
4137 icUInt8Number *pMatrix = m_RawData + i*nBytesPerMatrix;
4138
4139 n=2*sizeof(icUInt16Number);
4140
4141 if (nSizeLeft<n)
4142 return false;
4143 if (pIO->Read16(pMatrix, 2)!=2) {
4144 return false;
4145 }
4146
4147 nSizeLeft -= n;
4148 pos += n;
4149
4150 nRows = *((icUInt16Number*)pMatrix);
4151
4152 n=(nRows+1)*sizeof(icUInt16Number);
4153
4154 if (nSizeLeft<n)
4155 return false;
4156 if (pIO->Read16(pMatrix+2*sizeof(icUInt16Number), nRows+1)!=nRows+1) {
4157 return false;
4158 }
4159
4160 nSizeLeft -= n;
4161 pos += n;
4162 mtx.Reset(pMatrix, nBytesPerMatrix, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), true);
4163
4164 if (mtx.GetNumEntries()>mtx.MaxEntries(nChannels*sizeof(icFloatNumber), mtx.Rows(), sizeof(icFloatNumber)))
4165 return false;
4166
4167 n=mtx.GetNumEntries()*sizeof(icUInt16Number);
4168
4169 if (nSizeLeft<n)
4170 return false;
4171
4172 if (pIO->Read16(mtx.GetColumnsForRow(0), mtx.GetNumEntries())!=mtx.GetNumEntries())
4173 return false;
4174
4175 nSizeLeft -= n;
4176 pos += n;
4177
4178 nAligned = ((pos+3)/4)*4;
4179 if (nAligned != pos) {
4180 n = nAligned - pos;
4181 if (nSizeLeft < n)
4182 return false;
4183
4184 char zbuf[3];
4185 if (pIO->Read8(&zbuf[0], n)!=n)
4186 return false;
4187 for (j=0; j<(int)n; j++) {
4188 if (zbuf[j])
4189 m_bNonZeroPadding = true;
4190 }
4191
4192 nSizeLeft -= n;
4193 pos += n;
4194 }
4195
4196 switch(m_nMatrixType) {
4197 case icSparseMatrixUInt8:
4198 n=mtx.GetNumEntries()*sizeof(icUInt8Number);
4199 if (nSizeLeft<n)
4200 return false;
4201
4202 if (pIO->ReadUInt8Float(mtx.GetData()->getPtr(0), mtx.GetNumEntries())!=mtx.GetNumEntries())
4203 return false;
4204
4205 break;
4206
4207 case icSparseMatrixUInt16:
4208 n=mtx.GetNumEntries()*sizeof(icUInt16Number);
4209 if (nSizeLeft<n)
4210 return false;
4211
4212 if (pIO->ReadUInt16Float(mtx.GetData()->getPtr(0), mtx.GetNumEntries())!=mtx.GetNumEntries())
4213 return false;
4214
4215 break;
4216
4217 case icSparseMatrixFloat16:
4218 n=mtx.GetNumEntries()*sizeof(icFloat16Number);
4219 if (nSizeLeft<n)
4220 return false;
4221
4222 if (pIO->ReadFloat16Float(mtx.GetData()->getPtr(0), mtx.GetNumEntries())!=mtx.GetNumEntries())
4223 return false;
4224
4225 break;
4226
4227 case icSparseMatrixFloat32:
4228 n=mtx.GetNumEntries()*sizeof(icFloat32Number);
4229 if (nSizeLeft<n)
4230 return false;
4231
4232 if (pIO->ReadFloat32Float(mtx.GetData()->getPtr(0), mtx.GetNumEntries())!=mtx.GetNumEntries())
4233 return false;
4234
4235 break;
4236
4237 default:
4238 return false;
4239 }
4240 nSizeLeft -= n;
4241 pos += n;
4242
4243 nAligned = ((pos+3)/4)*4;
4244 if (nAligned != pos) {
4245 n = nAligned - pos;
4246 if (nSizeLeft < n)
4247 return false;
4248
4249 icUInt8Number zbuf[3];
4250 if (pIO->Read8(&zbuf[0], n)!=n)
4251 return false;
4252 for (j=0; j<(int)n; j++) {
4253 if (zbuf[j])
4254 m_bNonZeroPadding = true;
4255 }
4256
4257 nSizeLeft -= n;
4258 pos += n;
4259 }
4260 }
4261 if (nSizeLeft) {
4262 icUInt8Number b;
4263 for (i=0; i<(int)nSizeLeft; i++) {
4264 if (!pIO->Read8(&b))
4265 return false;
4266 if (b)
4267 m_bNonZeroPadding = true;
4268 }
4269 }
4270 }
4271
4272 return true;
4273}
4274
4275
4276/**
4277 ****************************************************************************
4278 * Name: CIccTagSparseMatrixArray::Write
4279 *
4280 * Purpose: Write the tag to a file
4281 *
4282 * Args:
4283 * pIO - The IO object to write tag to.
4284 *
4285 * Return:
4286 * true = succesful, false = failure
4287 *****************************************************************************
4288 */
4289bool CIccTagSparseMatrixArray::Write(CIccIO *pIO)
4290{
4291 icTagTypeSignature sig = GetType();
4292 icUInt16Number nTemp = m_nMatrixType;
4293
4294 if (!pIO)
4295 return false;
4296
4297 if (!pIO->Write32(&sig) ||
4298 !pIO->Write32(&m_nReserved) ||
4299 !pIO->Write16(&m_nChannelsPerMatrix) ||
4300 !pIO->Write16(&nTemp) ||
4301 !pIO->Write32(&m_nSize))
4302 return false;
4303
4304 icUInt32Number nBytesPerMatrix = m_nChannelsPerMatrix * sizeof(icFloatNumber);
4305 CIccSparseMatrix mtx;
4306 icUInt16Number nRows;
4307 int i, n;
4308
4309 for (i=0; i<(int)m_nSize; i++) {
4310 icUInt8Number *pMatrix = m_RawData + i*nBytesPerMatrix;
4311 mtx.Reset(pMatrix, nBytesPerMatrix, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), true);
4312 nRows = mtx.Rows();
4313
4314 n=(nRows+3)*sizeof(icUInt16Number);
4315
4316 if (pIO->Write16(pMatrix, nRows+3)!=nRows+3 ||
4317 pIO->Write16(mtx.GetColumnsForRow(0), mtx.GetNumEntries())!=mtx.GetNumEntries()) {
4318 return false;
4319 }
4320
4321 if (!pIO->Align32())
4322 return false;
4323
4324 switch(m_nMatrixType) {
4325 case icSparseMatrixUInt8:
4326 if (pIO->WriteUInt8Float(mtx.GetData()->getPtr(), mtx.GetNumEntries())!=mtx.GetNumEntries()) {
4327 return false;
4328 }
4329 break;
4330 case icSparseMatrixUInt16:
4331 if (pIO->WriteUInt16Float(mtx.GetData()->getPtr(), mtx.GetNumEntries())!=mtx.GetNumEntries()) {
4332 return false;
4333 }
4334 break;
4335 case icSparseMatrixFloat16:
4336 if (pIO->WriteFloat16Float(mtx.GetData()->getPtr(), mtx.GetNumEntries())!=mtx.GetNumEntries()) {
4337 return false;
4338 }
4339 break;
4340 case icSparseMatrixFloat32:
4341 if (pIO->WriteFloat32Float(mtx.GetData()->getPtr(), mtx.GetNumEntries())!=mtx.GetNumEntries()) {
4342 return false;
4343 }
4344 break;
4345 default:
4346 return false;
4347 }
4348
4349 if (!pIO->Align32())
4350 return false;
4351
4352 }
4353
4354 return true;
4355}
4356
4357/**
4358 ****************************************************************************
4359 * Name: CIccTagSparseMatrixArray::Describe
4360 *
4361 * Purpose: Dump data associated with the tag to a string
4362 *
4363 * Args:
4364 * sDescription - string to concatenate tag dump to
4365 *****************************************************************************
4366 */
4367void CIccTagSparseMatrixArray::Describe(std::string &sDescription)
4368{
4369 icChar buf[128];
4370
4371 sDescription += "Begin_SparseMatrix_Array\r\n";
4372 sprintf(buf, "OutputChannels = %d\r\n", m_nChannelsPerMatrix);
4373 sDescription += buf;
4374 sprintf(buf, "MatrixType = %d\r\n", m_nMatrixType);
4375 sDescription += buf;
4376
4377 int i, r, c;
4378 icUInt32Number nBytesPerMatrix = m_nChannelsPerMatrix * sizeof(icFloatNumber);
4379 for (i=0; i<(int)m_nSize; i++) {
4380 CIccSparseMatrix mtx(&m_RawData[i*nBytesPerMatrix], nBytesPerMatrix, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), true);
4381
4382 sprintf(buf, "\r\nBegin_Matrix_%d\r\n", i);
4383 sDescription += buf;
4384
4385 icUInt16Number *start = mtx.GetRowStart();
4386 icUInt16Number *cols = mtx.GetColumnsForRow(0);
4387 for (r=0; r<mtx.Rows(); r++) {
4388 icUInt16Number rs = start[r];
4389 icUInt16Number re = start[r+1];
4390 sprintf(buf, "Row%d:", r);
4391 sDescription += buf;
4392
4393 for (c=rs; c<re; c++) {
4394 sprintf(buf, " (%d, %.4lf)", cols[c], mtx.GetData()->get(c));
4395 sDescription += buf;
4396 }
4397 }
4398
4399 sprintf(buf, "End_Matrix_%d\r\n", i);
4400 sDescription += buf;
4401 }
4402 sDescription += "\r\nEnd_SparseMatrix_Array\r\n";
4403
4404}
4405
4406/**
4407 ****************************************************************************
4408 * Name: CIccTagSparseMatrixArray::Validate
4409 *
4410 * Purpose: Validates tag data
4411 *
4412 * Args:
4413 * sigPath - signature path of tag in profile to validate
4414 * sReport - string to put validation report results
4415 * profile - pointer to profile that contains the tag
4416 *****************************************************************************
4417 */
4418icValidateStatus CIccTagSparseMatrixArray::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
4419{
4420 icValidateStatus rv = icValidateOK;
4421 CIccInfo Info;
4422 std::string sSigPathName = Info.GetSigPathName(sigPath);
4423
4424 switch(m_nMatrixType) {
4425 case icSparseMatrixUInt8:
4426 case icSparseMatrixUInt16:
4427 case icSparseMatrixFloat16:
4428 case icSparseMatrixFloat32:
4429 break;
4430 default:
4431 sReport += icMsgValidateCriticalError;
4432 sReport += sSigPathName;
4433 sReport += " - Invalid Sparse Matrix Type.\r\n";
4434 rv = icMaxStatus(rv, icValidateCriticalError);
4435
4436 }
4437
4438 bool bCheckPCS=false;
4439
4440 icSignature sig1 = icGetFirstSigPathSig(sigPath);
4441 icSignature sig2 = icGetSecondSigPathSig(sigPath);
4442
4443 if (sig1==icSigSpectralWhitePointTag) {
4444 bCheckPCS = true;
4445 }
4446
4447 if (bCheckPCS && pProfile) {
4448 if (!icIsSameColorSpaceType(pProfile->m_Header.spectralPCS, icSigSparseMatrixReflectanceData)((((icUInt32Number)pProfile->m_Header.spectralPCS)&0xffff0000
)==((icUInt32Number)(icSigSparseMatrixReflectanceData)))
) {
4449 sReport += icMsgValidateCriticalError;
4450 sReport += sSigPathName;
4451 sReport += " - SparseMatrix data incompatible with spectral PCS.\r\n";
4452 rv = icMaxStatus(rv, icValidateCriticalError);
4453 }
4454 else if (icGetSpaceSamples((icColorSpaceSignature)pProfile->m_Header.spectralPCS)!=m_nChannelsPerMatrix) {
4455 sReport += icMsgValidateCriticalError;
4456 sReport += sSigPathName;
4457 sReport += " - SparseMatrix Output channels doesn't match spectral PCS channels.\r\n";
4458 rv = icMaxStatus(rv, icValidateCriticalError);
4459 }
4460 }
4461
4462 if (m_bNonZeroPadding) {
4463 sReport += icMsgValidateNonCompliant;
4464 sReport += sSigPathName;
4465 sReport += " - Non zero padding in matrices used.\r\n";
4466 rv = icMaxStatus(rv, icValidateNonCompliant);
4467 }
4468
4469 if (!m_nSize) {
4470 sReport += icMsgValidateWarning;
4471 sReport += sSigPathName;
4472 sReport += " - No Matrices Defined.\r\n";
4473 rv = icMaxStatus(rv, icValidateWarning);
4474 return rv;
4475 }
4476
4477 if (!m_RawData) {
4478 sReport += icMsgValidateCriticalError;
4479 sReport += sSigPathName;
4480 sReport += " - Data dont defined for matrices\r\n";
4481 rv = icMaxStatus(rv, icValidateCriticalError);
4482 return rv;
4483 }
4484
4485 icUInt16Number nRows, nCols;
4486 CIccSparseMatrix mtx;
4487 int i;
4488
4489 icUInt16Number nBytesPerMatrix = m_nChannelsPerMatrix * sizeof(icFloatNumber);
4490
4491 mtx.Reset(m_RawData, nBytesPerMatrix, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), true);
4492 nRows = mtx.Rows();
4493 nCols = mtx.Cols();
4494 icUInt32Number nMaxElements = CIccSparseMatrix::MaxEntries(nBytesPerMatrix, nRows, sizeof(icFloatNumber));
4495 char buf[128];
4496 icUInt8Number *temp = new icUInt8Number[nBytesPerMatrix];
4497
4498 for (i=0; i<(int)m_nSize; i++) {
4499 mtx.Reset(m_RawData+i*nBytesPerMatrix, nBytesPerMatrix, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), true);
4500 if (mtx.Rows() != nRows || mtx.Cols() != nCols) {
4501 sReport += icMsgValidateCriticalError;
4502 sReport += sSigPathName;
4503 sprintf(buf, " - Matrix[%d] doesn't have matching rows and columns.\r\n", i);
4504 sReport += buf;
4505 rv = icMaxStatus(rv, icValidateCriticalError);
4506 }
4507
4508 if (mtx.GetNumEntries()>nMaxElements) {
4509 sReport += icMsgValidateCriticalError;
4510 sReport += sSigPathName;
4511 sprintf(buf, " - Matrix[%d] entries exceeds number supported by Output channels.\r\n", i);
4512 sReport += buf;
4513 rv = icMaxStatus(rv, icValidateCriticalError);
4514 }
4515
4516 if (!mtx.IsValid()) {
4517 sReport += icMsgValidateCriticalError;
4518 sReport += sSigPathName;
4519 sprintf(buf, " - Matrix[%d] has an invalid matrix structure.\r\n", i);
4520 sReport += buf;
4521 rv = icMaxStatus(rv, icValidateCriticalError);
4522 }
4523
4524 if (i<(int)(m_nSize-1)) {
4525 CIccSparseMatrix umtx(temp, nBytesPerMatrix, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), false);
4526 CIccSparseMatrix mtx2(m_RawData+(i+1)*nBytesPerMatrix, nBytesPerMatrix, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), true);
4527
4528 umtx.Init(nRows, nCols);
4529 if (!umtx.Union(mtx, mtx2)) {
4530 sReport += icMsgValidateCriticalError;
4531 sReport += sSigPathName;
4532 sprintf(buf, " - Interpolation from Matrix[%d] exceeds number of supported Output channels.\r\n", i);
4533 sReport += buf;
4534 rv = icMaxStatus(rv, icValidateCriticalError);
4535 }
4536 }
4537 }
4538 delete [] temp;
4539
4540 return rv;
4541}
4542
4543
4544/**
4545 ****************************************************************************
4546 * Name: CIccTagSparseMatrixArray::Reset
4547 *
4548 * Purpose: Sets the size of the data array erasing all previous values
4549 *
4550 * Args:
4551 * nNumMatrices - number of matrices
4552 * numChannelsPerMatrix - Equivalent number of output channels that
4553 * determines the fixed block size for each matrix
4554 *****************************************************************************
4555 */
4556bool CIccTagSparseMatrixArray::Reset(icUInt32Number nNumMatrices, icUInt16Number nChannelsPerMatrix)
4557{
4558 if (nNumMatrices==m_nSize && nChannelsPerMatrix==m_nChannelsPerMatrix)
4559 return true;
4560
4561 m_nSize = nNumMatrices;
4562 m_nChannelsPerMatrix = nChannelsPerMatrix;
4563
4564 icUInt32Number nSize = m_nSize * GetBytesPerMatrix();
4565
4566 m_RawData = (icUInt8Number *)icRealloc(m_RawData, nSize);
4567
4568 if (!m_RawData) {
4569 m_nSize = 0;
4570 return false;
4571 }
4572
4573 memset(m_RawData, 0, nSize);
4574 return true;
4575}
4576
4577
4578/**
4579****************************************************************************
4580* Name: CIccTagSparseMatrixArray::GetValues
4581*
4582* Purpose: Gets values from the num array tag as floating point numbers
4583*
4584* Args:
4585* nSize - number of data entries,
4586* bZeroNew - flag to zero newly formed values
4587*****************************************************************************
4588*/
4589bool CIccTagSparseMatrixArray::GetSparseMatrix(CIccSparseMatrix &mtx, int nIndex, bool bInitFromData/*=true*/)
4590{
4591 if (nIndex<0 || nIndex>(int)m_nSize) {
4592 mtx.Reset(NULL__null, 0, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), false);
4593 return false;
4594 }
4595
4596 icUInt32Number nBytesPerMatrix = GetBytesPerMatrix();
4597
4598 mtx.Reset(m_RawData+nIndex*GetBytesPerMatrix(), nBytesPerMatrix, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), bInitFromData);
4599
4600 return true;
4601}
4602
4603bool CIccTagSparseMatrixArray::GetValues(icFloatNumber *DstVector, icUInt32Number nStart/*=0*/, icUInt32Number nVectorSize/*=1*/) const
4604{
4605 icUInt32Number nBytesPerMatrix = GetBytesPerMatrix();
4606 if (nVectorSize!=nBytesPerMatrix)
4607 return false;
4608 if (nStart % nBytesPerMatrix != 0)
4609 return false;
4610
4611 if (nStart / nBytesPerMatrix > m_nSize)
4612 return false;
4613
4614 memcpy(DstVector, m_RawData+nStart, nVectorSize);
4615 return true;
4616}
4617
4618
4619/**
4620****************************************************************************
4621* Name: CIccTagSparseMatrixArray::Interpolate
4622*
4623* Purpose: Gets values from the num array tag as floating point numbers
4624*
4625* Args:
4626* nSize - number of data entries,
4627* bZeroNew - flag to zero newly formed values
4628*****************************************************************************
4629*/
4630bool CIccTagSparseMatrixArray::Interpolate(icFloatNumber *DstVector, icFloatNumber pos,
4631 icUInt32Number nVectorSize, icFloatNumber *zeroVals) const
4632{
4633 icUInt32Number nMatrix = m_nSize;
4634
4635 if (!nMatrix || nVectorSize != GetBytesPerMatrix())
4636 return false;
4637
4638 if (zeroVals)
4639 nMatrix ++;
4640 else if (nMatrix<=1)
4641 return false;
4642
4643 if (pos<0.0)
4644 pos=0.0;
4645 if (pos>1.0)
4646 pos=1.0;
4647
4648 icFloatNumber fpos = (icFloatNumber)(nMatrix-1) * pos;
4649 icUInt32Number iPos = (icUInt32Number)fpos;
4650 icFloatNumber x = fpos - iPos;
4651
4652 if (iPos == nMatrix-1) {
4653 iPos--;
4654 x = (icFloatNumber)1.0;
4655 }
4656
4657 icUInt8Number *lo, *hi;
4658
4659 if (zeroVals) {
4660 if (!iPos) {
4661 lo = (icUInt8Number*)zeroVals;
4662 hi = m_RawData;
4663 }
4664 else {
4665 lo = &m_RawData[(iPos-1)*nVectorSize];
4666 hi = &lo[nVectorSize];
4667 }
4668 }
4669 else {
4670 lo = &m_RawData[iPos*nVectorSize];
4671 hi = &lo[nVectorSize];
4672 }
4673
4674 CIccSparseMatrix mlo(lo, nVectorSize, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), true);
4675 CIccSparseMatrix mhi(hi, nVectorSize, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), true);
4676 CIccSparseMatrix dst((icUInt8Number*)DstVector, nVectorSize, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), false);
4677
4678 if (mlo.Rows()!=mhi.Rows() || mlo.Cols()!=mhi.Cols())
4679 return false;
4680
4681 if (!dst.Interp(1.0f-x, mlo, x, mhi))
4682 return false;
4683
4684 return true;
4685}
4686
4687
4688/**
4689****************************************************************************
4690* Name: CIccTagSparseMatrixArray::ValuePos
4691*
4692* Purpose: Gets position of a value int the num array tag
4693*
4694* Args:
4695* DstPos - position of val in array
4696* val - value to look for in array.
4697* bNoZero - flag indicating whether first entry is zero
4698*****************************************************************************
4699*/
4700bool CIccTagSparseMatrixArray::ValuePos(icFloatNumber &DstPos, icFloatNumber val, bool &bNoZero) const
4701{
4702 //ValuePos not supported for Sparse Matrices
4703 return false;
4704}
4705
4706
4707/**
4708 ****************************************************************************
4709 * Name: CIccTagFixedNum::CIccTagFixedNum
4710 *
4711 * Purpose: CIccTagFixedNumConstructor
4712 *
4713 * Args:
4714 * nSize = number of data entries
4715 *
4716 *****************************************************************************
4717 */
4718template <class T, icTagTypeSignature Tsig>
4719CIccTagFixedNum<T, Tsig>::CIccTagFixedNum(int nSize/*=1*/)
4720{
4721 m_nSize = nSize;
4722 if (m_nSize <1)
4723 m_nSize = 1;
4724 m_Num = (T*)calloc(nSize, sizeof(T));
4725}
4726
4727
4728/**
4729 ****************************************************************************
4730 * Name: CIccTagFixedNum::CIccTagFixedNum
4731 *
4732 * Purpose: Copy Constructor
4733 *
4734 * Args:
4735 * ITFN = The CIccTagFixedNum object to be copied
4736 *****************************************************************************
4737 */
4738template <class T, icTagTypeSignature Tsig>
4739CIccTagFixedNum<T, Tsig>::CIccTagFixedNum(const CIccTagFixedNum<T, Tsig> &ITFN)
4740{
4741 m_nSize = ITFN.m_nSize;
4742 m_Num = (T*)calloc(m_nSize, sizeof(T));
4743 memcpy(m_Num, ITFN.m_Num, m_nSize*sizeof(T));
4744}
4745
4746
4747/**
4748 ****************************************************************************
4749 * Name: CIccTagFixedNum::operator=
4750 *
4751 * Purpose: Copy Operator
4752 *
4753 * Args:
4754 * ITFN = The CIccTagFixedNum object to be copied
4755 *****************************************************************************
4756 */
4757template <class T, icTagTypeSignature Tsig>
4758CIccTagFixedNum<T, Tsig> &CIccTagFixedNum<T, Tsig>::operator=(const CIccTagFixedNum<T, Tsig> &ITFN)
4759{
4760 if (&ITFN == this)
4761 return *this;
4762
4763 m_nSize = ITFN.m_nSize;
4764
4765 if (m_Num)
4766 free(m_Num);
4767 m_Num = (T*)calloc(m_nSize, sizeof(T));
4768 memcpy(m_Num, ITFN.m_Num, m_nSize*sizeof(T));
4769
4770 return *this;
4771}
4772
4773
4774
4775/**
4776 ****************************************************************************
4777 * Name: CIccTagFixedNum::~CIccTagFixedNum
4778 *
4779 * Purpose: Destructor
4780 *
4781 *****************************************************************************
4782 */
4783template <class T, icTagTypeSignature Tsig>
4784CIccTagFixedNum<T, Tsig>::~CIccTagFixedNum()
4785{
4786 if (m_Num)
4787 free(m_Num);
4788}
4789
4790/**
4791 ****************************************************************************
4792 * Name: CIccTagFixedNum::GetClassName
4793 *
4794 * Purpose: Returns the tag type class name
4795 *
4796 *****************************************************************************
4797 */
4798template <class T, icTagTypeSignature Tsig>
4799const icChar* CIccTagFixedNum<T, Tsig>::GetClassName() const
4800{
4801 if (Tsig==icSigS15Fixed16ArrayType)
4802 return "CIccTagS15Fixed16";
4803 else
4804 return "CIccTagU16Fixed16";
4805}
4806
4807
4808/**
4809 ****************************************************************************
4810 * Name: CIccTagFixedNum::Read
4811 *
4812 * Purpose: Read in the tag contents into a data block
4813 *
4814 * Args:
4815 * size - # of bytes in tag,
4816 * pIO - IO object to read tag from
4817 *
4818 * Return:
4819 * true = successful, false = failure
4820 *****************************************************************************
4821 */
4822template <class T, icTagTypeSignature Tsig>
4823bool CIccTagFixedNum<T, Tsig>::Read(icUInt32Number size, CIccIO *pIO)
4824{
4825 icTagTypeSignature sig;
4826
4827 if (sizeof(icTagTypeSignature) +
4828 sizeof(icUInt32Number) +
4829 sizeof(T) > size)
4830 return false;
4831
4832 if (!pIO) {
4833 return false;
4834 }
4835
4836 if (!pIO->Read32(&sig))
4837 return false;
4838
4839 if (!pIO->Read32(&m_nReserved))
4840 return false;
4841
4842 icUInt32Number nSize=((size-2*sizeof(icUInt32Number)) / sizeof(T));
4843
4844 if (!SetSize(nSize))
4845 return false;
4846
4847 if (pIO->Read32(m_Num, nSize) != (icInt32Number)nSize )
4848 return false;
4849
4850 return true;
4851}
4852
4853
4854/**
4855 ****************************************************************************
4856 * Name: CIccTagFixedNum::Write
4857 *
4858 * Purpose: Write the tag to a file
4859 *
4860 * Args:
4861 * pIO - The IO object to write tag to.
4862 *
4863 * Return:
4864 * true = succesful, false = failure
4865 *****************************************************************************
4866 */
4867template <class T, icTagTypeSignature Tsig>
4868bool CIccTagFixedNum<T, Tsig>::Write(CIccIO *pIO)
4869{
4870 icTagTypeSignature sig = GetType();
4871
4872 if (!pIO)
4873 return false;
4874
4875 if (!pIO->Write32(&sig))
4876 return false;
4877
4878 if (!pIO->Write32(&m_nReserved))
4879 return false;
4880
4881 if (pIO->Write32(m_Num, m_nSize) != (icInt32Number)m_nSize)
4882 return false;
4883
4884 return true;
4885}
4886
4887/**
4888 ****************************************************************************
4889 * Name: CIccTagFixedNum::Describe
4890 *
4891 * Purpose: Dump data associated with the tag to a string
4892 *
4893 * Args:
4894 * sDescription - string to concatenate tag dump to
4895 *****************************************************************************
4896 */
4897template <class T, icTagTypeSignature Tsig>
4898void CIccTagFixedNum<T, Tsig>::Describe(std::string &sDescription)
4899{
4900 icChar buf[128];
4901
4902 if (m_nSize == 1 ) {
4903 if (Tsig==icSigS15Fixed16ArrayType)
4904 sprintf(buf, "Value = %.4lf\r\n", icFtoD(m_Num[0]));
4905 else
4906 sprintf(buf, "Value = %.4lf\r\n", icUFtoD(m_Num[0]));
4907 sDescription += buf;
4908 }
4909 else {
4910 icUInt32Number i;
4911
4912 if (Tsig==icSigS15Fixed16ArrayType && m_nSize==9) {
4913 sDescription += "Matrix Form:\r\n";
4914 icMatrixDump(sDescription, (icS15Fixed16Number*)m_Num);
4915
4916 sDescription += "\r\nArrayForm:\r\n";
4917 }
4918 sDescription.reserve(sDescription.size() + m_nSize*79);
4919
4920 for (i=0; i<m_nSize; i++) {
4921 if (Tsig==icSigS15Fixed16ArrayType)
4922 sprintf(buf, "Value[%u] = %8.4lf\r\n", i, icFtoD(m_Num[i]));
4923 else
4924 sprintf(buf, "Value[%u] = %8.4lf\r\n", i, icUFtoD(m_Num[i]));
4925 sDescription += buf;
4926 }
4927 }
4928}
4929
4930/**
4931 ****************************************************************************
4932 * Name: CIccTagFixedNum::SetSize
4933 *
4934 * Purpose: Sets the size of the data array.
4935 *
4936 * Args:
4937 * nSize - number of data entries,
4938 * bZeroNew - flag to zero newly formed values
4939 *****************************************************************************
4940 */
4941template <class T, icTagTypeSignature Tsig>
4942bool CIccTagFixedNum<T, Tsig>::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
4943{
4944 if (nSize==m_nSize)
4945 return true;
4946
4947 m_Num = (T*)icRealloc(m_Num, nSize*sizeof(T));
4948
4949 if (!m_Num) {
4950 m_nSize = 0;
4951 return false;
4952 }
4953
4954 if (bZeroNew && m_nSize < nSize) {
4955 memset(&m_Num[m_nSize], 0, (nSize-m_nSize)*sizeof(T));
4956 }
4957 m_nSize = nSize;
4958
4959 return true;
4960}
4961
4962/**
4963****************************************************************************
4964* Name: CIccTagFixedNum::GetValues
4965*
4966* Purpose: Gets values from the num array tag as floating point numbers
4967*
4968* Args:
4969* nSize - number of data entries,
4970* bZeroNew - flag to zero newly formed values
4971*****************************************************************************
4972*/
4973template <class T, icTagTypeSignature Tsig>
4974bool CIccTagFixedNum<T, Tsig>::GetValues(icFloatNumber *DstVector, icUInt32Number nStart, icUInt32Number nVectorSize) const
4975{
4976 if (nVectorSize+nStart >m_nSize)
4977 return false;
4978
4979 icUInt32Number i;
4980
4981 switch (Tsig) {
4982 case icSigS15Fixed16ArrayType:
4983 for (i=0; i<m_nSize; i++) {
4984 DstVector[i] = (icFloatNumber)icFtoD(m_Num[i+nStart]);
4985 }
4986 break;
4987 case icSigU16Fixed16ArrayType:
4988 for (i=0; i<m_nSize; i++) {
4989 DstVector[i] = (icFloatNumber)icUFtoD(m_Num[i+nStart]);
4990 }
4991 break;
4992 default:
4993 return false;
4994 }
4995 return true;
4996}
4997
4998
4999/**
5000****************************************************************************
5001* Name: CIccTagFixedNum::Interpolate
5002*
5003* Purpose: Gets values from the num array tag as floating point numbers
5004*
5005* Args:
5006* nSize - number of data entries,
5007* bZeroNew - flag to zero newly formed values
5008*****************************************************************************
5009*/
5010template <class T, icTagTypeSignature Tsig>
5011bool CIccTagFixedNum<T, Tsig>::Interpolate(icFloatNumber *DstVector, icFloatNumber pos,
5012 icUInt32Number nVectorSize, icFloatNumber *zeroVals) const
5013{
5014 icUInt32Number nVector = m_nSize / nVectorSize;
5015
5016 if (!nVector)
5017 return false;
5018
5019 if (zeroVals)
5020 nVector ++;
5021 else if (nVector<=1)
5022 return false;
5023
5024 if (pos<0.0)
5025 pos=0.0;
5026 if (pos>1.0)
5027 pos=1.0;
5028
5029 icFloatNumber fpos = (icFloatNumber)(nVector-1) * pos;
5030 icUInt32Number iPos = (icUInt32Number)fpos;
5031 icFloatNumber x = fpos - iPos;
5032
5033 if (iPos == nVector-1) {
5034 iPos--;
5035 x = (icFloatNumber)1.0;
5036 }
5037
5038 T *lo, *hi;
5039
5040 if (zeroVals) {
5041 if (!iPos) {
5042 lo = NULL__null;
5043 hi = m_Num;
5044 }
5045 else {
5046 lo = &m_Num[(iPos-1)*nVectorSize];
5047 hi = &lo[nVectorSize];
5048 }
5049 }
5050 else {
5051 lo = &m_Num[iPos*nVectorSize];
5052 hi = &lo[nVectorSize];
5053 }
5054
5055 icUInt32Number i;
5056
5057 switch (Tsig) {
5058 case icSigS15Fixed16ArrayType:
5059 if (!lo) {
5060 for (i=0; i<m_nSize; i++) {
5061 DstVector[i] = (icFloatNumber)(zeroVals[i]*(1.0f-x) + icFtoD(hi[i])*x);
5062 }
5063 }
5064 else {
5065 for (i=0; i<m_nSize; i++) {
5066 DstVector[i] = (icFloatNumber)(icFtoD(lo[i])*(1.0-x) + icFtoD(hi[i])*x);
5067 }
5068 }
5069 break;
5070 case icSigU16Fixed16ArrayType:
5071 if (!lo) {
5072 for (i=0; i<m_nSize; i++) {
5073 DstVector[i] = (icFloatNumber)(zeroVals[i]*(1.0-x) + icUFtoD(hi[i])*x);
5074 }
5075 }
5076 else {
5077 for (i=0; i<m_nSize; i++) {
5078 DstVector[i] = (icFloatNumber)(icUFtoD(lo[i])*(1.0-x) + icUFtoD(hi[i])*x);
5079 }
5080 }
5081 break;
5082 default:
5083 return false;
5084 }
5085 return true;
5086}
5087
5088/**
5089****************************************************************************
5090* Name: CIccTagFixedNum::ValuePos
5091*
5092* Purpose: Gets position of a value int the num array tag
5093*
5094* Args:
5095* DstPos - position of val in array
5096* val - value to look for in array.
5097* bNoZero - flag indicating whether first entry is zero
5098*****************************************************************************
5099*/
5100template <class T, icTagTypeSignature Tsig>
5101bool CIccTagFixedNum<T, Tsig>::ValuePos(icFloatNumber &DstPos, icFloatNumber val, bool &bNoZero) const
5102{
5103 if(val<0.0)
5104 return false;
5105
5106 icFloatNumber nv, lv;
5107 switch (Tsig) {
5108 case icSigS15Fixed16ArrayType:
5109 lv = icFtoD(m_Num[0]);
5110 break;
5111 case icSigU16Fixed16ArrayType:
5112 lv = icUFtoD(m_Num[0]);
5113 break;
5114 default:
5115 return false;
5116 }
5117 bNoZero = (lv!=0.0);
5118
5119 if (val<lv) {
5120 DstPos = val/lv - 1.0f;
5121 return true;
5122 }
5123
5124 icUInt32Number i;
5125 for (i=1; i<m_nSize; i++, lv=nv) {
5126 switch (Tsig) {
5127 case icSigS15Fixed16ArrayType:
5128 nv = icFtoD(m_Num[i]);
5129 break;
5130 case icSigU16Fixed16ArrayType:
5131 nv = icUFtoD(m_Num[i]);
5132 break;
5133 default:
5134 return false;
5135 }
5136 if (val<=nv) {
5137 DstPos = (val-lv)/(nv-lv) + i - 1.0f;
5138 return true;
5139 }
5140 }
5141
5142 return false;
5143}
5144
5145
5146//Make sure typedef classes get built
5147template class CIccTagFixedNum<icS15Fixed16Number, icSigS15Fixed16ArrayType>;
5148template class CIccTagFixedNum<icU16Fixed16Number, icSigU16Fixed16ArrayType>;
5149
5150
5151/**
5152 ****************************************************************************
5153 * Name: CIccTagNum::CIccTagNum
5154 *
5155 * Purpose: Constructor
5156 *
5157 * Args:
5158 * nSize = number of data entries
5159 *****************************************************************************
5160 */
5161template <class T, icTagTypeSignature Tsig>
5162CIccTagNum<T, Tsig>::CIccTagNum(int nSize/*=1*/)
5163{
5164 m_nSize = nSize;
5165 if (m_nSize <1)
5166 m_nSize = 1;
5167 m_Num = (T*)calloc(nSize, sizeof(T));
5168}
5169
5170
5171/**
5172 ****************************************************************************
5173 * Name: CIccTagNum::CIccTagNum
5174 *
5175 * Purpose: Copy Constructor
5176 *
5177 * Args:
5178 * ITNum = The CIccTagNum object to be copied
5179 *****************************************************************************
5180 */
5181template <class T, icTagTypeSignature Tsig>
5182CIccTagNum<T, Tsig>::CIccTagNum(const CIccTagNum<T, Tsig> &ITNum)
5183{
5184 m_nSize = ITNum.m_nSize;
5185
5186 m_Num = (T*)calloc(m_nSize, sizeof(T));
5187 memcpy(m_Num, ITNum.m_Num, m_nSize * sizeof(T));
5188}
5189
5190
5191/**
5192 ****************************************************************************
5193 * Name: CIccTagNum::operator=
5194 *
5195 * Purpose: Copy Operator
5196 *
5197 * Args:
5198 * ITNum = The CIccTagNum object to be copied
5199 *****************************************************************************
5200 */
5201template <class T, icTagTypeSignature Tsig>
5202CIccTagNum<T, Tsig> &CIccTagNum<T, Tsig>::operator=(const CIccTagNum<T, Tsig> &ITNum)
5203{
5204 if (&ITNum == this)
5205 return *this;
5206
5207 m_nSize = ITNum.m_nSize;
5208
5209 m_Num = (T*)calloc(m_nSize, sizeof(T));
5210 memcpy(m_Num, ITNum.m_Num, m_nSize * sizeof(T));
5211
5212 return *this;
5213}
5214
5215
5216
5217/**
5218 ****************************************************************************
5219 * Name: CIccTagNum::~CIccTagNum
5220 *
5221 * Purpose: Destructor
5222 *
5223 *****************************************************************************
5224 */
5225template <class T, icTagTypeSignature Tsig>
5226CIccTagNum<T, Tsig>::~CIccTagNum()
5227{
5228 if (m_Num)
5229 free(m_Num);
5230}
5231
5232/**
5233 ****************************************************************************
5234 * Name: CIccTagNum::GetClassName
5235 *
5236 * Purpose: Returns the tag type class name
5237 *
5238 *****************************************************************************
5239 */
5240template <class T, icTagTypeSignature Tsig>
5241const icChar *CIccTagNum<T, Tsig>::GetClassName() const
5242{
5243 if (sizeof(T)==sizeof(icUInt8Number))
5244 return "CIccTagUInt8";
5245 else if (sizeof(T)==sizeof(icUInt16Number))
5246 return "CIccTagUInt16";
5247 else if (sizeof(T)==sizeof(icUInt32Number))
5248 return "CIccTagUInt32";
5249 else if (sizeof(T)==sizeof(icUInt64Number))
5250 return "CIccTagUInt64";
5251 else
5252 return "CIccTagNum<>";
5253}
5254
5255
5256/**
5257 ****************************************************************************
5258 * Name: CIccTagNum::Read
5259 *
5260 * Purpose: Read in the tag contents into a data block
5261 *
5262 * Args:
5263 * size - # of bytes in tag,
5264 * pIO - IO object to read tag from
5265 *
5266 * Return:
5267 * true = successful, false = failure
5268 *****************************************************************************
5269 */
5270template <class T, icTagTypeSignature Tsig>
5271bool CIccTagNum<T, Tsig>::Read(icUInt32Number size, CIccIO *pIO)
5272{
5273 icTagTypeSignature sig;
5274
5275 if (sizeof(icTagTypeSignature) +
5276 sizeof(icUInt32Number) +
5277 sizeof(T) > size)
5278 return false;
5279
5280 if (!pIO) {
5281 return false;
5282 }
5283
5284 if (!pIO->Read32(&sig))
5285 return false;
5286
5287 if (!pIO->Read32(&m_nReserved))
5288 return false;
5289
5290 icUInt32Number nSize=((size-2*sizeof(icUInt32Number)) / sizeof(T));
5291
5292 if (!SetSize(nSize))
5293 return false;
5294
5295 if (sizeof(T)==sizeof(icUInt8Number)) {
5296 if (pIO->Read8(m_Num, nSize) != (icInt32Number)nSize )
5297 return false;
5298 }
5299 else if (sizeof(T)==sizeof(icUInt16Number)) {
5300 if (pIO->Read16(m_Num, nSize) != (icInt32Number)nSize )
5301 return false;
5302 }
5303 else if (sizeof(T)==sizeof(icUInt32Number)) {
5304 if (pIO->Read32(m_Num, nSize) != (icInt32Number)nSize )
5305 return false;
5306 }
5307 else if (sizeof(T)==sizeof(icUInt64Number)) {
5308 if (pIO->Read64(m_Num, nSize) != (icInt32Number)nSize )
5309 return false;
5310 }
5311 else
5312 return false;
5313
5314 return true;
5315}
5316
5317
5318/**
5319 ****************************************************************************
5320 * Name: CIccTagNum::Write
5321 *
5322 * Purpose: Write the tag to a file
5323 *
5324 * Args:
5325 * pIO - The IO object to write tag to.
5326 *
5327 * Return:
5328 * true = succesful, false = failure
5329 *****************************************************************************
5330 */
5331template <class T, icTagTypeSignature Tsig>
5332bool CIccTagNum<T, Tsig>::Write(CIccIO *pIO)
5333{
5334 icTagTypeSignature sig = GetType();
5335
5336 if (!pIO)
5337 return false;
5338
5339 if (!pIO->Write32(&sig))
5340 return false;
5341
5342 if (!pIO->Write32(&m_nReserved))
5343 return false;
5344
5345 if (sizeof(T)==sizeof(icUInt8Number)) {
5346 if (pIO->Write8(m_Num, m_nSize) != (icInt32Number)m_nSize)
5347 return false;
5348 }
5349 else if (sizeof(T)==sizeof(icUInt16Number)) {
5350 if (pIO->Write16(m_Num, m_nSize) != (icInt32Number)m_nSize)
5351 return false;
5352 }
5353 else if (sizeof(T)==sizeof(icUInt32Number)) {
5354 if (pIO->Write32(m_Num, m_nSize) != (icInt32Number)m_nSize)
5355 return false;
5356 }
5357 else if (sizeof(T)==sizeof(icUInt64Number)) {
5358 if (pIO->Write64(m_Num, m_nSize) != (icInt32Number)m_nSize)
5359 return false;
5360 }
5361 else
5362 return false;
5363
5364 return true;
5365}
5366
5367
5368/**
5369 ****************************************************************************
5370 * Name: CIccTagNum::Describe
5371 *
5372 * Purpose: Dump data associated with the tag to a string
5373 *
5374 * Args:
5375 * sDescription - string to concatenate tag dump to
5376 *****************************************************************************
5377 */
5378template <class T, icTagTypeSignature Tsig>
5379void CIccTagNum<T, Tsig>::Describe(std::string &sDescription)
5380{
5381 icChar buf[128];
5382
5383 if (m_nSize == 1 ) {
5384 switch (sizeof(T)) {
5385 case 1:
5386 sprintf(buf, "Value = %u (0x02%x)\r\n", m_Num[0], m_Num[0]);
5387 break;
5388 case 2:
5389 sprintf(buf, "Value = %u (0x04%x)\r\n", m_Num[0], m_Num[0]);
5390 break;
5391 case 4:
5392 sprintf(buf, "Value = %u (0x08%x)\r\n", m_Num[0], m_Num[0]);
5393 break;
5394 case 8:
5395 sprintf(buf, "Value = %u (0x016%x)\r\n", m_Num[0], m_Num[0]);
5396 break;
5397 default:
5398 sprintf(buf, "Value = %u (0x%x)\r\n", m_Num[0], m_Num[0]);
5399 break;
5400 }
5401 sDescription += buf;
5402 }
5403 else {
5404 icUInt32Number i;
5405 sDescription.reserve(sDescription.size() + m_nSize*79);
5406
5407 for (i=0; i<m_nSize; i++) {
5408 switch (sizeof(T)) {
5409 case 1:
5410 sprintf(buf, "Value = %u (0x02%x)\r\n", m_Num[i], m_Num[i]);
5411 break;
5412 case 2:
5413 sprintf(buf, "Value = %u (0x04%x)\r\n", m_Num[i], m_Num[i]);
5414 break;
5415 case 4:
5416 sprintf(buf, "Value = %u (0x08%x)\r\n", m_Num[i], m_Num[i]);
5417 break;
5418 case 8:
5419 sprintf(buf, "Value = %u (0x016%x)\r\n", m_Num[i], m_Num[i]);
5420 break;
5421 default:
5422 sprintf(buf, "Value = %u (0x%x)\r\n", m_Num[i], m_Num[i]);
5423 break;
5424 }
5425 sDescription += buf;
5426 }
5427 }
5428}
5429
5430template <class T, icTagTypeSignature Tsig>
5431icValidateStatus CIccTagNum<T, Tsig>::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile) const
5432{
5433 icValidateStatus rv = icValidateOK;
5434 //Check # of channels
5435 if (icGetFirstSigPathSig(sigPath) == icSigMaterialDefaultValuesTag &&
5436 pProfile &&
5437 m_nSize != icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs)) {
5438 CIccInfo Info;
5439 std::string sSigPathName = Info.GetSigPathName(sigPath);
5440
5441 sReport += icMsgValidateCriticalError;
5442 sReport += sSigPathName;
5443 sReport += " - Number of material default values does not match MCS in header.\r\n";
5444 rv = icMaxStatus(rv, icValidateCriticalError);
5445 }
5446
5447 rv = icMaxStatus(rv, CIccTagNumArray::Validate(sigPath, sReport, pProfile));
5448
5449 return rv;
5450}
5451
5452// template function specialization to handle need for %llu and %llx for 64-bit ints
5453template <>
5454void CIccTagNum<icUInt64Number, icSigUInt64ArrayType>::Describe(std::string &sDescription)
5455{
5456 icChar buf[128];
5457
5458 if (m_nSize == 1 ) {
5459 sprintf(buf, "Value = %llu (0x016%llx)\r\n", m_Num[0], m_Num[0]);
5460 sDescription += buf;
5461 }
5462 else {
5463 icUInt32Number i;
5464 sDescription.reserve(sDescription.size() + m_nSize*79);
5465
5466 for (i=0; i<m_nSize; i++) {
5467 sprintf(buf, "Value = %llu (0x016%llx)\r\n", m_Num[i], m_Num[i]);
5468 sDescription += buf;
5469 }
5470 }
5471}
5472
5473
5474
5475
5476/**
5477 ****************************************************************************
5478 * Name: CIccTagNum::SetSize
5479 *
5480 * Purpose: Sets the size of the data array.
5481 *
5482 * Args:
5483 * nSize - number of data entries,
5484 * bZeroNew - flag to zero newly formed values
5485 *****************************************************************************
5486 */
5487template <class T, icTagTypeSignature Tsig>
5488bool CIccTagNum<T, Tsig>::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
5489{
5490 if (nSize==m_nSize)
5491 return true;
5492
5493 m_Num = (T*)icRealloc(m_Num, nSize*sizeof(T));
5494
5495 if (!m_Num) {
5496 m_nSize = 0;
5497 return false;
5498 }
5499
5500 if (bZeroNew && m_nSize < nSize) {
5501 memset(&m_Num[m_nSize], 0, (nSize-m_nSize)*sizeof(T));
5502 }
5503 m_nSize = nSize;
5504
5505 return true;
5506}
5507
5508/**
5509****************************************************************************
5510* Name: CIccTagNum::GetValues
5511*
5512* Purpose: Gets values from the num array tag as floating point numbers
5513*
5514* Args:
5515* nSize - number of data entries,
5516* bZeroNew - flag to zero newly formed values
5517*****************************************************************************
5518*/
5519template <class T, icTagTypeSignature Tsig>
5520bool CIccTagNum<T, Tsig>::GetValues(icFloatNumber *DstVector, icUInt32Number nStart, icUInt32Number nVectorSize) const
5521{
5522 if (nVectorSize+nStart >m_nSize)
5523 return false;
5524
5525 icUInt32Number i;
5526
5527 switch (Tsig) {
5528 case icSigUInt8ArrayType:
5529 for (i=0; i<m_nSize; i++) {
5530 DstVector[i] = icU8toF((icUInt8Number)(m_Num[i+nStart]));
5531 }
5532 break;
5533 case icSigUInt16ArrayType:
5534 for (i=0; i<m_nSize; i++) {
5535 DstVector[i] = icU16toF((icUInt16Number)(m_Num[i+nStart]));
5536 }
5537 break;
5538 case icSigUInt32ArrayType: //Not Supported
5539 case icSigUInt64ArrayType: //Not Supported
5540 default:
5541 return false;
5542 }
5543 return true;
5544}
5545
5546//Avoid casting warnings for 32 and 64 bit numbers
5547template <>
5548bool CIccTagNum<icUInt32Number, icSigUInt32ArrayType>::GetValues(icFloatNumber *DstVector, icUInt32Number nStart, icUInt32Number nVectorSize) const
5549{
5550 return false;
5551}
5552template <>
5553bool CIccTagNum<icUInt64Number, icSigUInt64ArrayType>::GetValues(icFloatNumber *DstVector, icUInt32Number nStart, icUInt32Number nVectorSize) const
5554{
5555 return false;
5556}
5557
5558/**
5559****************************************************************************
5560* Name: CIccTagNum::Interpolate
5561*
5562* Purpose: Gets values from the num array tag as floating point numbers
5563*
5564* Args:
5565* nSize - number of data entries,
5566* bZeroNew - flag to zero newly formed values
5567*****************************************************************************
5568*/
5569template <class T, icTagTypeSignature Tsig>
5570bool CIccTagNum<T, Tsig>::Interpolate(icFloatNumber *DstVector, icFloatNumber pos,
5571 icUInt32Number nVectorSize, icFloatNumber *zeroVals) const
5572{
5573 icUInt32Number nVector = m_nSize / nVectorSize;
5574
5575 if (!nVector)
5576 return false;
5577
5578 if (zeroVals)
5579 nVector ++;
5580 else if (nVector<=1)
5581 return false;
5582
5583 if (pos<0.0)
5584 pos=0.0;
5585 if (pos>1.0)
5586 pos=1.0;
5587
5588 icFloatNumber fpos = (icFloatNumber)(nVector-1) * pos;
5589 icUInt32Number iPos = (icUInt32Number)fpos;
5590 icFloatNumber x = fpos - iPos;
5591
5592 if (iPos == nVector-1) {
5593 iPos--;
5594 x = (icFloatNumber)1.0;
5595 }
5596
5597 T *lo, *hi;
5598
5599 if (!zeroVals) {
5600 if (!iPos) {
5601 lo = NULL__null;
5602 hi = m_Num;
5603 }
5604 else {
5605 lo = &m_Num[(iPos-1)*nVectorSize];
5606 hi = &lo[nVectorSize];
5607 }
5608 }
5609 else {
5610 lo = &m_Num[iPos*nVectorSize];
5611 hi = &lo[nVectorSize];
5612 }
5613
5614 icUInt32Number i;
5615
5616 switch (Tsig) {
5617 case icSigUInt8ArrayType:
5618 if (!lo) {
5619 for (i=0; i<m_nSize; i++) {
5620 DstVector[i] = zeroVals[i]*(1.0f-x) + icU8toF((icUInt8Number)hi[i])*x;
5621 }
5622 }
5623 else {
5624 for (i=0; i<m_nSize; i++) {
5625 DstVector[i] = icU8toF((icUInt8Number)lo[i])*(1.0f-x) + icU8toF((icUInt8Number)hi[i])*x;
5626 }
5627 }
5628 break;
5629 case icSigUInt16ArrayType:
5630 if (!lo) {
5631 for (i=0; i<m_nSize; i++) {
5632 DstVector[i] = zeroVals[i]*(1.0f-x) + icU16toF((icUInt16Number)hi[i])*x;
5633 }
5634 }
5635 else {
5636 for (i=0; i<m_nSize; i++) {
5637 DstVector[i] = icU16toF((icUInt16Number)lo[i])*(1.0f-x) + icU16toF((icUInt16Number)hi[i])*x;
5638 }
5639 }
5640 break;
5641 case icSigUInt32ArrayType:
5642 case icSigUInt64ArrayType:
5643 default:
5644 return false;
5645 }
5646 return true;
5647}
5648
5649
5650/**
5651****************************************************************************
5652* Name: CIccTagNum::ValuePos
5653*
5654* Purpose: Gets position of a value int the num array tag
5655*
5656* Args:
5657* DstPos - position of val in array
5658* val - value to look for in array.
5659* bNoZero - flag indicating whether first entry is zero
5660*****************************************************************************
5661*/
5662template <class T, icTagTypeSignature Tsig>
5663bool CIccTagNum<T, Tsig>::ValuePos(icFloatNumber &DstPos, icFloatNumber val, bool &bNoZero) const
5664{
5665 if(val<0.0)
5666 return false;
5667
5668 icFloatNumber nv, lv;
5669 switch (Tsig) {
5670 case icSigUInt8ArrayType:
5671 lv = icU8toF((icUInt8Number)m_Num[0]);
5672 break;
5673 case icSigUInt16ArrayType:
5674 lv = icU16toF((icUInt16Number)m_Num[0]);
5675 break;
5676 case icSigUInt32ArrayType:
5677 case icSigUInt64ArrayType:
5678 default:
5679 return false;
5680 }
5681 bNoZero = (lv!=0.0);
5682
5683 if (val<lv) {
5684 DstPos = val/lv - 1.0f;
5685 return true;
5686 }
5687
5688 icUInt32Number i;
5689 for (i=1; i<m_nSize; i++, lv=nv) {
5690 switch (Tsig) {
5691 case icSigUInt8ArrayType:
5692 nv = icU8toF((icUInt8Number)m_Num[i]);
5693 break;
5694 case icSigUInt16ArrayType:
5695 nv = icU16toF((icUInt16Number)m_Num[i]);
5696 break;
5697 case icSigUInt32ArrayType:
5698 case icSigUInt64ArrayType:
5699 default:
5700 return false;
5701 }
5702 if (val<=nv) {
5703 DstPos = (val-lv)/(nv-lv) + i - 1.0f;
5704 return true;
5705 }
5706 }
5707
5708 return false;
5709}
5710
5711//Avoid casting warnings for 32 and 64 bit numbers
5712template <>
5713bool CIccTagNum<icUInt32Number, icSigUInt32ArrayType>::Interpolate(icFloatNumber *DstVector, icFloatNumber pos,
5714 icUInt32Number nVectorSize, icFloatNumber *zeroVals) const
5715{
5716 return false;
5717}
5718template <>
5719bool CIccTagNum<icUInt64Number, icSigUInt64ArrayType>::Interpolate(icFloatNumber *DstVector, icFloatNumber pos,
5720 icUInt32Number nVectorSize, icFloatNumber *zeroVals) const
5721{
5722 return false;
5723}
5724
5725template <>
5726bool CIccTagNum<icUInt32Number, icSigUInt32ArrayType>::ValuePos(icFloatNumber&DstPos, icFloatNumber val, bool &bNoZero) const
5727{
5728 return false;
5729}
5730template <>
5731bool CIccTagNum<icUInt64Number, icSigUInt64ArrayType>::ValuePos(icFloatNumber&DstPos, icFloatNumber val, bool &bNoZero) const
5732{
5733 return false;
5734}
5735
5736//Make sure typedef classes get built
5737template class CIccTagNum<icUInt8Number, icSigUInt8ArrayType>;
5738template class CIccTagNum<icUInt16Number, icSigUInt16ArrayType>;
5739template class CIccTagNum<icUInt32Number, icSigUInt32ArrayType>;
5740template class CIccTagNum<icUInt64Number, icSigUInt64ArrayType>;
5741
5742
5743/**
5744 ****************************************************************************
5745 * Name: CIccTagFloatNum::CIccTagFloatNum
5746 *
5747 * Purpose: Constructor
5748 *
5749 * Args:
5750 * nSize = number of data entries
5751 *****************************************************************************
5752 */
5753template <class T, icTagTypeSignature Tsig>
5754CIccTagFloatNum<T, Tsig>::CIccTagFloatNum(int nSize/*=1*/)
5755{
5756 m_nSize = nSize;
5757 if (m_nSize <1)
5758 m_nSize = 1;
5759 m_Num = (T*)calloc(nSize, sizeof(T));
5760}
5761
5762
5763/**
5764 ****************************************************************************
5765 * Name: CIccTagFloatNum::CIccTagFloatNum
5766 *
5767 * Purpose: Copy Constructor
5768 *
5769 * Args:
5770 * ITNum = The CIccTagNum object to be copied
5771 *****************************************************************************
5772 */
5773template <class T, icTagTypeSignature Tsig>
5774CIccTagFloatNum<T, Tsig>::CIccTagFloatNum(const CIccTagFloatNum<T, Tsig> &ITNum)
5775{
5776 m_nSize = ITNum.m_nSize;
5777
5778 m_Num = (T*)calloc(m_nSize, sizeof(T));
5779 memcpy(m_Num, ITNum.m_Num, m_nSize * sizeof(T));
5780}
5781
5782
5783/**
5784 ****************************************************************************
5785 * Name: CIccTagFloatNum::operator=
5786 *
5787 * Purpose: Copy Operator
5788 *
5789 * Args:
5790 * ITNum = The CIccTagNum object to be copied
5791 *****************************************************************************
5792 */
5793template <class T, icTagTypeSignature Tsig>
5794CIccTagFloatNum<T, Tsig> &CIccTagFloatNum<T, Tsig>::operator=(const CIccTagFloatNum<T, Tsig> &ITNum)
5795{
5796 if (&ITNum == this)
5797 return *this;
5798
5799 m_nSize = ITNum.m_nSize;
5800
5801 m_Num = (T*)calloc(m_nSize, sizeof(T));
5802 memcpy(m_Num, ITNum.m_Num, m_nSize * sizeof(T));
5803
5804 return *this;
5805}
5806
5807
5808
5809/**
5810 ****************************************************************************
5811 * Name: CIccTagFloatNum::~CIccTagFloatNum
5812 *
5813 * Purpose: Destructor
5814 *
5815 *****************************************************************************
5816 */
5817template <class T, icTagTypeSignature Tsig>
5818CIccTagFloatNum<T, Tsig>::~CIccTagFloatNum()
5819{
5820 if (m_Num)
5821 free(m_Num);
5822}
5823
5824/**
5825 ****************************************************************************
5826 * Name: CIccTagFloatNum::GetClassName
5827 *
5828 * Purpose: Returns the tag type class name
5829 *
5830 *****************************************************************************
5831 */
5832template <class T, icTagTypeSignature Tsig>
5833const icChar *CIccTagFloatNum<T, Tsig>::GetClassName() const
5834{
5835 if (Tsig==icSigFloat16ArrayType)
5836 return "CIccFlaot16";
5837 if (Tsig==icSigFloat32ArrayType)
5838 return "CIccFloat32";
5839 else if (Tsig==icSigFloat64ArrayType)
5840 return "CIccFloat64";
5841 else
5842 return "CIccTagFloatNum<>";
5843}
5844
5845
5846/**
5847 ****************************************************************************
5848 * Name: CIccTagFloatNum::Read
5849 *
5850 * Purpose: Read in the tag contents into a data block
5851 *
5852 * Args:
5853 * size - # of bytes in tag,
5854 * pIO - IO object to read tag from
5855 *
5856 * Return:
5857 * true = successful, false = failure
5858 *****************************************************************************
5859 */
5860template <class T, icTagTypeSignature Tsig>
5861bool CIccTagFloatNum<T, Tsig>::Read(icUInt32Number size, CIccIO *pIO)
5862{
5863 icTagTypeSignature sig;
5864
5865 if (Tsig==icSigFloat16ArrayType) {
5866 if (sizeof(icTagTypeSignature) +
5867 sizeof(icUInt32Number) +
5868 sizeof(icFloat16Number) > size)
5869 return false;
5870 }
5871 else {
5872 if (sizeof(icTagTypeSignature) +
5873 sizeof(icUInt32Number) +
5874 sizeof(T) > size)
5875 return false;
5876 }
5877
5878 if (!pIO) {
5879 return false;
5880 }
5881
5882 if (!pIO->Read32(&sig))
5883 return false;
5884
5885 if (!pIO->Read32(&m_nReserved))
5886 return false;
5887
5888 if (Tsig==icSigFloat16ArrayType) {
5889 icUInt32Number nSize=((size-2*sizeof(icUInt32Number)) / sizeof(icFloat16Number));
5890
5891 if (!SetSize(nSize))
5892 return false;
5893
5894 if (pIO->ReadFloat16Float(&m_Num[0], nSize) != (icInt32Number)nSize)
5895 return false;
5896 }
5897 else if (Tsig==icSigFloat32ArrayType) {
5898 icUInt32Number nSize=((size-2*sizeof(icUInt32Number)) / sizeof(icFloat32Number));
5899
5900 if (!SetSize(nSize))
5901 return false;
5902
5903 if (pIO->Read32(m_Num, nSize) != (icInt32Number)nSize )
5904 return false;
5905 }
5906 else if (Tsig==icSigFloat64ArrayType) {
5907 icUInt32Number nSize=((size-2*sizeof(icUInt32Number)) / sizeof(icFloat64Number));
5908
5909 if (!SetSize(nSize))
5910 return false;
5911
5912 if (pIO->Read64(m_Num, nSize) != (icInt32Number)nSize )
5913 return false;
5914 }
5915 else
5916 return false;
5917
5918 return true;
5919}
5920
5921
5922/**
5923 ****************************************************************************
5924 * Name: CIccTagFloatNum::Write
5925 *
5926 * Purpose: Write the tag to a file
5927 *
5928 * Args:
5929 * pIO - The IO object to write tag to.
5930 *
5931 * Return:
5932 * true = succesful, false = failure
5933 *****************************************************************************
5934 */
5935template <class T, icTagTypeSignature Tsig>
5936bool CIccTagFloatNum<T, Tsig>::Write(CIccIO *pIO)
5937{
5938 icTagTypeSignature sig = GetType();
5939
5940 if (!pIO)
5941 return false;
5942
5943 if (!pIO->Write32(&sig))
5944 return false;
5945
5946 if (!pIO->Write32(&m_nReserved))
5947 return false;
5948
5949 if (Tsig==icSigFloat16ArrayType) {
5950 if (pIO->WriteFloat16Float(m_Num, m_nSize) != (icInt32Number)m_nSize)
5951 return false;
5952 }
5953 else if (Tsig == icSigFloat32ArrayType) {
5954 if (pIO->Write32(m_Num, m_nSize) != (icInt32Number)m_nSize)
5955 return false;
5956 }
5957 else if (Tsig == icSigFloat64ArrayType) {
5958 if (pIO->Write64(m_Num, m_nSize) != (icInt32Number)m_nSize)
5959 return false;
5960 }
5961 else
5962 return false;
5963
5964 return true;
5965}
5966
5967
5968/**
5969 ****************************************************************************
5970 * Name: CIccTagFloatNum::Describe
5971 *
5972 * Purpose: Dump data associated with the tag to a string
5973 *
5974 * Args:
5975 * sDescription - string to concatenate tag dump to
5976 *****************************************************************************
5977 */
5978template <class T, icTagTypeSignature Tsig>
5979void CIccTagFloatNum<T, Tsig>::Describe(std::string &sDescription)
5980{
5981 icChar buf[128];
5982
5983 if (m_nSize == 1 ) {
5984 switch (sizeof(T)) {
5985 case 4:
5986 sprintf(buf, "Value = %.8f\r\n", m_Num[0]);
5987 break;
5988 case 8:
5989 sprintf(buf, "Value = %.16f\r\n", m_Num[0]);
5990 break;
5991 default:
5992 sprintf(buf, "Value = %.f\r\n", m_Num[0]);
5993 break;
5994 }
5995 sDescription += buf;
5996 }
5997 else {
5998 icUInt32Number i, n;
5999 sDescription.reserve(sDescription.size() + m_nSize*79);
6000
6001 sprintf(buf, "Begin_Value_Array[%d]\r\n", m_nSize);
6002 sDescription += buf;
6003
6004 if (sizeof(T)!=8)
6005 n=8;
6006 else
6007 n=4;
6008
6009 for (i=0; i<m_nSize; i++) {
6010 if (i&& !(i%n))
6011 sDescription += "\r\n";
6012
6013 switch (sizeof(T)) {
6014 case 4:
6015 sprintf(buf, " %.8f", m_Num[i]);
6016 break;
6017 case 8:
6018 sprintf(buf, " %.16f", m_Num[i]);
6019 break;
6020 default:
6021 sprintf(buf, " %f", m_Num[i]);
6022 }
6023 sDescription += buf;
6024 }
6025 if ((i%n)!=1)
6026 sDescription += "\r\n";
6027 sDescription += "End_Value_Array\r\n";
6028 }
6029}
6030
6031
6032/**
6033 ****************************************************************************
6034 * Name: CIccTagFloatNum::SetSize
6035 *
6036 * Purpose: Sets the size of the data array.
6037 *
6038 * Args:
6039 * nSize - number of data entries,
6040 * bZeroNew - flag to zero newly formed values
6041 *****************************************************************************
6042 */
6043template <class T, icTagTypeSignature Tsig>
6044bool CIccTagFloatNum<T, Tsig>::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
6045{
6046 if (nSize==m_nSize)
6047 return true;
6048
6049 m_Num = (T*)icRealloc(m_Num, nSize*sizeof(T));
6050
6051 if (!m_Num) {
6052 m_nSize = 0;
6053 return false;
6054 }
6055
6056 if (bZeroNew && m_nSize < nSize) {
6057 memset(&m_Num[m_nSize], 0, (nSize-m_nSize)*sizeof(T));
6058 }
6059 m_nSize = nSize;
6060
6061 return true;
6062}
6063
6064/**
6065****************************************************************************
6066* Name: CIccTagFloatNum::GetValues
6067*
6068* Purpose: Gets values from the num array tag as floating point numbers
6069*
6070* Args:
6071* nSize - number of data entries,
6072* bZeroNew - flag to zero newly formed values
6073*****************************************************************************
6074*/
6075template <class T, icTagTypeSignature Tsig>
6076bool CIccTagFloatNum<T, Tsig>::GetValues(icFloatNumber *DstVector, icUInt32Number nStart, icUInt32Number nVectorSize) const
6077{
6078 if (nVectorSize >m_nSize)
6079 return false;
6080
6081 icUInt32Number i;
6082
6083 for (i=0; i<m_nSize; i++) {
6084 DstVector[i] = (icFloatNumber)m_Num[i+nStart];
6085 }
6086 return true;
6087}
6088
6089
6090/**
6091****************************************************************************
6092* Name: CIccTagFloatNum::Interpolate
6093*
6094* Purpose: Gets values from the num array tag as floating point numbers
6095*
6096* Args:
6097* nSize - number of data entries,
6098* bZeroNew - flag to zero newly formed values
6099*****************************************************************************
6100*/
6101template <class T, icTagTypeSignature Tsig>
6102icValidateStatus CIccTagFloatNum<T, Tsig>::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile) const
6103{
6104 icValidateStatus rv = icValidateOK;
6105 //Check # of channels
6106 if (icGetFirstSigPathSig(sigPath) == icSigMaterialDefaultValuesTag &&
6107 pProfile &&
6108 m_nSize != icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs)) {
6109 CIccInfo Info;
6110 std::string sSigPathName = Info.GetSigPathName(sigPath);
6111
6112 sReport += icMsgValidateCriticalError;
6113 sReport += sSigPathName;
6114 sReport += " - Number of material default values does not match MCS in header.\r\n";
6115 rv = icMaxStatus(rv, icValidateCriticalError);
6116 }
6117
6118 rv = icMaxStatus(rv, CIccTagNumArray::Validate(sigPath, sReport, pProfile));
6119
6120 return rv;
6121}
6122
6123
6124
6125/**
6126****************************************************************************
6127* Name: CIccTagFloatNum::Interpolate
6128*
6129* Purpose: Gets values from the num array tag as floating point numbers
6130*
6131* Args:
6132* nSize - number of data entries,
6133* bZeroNew - flag to zero newly formed values
6134*****************************************************************************
6135*/
6136template <class T, icTagTypeSignature Tsig>
6137bool CIccTagFloatNum<T, Tsig>::Interpolate(icFloatNumber *DstVector, icFloatNumber pos,
6138 icUInt32Number nVectorSize, icFloatNumber *zeroVals) const
6139{
6140 icUInt32Number nVector = m_nSize / nVectorSize;
6141
6142 if (!nVector)
6143 return false;
6144
6145 if (zeroVals)
6146 nVector ++;
6147 else if (nVector<=1)
6148 return false;
6149
6150 if (pos<0.0)
6151 pos=0.0;
6152 if (pos>1.0)
6153 pos=1.0;
6154
6155 icFloatNumber fpos = (icFloatNumber)(nVector-1) * pos;
6156 icUInt32Number iPos = (icUInt32Number)fpos;
6157 icFloatNumber x = fpos - iPos;
6158 icFloatNumber invx = (1.0f - x);
6159
6160 if (iPos == nVector-1) {
6161 iPos--;
6162 x = (icFloatNumber)1.0f;
6163 invx = (icFloatNumber)0.0f;
6164 }
6165
6166 T *lo, *hi;
6167
6168 if (zeroVals) {
6169 if (!iPos) {
6170 lo = NULL__null;
6171 hi = m_Num;
6172 }
6173 else {
6174 lo = &m_Num[(iPos-1)*nVectorSize];
6175 hi = &lo[nVectorSize];
6176 }
6177 }
6178 else {
6179 lo = &m_Num[iPos*nVectorSize];
6180 hi = &lo[nVectorSize];
6181 }
6182
6183 icUInt32Number i;
6184
6185 if (!lo) {
6186 for (i=0; i<nVectorSize; i++) {
6187 DstVector[i] = (icFloatNumber)(zeroVals[i]*invx + hi[i]*x);
6188 }
6189 }
6190 else {
6191 for (i=0; i<nVectorSize; i++) {
6192 DstVector[i] = (icFloatNumber)(lo[i]*invx + hi[i]*x);
6193 }
6194 }
6195 return true;
6196}
6197
6198
6199/**
6200****************************************************************************
6201* Name: CIccTagFloatNum::ValuePos
6202*
6203* Purpose: Gets position of a value int the num array tag
6204*
6205* Args:
6206* DstPos - position of val in array
6207* val - value to look for in array.
6208* bNoZero - flag indicating whether first entry is zero
6209*****************************************************************************
6210*/
6211template <class T, icTagTypeSignature Tsig>
6212bool CIccTagFloatNum<T, Tsig>::ValuePos(icFloatNumber &DstPos, icFloatNumber val, bool &bNoZero) const
6213{
6214 if(val<0.0)
6215 return false;
6216
6217 icFloatNumber nv, lv;
6218
6219 lv = (icFloatNumber)m_Num[0];
6220
6221 bNoZero = (lv!=0.0);
6222
6223 if (val<lv) {
6224 DstPos = val/lv - 1.0f;
6225 return true;
6226 }
6227
6228 icUInt32Number i;
6229 for (i=1; i<m_nSize; i++, lv=nv) {
6230 nv = (icFloatNumber)m_Num[i];
6231
6232 if (val<=nv) {
6233 DstPos = (val-lv)/(nv-lv) + i - 1.0f;
6234 return true;
6235 }
6236 }
6237
6238 return false;
6239}
6240
6241
6242//Make sure typedef classes get built
6243template class CIccTagFloatNum<icFloat32Number, icSigFloat16ArrayType>;
6244template class CIccTagFloatNum<icFloat32Number, icSigFloat32ArrayType>;
6245template class CIccTagFloatNum<icFloat64Number, icSigFloat64ArrayType>;
6246
6247/**
6248 ****************************************************************************
6249 * Name: CIccTagMeasurement::CIccTagMeasurement
6250 *
6251 * Purpose: Constructor
6252 *
6253 *****************************************************************************
6254 */
6255CIccTagMeasurement::CIccTagMeasurement()
6256{
6257 memset(&m_Data, 0, sizeof(m_Data));
6258}
6259
6260
6261/**
6262 ****************************************************************************
6263 * Name: CIccTagMeasurement::CIccTagMeasurement
6264 *
6265 * Purpose: Copy Constructor
6266 *
6267 * Args:
6268 * ITM = The CIccTagMeasurement object to be copied
6269 *****************************************************************************
6270 */
6271CIccTagMeasurement::CIccTagMeasurement(const CIccTagMeasurement &ITM)
6272{
6273 memcpy(&m_Data, &ITM.m_Data, sizeof(m_Data));
6274}
6275
6276
6277/**
6278 ****************************************************************************
6279 * Name: CIccTagMeasurement::operator=
6280 *
6281 * Purpose: Copy Operator
6282 *
6283 * Args:
6284 * MeasTag = The CIccTagMeasurement object to be copied
6285 *****************************************************************************
6286 */
6287CIccTagMeasurement &CIccTagMeasurement::operator=(const CIccTagMeasurement &MeasTag)
6288{
6289 if (&MeasTag == this)
6290 return *this;
6291
6292 memcpy(&m_Data, &MeasTag.m_Data, sizeof(m_Data));
6293
6294 return *this;
6295}
6296
6297
6298
6299/**
6300 ****************************************************************************
6301 * Name: CIccTagMeasurement::~CIccTagMeasurement
6302 *
6303 * Purpose: Destructor
6304 *
6305 *****************************************************************************
6306 */
6307CIccTagMeasurement::~CIccTagMeasurement()
6308{
6309}
6310
6311
6312/**
6313 ****************************************************************************
6314 * Name: CIccTagMeasurement::Read
6315 *
6316 * Purpose: Read in the tag contents into a data block
6317 *
6318 * Args:
6319 * size - # of bytes in tag,
6320 * pIO - IO object to read tag from
6321 *
6322 * Return:
6323 * true = successful, false = failure
6324 *****************************************************************************
6325 */
6326bool CIccTagMeasurement::Read(icUInt32Number size, CIccIO *pIO)
6327{
6328 icTagTypeSignature sig;
6329
6330 if (sizeof(icTagTypeSignature) +
6331 sizeof(icUInt32Number) +
6332 sizeof(m_Data) > size)
6333 return false;
6334
6335 if (!pIO) {
6336 return false;
6337 }
6338
6339 if (!pIO->Read32(&sig))
6340 return false;
6341
6342 if (!pIO->Read32(&m_nReserved))
6343 return false;
6344
6345 icUInt32Number nSize=sizeof(m_Data)/sizeof(icUInt32Number);
6346
6347 if (pIO->Read32(&m_Data,nSize) != (icInt32Number)nSize)
6348 return false;
6349
6350 return true;
6351}
6352
6353
6354/**
6355 ****************************************************************************
6356 * Name: CIccTagMeasurement::Write
6357 *
6358 * Purpose: Write the tag to a file
6359 *
6360 * Args:
6361 * pIO - The IO object to write tag to.
6362 *
6363 * Return:
6364 * true = succesful, false = failure
6365 *****************************************************************************
6366 */
6367bool CIccTagMeasurement::Write(CIccIO *pIO)
6368{
6369 icTagTypeSignature sig = GetType();
6370
6371 if (!pIO)
6372 return false;
6373
6374 if (!pIO->Write32(&sig))
6375 return false;
6376
6377 if (!pIO->Write32(&m_nReserved))
6378 return false;
6379
6380 icUInt32Number nSize=sizeof(m_Data)/sizeof(icUInt32Number);
6381
6382 if (pIO->Write32(&m_Data,nSize) != (icInt32Number)nSize)
6383 return false;
6384
6385 return true;
6386}
6387
6388
6389/**
6390 ****************************************************************************
6391 * Name: CIccTagMeasurement::Describe
6392 *
6393 * Purpose: Dump data associated with the tag to a string
6394 *
6395 * Args:
6396 * sDescription - string to concatenate tag dump to
6397 *****************************************************************************
6398 */
6399void CIccTagMeasurement::Describe(std::string &sDescription)
6400{
6401 CIccInfo Fmt;
6402 icChar buf[128];
6403
6404 sDescription += Fmt.GetStandardObserverName(m_Data.stdObserver); sDescription += "\r\n";
6405 sprintf(buf, "Backing measurement: X=%.4lf, Y=%.4lf, Z=%.4lf\r\n",
6406 icFtoD(m_Data.backing.X),
6407 icFtoD(m_Data.backing.Y),
6408 icFtoD(m_Data.backing.Z));
6409 sDescription += buf;
6410 sDescription += Fmt.GetMeasurementGeometryName(m_Data.geometry); sDescription += "\r\n";
6411 sDescription += Fmt.GetMeasurementFlareName(m_Data.flare); sDescription += "\r\n";
6412 sDescription += Fmt.GetIlluminantName(m_Data.illuminant); sDescription += "\r\n";
6413}
6414
6415
6416/**
6417******************************************************************************
6418* Name: CIccTagMeasurement::Validate
6419*
6420* Purpose: Check tag data validity.
6421*
6422* Args:
6423* sig = signature of tag being validated,
6424* sReport = String to add report information to
6425*
6426* Return:
6427* icValidateStatusOK if valid, or other error status.
6428******************************************************************************
6429*/
6430icValidateStatus CIccTagMeasurement::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
6431{
6432 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
6433
6434 CIccInfo Info;
6435 std::string sSigPathName = Info.GetSigPathName(sigPath);
6436
6437 switch(m_Data.stdObserver) {
6438 case icStdObsUnknown:
6439 case icStdObs1931TwoDegrees:
6440 case icStdObs1964TenDegrees:
6441 break;
6442
6443 default:
6444 sReport += icMsgValidateNonCompliant;
6445 sReport += sSigPathName;
6446 sReport += " - Invalid standard observer encoding.\r\n";
6447 rv = icMaxStatus(rv, icValidateNonCompliant);
6448 }
6449
6450 switch(m_Data.geometry) {
6451 case icGeometryUnknown:
6452 case icGeometry045or450:
6453 case icGeometry0dord0:
6454 break;
6455
6456 default:
6457 sReport += icMsgValidateNonCompliant;
6458 sReport += sSigPathName;
6459 sReport += " - Invalid measurement geometry encoding.\r\n";
6460 rv = icMaxStatus(rv, icValidateNonCompliant);
6461 }
6462
6463 switch(m_Data.illuminant) {
6464 case icIlluminantUnknown:
6465 case icIlluminantD50:
6466 case icIlluminantD65:
6467 case icIlluminantD93:
6468 case icIlluminantF2:
6469 case icIlluminantD55:
6470 case icIlluminantA:
6471 case icIlluminantEquiPowerE:
6472 case icIlluminantF8:
6473 break;
6474
6475 default:
6476 sReport += icMsgValidateNonCompliant;
6477 sReport += sSigPathName;
6478 sReport += " - Invalid standard illuminant encoding.\r\n";
6479 rv = icMaxStatus(rv, icValidateNonCompliant);
6480 }
6481
6482 return rv;
6483}
6484
6485
6486/**
6487 ****************************************************************************
6488 * Name: CIccLocalizedUnicode::CIccLocalizedUnicode
6489 *
6490 * Purpose: Constructor
6491 *
6492 *****************************************************************************
6493 */
6494CIccLocalizedUnicode::CIccLocalizedUnicode()
6495{
6496 m_pBuf = (icUInt16Number*)malloc(1*sizeof(icUInt16Number));
6497 *m_pBuf = 0;
6498 m_nLength = 0;
6499}
6500
6501
6502/**
6503 ****************************************************************************
6504 * Name: CIccLocalizedUnicode::CIccLocalizedUnicode
6505 *
6506 * Purpose: Copy Constructor
6507 *
6508 * Args:
6509 * ILU = The CIccLocalizedUnicode object to be copied
6510 *****************************************************************************
6511 */
6512CIccLocalizedUnicode::CIccLocalizedUnicode(const CIccLocalizedUnicode& ILU)
6513{
6514 m_nLength = ILU.GetLength();
6515 m_pBuf = (icUInt16Number*)malloc((m_nLength+1) * sizeof(icUInt16Number));
6516 if (m_nLength)
6517 memcpy(m_pBuf, ILU.GetBuf(), m_nLength*sizeof(icUInt16Number));
6518 m_pBuf[m_nLength] = 0;
6519 m_nLanguageCode = ILU.m_nLanguageCode;
6520 m_nCountryCode = ILU.m_nCountryCode;
6521}
6522
6523
6524/**
6525 ****************************************************************************
6526 * Name: CIccLocalizedUnicode::operator=
6527 *
6528 * Purpose: Copy Operator
6529 *
6530 * Args:
6531 * UnicodeText = The CIccLocalizedUnicode object to be copied
6532 *****************************************************************************
6533 */
6534CIccLocalizedUnicode &CIccLocalizedUnicode::operator=(const CIccLocalizedUnicode &UnicodeText)
6535{
6536 if (&UnicodeText == this)
6537 return *this;
6538
6539 if (SetSize(UnicodeText.GetLength())) {
6540 memcpy(m_pBuf, UnicodeText.GetBuf(), m_nLength*sizeof(icUInt16Number));
6541 }
6542 m_nLanguageCode = UnicodeText.m_nLanguageCode;
6543 m_nCountryCode = UnicodeText.m_nCountryCode;
6544
6545 return *this;
6546}
6547
6548
6549/**
6550 ****************************************************************************
6551 * Name: CIccLocalizedUnicode::~CIccLocalizedUnicode
6552 *
6553 * Purpose: Destructor
6554 *
6555 *****************************************************************************
6556 */
6557CIccLocalizedUnicode::~CIccLocalizedUnicode()
6558{
6559 if (m_pBuf)
6560 free(m_pBuf);
6561}
6562
6563/**
6564 ****************************************************************************
6565 * Name: CIccLocalizedUnicode::GetAnsiSize
6566 *
6567 * Purpose: Returns the size of the ANSI data buffer
6568 *
6569 *****************************************************************************
6570 */
6571icUInt32Number CIccLocalizedUnicode::GetAnsiSize()
6572{
6573 icUInt32Number len;
6574#ifdef USE_WINDOWS_MB_SUPPORT
6575 len = WideCharToMultiByte(CP_ACP, 0x00000400, (LPCWSTR)m_pBuf, m_nLength, NULL__null, 0, NULL__null, NULL__null);
6576#else
6577 len = m_nLength;
6578#endif
6579
6580 return len;
6581}
6582
6583/**
6584 ****************************************************************************
6585 * Name: CIccLocalizedUnicode::GetAnsi
6586 *
6587 * Purpose: Extracts the ANSI data buffer
6588 *
6589 * Args:
6590 * szBuf = pointer where the returned string buffer is to be stored
6591 * nBufSize = size of the buffer to be extracted
6592 *
6593 * Return:
6594 * Pointer to the ANSI data string
6595 *****************************************************************************
6596 */
6597const icChar *CIccLocalizedUnicode::GetAnsi(icChar *szBuf, icUInt32Number nBufSize)
6598{
6599 if (!szBuf)
6600 return NULL__null;
6601
6602 if (!m_nLength) {
6603 *szBuf='\0';
6604 }
6605 else {
6606#ifdef USE_WINDOWS_MB_SUPPORT
6607 int len = WideCharToMultiByte(CP_ACP, 0x00000400, (LPCWSTR)m_pBuf, m_nLength, szBuf, nBufSize, NULL__null, NULL__null);
6608 szBuf[len]='\0';
6609#else
6610 icUInt32Number i;
6611
6612 for (i=0; i<m_nLength; i++) {
6613 if (m_pBuf[i]<256) {
6614 szBuf[i] = (icChar)m_pBuf[i];
6615 }
6616 else {
6617 szBuf[i] = '?';
6618 }
6619 }
6620#endif
6621 }
6622
6623 return szBuf;
6624}
6625
6626/**
6627****************************************************************************
6628* Name: CIccLocalizedUnicode::GetText
6629*
6630* Purpose: Sets a standard string with the text
6631*
6632* Args:
6633* nSize - length of the string
6634*
6635*****************************************************************************
6636*/
6637bool CIccLocalizedUnicode::GetText(std::string &sText)
6638{
6639 icUInt32Number size = GetAnsiSize();
6640 char *buf = (char*)malloc(size+1);
6641 if (buf) {
6642 GetAnsi(buf, size);
6643 sText = buf;
6644 free(buf);
6645 return true;
6646 }
6647 sText = "";
6648 return false;
6649}
6650
6651
6652/**
6653 ****************************************************************************
6654 * Name: CIccLocalizedUnicode::SetSize
6655 *
6656 * Purpose: Sets the size of the string buffer.
6657 *
6658 * Args:
6659 * nSize - length of the string
6660 *
6661 *****************************************************************************
6662 */
6663bool CIccLocalizedUnicode::SetSize(icUInt32Number nSize)
6664{
6665 if (nSize == m_nLength)
6666 return true;
6667
6668 m_pBuf = (icUInt16Number*)icRealloc(m_pBuf, (nSize+1)*sizeof(icUInt16Number));
6669
6670 if (!m_pBuf) {
6671 m_nLength = 0;
6672 return false;
6673 }
6674
6675 m_nLength = nSize;
6676
6677 m_pBuf[nSize]=0;
6678
6679 return true;
6680}
6681
6682/**
6683 ****************************************************************************
6684 * Name: CIccLocalizedUnicode::SetText
6685 *
6686 * Purpose: Allows text data associated with the tag to be set.
6687 *
6688 * Args:
6689 * szText = zero terminated string to put in tag,
6690 * nLanguageCode = the language code type as defined by icLanguageCode,
6691 * nRegionCode = the region code type as defined by icCountryCode
6692 *****************************************************************************
6693 */
6694bool CIccLocalizedUnicode::SetText(const icChar *szText,
6695 icLanguageCode nLanguageCode/* = icLanguageCodeEnglish*/,
6696 icCountryCode nRegionCode/* = icCountryCodeUSA*/)
6697{
6698 int len=(icInt32Number)strlen(szText), i;
6699 icUInt16Number *pBuf;
6700
6701 if (!SetSize(len))
6702 return false;
6703
6704 pBuf = m_pBuf;
6705 for (i=0; i<len; i++) {
6706 *pBuf++ = *szText++;
6707 }
6708 *pBuf = 0;
6709
6710 m_nLanguageCode = nLanguageCode;
6711 m_nCountryCode = nRegionCode;
6712
6713 return true;
6714}
6715
6716/**
6717 ****************************************************************************
6718 * Name: CIccLocalizedUnicode::SetText
6719 *
6720 * Purpose: Allows text data associated with the tag to be set.
6721 *
6722 * Args:
6723 * sszUnicode16Text = Unicode16 text to be set,
6724 * nLanguageCode = the language code type as defined by icLanguageCode,
6725 * nRegionCode = the region code type as defined by icCountryCode
6726 *****************************************************************************
6727 */
6728bool CIccLocalizedUnicode::SetText(const icUInt16Number *sszUnicode16Text,
6729 icLanguageCode nLanguageCode/* = icLanguageCodeEnglish*/,
6730 icCountryCode nRegionCode/* = icCountryCodeUSA*/)
6731{
6732 const icUInt16Number *pBuf=sszUnicode16Text;
6733 int len;
6734
6735 for (len=0; *pBuf; len++, pBuf++);
6736
6737 if (!SetSize(len))
6738 return false;
6739 memcpy(m_pBuf, sszUnicode16Text, (len+1)*sizeof(icUInt16Number));
6740
6741 m_nLanguageCode = nLanguageCode;
6742 m_nCountryCode = nRegionCode;
6743
6744 return true;
6745}
6746
6747/**
6748****************************************************************************
6749* Name: CIccLocalizedUnicode::SetText
6750*
6751* Purpose: Allows text data associated with the tag to be set.
6752*
6753* Args:
6754* sszUnicode32Text = Unicode32 text to be set,
6755* nLanguageCode = the language code type as defined by icLanguageCode,
6756* nRegionCode = the region code type as defined by icCountryCode
6757*****************************************************************************
6758*/
6759bool CIccLocalizedUnicode::SetText(const icUInt32Number *sszUnicode32Text,
6760 icLanguageCode nLanguageCode/* = icLanguageCodeEnglish*/,
6761 icCountryCode nRegionCode/* = icCountryCodeUSA*/)
6762{
6763 const icUInt32Number *pBuf=sszUnicode32Text;
6764 int len;
6765
6766 for (len=0; *pBuf; len++, pBuf++);
6767 if (*pBuf)
6768 pBuf--;
6769
6770 if (!SetSize(len*2))
6771 return false;
6772
6773 const icUInt32Number *srcStart = sszUnicode32Text;
6774 icUInt16Number *dstStart = m_pBuf;
6775 icConvertUTF32toUTF16(&srcStart, &srcStart[len], &dstStart, &dstStart[len*2], lenientConversion);
6776
6777 *dstStart=0;
6778 if (!SetSize((icUInt32Number)(dstStart - m_pBuf)))
6779 return false;
6780
6781 m_nLanguageCode = nLanguageCode;
6782 m_nCountryCode = nRegionCode;
6783
6784 return true;
6785}
6786
6787
6788/**
6789 ****************************************************************************
6790 * Name: CIccTagMultiLocalizedUnicode::CIccTagMultiLocalizedUnicode
6791 *
6792 * Purpose: Constructor
6793 *
6794 *****************************************************************************
6795 */
6796CIccTagMultiLocalizedUnicode::CIccTagMultiLocalizedUnicode()
6797{
6798 m_Strings = new(CIccMultiLocalizedUnicode);
6799}
6800
6801
6802/**
6803 ****************************************************************************
6804 * Name: CIccTagMultiLocalizedUnicode::CIccTagMultiLocalizedUnicode
6805 *
6806 * Purpose: Copy Constructor
6807 *
6808 * Args:
6809 * ITMLU = The CIccTagMultiLocalizedUnicode object to be copied
6810 *****************************************************************************
6811 */
6812CIccTagMultiLocalizedUnicode::CIccTagMultiLocalizedUnicode(const CIccTagMultiLocalizedUnicode& ITMLU)
6813{
6814 m_Strings = new(CIccMultiLocalizedUnicode);
6815 *m_Strings = *ITMLU.m_Strings;
6816}
6817
6818
6819/**
6820 ****************************************************************************
6821 * Name: CIccTagMultiLocalizedUnicode::operator=
6822 *
6823 * Purpose: Copy Operator
6824 *
6825 * Args:
6826 * MultiLocalizedTag = The CIccTagMultiLocalizedUnicode object to be copied
6827 *****************************************************************************
6828 */
6829CIccTagMultiLocalizedUnicode &CIccTagMultiLocalizedUnicode::operator=(const CIccTagMultiLocalizedUnicode &MultiLocalizedTag)
6830{
6831 if (&MultiLocalizedTag == this)
6832 return *this;
6833
6834 m_Strings->clear();
6835 *m_Strings = *MultiLocalizedTag.m_Strings;
6836
6837 return *this;
6838}
6839
6840
6841/**
6842 ****************************************************************************
6843 * Name: CIccTagMultiLocalizedUnicode::~CIccTagMultiLocalizedUnicode
6844 *
6845 * Purpose: Destructor
6846 *
6847 *****************************************************************************
6848 */
6849CIccTagMultiLocalizedUnicode::~CIccTagMultiLocalizedUnicode()
6850{
6851 delete m_Strings;
6852}
6853
6854
6855/**
6856 ****************************************************************************
6857 * Name: CIccTagMultiLocalizedUnicode::Read
6858 *
6859 * Purpose: Read in the tag contents into a data block
6860 *
6861 * Since MultiLocalizedUnicode tags can be embedded in other tags
6862 * this function ensures that the current read pointer will be set to the
6863 * position just after the last name record.
6864 *
6865 * Args:
6866 * size - # of bytes in tag,
6867 * pIO - IO object to read tag from
6868 *
6869 * Return:
6870 * true = successful, false = failure
6871 *****************************************************************************
6872 */
6873bool CIccTagMultiLocalizedUnicode::Read(icUInt32Number size, CIccIO *pIO)
6874{
6875 icTagTypeSignature sig;
6876 icUInt32Number nNumRec, nRecSize;
6877 icLanguageCode nLanguageCode;
6878 icCountryCode nRegionCode;
6879 icUInt32Number nLength, nOffset, nNumChar;
6880
6881 if (!m_Strings->empty())
6882 m_Strings->clear();
6883
6884 if (sizeof(icTagTypeSignature) +
6885 sizeof(icUInt32Number)*3 > size)
6886 return false;
6887
6888 if (!pIO) {
6889 return false;
6890 }
6891
6892 icUInt32Number nTagPos = pIO->Tell();
6893
6894 if (!pIO->Read32(&sig) ||
6895 !pIO->Read32(&m_nReserved) ||
6896 !pIO->Read32(&nNumRec) ||
6897 !pIO->Read32(&nRecSize))
6898 return false;
6899
6900
6901 if (nRecSize!=12) { //Recognized version name records are 12 bytes each
6902 return false;
6903 }
6904
6905 icUInt32Number i;
6906 CIccLocalizedUnicode Unicode;
6907 icUInt32Number nLastPos = 0;
6908
6909 for (i=0; i<nNumRec; i++) {
6910 if (4*sizeof(icUInt32Number) + (i+1)*12 > size)
6911 return false;
6912
6913 pIO->Seek(nTagPos+4*sizeof(icUInt32Number) + i*12, icSeekSet);
6914
6915 if (!pIO->Read16(&nLanguageCode) ||
6916 !pIO->Read16(&nRegionCode) ||
6917 !pIO->Read32(&nLength) ||
6918 !pIO->Read32(&nOffset))
6919 return false;
6920
6921 if (nOffset+nLength > size)
6922 return false;
6923
6924 //Find out position of the end of last named record
6925 if (nOffset+nLength > nLastPos)
6926 nLastPos = nOffset + nLength;
6927
6928 nNumChar = nLength / sizeof(icUInt16Number);
6929
6930 if (!Unicode.SetSize(nNumChar))
6931 return false;
6932
6933 Unicode.m_nLanguageCode = nLanguageCode;
6934 Unicode.m_nCountryCode = nRegionCode;
6935
6936 pIO->Seek(nTagPos+nOffset, icSeekSet);
6937
6938 if (pIO->Read16(Unicode.GetBuf(), nNumChar) != (icInt32Number)nNumChar)
6939 return false;
6940
6941 m_Strings->push_back(Unicode);
6942 }
6943
6944 //Now seek past the last named record
6945 if (nLastPos > 0)
6946 pIO->Seek(nTagPos+nLastPos, icSeekSet);
6947
6948 return true;
6949}
6950
6951
6952/**
6953 ****************************************************************************
6954 * Name: CIccTagMultiLocalizedUnicode::Write
6955 *
6956 * Purpose: Write the tag to a file
6957 *
6958 * Args:
6959 * pIO - The IO object to write tag to.
6960 *
6961 * Return:
6962 * true = succesful, false = failure
6963 *****************************************************************************
6964 */
6965bool CIccTagMultiLocalizedUnicode::Write(CIccIO *pIO)
6966{
6967 icTagTypeSignature sig = GetType();
6968 icUInt32Number nNumRec=(icUInt32Number)m_Strings->size(), nRecSize=12;
6969 icUInt32Number nLength;
6970
6971 if (!pIO) {
6972 return false;
6973 }
6974
6975 if (!pIO->Write32(&sig) ||
6976 !pIO->Write32(&m_nReserved) ||
6977 !pIO->Write32(&nNumRec) ||
6978 !pIO->Write32(&nRecSize))
6979 return false;
6980
6981
6982 icUInt32Number nPos = 4*sizeof(icUInt32Number) + nNumRec*12;
6983
6984 CIccMultiLocalizedUnicode::iterator i;
6985
6986 for (i=m_Strings->begin(); i!=m_Strings->end(); i++) {
6987 nLength = i->GetLength() * sizeof(icUInt16Number);
6988
6989 if (!pIO->Write16(&i->m_nLanguageCode) ||
6990 !pIO->Write16(&i->m_nCountryCode) ||
6991 !pIO->Write32(&nLength) ||
6992 !pIO->Write32(&nPos))
6993 return false;
6994 nPos += nLength;
6995 }
6996
6997 for (i=m_Strings->begin(); i!=m_Strings->end(); i++) {
6998 nLength = i->GetLength();
6999
7000 if (nLength) {
7001 if (pIO->Write16(i->GetBuf(), nLength) != (icInt32Number)nLength)
7002 return false;
7003 }
7004 }
7005
7006 return true;
7007}
7008
7009
7010/**
7011 ****************************************************************************
7012 * Name: CIccTagMultiLocalizedUnicode::Describe
7013 *
7014 * Purpose: Dump data associated with the tag to a string
7015 *
7016 * Args:
7017 * sDescription - string to concatenate tag dump to
7018 *****************************************************************************
7019 */
7020void CIccTagMultiLocalizedUnicode::Describe(std::string &sDescription)
7021{
7022 icChar *szBuf = (icChar*)malloc(128);
7023 int nSize = 127, nAnsiSize;
7024 CIccMultiLocalizedUnicode::iterator i;
7025
7026 if (!szBuf) {
7027 sDescription += "***Allocation Error***\r\n";
7028 return;
7029 }
7030
7031 for (i=m_Strings->begin(); i!=m_Strings->end(); i++) {
7032 if (i!=m_Strings->begin())
7033 sDescription += "\r\n";
7034
7035 sprintf(szBuf, "Language = '%c%c', Region = '%c%c'\r\n",
7036 i->m_nLanguageCode>>8, i->m_nLanguageCode,
7037 i->m_nCountryCode>>8, i->m_nCountryCode);
7038
7039 sDescription += szBuf;
7040
7041 nAnsiSize = i->GetAnsiSize();
7042
7043 if (nAnsiSize>nSize) {
7044 szBuf = (icChar*)icRealloc(szBuf, nAnsiSize+1);
7045
7046 if (!szBuf)
7047 nSize = 0;
7048 else
7049 nSize = nAnsiSize;
7050 }
7051 if (szBuf) {
7052 i->GetAnsi(szBuf, nSize);
7053 sDescription += "\"";
7054 sDescription += szBuf;
7055 sDescription += "\"\r\n";
7056 }
7057 else {
7058 sDescription += "***Allocation Error***\r\n";
7059 }
7060 }
7061}
7062
7063
7064/**
7065******************************************************************************
7066* Name: CIccTagMultiLocalizedUnicode::Validate
7067*
7068* Purpose: Check tag data validity.
7069*
7070* Args:
7071* sig = signature of tag being validated,
7072* sReport = String to add report information to
7073*
7074* Return:
7075* icValidateStatusOK if valid, or other error status.
7076******************************************************************************
7077*/
7078icValidateStatus CIccTagMultiLocalizedUnicode::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
7079{
7080 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
7081
7082 CIccInfo Info;
7083 std::string sSigPathName = Info.GetSigPathName(sigPath);
7084
7085 if (!m_Strings->size()) {
7086 sReport += icMsgValidateWarning;
7087 sReport += sSigPathName;
7088 sReport += " - Empty tag!\r\n";
7089 rv = icMaxStatus(rv, icValidateWarning);
7090 }
7091
7092 // TODO: Look at the ISO-639 and ISO-3166 documents for valid
7093 // Language and Region codes
7094/*
7095 CIccMultiLocalizedUnicode::iterator i;
7096 for (i=m_Strings->begin(); i!=m_Strings->end(); i++) {
7097 switch(i->m_nLanguageCode) {
7098 case :
7099 break;
7100 default:
7101 }
7102
7103 switch(i->m_nRegionCode) {
7104 case :
7105 break;
7106 default:
7107 }
7108 }
7109*/
7110
7111 return rv;
7112}
7113
7114/**
7115****************************************************************************
7116* Name: refIccMAX::CIccTagMultiLocalizedUnicode::Find
7117*
7118* Purpose:
7119*
7120* Args:
7121* nLanguageCode
7122* nRegionCode
7123*
7124* Return:
7125* Pointer to CIccLocalizedUnicode object associated with the nLanguageCode
7126* and nRegionCode or NULL if not found
7127*****************************************************************************
7128*/
7129CIccLocalizedUnicode *CIccTagMultiLocalizedUnicode::Find(icLanguageCode nLanguageCode /* = icLanguageCodeEnglish */,
7130 icCountryCode nRegionCode /* = icCountryCodeUSA */)
7131{
7132 CIccMultiLocalizedUnicode::iterator i;
7133
7134 for (i=m_Strings->begin(); i!=m_Strings->end(); i++) {
7135 if (i->m_nLanguageCode == nLanguageCode &&
7136 i->m_nCountryCode == nRegionCode) {
7137 return &(*i);
7138 }
7139 }
7140
7141 return NULL__null;
7142}
7143
7144/**
7145****************************************************************************
7146* Name: refIccMAX::CIccTagMultiLocalizedUnicode::SetText
7147*
7148* Purpose:
7149*
7150* Args:
7151* sszUnicodeText
7152* nLanguageCode
7153* RegionCode
7154*****************************************************************************
7155*/
7156void CIccTagMultiLocalizedUnicode::SetText(const icChar *szText,
7157 icLanguageCode nLanguageCode /* = icLanguageCodeEnglish */,
7158 icCountryCode nRegionCode /* = icCountryCodeUSA */)
7159{
7160 CIccLocalizedUnicode *pText = Find(nLanguageCode, nRegionCode);
7161
7162 if (!pText) {
7163 CIccLocalizedUnicode newText;
7164 newText.SetText(szText, nLanguageCode, nRegionCode);
7165 m_Strings->push_back(newText);
7166 }
7167 else {
7168 pText->SetText(szText, nLanguageCode, nRegionCode);
7169 }
7170}
7171
7172
7173/**
7174****************************************************************************
7175* Name: refIccMAX::CIccTagMultiLocalizedUnicode::SetText
7176*
7177* Purpose:
7178*
7179* Args:
7180* sszUnicodeText
7181* nLanguageCode
7182* RegionCode
7183*****************************************************************************
7184*/
7185void CIccTagMultiLocalizedUnicode::SetText(const icUInt16Number *sszUnicode16Text,
7186 icLanguageCode nLanguageCode /* = icLanguageCodeEnglish */,
7187 icCountryCode nRegionCode /* = icCountryCodeUSA */)
7188{
7189 CIccLocalizedUnicode *pText = Find(nLanguageCode, nRegionCode);
7190
7191 if (!pText) {
7192 CIccLocalizedUnicode newText;
7193 newText.SetText(sszUnicode16Text, nLanguageCode, nRegionCode);
7194 m_Strings->push_back(newText);
7195 }
7196 else {
7197 pText->SetText(sszUnicode16Text, nLanguageCode, nRegionCode);
7198 }
7199}
7200
7201/**
7202****************************************************************************
7203* Name: refIccMAX::CIccTagMultiLocalizedUnicode::SetText
7204*
7205* Purpose:
7206*
7207* Args:
7208* sszUnicodeText
7209* nLanguageCode
7210* RegionCode
7211*****************************************************************************
7212*/
7213void CIccTagMultiLocalizedUnicode::SetText(const icUInt32Number *sszUnicode32Text,
7214 icLanguageCode nLanguageCode /* = icLanguageCodeEnglish */,
7215 icCountryCode nRegionCode /* = icCountryCodeUSA */)
7216{
7217 CIccLocalizedUnicode *pText = Find(nLanguageCode, nRegionCode);
7218
7219 if (!pText) {
7220 CIccLocalizedUnicode newText;
7221 newText.SetText(sszUnicode32Text, nLanguageCode, nRegionCode);
7222 m_Strings->push_back(newText);
7223 }
7224 else {
7225 pText->SetText(sszUnicode32Text, nLanguageCode, nRegionCode);
7226 }
7227}
7228
7229//
7230// MD: Moved Curve and LUT tags to IccTagLut.cpp (4-30-05)
7231//
7232
7233
7234/**
7235 ****************************************************************************
7236 * Name: CIccTagData::CIccTagData
7237 *
7238 * Purpose: Constructor
7239 *
7240 * Args:
7241 * nSize = number of data entries
7242 *
7243 *****************************************************************************
7244 */
7245CIccTagData::CIccTagData(int nSize/*=1*/)
7246{
7247 m_nSize = nSize;
7248 if (m_nSize <1)
7249 m_nSize = 1;
7250 m_pData = (icUInt8Number*)calloc(nSize, sizeof(icUInt8Number));
7251}
7252
7253
7254/**
7255 ****************************************************************************
7256 * Name: CIccTagData::CIccTagData
7257 *
7258 * Purpose: Copy Constructor
7259 *
7260 * Args:
7261 * ITD = The CIccTagData object to be copied
7262 *****************************************************************************
7263 */
7264CIccTagData::CIccTagData(const CIccTagData &ITD)
7265{
7266 m_nDataFlag = ITD.m_nDataFlag;
7267 m_nSize = ITD.m_nSize;
7268
7269 m_pData = (icUInt8Number*)calloc(m_nSize, sizeof(icUInt8Number));
7270 memcpy(m_pData, ITD.m_pData, sizeof(icUInt8Number)*m_nSize);
7271}
7272
7273
7274/**
7275 ****************************************************************************
7276 * Name: CIccTagData::operator=
7277 *
7278 * Purpose: Copy Operator
7279 *
7280 * Args:
7281 * DataTag = The CIccTagData object to be copied
7282 *****************************************************************************
7283 */
7284CIccTagData &CIccTagData::operator=(const CIccTagData &DataTag)
7285{
7286 if (&DataTag == this)
7287 return *this;
7288
7289 m_nDataFlag = DataTag.m_nDataFlag;
7290 m_nSize = DataTag.m_nSize;
7291
7292 if (m_pData)
7293 free(m_pData);
7294 m_pData = (icUInt8Number*)calloc(m_nSize, sizeof(icUInt8Number));
7295 memcpy(m_pData, DataTag.m_pData, sizeof(icUInt8Number)*m_nSize);
7296
7297 return *this;
7298}
7299
7300
7301/**
7302 ****************************************************************************
7303 * Name: CIccTagData::~CIccTagData
7304 *
7305 * Purpose: Destructor
7306 *
7307 *****************************************************************************
7308 */
7309CIccTagData::~CIccTagData()
7310{
7311 if (m_pData)
7312 free(m_pData);
7313}
7314
7315
7316/**
7317 ****************************************************************************
7318 * Name: CIccTagData::Read
7319 *
7320 * Purpose: Read in the tag contents into a data block
7321 *
7322 * Args:
7323 * size - # of bytes in tag,
7324 * pIO - IO object to read tag from
7325 *
7326 * Return:
7327 * true = successful, false = failure
7328 *****************************************************************************
7329 */
7330bool CIccTagData::Read(icUInt32Number size, CIccIO *pIO)
7331{
7332 icTagTypeSignature sig;
7333
7334 if (sizeof(icTagTypeSignature) +
7335 sizeof(icUInt32Number) +
7336 sizeof(icUInt32Number) +
7337 sizeof(icUInt8Number) > size)
7338 return false;
7339
7340 if (!pIO) {
7341 return false;
7342 }
7343
7344 if (!pIO->Read32(&sig))
7345 return false;
7346
7347 if (!pIO->Read32(&m_nReserved))
7348 return false;
7349
7350 if (!pIO->Read32(&m_nDataFlag))
7351 return false;
7352
7353 icUInt32Number nNum = size-3*sizeof(icUInt32Number);
7354
7355 if (!SetSize(nNum))
7356 return false;
7357
7358 if (pIO->Read8(m_pData, nNum) != (icInt32Number)nNum)
7359 return false;
7360
7361 if (IsTypeCompressed()) {
7362 //Uncompress data here
7363 }
7364
7365 return true;
7366}
7367
7368
7369/**
7370 ****************************************************************************
7371 * Name: CIccTagData::Write
7372 *
7373 * Purpose: Write the tag to a file
7374 *
7375 * Args:
7376 * pIO - The IO object to write tag to.
7377 *
7378 * Return:
7379 * true = succesful, false = failure
7380 *****************************************************************************
7381 */
7382bool CIccTagData::Write(CIccIO *pIO)
7383{
7384 icTagTypeSignature sig = GetType();
7385
7386 if (!pIO)
7387 return false;
7388
7389 if (!pIO->Write32(&sig))
7390 return false;
7391
7392 if (!pIO->Write32(&m_nReserved))
7393 return false;
7394
7395 if (!pIO->Write32(&m_nDataFlag))
7396 return false;
7397
7398 if (IsTypeCompressed()) {
7399 icUInt32Number *pData = NULL__null;
7400 icInt32Number nSize = 0;
7401 //Compress data here
7402
7403 if (pIO->Write8(pData, nSize) != (icInt32Number)nSize)
7404 return false;
7405 }
7406 else {
7407 if (pIO->Write8(m_pData, m_nSize) != (icInt32Number)m_nSize)
7408 return false;
7409 }
7410
7411 return true;
7412}
7413
7414
7415/**
7416 ****************************************************************************
7417 * Name: CIccTagData::Describe
7418 *
7419 * Purpose: Dump data associated with the tag to a string
7420 *
7421 * Args:
7422 * sDescription - string to concatenate tag dump to
7423 *****************************************************************************
7424 */
7425void CIccTagData::Describe(std::string &sDescription)
7426{
7427 icChar buf[128];
7428
7429 sDescription = "\r\n";
7430 if (IsTypeCompressed())
7431 sDescription += "Compressed "; // If data is compressed, prepend appropriate text
7432
7433 if (IsTypeAscii()) {
7434 sDescription = "Ascii Data:\r\n";
7435
7436 for (int i=0; i<(int)m_nSize; i++)
7437 sDescription += (icChar)m_pData[i];
7438 }
7439 else if (IsTypeUtf()) {
7440 if (m_nSize>2 &&
7441 ((m_pData[0]==0xff && m_pData[1]==0xfe) || //UTF-16LE
7442 (m_pData[0]==0xfe && m_pData[1]==0xff))) { //UTF-16BE
7443 sprintf(buf, "UTF-16%s Data:", m_pData[0]==0xff ? "LE" : "BE" );
7444 sDescription = buf;
7445
7446 icMemDump(sDescription, m_pData, m_nSize);
7447 }
7448 else { //UTF-8
7449 sDescription = "UTF-8 Data:\r\n";
7450
7451 for (int i=0; i<(int)m_nSize; i++)
7452 sDescription += (icChar)m_pData[i];
7453 }
7454 }
7455 else {
7456 if (IsTypeBinary()) {
7457 sDescription = "Binary Data:\r\n";
7458 }
7459 else {
7460 sDescription = "Other Data:\r\n";
7461 }
7462
7463 icMemDump(sDescription, m_pData, m_nSize);
7464 }
7465 sDescription += "\r\n";
7466}
7467
7468/**
7469 ****************************************************************************
7470 * Name: CIccTagData::SetSize
7471 *
7472 * Purpose: Sets the size of the data array.
7473 *
7474 * Args:
7475 * nSize - number of data entries,
7476 * bZeroNew - flag to zero newly formed values
7477 *****************************************************************************
7478 */
7479bool CIccTagData::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
7480{
7481 if (m_nSize == nSize)
7482 return true;
7483
7484 m_pData = (icUInt8Number*)icRealloc(m_pData, nSize*sizeof(icUInt8Number));
7485
7486 if (!m_pData) {
7487 m_nSize = 0;
7488 return false;
7489 }
7490
7491 if (bZeroNew && nSize > m_nSize) {
7492 memset(&m_pData[m_nSize], 0, (nSize-m_nSize)*sizeof(icUInt8Number));
7493 }
7494 m_nSize = nSize;
7495
7496 return true;
7497}
7498
7499
7500/**
7501******************************************************************************
7502* Name: CIccTagData::Validate
7503*
7504* Purpose: Check tag data validity.
7505*
7506* Args:
7507* sig = signature of tag being validated,
7508* sReport = String to add report information to
7509*
7510* Return:
7511* icValidateStatusOK if valid, or other error status.
7512******************************************************************************
7513*/
7514icValidateStatus CIccTagData::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
7515{
7516 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
7517
7518 CIccInfo Info;
7519 std::string sSigPathName = Info.GetSigPathName(sigPath);
7520
7521 // Mask bits to match processing in Describe() so warnings are appropriate
7522 switch(m_nDataFlag&(icCompressedData0x00010000|icDataTypeMask0x0000ffff)) {
7523 case icAsciiData:
7524 for (int i = 0; i < (int)m_nSize; i++) {
7525 if (m_pData[i] & 0x80) {
7526 sReport += icMsgValidateWarning;
7527 sReport += sSigPathName;
7528 sReport += " - Ascii Data is not just 7-bit data.\r\n";
7529 rv = icMaxStatus(rv, icValidateWarning);
7530 break;
7531 }
7532 }
7533 break;
7534 case icBinaryData:
7535 case icUtfData:
7536 case icCompressedAsciiData:
7537 case icCompressedBinaryData:
7538 case icCompressedUtfData:
7539 break;
7540 default:
7541 sReport += icMsgValidateNonCompliant;
7542 sReport += sSigPathName;
7543 sReport += " - Invalid data flag encoding.\r\n";
7544 rv = icMaxStatus(rv, icValidateNonCompliant);
7545 }
7546
7547 if (m_nDataFlag & ~(icCompressedData0x00010000 | icDataTypeMask0x0000ffff)) {
7548 sReport += icMsgValidateNonCompliant;
7549 sReport += sSigPathName;
7550 sReport += " - Invalid data flag encoding (reserved high order bits).\r\n";
7551 rv = icMaxStatus(rv, icValidateNonCompliant);
7552 }
7553
7554 return rv;
7555}
7556
7557
7558/**
7559 ****************************************************************************
7560 * Name: CIccTagDateTime::CIccTagDateTime
7561 *
7562 * Purpose: Constructor
7563 *
7564 *****************************************************************************
7565 */
7566CIccTagDateTime::CIccTagDateTime()
7567{
7568 memset(&m_DateTime, 0, sizeof(m_DateTime));
7569}
7570
7571
7572/**
7573 ****************************************************************************
7574 * Name: CIccTagDateTime::CIccTagDateTime
7575 *
7576 * Purpose: Copy Constructor
7577 *
7578 * Args:
7579 * ITDT = The CIccTagDateTime object to be copied
7580 *****************************************************************************
7581 */
7582CIccTagDateTime::CIccTagDateTime(const CIccTagDateTime &ITDT)
7583{
7584 memcpy(&m_DateTime, &ITDT.m_DateTime, sizeof(m_DateTime));
7585}
7586
7587
7588/**
7589 ****************************************************************************
7590 * Name: CIccTagDateTime::operator=
7591 *
7592 * Purpose: Copy Operator
7593 *
7594 * Args:
7595 * DateTimeTag = The CIccTagDateTime object to be copied
7596 *****************************************************************************
7597 */
7598CIccTagDateTime &CIccTagDateTime::operator=(const CIccTagDateTime &DateTimeTag)
7599{
7600 if (&DateTimeTag == this)
7601 return *this;
7602
7603 memcpy(&m_DateTime, &DateTimeTag.m_DateTime, sizeof(m_DateTime));
7604
7605 return *this;
7606}
7607
7608
7609/**
7610 ****************************************************************************
7611 * Name: CIccTagDateTime::~CIccTagDateTime
7612 *
7613 * Purpose: Destructor
7614 *
7615 *****************************************************************************
7616 */
7617CIccTagDateTime::~CIccTagDateTime()
7618{
7619}
7620
7621
7622
7623/**
7624 ****************************************************************************
7625 * Name: CIccTagDateTime::Read
7626 *
7627 * Purpose: Read in the tag contents into a data block
7628 *
7629 * Args:
7630 * size - # of bytes in tag,
7631 * pIO - IO object to read tag from
7632 *
7633 * Return:
7634 * true = successful, false = failure
7635 *****************************************************************************
7636 */
7637bool CIccTagDateTime::Read(icUInt32Number size, CIccIO *pIO)
7638{
7639 icTagTypeSignature sig;
7640
7641 if (sizeof(icTagTypeSignature) +
7642 sizeof(icUInt32Number) +
7643 sizeof(icDateTimeNumber) > size)
7644 return false;
7645
7646 if (!pIO) {
7647 return false;
7648 }
7649
7650 if (!pIO->Read32(&sig))
7651 return false;
7652
7653 if (!pIO->Read32(&m_nReserved))
7654 return false;
7655
7656
7657 icUInt32Number nsize = (size-2*sizeof(icUInt32Number))/sizeof(icUInt16Number);
7658
7659 if (nsize > sizeof(m_DateTime) / sizeof(icUInt16Number))
7660 return false;
7661
7662 if (pIO->Read16(&m_DateTime,nsize) != (icInt32Number)nsize)
7663 return false;
7664
7665 return true;
7666}
7667
7668
7669
7670/**
7671 ****************************************************************************
7672 * Name: CIccTagDateTime::Write
7673 *
7674 * Purpose: Write the tag to a file
7675 *
7676 * Args:
7677 * pIO - The IO object to write tag to.
7678 *
7679 * Return:
7680 * true = succesful, false = failure
7681 *****************************************************************************
7682 */
7683bool CIccTagDateTime::Write(CIccIO *pIO)
7684{
7685 icTagTypeSignature sig = GetType();
7686
7687 if (!pIO)
7688 return false;
7689
7690 if (!pIO->Write32(&sig))
7691 return false;
7692
7693 if (!pIO->Write32(&m_nReserved))
7694 return false;
7695
7696 if (pIO->Write16(&m_DateTime,6) != 6)
7697 return false;
7698
7699 return true;
7700}
7701
7702
7703
7704/**
7705 ****************************************************************************
7706 * Name: CIccTagDateTime::Describe
7707 *
7708 * Purpose: Dump data associated with the tag to a string
7709 *
7710 * Args:
7711 * sDescription - string to concatenate tag dump to
7712 *****************************************************************************
7713 */
7714void CIccTagDateTime::Describe(std::string &sDescription)
7715{
7716 icChar buf[128];
7717
7718 sDescription = "Date = ";
7719 sprintf(buf, "%u-%u-%u\r\n", m_DateTime.month, m_DateTime.day, m_DateTime.year);
7720 sDescription += buf;
7721
7722 sDescription += "Time = ";
7723 sprintf(buf, "%u:%u:%u\r\n", m_DateTime.hours, m_DateTime.minutes, m_DateTime.seconds);
7724 sDescription += buf;
7725}
7726
7727
7728/**
7729******************************************************************************
7730* Name: CIccTagDateTime::Validate
7731*
7732* Purpose: Check tag data validity.
7733*
7734* Args:
7735* sig = signature of tag being validated,
7736* sReport = String to add report information to
7737*
7738* Return:
7739* icValidateStatusOK if valid, or other error status.
7740******************************************************************************
7741*/
7742icValidateStatus CIccTagDateTime::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
7743{
7744 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
7745 CIccInfo Info;
7746
7747 rv = icMaxStatus(rv, Info.CheckData(sReport, m_DateTime));
7748
7749 return rv;
7750}
7751
7752
7753
7754/**
7755 ****************************************************************************
7756 * Name: CIccTagColorantOrder::CIccTagColorantOrder
7757 *
7758 * Purpose: Constructor
7759 *
7760 * Args:
7761 * nSize = number of channels
7762 *
7763 *****************************************************************************
7764 */
7765CIccTagColorantOrder::CIccTagColorantOrder(int nsize/*=1*/)
7766{
7767 m_nCount = nsize;
7768 if (m_nCount <1)
7769 m_nCount = 1;
7770 m_pData = (icUInt8Number*)calloc(nsize, sizeof(icUInt8Number));
7771}
7772
7773
7774
7775/**
7776 ****************************************************************************
7777 * Name: CIccTagColorantOrder::CIccTagColorantOrder
7778 *
7779 * Purpose: Copy Constructor
7780 *
7781 * Args:
7782 * ITCO = The CIccTagColorantOrder object to be copied
7783 *****************************************************************************
7784 */
7785CIccTagColorantOrder::CIccTagColorantOrder(const CIccTagColorantOrder &ITCO)
7786{
7787 m_nCount = ITCO.m_nCount;
7788
7789 m_pData = (icUInt8Number*)calloc(m_nCount, sizeof(icUInt8Number));
7790 memcpy(m_pData, ITCO.m_pData, sizeof(icUInt8Number)*m_nCount);
7791}
7792
7793
7794/**
7795 ****************************************************************************
7796 * Name: CIccTagColorantOrder::operator=
7797 *
7798 * Purpose: Copy Operator
7799 *
7800 * Args:
7801 * ColorantOrderTag = The CIccTagColorantOrder object to be copied
7802 *****************************************************************************
7803 */
7804CIccTagColorantOrder &CIccTagColorantOrder::operator=(const CIccTagColorantOrder &ColorantOrderTag)
7805{
7806 if (&ColorantOrderTag == this)
7807 return *this;
7808
7809 m_nCount = ColorantOrderTag.m_nCount;
7810
7811 if (m_pData)
7812 free(m_pData);
7813 m_pData = (icUInt8Number*)calloc(m_nCount, sizeof(icUInt8Number));
7814 memcpy(m_pData, ColorantOrderTag.m_pData, sizeof(icUInt8Number)*m_nCount);
7815
7816 return *this;
7817}
7818
7819
7820/**
7821 ****************************************************************************
7822 * Name: CIccTagColorantOrder::~CIccTagColorantOrder
7823 *
7824 * Purpose: Destructor
7825 *
7826 *****************************************************************************
7827 */
7828CIccTagColorantOrder::~CIccTagColorantOrder()
7829{
7830 if (m_pData)
7831 free(m_pData);
7832}
7833
7834
7835
7836/**
7837 ****************************************************************************
7838 * Name: CIccTagColorantOrder::Read
7839 *
7840 * Purpose: Read in the tag contents into a data block
7841 *
7842 * Args:
7843 * size - # of bytes in tag,
7844 * pIO - IO object to read tag from
7845 *
7846 * Return:
7847 * true = successful, false = failure
7848 *****************************************************************************
7849 */
7850bool CIccTagColorantOrder::Read(icUInt32Number size, CIccIO *pIO)
7851{
7852 icTagTypeSignature sig;
7853 icUInt32Number nCount;
7854
7855 if (sizeof(icTagTypeSignature) +
7856 sizeof(icUInt32Number) +
7857 sizeof(icUInt32Number) > size)
7858 return false;
7859
7860 if (!pIO) {
7861 return false;
7862 }
7863
7864 if (!pIO->Read32(&sig))
7865 return false;
7866
7867 if (!pIO->Read32(&m_nReserved))
7868 return false;
7869
7870 if (!pIO->Read32(&nCount))
7871 return false;
7872
7873 icUInt32Number nNum = (size - 3*sizeof(icUInt32Number))/sizeof(icUInt8Number);
7874
7875 if (nNum < nCount)
7876 return false;
7877
7878 if (!SetSize((icUInt16Number)nCount))
7879 return false;
7880
7881 if (pIO->Read8(&m_pData[0], m_nCount) != (icInt32Number)m_nCount)
7882 return false;
7883
7884 return true;
7885}
7886
7887
7888
7889/**
7890 ****************************************************************************
7891 * Name: CIccTagColorantOrder::Write
7892 *
7893 * Purpose: Write the tag to a file
7894 *
7895 * Args:
7896 * pIO - The IO object to write tag to.
7897 *
7898 * Return:
7899 * true = succesful, false = failure
7900 *****************************************************************************
7901 */
7902bool CIccTagColorantOrder::Write(CIccIO *pIO)
7903{
7904 icTagTypeSignature sig = GetType();
7905
7906 if (!pIO)
7907 return false;
7908
7909 if (!pIO->Write32(&sig))
7910 return false;
7911
7912 if (!pIO->Write32(&m_nReserved))
7913 return false;
7914
7915 if (!pIO->Write32(&m_nCount))
7916 return false;
7917
7918 if (pIO->Write8(&m_pData[0], m_nCount) != (icInt32Number)m_nCount)
7919 return false;
7920
7921 return true;
7922}
7923
7924
7925
7926/**
7927 ****************************************************************************
7928 * Name: CIccTagColorantOrder::Describe
7929 *
7930 * Purpose: Dump data associated with the tag to a string
7931 *
7932 * Args:
7933 * sDescription - string to concatenate tag dump to
7934 *****************************************************************************
7935 */
7936void CIccTagColorantOrder::Describe(std::string &sDescription)
7937{
7938 icChar buf[128];
7939
7940 sprintf(buf, "Colorant Count : %u\r\n", m_nCount);
7941 sDescription += buf;
7942 sDescription += "Order of Colorants:\r\n";
7943
7944 for (int i=0; i<(int)m_nCount; i++) {
7945 sprintf(buf, "%u\r\n", m_pData[i]);
7946 sDescription += buf;
7947 }
7948}
7949
7950
7951/**
7952 ****************************************************************************
7953 * Name: CIccTagColorantOrder::SetSize
7954 *
7955 * Purpose: Sets the size of the data array.
7956 *
7957 * Args:
7958 * nSize - number of channels,
7959 * bZeroNew - flag to zero newly formed values
7960 *****************************************************************************
7961 */
7962bool CIccTagColorantOrder::SetSize(icUInt16Number nSize, bool bZeroNew/*=true*/)
7963{
7964 if (m_nCount == nSize)
7965 return true;
7966
7967 m_pData = (icUInt8Number*)icRealloc(m_pData, nSize*sizeof(icUInt8Number));
7968
7969 if (!m_pData) {
7970 m_nCount = 0;
7971 return false;
7972 }
7973
7974 if (bZeroNew && nSize > m_nCount) {
7975 memset(&m_pData[m_nCount], 0, (nSize - m_nCount)*sizeof(icUInt8Number));
7976 }
7977
7978 m_nCount = nSize;
7979
7980 return true;
7981}
7982
7983
7984/**
7985******************************************************************************
7986* Name: CIccTagColorantOrder::Validate
7987*
7988* Purpose: Check tag data validity.
7989*
7990* Args:
7991* sig = signature of tag being validated,
7992* sReport = String to add report information to
7993*
7994* Return:
7995* icValidateStatusOK if valid, or other error status.
7996******************************************************************************
7997*/
7998icValidateStatus CIccTagColorantOrder::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
7999{
8000 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
8001
8002 CIccInfo Info;
8003 std::string sSigPathName = Info.GetSigPathName(sigPath);
8004
8005 if (!pProfile) {
8006 sReport += icMsgValidateWarning;
8007 sReport += sSigPathName;
8008 sReport += " - Tag validation incomplete: Pointer to profile unavailable.\r\n";
8009 rv = icMaxStatus(rv, icValidateWarning);
8010 return rv;
8011 }
8012
8013 if (sigPath==icGetSigPath(icSigColorantTableTag)) {
8014 if (m_nCount != icGetSpaceSamples(pProfile->m_Header.colorSpace)) {
8015 sReport += icMsgValidateNonCompliant;
8016 sReport += sSigPathName;
8017 sReport += " - Incorrect number of colorants.\r\n";
8018 rv = icMaxStatus(rv, icValidateNonCompliant);
8019 }
8020 }
8021 else if (sigPath==icGetSigPath(icSigColorantTableOutTag)) {
8022 if (m_nCount != icGetSpaceSamples(pProfile->m_Header.pcs)) {
8023 sReport += icMsgValidateNonCompliant;
8024 sReport += sSigPathName;
8025 sReport += " - Incorrect number of colorants.\r\n";
8026 rv = icMaxStatus(rv, icValidateNonCompliant);
8027 }
8028 }
8029 else {
8030 sReport += icMsgValidateWarning;
8031 sReport += sSigPathName;
8032 sReport += " - Unknown number of required colorants.\r\n";
8033 rv = icMaxStatus(rv, icValidateWarning);
8034 }
8035
8036 return rv;
8037}
8038
8039
8040
8041/**
8042 ****************************************************************************
8043 * Name: CIccTagColorantTable::CIccTagColorantTable
8044 *
8045 * Purpose: Constructor
8046 *
8047 * Args:
8048 * nSize = number of entries
8049 *
8050 *****************************************************************************
8051 */
8052CIccTagColorantTable::CIccTagColorantTable(int nSize/*=1*/)
8053{
8054 m_nCount = nSize;
8055 if (m_nCount<1)
8056 m_nCount = 1;
8057
8058 m_pData = (icColorantTableEntry*)calloc(nSize, sizeof(icColorantTableEntry));
8059}
8060
8061
8062/**
8063 ****************************************************************************
8064 * Name: CIccTagColorantTable::CIccTagColorantTable
8065 *
8066 * Purpose: Copy Constructor
8067 *
8068 * Args:
8069 * ITCT = The CIccTagUnknown object to be copied
8070 *****************************************************************************
8071 */
8072CIccTagColorantTable::CIccTagColorantTable(const CIccTagColorantTable &ITCT)
8073{
8074 m_PCS = ITCT.m_PCS;
8075 m_nCount = ITCT.m_nCount;
8076
8077 m_pData = (icColorantTableEntry*)calloc(m_nCount, sizeof(icColorantTableEntry));
8078 memcpy(m_pData, ITCT.m_pData, m_nCount*sizeof(icColorantTableEntry));
8079}
8080
8081
8082/**
8083 ****************************************************************************
8084 * Name: CIccTagColorantTable::operator=
8085 *
8086 * Purpose: Copy Operator
8087 *
8088 * Args:
8089 * ColorantTableTag = The CIccTagColorantTable object to be copied
8090 *****************************************************************************
8091 */
8092CIccTagColorantTable &CIccTagColorantTable::operator=(const CIccTagColorantTable &ColorantTableTag)
8093{
8094 if (&ColorantTableTag == this)
8095 return *this;
8096
8097 m_PCS = ColorantTableTag.m_PCS;
8098 m_nCount = ColorantTableTag.m_nCount;
8099
8100 if (m_pData)
8101 free(m_pData);
8102 m_pData = (icColorantTableEntry*)calloc(m_nCount, sizeof(icColorantTableEntry));
8103 memcpy(m_pData, ColorantTableTag.m_pData, m_nCount*sizeof(icColorantTableEntry));
8104
8105 return *this;
8106}
8107
8108
8109/**
8110 ****************************************************************************
8111 * Name: CIccTagColorantTable::~CIccTagColorantTable
8112 *
8113 * Purpose: Destructor
8114 *
8115 *****************************************************************************
8116 */
8117CIccTagColorantTable::~CIccTagColorantTable()
8118{
8119 if (m_pData)
8120 free(m_pData);
8121}
8122
8123
8124/**
8125 ****************************************************************************
8126 * Name: CIccTagColorantTable::Read
8127 *
8128 * Purpose: Read in the tag contents into a data block
8129 *
8130 * Args:
8131 * size - # of bytes in tag,
8132 * pIO - IO object to read tag from
8133 *
8134 * Return:
8135 * true = successful, false = failure
8136 *****************************************************************************
8137 */
8138bool CIccTagColorantTable::Read(icUInt32Number size, CIccIO *pIO)
8139{
8140 icTagTypeSignature sig;
8141 icUInt32Number nCount;
8142
8143 if (sizeof(icTagTypeSignature) +
8144 sizeof(icUInt32Number) +
8145 sizeof(icUInt32Number) +
8146 sizeof(icColorantTableEntry) > size)
8147 return false;
8148
8149 if (!pIO) {
8150 return false;
8151 }
8152
8153 if (!pIO->Read32(&sig))
8154 return false;
8155
8156 if (!pIO->Read32(&m_nReserved))
8157 return false;
8158
8159 if (!pIO->Read32(&nCount))
8160 return false;
8161
8162 icUInt32Number nNum = (size - 3*sizeof(icUInt32Number))/sizeof(icColorantTableEntry);
8163 icUInt32Number nNum8 = sizeof(m_pData->name);
8164 icUInt32Number nNum16 = sizeof(m_pData->data)/sizeof(icUInt16Number);
8165
8166 if (nNum < nCount || nCount > 0xffff)
8167 return false;
8168
8169 if (!SetSize((icUInt16Number)nCount))
8170 return false;
8171
8172 for (icUInt32Number i=0; i<nCount; i++) {
8173 if (pIO->Read8(&m_pData[i].name[0], nNum8) != (icInt32Number)nNum8)
8174 return false;
8175
8176 if (pIO->Read16(&m_pData[i].data[0], nNum16) != (icInt32Number)nNum16)
8177 return false;
8178 }
8179
8180 return true;
8181}
8182
8183
8184/**
8185 ****************************************************************************
8186 * Name: CIccTagColorantTable::Write
8187 *
8188 * Purpose: Write the tag to a file
8189 *
8190 * Args:
8191 * pIO - The IO object to write tag to.
8192 *
8193 * Return:
8194 * true = succesful, false = failure
8195 *****************************************************************************
8196 */
8197bool CIccTagColorantTable::Write(CIccIO *pIO)
8198{
8199 icTagTypeSignature sig = GetType();
8200
8201 if (!pIO)
8202 return false;
8203
8204 if (!pIO->Write32(&sig))
8205 return false;
8206
8207 if (!pIO->Write32(&m_nReserved))
8208 return false;
8209
8210 if (!pIO->Write32(&m_nCount))
8211 return false;
8212
8213 icUInt32Number nNum8 = sizeof(m_pData->name);
8214 icUInt32Number nNum16 = sizeof(m_pData->data)/sizeof(icUInt16Number);
8215
8216 for (icUInt32Number i=0; i<m_nCount; i++) {
8217 if (pIO->Write8(&m_pData[i].name[0],nNum8) != (icInt32Number)nNum8)
8218 return false;
8219
8220 if (pIO->Write16(&m_pData[i].data[0],nNum16) != (icInt32Number)nNum16)
8221 return false;
8222 }
8223
8224 return true;
8225}
8226
8227
8228/**
8229 ****************************************************************************
8230 * Name: CIccTagColorantTable::Describe
8231 *
8232 * Purpose: Dump data associated with the tag to a string
8233 *
8234 * Args:
8235 * sDescription - string to concatenate tag dump to
8236 *****************************************************************************
8237 */
8238void CIccTagColorantTable::Describe(std::string &sDescription)
8239{
8240 icChar buf[128];
8241
8242 icUInt32Number i, nLen, nMaxLen=0;
8243 icFloatNumber Lab[3];
8244
8245 sprintf(buf, "BEGIN_COLORANTS %u\r\n", m_nCount);
8246 sDescription += buf;
8247
8248 for (i=0; i<m_nCount; i++) {
8249 nLen = (icUInt32Number)strlen(m_pData[i].name);
8250 if (nLen>nMaxLen)
8251 nMaxLen =nLen;
8252 }
8253 sDescription += "# NAME ";
8254
8255 if (m_PCS == icSigXYZData) {
8256 sprintf(buf, "XYZ_X XYZ_Y XYZ_Z\r\n");
8257 sDescription += buf;
8258 }
8259 else {
8260 sprintf(buf, "Lab_L Lab_a Lab_b\r\n");
8261 sDescription += buf;
8262 }
8263 for (i=0; i<m_nCount; i++) {
8264 sprintf(buf, "%2u \"%s\"", i, m_pData[i].name);
8265 sDescription += buf;
8266 memset(buf, ' ', 128);
8267 buf[nMaxLen + 1 - strlen(m_pData[i].name)] ='\0';
8268 sDescription += buf;
8269
8270 if (m_PCS == icSigXYZData) {
8271 sprintf(buf, "%7.4lf %7.4lf %7.4lf\r\n", icUSFtoD(m_pData[i].data[0]), icUSFtoD(m_pData[i].data[1]), icUSFtoD(m_pData[i].data[2]));
8272 sDescription += buf;
8273 }
8274 else {
8275 Lab[0] = icU16toF(m_pData[i].data[0]);
8276 Lab[1] = icU16toF(m_pData[i].data[1]);
8277 Lab[2] = icU16toF(m_pData[i].data[2]);
8278 icLabFromPcs(Lab);
8279 sprintf(buf, "%7.4lf %8.4lf %8.4lf\r\n", Lab[0], Lab[1], Lab[2]);
8280 sDescription += buf;
8281 }
8282 }
8283
8284}
8285
8286/**
8287 ****************************************************************************
8288 * Name: CIccTagColorantTable::SetSize
8289 *
8290 * Purpose: Sets the size of the data array.
8291 *
8292 * Args:
8293 * nSize - number of entries,
8294 * bZeroNew - flag to zero newly formed values
8295 *****************************************************************************
8296 */
8297bool CIccTagColorantTable::SetSize(icUInt16Number nSize, bool bZeroNew/*=true*/)
8298{
8299 if (m_nCount == nSize)
8300 return true;
8301
8302 m_pData = (icColorantTableEntry*)icRealloc(m_pData, nSize*sizeof(icColorantTableEntry));
8303
8304 if (!m_pData) {
8305 m_nCount = 0;
8306 return false;
8307 }
8308
8309 if (bZeroNew && nSize > m_nCount) {
8310 memset(&m_pData[m_nCount], 0, (nSize-m_nCount)*sizeof(icColorantTableEntry));
8311 }
8312 m_nCount = nSize;
8313
8314 return true;
8315}
8316
8317
8318/**
8319******************************************************************************
8320* Name: CIccTagColorantTable::Validate
8321*
8322* Purpose: Check tag data validity.
8323*
8324* Args:
8325* sig = signature of tag being validated,
8326* sReport = String to add report information to
8327*
8328* Return:
8329* icValidateStatusOK if valid, or other error status.
8330******************************************************************************
8331*/
8332icValidateStatus CIccTagColorantTable::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
8333{
8334 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
8335
8336 CIccInfo Info;
8337 std::string sSigPathName = Info.GetSigPathName(sigPath);
8338 icSignature sig = icGetFirstSigPathSig(sigPath);
8339
8340 if (!pProfile) {
8341 sReport += icMsgValidateWarning;
8342 sReport += sSigPathName;
8343 sReport += " - Tag validation incomplete: Pointer to profile unavailable.\r\n";
8344 rv = icMaxStatus(rv, icValidateWarning);
8345 return rv;
8346 }
8347
8348
8349 if (sig==icSigColorantTableOutTag) {
8350 if (pProfile->m_Header.deviceClass!=icSigLinkClass) {
8351 sReport += icMsgValidateNonCompliant;
8352 sReport += sSigPathName;
8353 sReport += " - Use of this tag is allowed only in DeviceLink Profiles.\r\n";
8354 rv = icMaxStatus(rv, icValidateNonCompliant);
8355 }
8356 if (m_nCount != icGetSpaceSamples(pProfile->m_Header.pcs)) {
8357 sReport += icMsgValidateNonCompliant;
8358 sReport += sSigPathName;
8359 sReport += " - Incorrect number of colorants.\r\n";
8360 rv = icMaxStatus(rv, icValidateNonCompliant);
8361 }
8362 }
8363 else {
8364 if (m_nCount != icGetSpaceSamples(pProfile->m_Header.colorSpace)) {
8365 sReport += icMsgValidateNonCompliant;
8366 sReport += sSigPathName;
8367 sReport += " - Incorrect number of colorants.\r\n";
8368 rv = icMaxStatus(rv, icValidateNonCompliant);
8369 }
8370 }
8371
8372 return rv;
8373}
8374
8375
8376/**
8377 ****************************************************************************
8378 * Name: CIccTagViewingConditions::CIccTagViewingConditions
8379 *
8380 * Purpose: Constructor
8381 *
8382 *****************************************************************************
8383 */
8384CIccTagViewingConditions::CIccTagViewingConditions()
8385{
8386 m_XYZIllum.X = 0;
8387 m_XYZIllum.Y = 0;
8388 m_XYZIllum.Z = 0;
8389
8390 m_XYZSurround.X = 0;
8391 m_XYZSurround.Y = 0;
8392 m_XYZSurround.Z = 0;
8393
8394 m_illumType = icIlluminantUnknown;
8395}
8396
8397
8398/**
8399 ****************************************************************************
8400 * Name: CIccTagViewingConditions::CIccTagViewingConditions
8401 *
8402 * Purpose: Copy Constructor
8403 *
8404 * Args:
8405 * ITVC = The CIccTagViewingConditions object to be copied
8406 *****************************************************************************
8407 */
8408CIccTagViewingConditions::CIccTagViewingConditions(const CIccTagViewingConditions &ITVC)
8409{
8410 m_illumType = ITVC.m_illumType;
8411
8412 memcpy(&m_XYZIllum, &ITVC.m_XYZIllum, sizeof(icXYZNumber));
8413 memcpy(&m_XYZSurround, &ITVC.m_XYZSurround, sizeof(icXYZNumber));
8414}
8415
8416
8417/**
8418 ****************************************************************************
8419 * Name: CIccTagViewingConditions::operator=
8420 *
8421 * Purpose: Copy Operator
8422 *
8423 * Args:
8424 * ViewCondTag = The CIccTagViewingConditions object to be copied
8425 *****************************************************************************
8426 */
8427CIccTagViewingConditions &CIccTagViewingConditions::operator=(const CIccTagViewingConditions &ViewCondTag)
8428{
8429 if (&ViewCondTag == this)
8430 return *this;
8431
8432 m_illumType = ViewCondTag.m_illumType;
8433
8434 memcpy(&m_XYZIllum, &ViewCondTag.m_XYZIllum, sizeof(icXYZNumber));
8435 memcpy(&m_XYZSurround, &ViewCondTag.m_XYZSurround, sizeof(icXYZNumber));
8436
8437 return *this;
8438}
8439
8440
8441/**
8442 ****************************************************************************
8443 * Name: CIccTagViewingConditions::~CIccTagViewingConditions
8444 *
8445 * Purpose: Destructor
8446 *
8447 *****************************************************************************
8448 */
8449CIccTagViewingConditions::~CIccTagViewingConditions()
8450{
8451}
8452
8453
8454/**
8455 ****************************************************************************
8456 * Name: CIccTagViewingConditions::Read
8457 *
8458 * Purpose: Read in the tag contents into a data block
8459 *
8460 * Args:
8461 * size - # of bytes in tag,
8462 * pIO - IO object to read tag from
8463 *
8464 * Return:
8465 * true = successful, false = failure
8466 *****************************************************************************
8467 */
8468bool CIccTagViewingConditions::Read(icUInt32Number size, CIccIO *pIO)
8469{
8470 icTagTypeSignature sig;
8471
8472 if (sizeof(icTagTypeSignature) +
8473 2*sizeof(icUInt32Number) +
8474 2*sizeof(icXYZNumber) > size)
8475 return false;
8476
8477 if (!pIO) {
8478 return false;
8479 }
8480
8481 if (!pIO->Read32(&sig))
8482 return false;
8483
8484 if (!pIO->Read32(&m_nReserved))
8485 return false;
8486
8487 if (pIO->Read32(&m_XYZIllum.X, 3) != 3)
8488 return false;
8489
8490 if (pIO->Read32(&m_XYZSurround.X, 3) != 3)
8491 return false;
8492
8493 if (!pIO->Read32(&m_illumType))
8494 return false;
8495
8496 return true;
8497}
8498
8499
8500/**
8501 ****************************************************************************
8502 * Name: CIccTagViewingConditions::Write
8503 *
8504 * Purpose: Write the tag to a file
8505 *
8506 * Args:
8507 * pIO - The IO object to write tag to.
8508 *
8509 * Return:
8510 * true = succesful, false = failure
8511 *****************************************************************************
8512 */
8513bool CIccTagViewingConditions::Write(CIccIO *pIO)
8514{
8515 icTagTypeSignature sig = GetType();
8516
8517 if (!pIO)
8518 return false;
8519
8520 if (!pIO->Write32(&sig))
8521 return false;
8522
8523 if (!pIO->Write32(&m_nReserved))
8524 return false;
8525
8526 if (pIO->Write32(&m_XYZIllum.X, 3) !=3)
8527 return false;
8528
8529 if (pIO->Write32(&m_XYZSurround.X, 3) !=3)
8530 return false;
8531
8532 if (!pIO->Write32(&m_illumType))
8533 return false;
8534
8535 return true;
8536}
8537
8538
8539/**
8540 ****************************************************************************
8541 * Name: CIccTagViewingConditions::Describe
8542 *
8543 * Purpose: Dump data associated with the tag to a string
8544 *
8545 * Args:
8546 * sDescription - string to concatenate tag dump to
8547 *****************************************************************************
8548 */
8549void CIccTagViewingConditions::Describe(std::string &sDescription)
8550{
8551 icChar buf[128];
8552 CIccInfo Fmt;
8553
8554 sprintf(buf, "Illuminant Tristimulus values: X = %.4lf, Y = %.4lf, Z = %.4lf\r\n",
8555 icFtoD(m_XYZIllum.X),
8556 icFtoD(m_XYZIllum.Y),
8557 icFtoD(m_XYZIllum.Z));
8558 sDescription += buf;
8559
8560 sprintf(buf, "Surround Tristimulus values: X = %.4lf, Y = %.4lf, Z = %.4lf\r\n",
8561 icFtoD(m_XYZSurround.X),
8562 icFtoD(m_XYZSurround.Y),
8563 icFtoD(m_XYZSurround.Z));
8564 sDescription += buf;
8565
8566 sDescription += "Illuminant Type: ";
8567
8568 sDescription += Fmt.GetIlluminantName(m_illumType);
8569 sDescription += "\r\n";
8570
8571}
8572
8573
8574/**
8575******************************************************************************
8576* Name: CIccTagViewingConditions::Validate
8577*
8578* Purpose: Check tag data validity.
8579*
8580* Args:
8581* sig = signature of tag being validated,
8582* sReport = String to add report information to
8583*
8584* Return:
8585* icValidateStatusOK if valid, or other error status.
8586******************************************************************************
8587*/
8588icValidateStatus CIccTagViewingConditions::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
8589{
8590 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
8591
8592 CIccInfo Info;
8593 std::string sSigPathName = Info.GetSigPathName(sigPath);
8594
8595 rv = icMaxStatus(rv, Info.CheckData(sReport, m_XYZIllum, "XYZ Illuminant"));
8596 rv = icMaxStatus(rv, Info.CheckData(sReport, m_XYZSurround, "XYZ Surround"));
8597
8598 return rv;
8599}
8600
8601
8602/**
8603 ****************************************************************************
8604 * Name: CIccProfileDescText::CIccProfileDescText
8605 *
8606 * Purpose: Constructor
8607 *
8608 *****************************************************************************
8609 */
8610CIccProfileDescText::CIccProfileDescText()
8611{
8612 m_pTag = NULL__null;
8613 m_bNeedsPading = false;
8614}
8615
8616
8617/**
8618 ****************************************************************************
8619 * Name: CIccProfileDescText::CIccProfileDescText
8620 *
8621 * Purpose: Copy Constructor
8622 *
8623 * Args:
8624 * IPDC = The CIccTagUnknown object to be copied
8625 *****************************************************************************
8626 */
8627CIccProfileDescText::CIccProfileDescText(const CIccProfileDescText &IPDC)
8628{
8629 if (IPDC.m_pTag) {
8630 m_pTag = IPDC.m_pTag->NewCopy();
8631 m_bNeedsPading = IPDC.m_bNeedsPading;
8632 }
8633 else {
8634 m_pTag = NULL__null;
8635 m_bNeedsPading = false;
8636 }
8637}
8638
8639
8640/**
8641 ****************************************************************************
8642 * Name: CIccProfileDescText::operator=
8643 *
8644 * Purpose: Copy Operator
8645 *
8646 * Args:
8647 * ProfDescText = The CIccProfileDescText object to be copied
8648 *****************************************************************************
8649 */
8650CIccProfileDescText &CIccProfileDescText::operator=(const CIccProfileDescText &ProfDescText)
8651{
8652 if (&ProfDescText == this)
8653 return *this;
8654
8655 if (m_pTag)
8656 delete m_pTag;
8657
8658 if (ProfDescText.m_pTag) {
8659 m_pTag = ProfDescText.m_pTag->NewCopy();
8660 m_bNeedsPading = ProfDescText.m_bNeedsPading;
8661 }
8662 else {
8663 m_pTag = NULL__null;
8664 m_bNeedsPading = false;
8665 }
8666
8667 return *this;
8668}
8669
8670
8671/**
8672 ****************************************************************************
8673 * Name: CIccProfileDescText::~CIccProfileDescText
8674 *
8675 * Purpose: Destructor
8676 *
8677 *****************************************************************************
8678 */
8679CIccProfileDescText::~CIccProfileDescText()
8680{
8681 if (m_pTag)
8682 delete m_pTag;
8683}
8684
8685
8686/**
8687 ****************************************************************************
8688 * Name: CIccProfileDescText::SetType
8689 *
8690 * Purpose: Sets the type of the profile description text. Could be either
8691 * a MultiLocalizedUnicodeType or a TextDescriptionType.
8692 *
8693 * Args:
8694 * nType = the tag type signature
8695 *
8696 * Return:
8697 * true = successful, false = failure
8698 *****************************************************************************
8699 */
8700bool CIccProfileDescText::SetType(icTagTypeSignature nType)
8701{
8702 if (m_pTag) {
8703 if (m_pTag->GetType() == nType)
8704 return true;
8705
8706 delete m_pTag;
8707 }
8708
8709 if (nType == icSigMultiLocalizedUnicodeType ||
8710 nType == icSigTextDescriptionType)
8711 m_pTag = CIccTag::Create(nType);
8712 else
8713 m_pTag = NULL__null;
8714
8715 return(m_pTag != NULL__null);
8716}
8717
8718
8719/**
8720 ****************************************************************************
8721 * Name: CIccProfileDescText::SetType
8722 *
8723 * Purpose: Gets the type of the profile description text. Could be either
8724 * a MultiLocalizedUnicodeType or a TextDescriptionType.
8725 *
8726 *****************************************************************************
8727 */
8728icTagTypeSignature CIccProfileDescText::GetType() const
8729{
8730 if (m_pTag)
8731 return m_pTag->GetType();
8732
8733 return icSigUnknownType((icTagTypeSignature) 0x3f3f3f3f);
8734}
8735
8736
8737/**
8738 ****************************************************************************
8739 * Name: CIccProfileDescText::Describe
8740 *
8741 * Purpose: Dump data associated with the tag to a string
8742 *
8743 * Args:
8744 * sDescription - string to concatenate tag dump to
8745 *****************************************************************************
8746 */
8747void CIccProfileDescText::Describe(std::string &sDescription)
8748{
8749 if (m_pTag)
8750 m_pTag->Describe(sDescription);
8751}
8752
8753
8754/**
8755 ****************************************************************************
8756 * Name: CIccProfileDescText::Read
8757 *
8758 * Purpose: Read in the tag contents into a data block
8759 *
8760 * Args:
8761 * size - # of bytes in tag,
8762 * pIO - IO object to read tag from
8763 *
8764 * Return:
8765 * true = successful, false = failure
8766 *****************************************************************************
8767 */
8768bool CIccProfileDescText::Read(icUInt32Number size, CIccIO *pIO)
8769{
8770 icTagTypeSignature sig;
8771 icUInt32Number nPos;
8772
8773 //Check for description tag type signature
8774 nPos = pIO->Tell();
8775
8776 if ((nPos&0x03) != 0)
8777 m_bNeedsPading = true;
8778
8779 if (!pIO->Read32(&sig))
8780 return false;
8781 pIO->Seek(nPos, icSeekSet);
8782
8783 if (sig==icSigTextDescriptionType)
8784 m_bNeedsPading = false;
8785
8786 if (!SetType(sig)) {
8787 //We couldn't find it, but we may be looking in the wrong place
8788 //Re-Sync to a 4 byte boundary
8789 pIO->Sync32();
8790
8791 nPos = pIO->Tell();
8792 if (!pIO->Read32(&sig))
8793 return false;
8794 pIO->Seek(nPos, icSeekSet);
8795
8796 if (!SetType(sig)) {
8797 return false;
8798 }
8799 }
8800
8801 if (m_pTag) {
8802 return m_pTag->Read(size, pIO);
8803 }
8804
8805 return false;
8806}
8807
8808
8809/**
8810 ****************************************************************************
8811 * Name: CIccProfileDescText::Write
8812 *
8813 * Purpose: Write the tag to a file
8814 *
8815 * Args:
8816 * pIO - The IO object to write tag to.
8817 *
8818 * Return:
8819 * true = succesful, false = failure
8820 *****************************************************************************
8821 */
8822bool CIccProfileDescText::Write(CIccIO *pIO)
8823{
8824 if (!m_pTag)
8825 return false;
8826
8827 if (m_pTag->Write(pIO)) {
8828 if (m_pTag->GetType() != icSigTextDescriptionType)
8829 return pIO->Align32();
8830 else
8831 return true;
8832 }
8833
8834 return false;
8835}
8836
8837
8838
8839/**
8840 ****************************************************************************
8841 * Name: CIccProfileDescStruct::CIccProfileDescStruct
8842 *
8843 * Purpose: Constructor
8844 *
8845 *****************************************************************************
8846 */
8847CIccProfileDescStruct::CIccProfileDescStruct()
8848{
8849}
8850
8851
8852/**
8853 ****************************************************************************
8854 * Name: CIccProfileDescStruct::CIccProfileDescStruct
8855 *
8856 * Purpose: Copy Constructor
8857 *
8858 * Args:
8859 * IPDS = The CIccProfileDescStruct object to be copied
8860 *****************************************************************************
8861 */
8862CIccProfileDescStruct::CIccProfileDescStruct(const CIccProfileDescStruct &IPDS)
8863{
8864 m_deviceMfg = IPDS.m_deviceMfg;
8865 m_deviceModel = IPDS.m_deviceModel;
8866 m_attributes = IPDS.m_attributes;
8867 m_technology = IPDS.m_technology;
8868 m_deviceMfgDesc = IPDS.m_deviceMfgDesc;
8869 m_deviceModelDesc = IPDS.m_deviceModelDesc;
8870}
8871
8872
8873
8874/**
8875 ****************************************************************************
8876 * Name: CIccProfileDescStruct::operator=
8877 *
8878 * Purpose: Copy Operator
8879 *
8880 * Args:
8881 * ProfDescStruct = The CIccProfileDescStruct object to be copied
8882 *****************************************************************************
8883 */
8884CIccProfileDescStruct &CIccProfileDescStruct::operator=(const CIccProfileDescStruct &ProfDescStruct)
8885{
8886 if (&ProfDescStruct == this)
8887 return *this;
8888
8889 m_deviceMfg = ProfDescStruct.m_deviceMfg;
8890 m_deviceModel = ProfDescStruct.m_deviceModel;
8891 m_attributes = ProfDescStruct.m_attributes;
8892 m_technology = ProfDescStruct.m_technology;
8893 m_deviceMfgDesc = ProfDescStruct.m_deviceMfgDesc;
8894 m_deviceModelDesc = ProfDescStruct.m_deviceModelDesc;
8895
8896 return *this;
8897}
8898
8899
8900
8901/**
8902 ****************************************************************************
8903 * Name: CIccTagProfileSeqDesc::CIccTagProfileSeqDesc
8904 *
8905 * Purpose: Constructor
8906 *
8907 *****************************************************************************
8908 */
8909CIccTagProfileSeqDesc::CIccTagProfileSeqDesc()
8910{
8911 m_Descriptions = new(CIccProfileSeqDesc);
8912}
8913
8914
8915/**
8916 ****************************************************************************
8917 * Name: CIccTagProfileSeqDesc::CIccTagProfileSeqDesc
8918 *
8919 * Purpose: Copy Constructor
8920 *
8921 * Args:
8922 * ITPSD = The CIccTagProfileSeqDesc object to be copied
8923 *****************************************************************************
8924 */
8925CIccTagProfileSeqDesc::CIccTagProfileSeqDesc(const CIccTagProfileSeqDesc &ITPSD)
8926{
8927 m_Descriptions = new(CIccProfileSeqDesc);
8928 *m_Descriptions = *ITPSD.m_Descriptions;
8929}
8930
8931
8932/**
8933 ****************************************************************************
8934 * Name: CIccTagProfileSeqDesc::operator=
8935 *
8936 * Purpose: Copy Operator
8937 *
8938 * Args:
8939 * ProfSeqDescTag = The CIccTagProfileSeqDesc object to be copied
8940 *****************************************************************************
8941 */
8942CIccTagProfileSeqDesc &CIccTagProfileSeqDesc::operator=(const CIccTagProfileSeqDesc &ProfSeqDescTag)
8943{
8944 if (&ProfSeqDescTag == this)
8945 return *this;
8946
8947 *m_Descriptions = *ProfSeqDescTag.m_Descriptions;
8948
8949 return *this;
8950}
8951
8952
8953/**
8954 ****************************************************************************
8955 * Name: CIccTagProfileSeqDesc::~CIccTagProfileSeqDesc
8956 *
8957 * Purpose: Destructor
8958 *
8959 *****************************************************************************
8960 */
8961CIccTagProfileSeqDesc::~CIccTagProfileSeqDesc()
8962{
8963 delete m_Descriptions;
8964}
8965
8966
8967/**
8968 ****************************************************************************
8969 * Name: CIccTagProfileSeqDesc::Read
8970 *
8971 * Purpose: Read in the tag contents into a data block
8972 *
8973 * Args:
8974 * size - # of bytes in tag,
8975 * pIO - IO object to read tag from
8976 *
8977 * Return:
8978 * true = successful, false = failure
8979 *****************************************************************************
8980 */
8981bool CIccTagProfileSeqDesc::Read(icUInt32Number size, CIccIO *pIO)
8982{
8983 icTagTypeSignature sig;
8984 icUInt32Number nCount, nEnd;
8985
8986 nEnd = pIO->Tell() + size;
8987
8988 if (sizeof(icTagTypeSignature) +
8989 sizeof(icUInt32Number)*2 > size)
8990 return false;
8991
8992 if (!pIO) {
8993 return false;
8994 }
8995
8996 if (!pIO->Read32(&sig) ||
8997 !pIO->Read32(&m_nReserved) ||
8998 !pIO->Read32(&nCount))
8999 return false;
9000
9001 if (!nCount)
9002 return true;
9003
9004 if (sizeof(icTagTypeSignature) +
9005 sizeof(icUInt32Number)*2 +
9006 sizeof(CIccProfileDescStruct) > size)
9007 return false;
9008
9009 icUInt32Number i, nPos;
9010 CIccProfileDescStruct ProfileDescStruct;
9011
9012 for (i=0; i<nCount; i++) {
9013
9014 if (!pIO->Read32(&ProfileDescStruct.m_deviceMfg) ||
9015 !pIO->Read32(&ProfileDescStruct.m_deviceModel) ||
9016 !pIO->Read64(&ProfileDescStruct.m_attributes) ||
9017 !pIO->Read32(&ProfileDescStruct.m_technology))
9018 return false;
9019
9020 nPos = pIO->Tell();
9021
9022 if (!ProfileDescStruct.m_deviceMfgDesc.Read(nEnd - nPos, pIO))
9023 return false;
9024
9025 nPos = pIO->Tell();
9026 if (!ProfileDescStruct.m_deviceModelDesc.Read(nEnd - nPos, pIO))
9027 return false;
9028
9029 m_Descriptions->push_back(ProfileDescStruct);
9030 }
9031
9032 return true;
9033}
9034
9035
9036/**
9037 ****************************************************************************
9038 * Name: CIccTagProfileSeqDesc::Write
9039 *
9040 * Purpose: Write the tag to a file
9041 *
9042 * Args:
9043 * pIO - The IO object to write tag to.
9044 *
9045 * Return:
9046 * true = succesful, false = failure
9047 *****************************************************************************
9048 */
9049bool CIccTagProfileSeqDesc::Write(CIccIO *pIO)
9050{
9051 icTagTypeSignature sig = GetType();
9052 icUInt32Number nCount=(icUInt32Number)m_Descriptions->size();
9053
9054 if (!pIO) {
9055 return false;
9056 }
9057
9058 if (!pIO->Write32(&sig) ||
9059 !pIO->Write32(&m_nReserved) ||
9060 !pIO->Write32(&nCount))
9061 return false;
9062
9063 CIccProfileSeqDesc::iterator i;
9064
9065 for (i=m_Descriptions->begin(); i!=m_Descriptions->end(); i++) {
9066
9067 if (!pIO->Write32(&i->m_deviceMfg) ||
9068 !pIO->Write32(&i->m_deviceModel) ||
9069 !pIO->Write64(&i->m_attributes) ||
9070 !pIO->Write32(&i->m_technology))
9071 return false;
9072
9073 if (!i->m_deviceMfgDesc.Write(pIO) ||
9074 !i->m_deviceModelDesc.Write(pIO))
9075 return false;
9076 }
9077
9078 return true;
9079}
9080
9081
9082/**
9083 ****************************************************************************
9084 * Name: CIccTagProfileSeqDesc::Describe
9085 *
9086 * Purpose: Dump data associated with the tag to a string
9087 *
9088 * Args:
9089 * sDescription - string to concatenate tag dump to
9090 *****************************************************************************
9091 */
9092void CIccTagProfileSeqDesc::Describe(std::string &sDescription)
9093{
9094 CIccProfileSeqDesc::iterator i;
9095 icChar buf[128], buf2[28];
9096 icUInt32Number count=0;
9097
9098 sprintf(buf, "Number of Profile Description Structures: %u\r\n", (icUInt32Number)m_Descriptions->size());
9099 sDescription += buf;
9100
9101 for (i=m_Descriptions->begin(); i!=m_Descriptions->end(); i++, count++) {
9102 sDescription += "\r\n";
9103
9104 sprintf(buf, "Profile Description Structure Number [%u] follows:\r\n", count+1);
9105 sDescription += buf;
9106
9107 sprintf(buf, "Device Manufacturer Signature: %s\r\n", icGetSig(buf2, i->m_deviceMfg, false));
9108 sDescription += buf;
9109
9110 sprintf(buf, "Device Model Signature: %s\r\n", icGetSig(buf2, i->m_deviceModel, false));
9111 sDescription += buf;
9112
9113 sprintf(buf, "Device Attributes: %08x%08x\r\n", (icUInt32Number)(i->m_attributes >> 32), (icUInt32Number)(i->m_attributes));
9114 sDescription += buf;
9115
9116 sprintf(buf, "Device Technology Signature: %s\r\n", icGetSig(buf2, i->m_technology, false));
9117 sDescription += buf;
9118
9119 sprintf(buf, "Description of device manufacturer: \r\n");
9120 sDescription += buf;
9121 i->m_deviceMfgDesc.Describe(sDescription);
9122
9123 sprintf(buf, "Description of device model: \r\n");
9124 sDescription += buf;
9125 i->m_deviceModelDesc.Describe(sDescription);
9126 }
9127}
9128
9129
9130/**
9131******************************************************************************
9132* Name: CIccTagProfileSeqDesc::Validate
9133*
9134* Purpose: Check tag data validity.
9135*
9136* Args:
9137* sig = signature of tag being validated,
9138* sReport = String to add report information to
9139*
9140* Return:
9141* icValidateStatusOK if valid, or other error status.
9142******************************************************************************
9143*/
9144icValidateStatus CIccTagProfileSeqDesc::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
9145{
9146 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
9147
9148 CIccInfo Info;
9149 char buf[128];
9150 std::string sSigPathName = Info.GetSigPathName(sigPath);
9151
9152 CIccProfileSeqDesc::iterator i;
9153 for (i=m_Descriptions->begin(); i!=m_Descriptions->end(); i++) {
9154 switch(i->m_technology) {
9155 case 0x00000000: //Technology not defined
9156 case icSigFilmScanner:
9157 case icSigDigitalCamera:
9158 case icSigReflectiveScanner:
9159 case icSigInkJetPrinter:
9160 case icSigThermalWaxPrinter:
9161 case icSigElectrophotographicPrinter:
9162 case icSigElectrostaticPrinter:
9163 case icSigDyeSublimationPrinter:
9164 case icSigPhotographicPaperPrinter:
9165 case icSigFilmWriter:
9166 case icSigVideoMonitor:
9167 case icSigVideoCamera:
9168 case icSigProjectionTelevision:
9169 case icSigCRTDisplay:
9170 case icSigPMDisplay:
9171 case icSigAMDisplay:
9172 case icSigPhotoCD:
9173 case icSigPhotoImageSetter:
9174 case icSigGravure:
9175 case icSigOffsetLithography:
9176 case icSigSilkscreen:
9177 case icSigFlexography:
9178 break;
9179
9180 default:
9181 {
9182 sReport += icMsgValidateNonCompliant;
9183 sReport += sSigPathName;
9184 sprintf(buf, " - %s: Unknown Technology.\r\n", Info.GetSigName(i->m_technology));
9185 sReport += buf;
9186 rv = icMaxStatus(rv, icValidateNonCompliant);
9187 }
9188 }
9189
9190 if (i->m_deviceMfgDesc.m_bNeedsPading) {
9191 sReport += icMsgValidateNonCompliant;
9192 sReport += sSigPathName;
9193
9194 sReport += " Contains non-aligned deviceMfgDesc text tag information\r\n";
9195
9196 rv = icMaxStatus(rv, icValidateNonCompliant);
9197 }
9198
9199 if (i->m_deviceModelDesc.m_bNeedsPading) {
9200 sReport += icMsgValidateNonCompliant;
9201 sReport += sSigPathName;
9202
9203 sReport += " Contains non-aligned deviceModelDesc text tag information\r\n";
9204
9205 rv = icMaxStatus(rv, icValidateNonCompliant);
9206 }
9207
9208 rv = icMaxStatus(rv, i->m_deviceMfgDesc.GetTag()->Validate(sigPath+icGetSigPath(GetType()), sReport, pProfile));
9209 rv = icMaxStatus(rv, i->m_deviceModelDesc.GetTag()->Validate(sigPath+icGetSigPath(GetType()), sReport, pProfile));
9210 }
9211
9212 return rv;
9213}
9214
9215
9216/**
9217 ****************************************************************************
9218 * Name: CIccResponseCurveStruct::CIccResponseCurveStruct
9219 *
9220 * Purpose: Constructor
9221 *
9222 * Args:
9223 * nChannels = number of channels
9224 *
9225 *****************************************************************************
9226 */
9227CIccResponseCurveStruct::CIccResponseCurveStruct(icUInt16Number nChannels/*=0*/)
9228{
9229 m_nChannels = nChannels;
9230 m_maxColorantXYZ = (icXYZNumber*)calloc(nChannels, sizeof(icXYZNumber));
9231 m_Response16ListArray = new CIccResponse16List[nChannels];
9232}
9233
9234
9235/**
9236 ****************************************************************************
9237 * Name: CIccResponseCurveStruct::CIccResponseCurveStruct
9238 *
9239 * Purpose: Constructor
9240 *
9241 * Args:
9242 * sig = measurement unit signature indicating the type of measurement data,
9243 * nChannels = number of channels
9244 *****************************************************************************
9245 */
9246CIccResponseCurveStruct::CIccResponseCurveStruct(icMeasurementUnitSig sig,icUInt16Number nChannels/*=0*/)
9247{
9248 m_nChannels = nChannels;
9249 m_measurementUnitSig = sig;
9250 m_maxColorantXYZ = (icXYZNumber*)calloc(nChannels, sizeof(icXYZNumber));
9251 m_Response16ListArray = new CIccResponse16List[nChannels];
9252}
9253
9254/**
9255 ****************************************************************************
9256 * Name: CIccResponseCurveStruct::CIccResponseCurveStruct
9257 *
9258 * Purpose: Copy Constructor
9259 *
9260 * Args:
9261 * IRCS = The CIccTagUnknown object to be copied
9262 *****************************************************************************
9263 */
9264CIccResponseCurveStruct::CIccResponseCurveStruct(const CIccResponseCurveStruct &IRCS)
9265{
9266 m_nChannels = IRCS.m_nChannels;
9267 m_measurementUnitSig = IRCS.m_measurementUnitSig;
9268
9269 m_maxColorantXYZ = (icXYZNumber*)calloc(m_nChannels, sizeof(icXYZNumber));
9270 memcpy(m_maxColorantXYZ, IRCS.m_maxColorantXYZ, m_nChannels*sizeof(icXYZNumber));
9271
9272 m_Response16ListArray = new CIccResponse16List[m_nChannels];
9273 for (icUInt32Number i=0; i<m_nChannels; i++)
9274 m_Response16ListArray[i] = IRCS.m_Response16ListArray[i];
9275}
9276
9277
9278/**
9279 ****************************************************************************
9280 * Name: CIccResponseCurveStruct::operator=
9281 *
9282 * Purpose: Copy Operator
9283 *
9284 * Args:
9285 * RespCurveStruct = The CIccResponseCurveStruct object to be copied
9286 *****************************************************************************
9287 */
9288CIccResponseCurveStruct &CIccResponseCurveStruct::operator=(const CIccResponseCurveStruct &RespCurveStruct)
9289{
9290 if (&RespCurveStruct == this)
9291 return *this;
9292
9293 m_nChannels = RespCurveStruct.m_nChannels;
9294 m_measurementUnitSig = RespCurveStruct.m_measurementUnitSig;
9295
9296 if (m_maxColorantXYZ)
9297 free(m_maxColorantXYZ);
9298
9299 m_maxColorantXYZ = (icXYZNumber*)calloc(m_nChannels, sizeof(icXYZNumber));
9300 memcpy(m_maxColorantXYZ, RespCurveStruct.m_maxColorantXYZ, m_nChannels*sizeof(icXYZNumber));
9301
9302 if (m_Response16ListArray)
9303 delete [] m_Response16ListArray;
9304 m_Response16ListArray = new CIccResponse16List[m_nChannels];
9305 for (icUInt32Number i=0; i<m_nChannels; i++)
9306 m_Response16ListArray[i] = RespCurveStruct.m_Response16ListArray[i];
9307
9308 return *this;
9309}
9310
9311
9312/**
9313 ****************************************************************************
9314 * Name: CIccResponseCurveStruct::~CIccResponseCurveStruct
9315 *
9316 * Purpose: Destructor
9317 *
9318 *****************************************************************************
9319 */
9320CIccResponseCurveStruct::~CIccResponseCurveStruct()
9321{
9322 if (m_maxColorantXYZ)
9323 free(m_maxColorantXYZ);
9324
9325 if (m_Response16ListArray)
9326 delete [] m_Response16ListArray;
9327}
9328
9329
9330/**
9331 ****************************************************************************
9332 * Name: CIccResponseCurveStruct::Read
9333 *
9334 * Purpose: Read in the tag contents into a data block
9335 *
9336 * Args:
9337 * size - # of bytes in tag,
9338 * pIO - IO object to read tag from
9339 *
9340 * Return:
9341 * true = successful, false = failure
9342 *****************************************************************************
9343 */
9344bool CIccResponseCurveStruct::Read(icUInt32Number size, CIccIO *pIO)
9345{
9346 if (!m_nChannels)
9347 return false;
9348
9349 if (sizeof(icTagTypeSignature) +
9350 m_nChannels * (sizeof(icUInt32Number) +
9351 sizeof(icXYZNumber) +
9352 sizeof(icResponse16Number)) > size)
9353 return false;
9354
9355 if (!pIO) {
9356 return false;
9357 }
9358
9359 if (!pIO->Read32(&m_measurementUnitSig))
9360 return false;
9361
9362 icUInt32Number* nMeasurements = new icUInt32Number[m_nChannels];
9363
9364 if (pIO->Read32(&nMeasurements[0],m_nChannels) != m_nChannels) {
9365 delete[] nMeasurements;
9366 return false;
9367 }
9368
9369 icUInt32Number nNum32 = m_nChannels*sizeof(icXYZNumber)/sizeof(icS15Fixed16Number);
9370 if (pIO->Read32(&m_maxColorantXYZ[0], nNum32) != (icInt32Number)nNum32) {
9371 delete[] nMeasurements;
9372 return false;
9373 }
9374
9375 icResponse16Number nResponse16;
9376 CIccResponse16List nResponseList;
9377
9378 for (int i = 0; i<m_nChannels; i++) {
9379 if (!nResponseList.empty())
9380 nResponseList.clear();
9381 for (int j=0; j<(int)nMeasurements[i]; j++) {
9382 if (!pIO->Read16(&nResponse16.deviceCode) ||
9383 !pIO->Read16(&nResponse16.reserved) ||
9384 !pIO->Read32(&nResponse16.measurementValue)) {
9385 delete[] nMeasurements;
9386 return false;
9387 }
9388 nResponseList.push_back(nResponse16);
9389 }
9390 m_Response16ListArray[i] = nResponseList;
9391 }
9392
9393 delete [] nMeasurements;
9394 return true;
9395}
9396
9397
9398/**
9399 ****************************************************************************
9400 * Name: CIccResponseCurveStruct::Write
9401 *
9402 * Purpose: Write the tag to a file
9403 *
9404 * Args:
9405 * pIO - The IO object to write tag to.
9406 *
9407 * Return:
9408 * true = succesful, false = failure
9409 *****************************************************************************
9410 */
9411bool CIccResponseCurveStruct::Write(CIccIO *pIO)
9412{
9413 if (!m_nChannels)
9414 return false;
9415
9416 icMeasurementUnitSig sig = GetMeasurementType();
9417
9418 if (!pIO) {
9419 return false;
9420 }
9421
9422 if (!pIO->Write32(&sig))
9423 return false;
9424
9425 if (m_nChannels) {
9426
9427 icUInt32Number* nMeasurements = new icUInt32Number[m_nChannels];
9428 for (int i=0; i<m_nChannels; i++)
9429 nMeasurements[i] = (icUInt32Number)m_Response16ListArray[i].size();
9430
9431 if (pIO->Write32(&nMeasurements[0],m_nChannels) != m_nChannels)
9432 return false;
9433 delete [] nMeasurements;
9434
9435 icUInt32Number nNum32 = m_nChannels*sizeof(icXYZNumber)/sizeof(icS15Fixed16Number);
9436 if (pIO->Write32(&m_maxColorantXYZ[0], nNum32) != (icInt32Number)nNum32)
9437 return false;
9438 }
9439 else
9440 return false;
9441
9442 CIccResponse16List nResponseList;
9443 CIccResponse16List::iterator j;
9444
9445 for (int i = 0; i<m_nChannels; i++) {
9446 nResponseList = m_Response16ListArray[i];
9447 for (j=nResponseList.begin(); j!=nResponseList.end(); j++) {
9448 if (!pIO->Write16(&j->deviceCode) ||
9449 !pIO->Write16(&j->reserved) ||
9450 !pIO->Write32(&j->measurementValue))
9451 return false;
9452 }
9453 nResponseList.clear();
9454 }
9455
9456 return true;
9457}
9458
9459
9460/**
9461 ****************************************************************************
9462 * Name: CIccResponseCurveStruct::Describe
9463 *
9464 * Purpose: Dump data associated with the tag to a string
9465 *
9466 * Args:
9467 * sDescription - string to concatenate tag dump to
9468 *****************************************************************************
9469 */
9470void CIccResponseCurveStruct::Describe(std::string &sDescription)
9471{
9472 icChar buf[128];
9473 CIccInfo Fmt;
9474 CIccResponse16List nResponseList;
9475 CIccResponse16List::iterator j;
9476
9477 sDescription += "Measurement Unit: ";
9478 sDescription += Fmt.GetMeasurementUnit((icSignature)GetMeasurementType()); sDescription += "\r\n";
9479
9480
9481 for (int i=0; i<m_nChannels; i++) {
9482 nResponseList = m_Response16ListArray[i];
9483
9484 sDescription += "\r\n";
9485 sprintf(buf, "Maximum Colorant XYZ Measurement for Channel-%u : X=%.4lf, Y=%.4lf, Z=%.4lf\r\n", i+1,
9486 icFtoD(m_maxColorantXYZ[i].X), icFtoD(m_maxColorantXYZ[i].Y), icFtoD(m_maxColorantXYZ[i].Z));
9487 sDescription += buf;
9488
9489 sprintf(buf, "Number of Measurements for Channel-%u : %u\r\n", i+1, (icUInt32Number)nResponseList.size());
9490 sDescription += buf;
9491
9492 sprintf(buf, "Measurement Data for Channel-%u follows:\r\n", i+1);
9493 sDescription += buf;
9494
9495 for (j=nResponseList.begin(); j!=nResponseList.end(); j++) {
9496 sprintf(buf, "Device Value= %u : Measurement Value= %.4lf\r\n", j->deviceCode, icFtoD(j->measurementValue));
9497 sDescription += buf;
9498 }
9499 }
9500}
9501
9502
9503/**
9504******************************************************************************
9505* Name: CIccResponseCurveStruct::Validate
9506*
9507* Purpose: Check tag data validity.
9508*
9509* Args:
9510* sig = signature of tag being validated,
9511* sReport = String to add report information to
9512*
9513* Return:
9514* icValidateStatusOK if valid, or other error status.
9515******************************************************************************
9516*/
9517icValidateStatus CIccResponseCurveStruct::Validate(std::string &sReport)
9518{
9519 icValidateStatus rv = icValidateOK;
9520
9521 CIccInfo Info;
9522 std::string sSigName = Info.GetSigName(m_measurementUnitSig);
9523 switch(m_measurementUnitSig) {
9524 case icSigStatusA:
9525 case icSigStatusE:
9526 case icSigStatusI:
9527 case icSigStatusT:
9528 case icSigStatusM:
9529 case icSigDN:
9530 case icSigDNP:
9531 case icSigDNN:
9532 case icSigDNNP:
9533 break;
9534
9535 default:
9536 sReport += icMsgValidateNonCompliant;
9537 sReport += sSigName;
9538 sReport += " - Unknown measurement unit signature.\r\n";
9539 rv = icMaxStatus(rv, icValidateNonCompliant);
9540 }
9541
9542 if (!m_nChannels) {
9543 sReport += icMsgValidateNonCompliant;
9544 sReport += sSigName;
9545 sReport += " - Incorrect number of channels.\r\n";
9546 rv = icMaxStatus(rv, icValidateNonCompliant);
9547 return rv;
9548 }
9549 for (int i=0; i<m_nChannels; i++) {
9550 rv = icMaxStatus(rv, Info.CheckData(sReport, m_maxColorantXYZ[i], "Max Colorant XYZ"));
9551 }
9552
9553 return rv;
9554}
9555
9556
9557
9558/**
9559 ****************************************************************************
9560 * Name: CIccTagResponseCurveSet16::CIccTagResponseCurveSet16
9561 *
9562 * Purpose: Constructor
9563 *
9564 *****************************************************************************
9565 */
9566CIccTagResponseCurveSet16::CIccTagResponseCurveSet16()
9567{
9568 m_nChannels = 0;
9569
9570 m_ResponseCurves = new(CIccResponseCurveSet);
9571 m_Curve = new(CIccResponseCurveSetIter);
9572 m_Curve->inited = false;
9573}
9574
9575
9576/**
9577 ****************************************************************************
9578 * Name: CIccTagResponseCurveSet16::CIccTagResponseCurveSet16
9579 *
9580 * Purpose: Copy Constructor
9581 *
9582 * Args:
9583 * ITRCS = The CIccTagResponseCurveSet16 object to be copied
9584 *****************************************************************************
9585 */
9586CIccTagResponseCurveSet16::CIccTagResponseCurveSet16(const CIccTagResponseCurveSet16 &ITRCS)
9587{
9588 m_nChannels = ITRCS.m_nChannels;
9589 m_ResponseCurves = new(CIccResponseCurveSet);
9590 *m_ResponseCurves = *ITRCS.m_ResponseCurves;
9591 m_Curve = new(CIccResponseCurveSetIter);
9592 *m_Curve = *ITRCS.m_Curve;
9593}
9594
9595
9596/**
9597 ****************************************************************************
9598 * Name: CIccTagResponseCurveSet16::operator=
9599 *
9600 * Purpose: Copy Operator
9601 *
9602 * Args:
9603 * RespCurveSet16Tag = The CIccTagResponseCurveSet16 object to be copied
9604 *****************************************************************************
9605 */
9606CIccTagResponseCurveSet16 &CIccTagResponseCurveSet16::operator=(const CIccTagResponseCurveSet16 &RespCurveSet16Tag)
9607{
9608 if (&RespCurveSet16Tag == this)
9609 return *this;
9610
9611 if (!m_ResponseCurves->empty())
9612 m_ResponseCurves->clear();
9613
9614 m_nChannels = RespCurveSet16Tag.m_nChannels;
9615 *m_ResponseCurves = *RespCurveSet16Tag.m_ResponseCurves;
9616 *m_Curve = *RespCurveSet16Tag.m_Curve;
9617
9618 return *this;
9619}
9620
9621
9622/**
9623 ****************************************************************************
9624 * Name: CIccTagResponseCurveSet16::~CIccTagResponseCurveSet16
9625 *
9626 * Purpose: Destructor
9627 *
9628 *****************************************************************************
9629 */
9630CIccTagResponseCurveSet16::~CIccTagResponseCurveSet16()
9631{
9632 if (!m_ResponseCurves->empty())
9633 m_ResponseCurves->clear();
9634
9635 delete m_ResponseCurves;
9636 delete m_Curve;
9637}
9638
9639
9640/**
9641 ****************************************************************************
9642 * Name: CIccTagResponseCurveSet16::Read
9643 *
9644 * Purpose: Read in the tag contents into a data block
9645 *
9646 * Args:
9647 * size - # of bytes in tag,
9648 * pIO - IO object to read tag from
9649 *
9650 * Return:
9651 * true = successful, false = failure
9652 *****************************************************************************
9653 */
9654bool CIccTagResponseCurveSet16::Read(icUInt32Number size, CIccIO *pIO)
9655{
9656 icTagTypeSignature sig;
9657
9658 icUInt32Number startPos = pIO->Tell();
9659
9660 unsigned long headerSize = sizeof(icTagTypeSignature) +
9661 sizeof(icUInt32Number) +
9662 sizeof(icUInt16Number) * 2;
9663 if (headerSize > size)
9664 return false;
9665
9666 if (!pIO) {
9667 return false;
9668 }
9669
9670 if (!pIO->Read32(&sig) ||
9671 !pIO->Read32(&m_nReserved))
9672 return false;
9673
9674 icUInt16Number nCountMeasmntTypes;
9675
9676 if (!pIO->Read16(&m_nChannels) ||
9677 !pIO->Read16(&nCountMeasmntTypes))
9678 return false;
9679
9680 if ((icUInt32Number)nCountMeasmntTypes * sizeof(icUInt32Number) > size - headerSize)
9681 return false;
9682
9683 icUInt32Number* nOffset = new icUInt32Number[nCountMeasmntTypes];
9684
9685 if (pIO->Read32(&nOffset[0], nCountMeasmntTypes) != nCountMeasmntTypes) {
9686 delete[] nOffset;
9687 return false;
9688 }
9689
9690 CIccResponseCurveStruct entry;
9691
9692 for (icUInt16Number i=0; i<nCountMeasmntTypes; i++) {
9693 if (nOffset[i] + 4 > size) {
9694 delete[] nOffset;
9695 return false;
9696 }
9697 pIO->Seek(startPos + nOffset[i], icSeekSet);
9698 entry = CIccResponseCurveStruct(m_nChannels);
9699 if (!entry.Read(size-nOffset[i], pIO)) {
9700 delete[] nOffset;
9701 return false;
9702 }
9703
9704 m_ResponseCurves->push_back(entry);
9705 }
9706 delete[] nOffset;
9707
9708
9709 m_Curve->inited = false;
9710
9711 return true;
9712}
9713
9714
9715/**
9716 ****************************************************************************
9717 * Name: CIccTagResponseCurveSet16::Write
9718 *
9719 * Purpose: Write the tag to a file
9720 *
9721 * Args:
9722 * pIO - The IO object to write tag to.
9723 *
9724 * Return:
9725 * true = succesful, false = failure
9726 *****************************************************************************
9727 */
9728bool CIccTagResponseCurveSet16::Write(CIccIO *pIO)
9729{
9730 icTagTypeSignature sig = GetType();
9731 icUInt16Number nCountMeasmntTypes = (icUInt16Number)m_ResponseCurves->size();
9732
9733 if (!pIO) {
9734 return false;
9735 }
9736
9737 icUInt32Number startPos = pIO->GetLength();
9738
9739 if (!pIO->Write32(&sig) ||
9740 !pIO->Write32(&m_nReserved))
9741 return false;
9742
9743
9744 if (!pIO->Write16(&m_nChannels) ||
9745 !pIO->Write16(&nCountMeasmntTypes))
9746 return false;
9747
9748 icUInt32Number offsetPos = pIO->GetLength();
9749 icUInt32Number* nOffset = new icUInt32Number[nCountMeasmntTypes];
9750
9751
9752 int j;
9753 for (j=0; j<nCountMeasmntTypes; j++) {
9754 nOffset[j] = 0;
9755 if (!pIO->Write32(&nOffset[j]))
9756 return false;
9757 }
9758
9759 CIccResponseCurveSet::iterator i;
9760
9761 for (i=m_ResponseCurves->begin(), j=0; i!=m_ResponseCurves->end(); i++, j++) {
9762 nOffset[j] = pIO->GetLength() - startPos;
9763 if (!i->Write(pIO))
9764 return false;
9765 }
9766
9767 icUInt32Number curPOs = pIO->GetLength();
9768
9769 pIO->Seek(offsetPos,icSeekSet);
9770
9771 for (j=0; j<nCountMeasmntTypes; j++) {
9772 if (!pIO->Write32(&nOffset[j]))
9773 return false;
9774 }
9775
9776 pIO->Seek(curPOs,icSeekSet);
9777 delete [] nOffset;
9778
9779 return true;
9780}
9781
9782
9783/**
9784 ****************************************************************************
9785 * Name: CIccTagResponseCurveSet16::Describe
9786 *
9787 * Purpose: Dump data associated with the tag to a string
9788 *
9789 * Args:
9790 * sDescription - string to concatenate tag dump to
9791 *****************************************************************************
9792 */
9793void CIccTagResponseCurveSet16::Describe(std::string &sDescription)
9794{
9795 CIccResponseCurveSet::iterator i;
9796 icChar buf[128];
9797
9798 sprintf(buf, "Number of Channels: %u\r\n", m_nChannels);
9799 sDescription += buf;
9800
9801 sprintf(buf, "Number of Measurement Types used: %u\r\n", (icUInt32Number)m_ResponseCurves->size());
9802 sDescription += buf;
9803
9804 int count = 0;
9805 for (i=m_ResponseCurves->begin(); i!=m_ResponseCurves->end(); i++, count++) {
9806 sDescription += "\r\n";
9807
9808 sprintf(buf, "Response Curve for measurement type [%u] follows:\r\n", count+1);
9809 sDescription += buf;
9810
9811 i->Describe(sDescription);
9812 }
9813}
9814
9815
9816/**
9817 ****************************************************************************
9818 * Name: CIccTagResponseCurveSet16::SetNumChannels
9819 *
9820 * Purpose: Sets the number of channels. This will delete any prior Response
9821 * curves from the set.
9822 *
9823 * Args:
9824 * nChannels = number of channels
9825 *****************************************************************************
9826 */
9827void CIccTagResponseCurveSet16::SetNumChannels(icUInt16Number nChannels)
9828{
9829 m_nChannels = nChannels;
9830
9831 if (!m_ResponseCurves->empty())
9832 m_ResponseCurves->clear();
9833}
9834
9835
9836/**
9837 ****************************************************************************
9838 * Name: CIccTagResponseCurveSet16::NewResponseCurves
9839 *
9840 * Purpose: Creates and adds a new set of response curves to the list.
9841 * SetNumChannels() must be called before calling this function.
9842 *
9843 * Args:
9844 * sig = measurement unit signature
9845 *****************************************************************************
9846 */
9847CIccResponseCurveStruct *CIccTagResponseCurveSet16::NewResponseCurves(icMeasurementUnitSig sig)
9848{
9849 if (!m_nChannels)
9850 return NULL__null;
9851
9852 CIccResponseCurveStruct *pResponseCurveStruct;
9853 pResponseCurveStruct = GetResponseCurves(sig);
9854
9855 if (pResponseCurveStruct)
9856 return pResponseCurveStruct;
9857
9858 CIccResponseCurveStruct entry;
9859 entry = CIccResponseCurveStruct(sig, m_nChannels);
9860 m_ResponseCurves->push_back(entry);
9861 m_Curve->inited = false;
9862
9863 return GetResponseCurves(sig);
9864}
9865
9866
9867/**
9868 ****************************************************************************
9869 * Name: CIccTagResponseCurveSet16::GetResponseCurves
9870 *
9871 * Purpose: Returns pointer to the requested set of response curves
9872 *
9873 * Args:
9874 * sig = measurement unit signature of the response curve set desired
9875 *****************************************************************************
9876 */
9877CIccResponseCurveStruct *CIccTagResponseCurveSet16::GetResponseCurves(icMeasurementUnitSig sig)
9878{
9879 if (!m_nChannels)
9880 return NULL__null;
9881
9882 CIccResponseCurveSet::iterator i;
9883
9884 for (i=m_ResponseCurves->begin(); i!=m_ResponseCurves->end(); i++) {
9885 if (i->GetMeasurementType() == sig)
9886 return (i->GetThis());
9887 }
9888
9889 return NULL__null;
9890}
9891
9892
9893/**
9894 ****************************************************************************
9895 * Name: CIccTagResponseCurveSet16::GetFirstCurves
9896 *
9897 * Purpose: Returns pointer to the first set of response curves in the list.
9898 *
9899 *****************************************************************************
9900 */
9901CIccResponseCurveStruct *CIccTagResponseCurveSet16::GetFirstCurves()
9902{
9903 if (!m_Curve)
9904 return NULL__null;
9905
9906 m_Curve->item = m_ResponseCurves->begin();
9907 if (m_Curve->item == m_ResponseCurves->end()) {
9908 m_Curve->inited = false;
9909 return NULL__null;
9910 }
9911 m_Curve->inited = true;
9912 return m_Curve->item->GetThis();
9913}
9914
9915
9916/**
9917 ****************************************************************************
9918 * Name: CIccTagResponseCurveSet16::GetNextCurves
9919 *
9920 * Purpose: Serves as an iterator for the list containing response curves.
9921 * GetFirstCurves() must be called before calling this function.
9922 *
9923 *****************************************************************************
9924 */
9925CIccResponseCurveStruct *CIccTagResponseCurveSet16::GetNextCurves()
9926{
9927 if (!m_Curve || !m_Curve->inited)
9928 return NULL__null;
9929
9930 m_Curve->item++;
9931 if (m_Curve->item==m_ResponseCurves->end()) {
9932 m_Curve->inited = false;
9933 return NULL__null;
9934 }
9935 return m_Curve->item->GetThis();
9936}
9937
9938
9939/**
9940 ****************************************************************************
9941 * Name: CIccTagResponseCurveSet16::GetNumResponseCurveTypes
9942 *
9943 * Purpose: Get the number of response curve types.
9944 *
9945 *****************************************************************************
9946 */
9947icUInt16Number CIccTagResponseCurveSet16::GetNumResponseCurveTypes() const
9948{
9949 return(icUInt16Number) m_ResponseCurves->size();
9950}
9951
9952
9953/**
9954******************************************************************************
9955* Name: CIccTagResponseCurveSet16::Validate
9956*
9957* Purpose: Check tag data validity.
9958*
9959* Args:
9960* sig = signature of tag being validated,
9961* sReport = String to add report information to
9962*
9963* Return:
9964* icValidateStatusOK if valid, or other error status.
9965******************************************************************************
9966*/
9967icValidateStatus CIccTagResponseCurveSet16::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
9968{
9969 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
9970
9971 CIccInfo Info;
9972 std::string sSigPathName = Info.GetSigPathName(sigPath);
9973
9974 if (!pProfile) {
9975 sReport += icMsgValidateWarning;
9976 sReport += sSigPathName;
9977 sReport += " - Tag validation incomplete: Pointer to profile unavailable.\r\n";
9978 rv = icMaxStatus(rv, icValidateWarning);
9979 return rv;
9980 }
9981
9982 if (m_nChannels!=icGetSpaceSamples(pProfile->m_Header.colorSpace)) {
9983 sReport += icMsgValidateWarning;
9984 sReport += sSigPathName;
9985 sReport += " - Incorrect number of channels.\r\n";
9986 }
9987
9988 if (!GetNumResponseCurveTypes()) {
9989 sReport += icMsgValidateWarning;
9990 sReport += sSigPathName;
9991 sReport += " - Empty Tag!.\r\n";
9992 rv = icMaxStatus(rv, icValidateWarning);
9993 }
9994 else {
9995 CIccResponseCurveSet::iterator i;
9996 for (i=m_ResponseCurves->begin(); i!=m_ResponseCurves->end(); i++) {
9997 rv = icMaxStatus(rv, i->Validate(sReport));
9998 }
9999 }
10000
10001 return rv;
10002}
10003
10004
10005/**
10006 ****************************************************************************
10007 * Name: CIccTagSpectralDataInfo::CIccTagSpectralDataInfo
10008 *
10009 * Purpose: Constructor
10010 *
10011 *****************************************************************************
10012 */
10013CIccTagSpectralDataInfo::CIccTagSpectralDataInfo()
10014{
10015 m_nSig = 0;
10016 memset(&m_spectralRange, 0, sizeof(m_spectralRange));
10017 memset(&m_biSpectralRange, 0, sizeof(m_biSpectralRange));
10018}
10019
10020
10021
10022/**
10023 ****************************************************************************
10024 * Name: CIccTagSpectralDataInfo::CIccTagSpectralDataInfo
10025 *
10026 * Purpose: Copy Constructor
10027 *
10028 * Args:
10029 * ITS = The CIccTagSpectralDataInfo object to be copied
10030 *****************************************************************************
10031 */
10032CIccTagSpectralDataInfo::CIccTagSpectralDataInfo(const CIccTagSpectralDataInfo &ITS)
10033{
10034 m_nSig = ITS.m_nSig;
10035 m_spectralRange = ITS.m_spectralRange;
10036 m_biSpectralRange = ITS.m_biSpectralRange;
10037}
10038
10039
10040
10041/**
10042 ****************************************************************************
10043 * Name: CIccTagSpectralDataInfo::operator=
10044 *
10045 * Purpose: Copy Operator
10046 *
10047 * Args:
10048 * SignatureTag = The CIccTagSignature object to be copied
10049 *****************************************************************************
10050 */
10051CIccTagSpectralDataInfo &CIccTagSpectralDataInfo::operator=(const CIccTagSpectralDataInfo &ITS)
10052{
10053 if (&ITS == this)
10054 return *this;
10055
10056 m_nSig = ITS.m_nSig;
10057 m_spectralRange = ITS.m_spectralRange;
10058 m_biSpectralRange = ITS.m_biSpectralRange;
10059
10060 return *this;
10061}
10062
10063
10064/**
10065 ****************************************************************************
10066 * Name: CIccTagSpectralDataInfo::~CIccTagSpectralDataInfo
10067 *
10068 * Purpose: Destructor
10069 *
10070 *****************************************************************************
10071 */
10072CIccTagSpectralDataInfo::~CIccTagSpectralDataInfo()
10073{
10074}
10075
10076/**
10077 ****************************************************************************
10078 * Name: CIccTagSpectralDataInfo::Read
10079 *
10080 * Purpose: Read in the tag contents into a data block
10081 *
10082 * Args:
10083 * size - # of bytes in tag,
10084 * pIO - IO object to read tag from
10085 *
10086 * Return:
10087 * true = successful, false = failure
10088 *****************************************************************************
10089 */
10090bool CIccTagSpectralDataInfo::Read(icUInt32Number size, CIccIO *pIO)
10091{
10092 icTagTypeSignature sig;
10093
10094 if (sizeof(icTagTypeSignature) + 2*sizeof(icUInt32Number) + 6*sizeof(icUInt16Number) > size)
10095 return false;
10096
10097 if (!pIO) {
10098 m_nSig = 0;
10099 memset(&m_spectralRange, 0, sizeof(m_spectralRange));
10100 memset(&m_biSpectralRange, 0, sizeof(m_biSpectralRange));
10101 return false;
10102 }
10103
10104 if (!pIO->Read32(&sig))
10105 return false;
10106
10107 if (!pIO->Read32(&m_nReserved))
10108 return false;
10109
10110 if (!pIO->Read32(&m_nSig))
10111 return false;
10112
10113 if (!pIO->Read16(&m_spectralRange.start))
10114 return false;
10115
10116 if (!pIO->Read16(&m_spectralRange.end))
10117 return false;
10118
10119 if (!pIO->Read16(&m_spectralRange.steps))
10120 return false;
10121
10122 if (!pIO->Read16(&m_biSpectralRange.start))
10123 return false;
10124
10125 if (!pIO->Read16(&m_biSpectralRange.end))
10126 return false;
10127
10128 if (!pIO->Read16(&m_biSpectralRange.steps))
10129 return false;
10130
10131 return true;
10132}
10133
10134/**
10135 ****************************************************************************
10136 * Name: CIccTagSpectralDataInfo::Write
10137 *
10138 * Purpose: Write the tag to a file
10139 *
10140 * Args:
10141 * pIO - The IO object to write tag to.
10142 *
10143 * Return:
10144 * true = succesful, false = failure
10145 *****************************************************************************
10146 */
10147bool CIccTagSpectralDataInfo::Write(CIccIO *pIO)
10148{
10149 icTagTypeSignature sig = GetType();
10150
10151 if (!pIO)
10152 return false;
10153
10154 if (!pIO->Write32(&sig))
10155 return false;
10156
10157 if (!pIO->Write32(&m_nReserved))
10158 return false;
10159
10160 if (!pIO->Write32(&m_nSig))
10161 return false;
10162
10163 if (!pIO->Write16(&m_spectralRange.start))
10164 return false;
10165
10166 if (!pIO->Write16(&m_spectralRange.end))
10167 return false;
10168
10169 if (!pIO->Write16(&m_spectralRange.steps))
10170 return false;
10171
10172 if (!pIO->Write16(&m_biSpectralRange.start))
10173 return false;
10174
10175 if (!pIO->Write16(&m_biSpectralRange.end))
10176 return false;
10177
10178 if (!pIO->Write16(&m_biSpectralRange.steps))
10179 return false;
10180 return true;
10181}
10182
10183
10184/**
10185 ****************************************************************************
10186 * Name: CIccTagSpectralDataInfo::Describe
10187 *
10188 * Purpose: Dump data associated with the tag to a string
10189 *
10190 * Args:
10191 * sDescription - string to concatenate tag dump to
10192 *****************************************************************************
10193 */
10194void CIccTagSpectralDataInfo::Describe(std::string &sDescription)
10195{
10196 char buf[256];
10197
10198 sDescription += "ColorSignature: ";
10199 sDescription += icGetColorSigStr(buf, m_nSig);
10200 sDescription += "\r\n";
10201
10202 sprintf(buf, "SpectralRange: start %fnm end %fnm with %d steps\r\n", icF16toF(m_spectralRange.start), icF16toF(m_spectralRange.end), m_spectralRange.steps);
10203 sDescription += buf;
10204 if (m_biSpectralRange.steps) {
10205 sprintf(buf, "BiSpectralRange: start %fnm end %fnm with %d steps\r\n", icF16toF(m_spectralRange.start), icF16toF(m_spectralRange.end), m_spectralRange.steps);
10206 sDescription += buf;
10207 }
10208}
10209
10210
10211/**
10212******************************************************************************
10213* Name: CIccTagSpectralDataInfo::Validate
10214*
10215* Purpose: Check tag data validity.
10216*
10217* Args:
10218* sig = signature of tag being validated,
10219* sReport = String to add report information to
10220*
10221* Return:
10222* icValidateStatusOK if valid, or other error status.
10223******************************************************************************
10224*/
10225icValidateStatus CIccTagSpectralDataInfo::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
10226{
10227 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
10228
10229 CIccInfo Info;
10230 std::string sSigPathName = Info.GetSigPathName(sigPath);
10231 icSignature sig = icGetFirstSigPathSig(sigPath);
10232
10233 if (sig==icSigSpectralDataInfoTag && pProfile->m_Header.spectralPCS) {
10234 const icHeader *pHdr = &pProfile->m_Header;
10235
10236 if (m_nSig != pHdr->spectralPCS ||
10237 memcmp(&m_spectralRange, &pHdr->spectralRange, sizeof(m_spectralRange)) ||
10238 memcmp(&m_biSpectralRange, &pHdr->biSpectralRange, sizeof(m_biSpectralRange))) {
10239 sReport += icMsgValidateCriticalError;
10240 sReport += sSigPathName;
10241 sReport += " - SpectralDataInfo should be the same as the profile spectralPCS.\r\n";
10242 rv = icMaxStatus(rv, icValidateCriticalError);
10243 }
10244 }
10245 rv = icMaxStatus(rv, Info.CheckData(sReport, m_spectralRange, "Spectral Range"));
10246 if (m_biSpectralRange.steps)
10247 rv = icMaxStatus(rv, Info.CheckData(sReport, m_biSpectralRange, "Bispectral Range"));
10248 return rv;
10249}
10250
10251
10252/**
10253 ****************************************************************************
10254 * Name: CIccTagSpectralViewingConditions::CIccTagSpectralViewingConditions
10255 *
10256 * Purpose: Constructor
10257 *
10258 *****************************************************************************
10259 */
10260CIccTagSpectralViewingConditions::CIccTagSpectralViewingConditions()
10261{
10262 m_stdObserver = icStdObs1931TwoDegrees;
10263 m_observerRange.start = 0;
10264 m_observerRange.end = 0;
10265 m_observerRange.steps = 0;
10266 m_observer = NULL__null;
10267
10268 m_stdIlluminant = icIlluminantD50;
10269 m_colorTemperature = 5000.0f;
10270
10271 m_illuminantRange.start = 0;
10272 m_illuminantRange.end = 0;
10273 m_illuminantRange.steps = 0;
10274
10275 m_illuminant = 0;
10276
10277 m_illuminantXYZ.X = 0;
10278 m_illuminantXYZ.Y = 0;
10279 m_illuminantXYZ.Z = 0;
10280
10281 m_surroundXYZ.X = 0;
10282 m_surroundXYZ.Y = 0;
10283 m_surroundXYZ.Z = 0;
10284}
10285
10286
10287/**
10288 ****************************************************************************
10289 * Name: CIccTagSpectralViewingConditions::CIccTagSpectralViewingConditions
10290 *
10291 * Purpose: Copy Constructor
10292 *
10293 * Args:
10294 * SVCT = The CIccTagSpectralViewingConditions object to be copied
10295 *****************************************************************************
10296 */
10297CIccTagSpectralViewingConditions::CIccTagSpectralViewingConditions(const CIccTagSpectralViewingConditions &SVCT)
10298{
10299 m_stdObserver = SVCT.m_stdObserver;
10300 m_observerRange.start = SVCT.m_observerRange.start;
10301 m_observerRange.end = SVCT.m_observerRange.end;
10302 m_observerRange.steps = SVCT.m_observerRange.steps;
10303
10304 if (SVCT.m_observer && SVCT.m_observerRange.steps) {
10305 m_observer = new icFloat32Number[SVCT.m_observerRange.steps*3];
10306 if (m_observer) {
10307 memcpy(m_observer, SVCT.m_observer, SVCT.m_observerRange.steps*3*sizeof(icFloat32Number));
10308 }
10309 }
10310 else {
10311 m_observer = NULL__null;
10312 }
10313
10314 m_stdIlluminant = SVCT.m_stdIlluminant;
10315 m_colorTemperature = SVCT.m_colorTemperature;
10316
10317 m_illuminantRange.start = 0;
10318 m_illuminantRange.end = 0;
10319 m_illuminantRange.steps = 0;
10320
10321 if (SVCT.m_illuminant && SVCT.m_illuminantRange.steps) {
10322 m_illuminant = new icFloat32Number[SVCT.m_illuminantRange.steps];
10323 if (m_illuminant) {
10324 memcpy(m_illuminant, SVCT.m_illuminant, SVCT.m_illuminantRange.steps*sizeof(icFloat32Number));
10325 }
10326 }
10327 else {
10328 m_illuminant = NULL__null;
10329 }
10330
10331 m_illuminantXYZ.X = 0;
10332 m_illuminantXYZ.Y = 0;
10333 m_illuminantXYZ.Z = 0;
10334
10335 m_surroundXYZ.X = 0;
10336 m_surroundXYZ.Y = 0;
10337 m_surroundXYZ.Z = 0;
10338}
10339
10340
10341/**
10342 ****************************************************************************
10343 * Name: CIccTagSpectralViewingConditions::operator=
10344 *
10345 * Purpose: Copy Operator
10346 *
10347 * Args:
10348 * specViewCondTag = The CIccTagSpectralViewingConditions object to be copied
10349 *****************************************************************************
10350 */
10351CIccTagSpectralViewingConditions &CIccTagSpectralViewingConditions::operator=(const CIccTagSpectralViewingConditions &SVCT)
10352{
10353 m_stdObserver = SVCT.m_stdObserver;
10354 m_observerRange.start = SVCT.m_observerRange.start;
10355 m_observerRange.end = SVCT.m_observerRange.end;
10356 m_observerRange.steps = SVCT.m_observerRange.steps;
10357
10358 if (SVCT.m_observer && SVCT.m_observerRange.steps) {
10359 m_observer = new icFloat32Number[SVCT.m_observerRange.steps*3];
10360 if (m_observer) {
10361 memcpy(m_observer, SVCT.m_observer, SVCT.m_observerRange.steps*3*sizeof(icFloat32Number));
10362 }
10363 }
10364 else {
10365 m_observer = NULL__null;
10366 }
10367
10368 m_stdIlluminant = SVCT.m_stdIlluminant;
10369 m_colorTemperature = SVCT.m_colorTemperature;
10370
10371 m_illuminantRange.start = 0;
10372 m_illuminantRange.end = 0;
10373 m_illuminantRange.steps = 0;
10374
10375 if (SVCT.m_illuminant && SVCT.m_illuminantRange.steps) {
10376 m_illuminant = new icFloat32Number[SVCT.m_illuminantRange.steps];
10377 if (m_illuminant) {
10378 memcpy(m_illuminant, SVCT.m_illuminant, SVCT.m_illuminantRange.steps*sizeof(icFloat32Number));
10379 }
10380 }
10381 else {
10382 m_illuminant = NULL__null;
10383 }
10384
10385 m_illuminantXYZ.X = 0;
10386 m_illuminantXYZ.Y = 0;
10387 m_illuminantXYZ.Z = 0;
10388
10389 m_surroundXYZ.X = 0;
10390 m_surroundXYZ.Y = 0;
10391 m_surroundXYZ.Z = 0;
10392
10393 return *this;
10394}
10395
10396
10397/**
10398 ****************************************************************************
10399 * Name: CIccTagSpectralViewingConditions::~CIccTagResponseCurveSet16
10400 *
10401 * Purpose: Destructor
10402 *
10403 *****************************************************************************
10404 */
10405CIccTagSpectralViewingConditions::~CIccTagSpectralViewingConditions()
10406{
10407 if (m_observer)
10408 delete [] m_observer;
10409
10410 if (m_illuminant)
10411 delete [] m_illuminant;
10412}
10413
10414
10415/**
10416 ****************************************************************************
10417 * Name: CIccTagSpectralViewingConditions::Read
10418 *
10419 * Purpose: Read in the tag contents into a data block
10420 *
10421 * Args:
10422 * size - # of bytes in tag,
10423 * pIO - IO object to read tag from
10424 *
10425 * Return:
10426 * true = successful, false = failure
10427 *****************************************************************************
10428 */
10429bool CIccTagSpectralViewingConditions::Read(icUInt32Number size, CIccIO *pIO)
10430{
10431 icTagTypeSignature sig;
10432
10433 //check size properly
10434 icUInt32Number headerSize = sizeof(icTagTypeSignature) +
10435 sizeof(icUInt32Number)*4;
10436 if (headerSize > size)
10437 return false;
10438
10439 if (!pIO) {
10440 return false;
10441 }
10442
10443 if (!pIO->Read32(&sig) ||
10444 !pIO->Read32(&m_nReserved))
10445 return false;
10446
10447
10448 if (!pIO->Read32(&m_stdObserver) ||
10449 !pIO->Read16(&m_observerRange.start) ||
10450 !pIO->Read16(&m_observerRange.end) ||
10451 !pIO->Read16(&m_observerRange.steps) ||
10452 !pIO->Read16(&m_reserved2))
10453 return false;
10454
10455 icUInt32Number vals;
10456
10457 if (m_observer) {
10458 delete [] m_observer;
10459 m_observer = NULL__null;
10460 }
10461
10462 icUInt32Number observerSize = 0;
10463
10464 if (m_observerRange.steps) {
10465 vals = m_observerRange.steps * 3;
10466
10467 observerSize = vals * sizeof(icFloat32Number);
10468
10469 if (headerSize + observerSize > size)
10470 return false;
10471
10472 m_observer = new icFloat32Number[vals];
10473 if (!m_observer)
10474 return false;
10475
10476 if (pIO->ReadFloat32Float(&m_observer[0], vals) != vals)
10477 return false;
10478 }
10479
10480 icUInt32Number illumInfoSize = 2 * sizeof(icUInt32Number) + 4 * sizeof(icUInt16Number);
10481 if (headerSize + observerSize +illumInfoSize > size)
10482 return false;
10483
10484 if (!pIO->Read32(&m_stdIlluminant) ||
10485 !pIO->ReadFloat32Float(&m_colorTemperature) ||
10486 !pIO->Read16(&m_illuminantRange.start) ||
10487 !pIO->Read16(&m_illuminantRange.end) ||
10488 !pIO->Read16(&m_illuminantRange.steps) ||
10489 !pIO->Read16(&m_reserved3))
10490 return false;
10491
10492
10493 if (m_illuminant) {
10494 delete [] m_illuminant;
10495 m_illuminant = NULL__null;
10496 }
10497
10498 icUInt32Number illuminantSize = 0;
10499
10500 if (m_illuminantRange.steps) {
10501 vals = m_illuminantRange.steps;
10502
10503 illuminantSize = vals * sizeof(icFloat32Number);
10504
10505 if (headerSize + observerSize + illumInfoSize + illuminantSize > size)
10506 return false;
10507
10508 m_illuminant = new icFloat32Number[vals];
10509 if (!m_illuminant)
10510 return false;
10511
10512 if (pIO->ReadFloat32Float(&m_illuminant[0], vals) != vals)
10513 return false;
10514 }
10515 else {
10516 setIlluminant(m_stdIlluminant, m_illuminantRange, NULL__null, m_colorTemperature);
10517 }
10518
10519 if (headerSize + observerSize + illumInfoSize + illuminantSize + 6*sizeof(icFloat32Number) > size)
10520 return false;
10521
10522 if (pIO->ReadFloat32Float(&m_illuminantXYZ, 3)!=3 ||
10523 pIO->ReadFloat32Float(&m_surroundXYZ, 3)!=3)
10524 return false;
10525
10526 return true;
10527}
10528
10529
10530/**
10531 ****************************************************************************
10532 * Name: CIccTagSpectralViewingConditions::Write
10533 *
10534 * Purpose: Write the tag to a file
10535 *
10536 * Args:
10537 * pIO - The IO object to write tag to.
10538 *
10539 * Return:
10540 * true = succesful, false = failure
10541 *****************************************************************************
10542 */
10543bool CIccTagSpectralViewingConditions::Write(CIccIO *pIO)
10544{
10545 icTagTypeSignature sig = GetType();
10546
10547 if (!pIO) {
10548 return false;
10549 }
10550
10551 if (!pIO->Write32(&sig) ||
10552 !pIO->Write32(&m_nReserved))
10553 return false;
10554
10555
10556 if (!pIO->Write32(&m_stdObserver) ||
10557 !pIO->Write16(&m_observerRange.start) ||
10558 !pIO->Write16(&m_observerRange.end) ||
10559 !pIO->Write16(&m_observerRange.steps) ||
10560 !pIO->Write16(&m_reserved2))
10561 return false;
10562
10563 icUInt32Number vals = m_observerRange.steps*3;
10564
10565 if (vals)
10566 if (pIO->WriteFloat32Float(&m_observer[0], vals) != vals)
10567 return false;
10568
10569 if (!pIO->Write32(&m_stdIlluminant) ||
10570 !pIO->WriteFloat32Float(&m_colorTemperature) ||
10571 !pIO->Write16(&m_illuminantRange.start) ||
10572 !pIO->Write16(&m_illuminantRange.end) ||
10573 !pIO->Write16(&m_illuminantRange.steps) ||
10574 !pIO->Write16(&m_reserved3))
10575 return false;
10576
10577 vals = m_illuminantRange.steps;
10578
10579 if (vals)
10580 if (pIO->WriteFloat32Float(&m_illuminant[0], vals) != vals)
10581 return false;
10582
10583 if (pIO->WriteFloat32Float(&m_illuminantXYZ, 3)!=3 ||
10584 pIO->WriteFloat32Float(&m_surroundXYZ, 3)!=3)
10585 return false;
10586
10587 return true;
10588}
10589
10590
10591/**
10592 ****************************************************************************
10593 * Name: CIccTagSpectralViewingConditions::Describe
10594 *
10595 * Purpose: Dump data associated with the tag to a string
10596 *
10597 * Args:
10598 * sDescription - string to concatenate tag dump to
10599 *****************************************************************************
10600 */
10601void CIccTagSpectralViewingConditions::Describe(std::string &sDescription)
10602{
10603 icChar buf[128];
10604 CIccInfo info;
10605
10606 sprintf(buf, "StdObserver: %s\r\n\r\n", info.GetStandardObserverName(m_stdObserver));
10607 sDescription += buf;
10608
10609 sprintf(buf, "Illuminant Tristimulus values: X = %.4lf, Y = %.4lf, Z = %.4lf\r\n\r\n",
10610 m_illuminantXYZ.X, m_illuminantXYZ.Y,m_illuminantXYZ.Z);
10611 sDescription += buf;
10612
10613 if (m_observer) {
10614 sprintf(buf, "Observer Functions: start=%.1fnm end=%.1fnm, steps=%d\r\n",
10615 icF16toF(m_observerRange.start), icF16toF(m_observerRange.end), m_observerRange.steps);
10616 sDescription += buf;
10617 icFloat32Number *ptr = m_observer;
10618 int i, j;
10619 for (j=0; j<3; j++) {
10620 for (i=0; i<m_observerRange.steps; i++) {
10621 sprintf(buf, " %.4f", *ptr);
10622 sDescription += buf;
10623 ptr++;
10624 }
10625 sDescription += "\r\n\r\n";
10626 }
10627 }
10628 else {
10629 sDescription += "No custom Observer defined\r\n\r\n";
10630 }
10631
10632 sDescription += "StdIlluminant Type: ";
10633
10634 sDescription += info.GetIlluminantName(m_stdIlluminant);
10635 sDescription += "\r\n";
10636
10637 sprintf(buf, "Color Temperature: %.1fK\r\n\r\n", m_colorTemperature);
10638 sDescription += buf;
10639
10640 if (m_illuminant) {
10641 sprintf(buf, "Illuminant SPD: start=%.1fm end=%.1fnm, steps=%d\r\n",
10642 icF16toF(m_illuminantRange.start), icF16toF(m_illuminantRange.end), m_illuminantRange.steps);
10643 sDescription += buf;
10644 icFloat32Number *ptr = m_illuminant;
10645 int i;
10646 for (i=0; i<m_illuminantRange.steps; i++) {
10647 sprintf(buf, " %.4f", *ptr);
10648 sDescription += buf;
10649 ptr++;
10650 }
10651 sDescription += "\r\n\r\n";
10652 }
10653 else {
10654 sDescription += "No custom Observer defined\r\n\r\n";
10655 }
10656
10657 sprintf(buf, "Surround Tristimulus values: X = %.4lf, Y = %.4lf, Z = %.4lf\r\n",
10658 m_surroundXYZ.X, m_surroundXYZ.Y, m_surroundXYZ.Z);
10659 sDescription += buf;
10660}
10661
10662
10663
10664/**
10665******************************************************************************
10666* Name: CIccTagSpectralViewingConditions::Validate
10667*
10668* Purpose: Check tag data validity.
10669*
10670* Args:
10671* sig = signature of tag being validated,
10672* sReport = String to add report information to
10673*
10674* Return:
10675* icValidateStatusOK if valid, or other error status.
10676******************************************************************************
10677*/
10678icValidateStatus CIccTagSpectralViewingConditions::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
10679{
10680 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
10681
10682 CIccInfo Info;
10683 std::string sSigPathName = Info.GetSigPathName(sigPath);
10684
10685 rv = icMaxStatus(rv, Info.CheckData(sReport, m_illuminantXYZ, sSigPathName+":>illuminantXYZ"));
10686 rv = icMaxStatus(rv, Info.CheckData(sReport, m_surroundXYZ, sSigPathName + ":>surroundXYZ"));
10687
10688 rv = icMaxStatus(rv, Info.CheckLuminance(sReport, m_illuminantXYZ, sSigPathName + ":>illuminantXYZ"));
10689 rv = icMaxStatus(rv, Info.CheckLuminance(sReport, m_surroundXYZ, sSigPathName + ":>surroundXYZ"));
10690
10691 if (m_observerRange.steps)
10692 rv = icMaxStatus(rv, Info.CheckData(sReport, m_observerRange, sSigPathName + ":>observerRange"));
10693 if (m_illuminantRange.steps)
10694 rv = icMaxStatus(rv, Info.CheckData(sReport, m_illuminantRange, sSigPathName + ":>illuminantRange"));
10695
10696 return rv;
10697}
10698
10699icFloatNumber *CIccTagSpectralViewingConditions::applyRangeToObserver(const icSpectralRange &newRange) const
10700{
10701 int n = newRange.steps*3;
10702 icFloatNumber *rv = (icFloatNumber*)malloc(n*sizeof(icFloatNumber));
10703
10704 CIccMatrixMath *range = CIccMatrixMath::rangeMap(m_observerRange, newRange);
10705 if (range) {
10706 range->VectorMult(rv, m_observer);
10707 range->VectorMult(&rv[newRange.steps], &m_observer[m_observerRange.steps]);
10708 range->VectorMult(&rv[newRange.steps*2], &m_observer[m_observerRange.steps*2]);
10709 delete range;
10710 }
10711 else {
10712 memcpy(rv, m_observer, m_observerRange.steps*3*sizeof(icFloatNumber));
10713 }
10714
10715 return rv;
10716}
10717
10718CIccMatrixMath *CIccTagSpectralViewingConditions::getObserverMatrix(const icSpectralRange &newRange) const
10719{
10720 CIccMatrixMath *pMtx=new CIccMatrixMath(3, newRange.steps);
10721
10722 CIccMatrixMath *range = CIccPcsXform::rangeMap(m_observerRange, newRange);
10723 if (range) {
10724 range->VectorMult(pMtx->entry(0), m_observer);
10725 range->VectorMult(pMtx->entry(1), &m_observer[m_observerRange.steps]);
10726 range->VectorMult(pMtx->entry(2), &m_observer[m_observerRange.steps*2]);
10727 delete range;
10728 }
10729 else {
10730 memcpy(pMtx->entry(0), m_observer, m_observerRange.steps*3*sizeof(icFloatNumber));
10731 }
10732
10733 return pMtx;
10734}
10735
10736const icFloatNumber *CIccTagSpectralViewingConditions::getIlluminant(icSpectralRange &illumRange) const
10737{
10738 illumRange = m_illuminantRange;
10739 return m_illuminant;
10740}
10741
10742bool CIccTagSpectralViewingConditions::setIlluminant(icIlluminant illumId, const icSpectralRange &illumRange, const icFloatNumber *illum, icFloatNumber illumCCT/* = 0.0f*/)
10743{
10744 m_stdIlluminant = illumId;
10745 m_colorTemperature = illumCCT;
10746
10747 if (m_illuminant) {
10748 free(m_illuminant);
10749 }
10750
10751 m_illuminantRange = illumRange;
10752
10753 if (illumRange.steps && illum) {
10754 icUInt32Number size = illumRange.steps * sizeof(icFloatNumber);
10755 m_illuminant = (icFloatNumber *)malloc(size);
10756 if (m_illuminant)
10757 memcpy(m_illuminant, illum, size);
10758 else {
10759 memset(&m_illuminantRange, 0, sizeof(m_illuminantRange));
10760 return false;
10761 }
10762 }
10763 else {
10764 if (!illum)
10765 memset(&m_illuminantRange, 0, sizeof(m_illuminantRange));
10766
10767 m_illuminant = NULL__null;
10768 }
10769
10770 return true;
10771}
10772
10773bool CIccTagSpectralViewingConditions::setIlluminant(icFloatNumber *pWhiteXYZ)
10774{
10775 icSpectralRange zeroRange;
10776 memset(&zeroRange, 0, sizeof(zeroRange));
10777 icFloatNumber white[3];
10778 white[0] = pWhiteXYZ[0] / pWhiteXYZ[1];
10779 white[1] = 1.0;
10780 white[2] = pWhiteXYZ[2] / pWhiteXYZ[1];
10781
10782 if (!pWhiteXYZ || !icNotZero(pWhiteXYZ[1])((pWhiteXYZ[1])>1.0e-8 || (pWhiteXYZ[1])<-1.0e-8)) {
10783 setIlluminant(icIlluminantUnknown, zeroRange, NULL__null);
10784 return false;
10785 }
10786
10787 if (m_stdObserver == icStdObs1931TwoDegrees) {
10788 if ((icIsNear(white[0], icD50XYZ[0]) && icIsNear(white[2], icD50XYZ[2])) ||
10789 (icIsNear(white[0], 0.9642f, 0.0001f) && icIsNear(white[2], 0.8251f, 0.0001f))) {
10790 return setIlluminant(icIlluminantD50, zeroRange, NULL__null, 5000);
10791 }
10792 else if (icIsNear(white[0], 0.9505f, 0.0001f) && icIsNear(white[2], 1.0888f, 0.0001f)) {
10793 return setIlluminant(icIlluminantD65, zeroRange, NULL__null, 6504);
10794 }
10795 }
10796// else if (m_stdObserver == icStdObs1964TenDegrees) {
10797// setIlluminant(icIlluminantUnknown, zeroRange, NULL);
10798// return false;
10799// }
10800
10801 setIlluminant(icIlluminantUnknown, zeroRange, NULL__null);
10802 return false;
10803}
10804
10805const icFloatNumber *CIccTagSpectralViewingConditions::getObserver(icSpectralRange &observerRange) const
10806{
10807 observerRange = m_observerRange;
10808 return m_observer;
10809}
10810
10811bool CIccTagSpectralViewingConditions::setObserver(icStandardObserver observerId, const icSpectralRange &observerRange, const icFloatNumber *observer)
10812{
10813 m_stdObserver = observerId;
10814 m_observerRange = observerRange;
10815 if (m_observer) {
10816 free(m_observer);
10817 }
10818
10819 if (observerRange.steps && observer) {
10820 icUInt32Number size = observerRange.steps * sizeof(icFloatNumber) * 3;
10821 m_observer = (icFloatNumber *)malloc(size);
10822 if (m_observer)
10823 memcpy(m_observer, observer, size);
10824 else {
10825 memset(&m_observerRange, 0, sizeof(m_observerRange));
10826 return false;
10827 }
10828 }
10829 else {
10830 if (!observer)
10831 memset(&m_observerRange, 0, sizeof(m_illuminantRange));
10832
10833 m_observer = NULL__null;
10834 }
10835
10836 return true;
10837}
10838
10839
10840bool icGetTagText(CIccTag *pTag, std::string &text)
10841{
10842 if (!pTag) {
10843 text = "";
10844 return false;
10845 }
10846 switch (pTag->GetType()) {
10847 case icSigTextType:
10848 {
10849 CIccTagText *pTextTag = (CIccTagText*)pTag;
10850 const char *szText = pTextTag->GetText();
10851 if (szText) {
10852 text = szText;
10853 return true;
10854 }
10855 }
10856 text = "";
10857 return false;
10858
10859 case icSigUtf8TextType:
10860 {
10861 CIccTagUtf8Text *pTextTag = (CIccTagUtf8Text*)pTag;
10862 const char *szText = (const char*)pTextTag->GetText();
10863 if (szText) {
10864 text = szText;
10865 return true;
10866 }
10867 }
10868 text = "";
10869 return false;
10870
10871 case icSigZipUtf8TextType:
10872 {
10873 CIccTagZipUtf8Text *pTextTag = (CIccTagZipUtf8Text*)pTag;
10874 bool rv = pTextTag->GetText(text);
10875 return rv;
10876 }
10877
10878 case icSigUtf16TextType:
10879 {
10880 CIccTagUtf16Text *pTextTag = (CIccTagUtf16Text*)pTag;
10881 const icChar *szText = pTextTag->GetText(text);
10882 if (szText)
10883 return true;
10884 }
10885 return false;
10886
10887 case icSigTextDescriptionType:
10888 {
10889 CIccTagTextDescription *pTextTag = (CIccTagTextDescription*)pTag;
10890 const char *szText = pTextTag->GetText();
10891 if (szText) {
10892 text = szText;
10893 return true;
10894 }
10895 }
10896 text = "";
10897 return false;
10898
10899 case icSigMultiLocalizedUnicodeType:
10900 {
10901 CIccTagMultiLocalizedUnicode *pTextTag = (CIccTagMultiLocalizedUnicode*)pTag;
10902 CIccLocalizedUnicode *pText = pTextTag->Find();
10903 if (pText) {
10904 bool rv = pText->GetText(text);
10905 return rv;
10906 }
10907 }
10908 text = "";
10909 return false;
10910
10911 default:
10912 text = "";
10913 return false;
10914 }
10915}
10916
10917
10918/**
10919****************************************************************************
10920* Name: CIccEmbeddedHeightImage::CIccEmbeddedHeightImage
10921*
10922* Purpose: Constructor
10923*
10924* Args:
10925* nSize =size of embedded image
10926*
10927*****************************************************************************
10928*/
10929CIccTagEmbeddedHeightImage::CIccTagEmbeddedHeightImage(int nSize/*=1*/)
10930{
10931 m_nSize = nSize;
10932 if (m_nSize <1)
10933 m_nSize = 1;
10934 m_pData = (icUInt8Number*)calloc(nSize, sizeof(icUInt8Number));
10935 m_nSeamlesIndicator = 0;
10936 m_nEncodingFormat = icPngImageType;
10937 m_fMetersMinPixelValue = 0;
10938 m_fMetersMaxPixelValue = 0;
10939}
10940
10941
10942/**
10943****************************************************************************
10944* Name: CIccTagEmbeddedHeightImage::CIccTagEmbeddedHeightImage
10945*
10946* Purpose: Copy Constructor
10947*
10948* Args:
10949* ITD = The CIccEmbeddedHeightImage object to be copied
10950*****************************************************************************
10951*/
10952CIccTagEmbeddedHeightImage::CIccTagEmbeddedHeightImage(const CIccTagEmbeddedHeightImage &IEHI)
10953{
10954 m_nSeamlesIndicator = IEHI.m_nSeamlesIndicator;
10955 m_nEncodingFormat = IEHI.m_nEncodingFormat;
10956 m_fMetersMinPixelValue = IEHI.m_fMetersMinPixelValue;
10957 m_fMetersMaxPixelValue = IEHI.m_fMetersMaxPixelValue;
10958 m_nSize = IEHI.m_nSize;
10959
10960 m_pData = (icUInt8Number*)calloc(m_nSize, sizeof(icUInt8Number));
10961 memcpy(m_pData, IEHI.m_pData, sizeof(icUInt8Number)*m_nSize);
10962}
10963
10964
10965/**
10966****************************************************************************
10967* Name: CIccTagEmbeddedHeightImage::operator=
10968*
10969* Purpose: Copy Operator
10970*
10971* Args:
10972* DataTag = The CIccTagData object to be copied
10973*****************************************************************************
10974*/
10975CIccTagEmbeddedHeightImage &CIccTagEmbeddedHeightImage::operator=(const CIccTagEmbeddedHeightImage &HeightImageTag)
10976{
10977 if (&HeightImageTag == this)
10978 return *this;
10979
10980 m_nSeamlesIndicator = HeightImageTag.m_nSeamlesIndicator;
10981 m_nEncodingFormat = HeightImageTag.m_nEncodingFormat;
10982 m_fMetersMinPixelValue = HeightImageTag.m_fMetersMinPixelValue;
10983 m_fMetersMaxPixelValue = HeightImageTag.m_fMetersMaxPixelValue;
10984 m_nSize = HeightImageTag.m_nSize;
10985
10986 if (m_pData)
10987 free(m_pData);
10988 m_pData = (icUInt8Number*)calloc(m_nSize, sizeof(icUInt8Number));
10989 memcpy(m_pData, HeightImageTag.m_pData, sizeof(icUInt8Number)*m_nSize);
10990
10991 return *this;
10992}
10993
10994
10995/**
10996****************************************************************************
10997* Name: CIccTagEmbeddedHeightImage::~CIccTagEmbeddedHeightImage
10998*
10999* Purpose: Destructor
11000*
11001*****************************************************************************
11002*/
11003CIccTagEmbeddedHeightImage::~CIccTagEmbeddedHeightImage()
11004{
11005 if (m_pData)
11006 free(m_pData);
11007}
11008
11009
11010/**
11011****************************************************************************
11012* Name: CIccTagEmbeddedHeightImage::Read
11013*
11014* Purpose: Read in the tag contents into a data block
11015*
11016* Args:
11017* size - # of bytes in tag,
11018* pIO - IO object to read tag from
11019*
11020* Return:
11021* true = successful, false = failure
11022*****************************************************************************
11023*/
11024bool CIccTagEmbeddedHeightImage::Read(icUInt32Number size, CIccIO *pIO)
11025{
11026 icTagTypeSignature sig;
11027
11028 if (sizeof(icTagTypeSignature) +
11029 sizeof(icUInt32Number) +
11030 sizeof(icUInt32Number) +
11031 sizeof(icUInt32Number) +
11032 sizeof(icFloat32Number) +
11033 sizeof(icFloat32Number) +
11034 sizeof(icUInt8Number) > size)
11035 return false;
11036
11037 if (!pIO) {
11038 return false;
11039 }
11040
11041 if (!pIO->Read32(&sig))
11042 return false;
11043
11044 if (!pIO->Read32(&m_nReserved))
11045 return false;
11046
11047 if (!pIO->Read32(&m_nSeamlesIndicator))
11048 return false;
11049
11050 if (!pIO->Read32(&m_nEncodingFormat))
11051 return false;
11052
11053 if (!pIO->ReadFloat32Float(&m_fMetersMinPixelValue))
11054 return false;
11055
11056 if (!pIO->ReadFloat32Float(&m_fMetersMaxPixelValue))
11057 return false;
11058
11059 icUInt32Number nNum = size - 6 * sizeof(icUInt32Number);
11060
11061 if (!SetSize(nNum))
11062 return false;
11063
11064 if (pIO->Read8(m_pData, nNum) != (icInt32Number)nNum)
11065 return false;
11066
11067 return true;
11068}
11069
11070
11071/**
11072****************************************************************************
11073* Name: CIccTagEmbeddedHeightImage::Write
11074*
11075* Purpose: Write the tag to a file
11076*
11077* Args:
11078* pIO - The IO object to write tag to.
11079*
11080* Return:
11081* true = succesful, false = failure
11082*****************************************************************************
11083*/
11084bool CIccTagEmbeddedHeightImage::Write(CIccIO *pIO)
11085{
11086 icTagTypeSignature sig = GetType();
11087
11088 if (!pIO)
11089 return false;
11090
11091 if (!pIO->Write32(&sig))
11092 return false;
11093
11094 if (!pIO->Write32(&m_nReserved))
11095 return false;
11096
11097 if (!pIO->Write32(&m_nSeamlesIndicator))
11098 return false;
11099
11100 if (!pIO->Write32(&m_nEncodingFormat))
11101 return false;
11102
11103 if (!pIO->WriteFloat32Float(&m_fMetersMinPixelValue))
11104 return false;
11105
11106 if (!pIO->WriteFloat32Float(&m_fMetersMaxPixelValue))
11107 return false;
11108
11109 if (pIO->Write8(m_pData, m_nSize) != (icInt32Number)m_nSize)
11110 return false;
11111
11112 return true;
11113}
11114
11115
11116/**
11117****************************************************************************
11118* Name: CIccTagEmbeddedHeightImage::Describe
11119*
11120* Purpose: Dump data associated with the tag to a string
11121*
11122* Args:
11123* sDescription - string to concatenate tag dump to
11124*****************************************************************************
11125*/
11126void CIccTagEmbeddedHeightImage::Describe(std::string &sDescription)
11127{
11128 icChar buf[128];
11129
11130 sprintf(buf, "\r\nSeamlessIndicater: %d\r\n", m_nSeamlesIndicator);
11131 sDescription += buf;
11132
11133 switch (m_nEncodingFormat) {
11134 case icPngImageType:
11135 strcpy(buf, "EncodingFormat: PNG\r\n");
11136 break;
11137 case icTiffImageType:
11138 strcpy(buf, "EncodingFormat: TIFF\r\n");
11139 break;
11140 default:
11141 sprintf(buf, "EncodingFormat: %d", m_nEncodingFormat);
11142 break;
11143 }
11144 sDescription += buf;
11145
11146 sprintf(buf, "Height minimum pixel: %.4fmeters\r\n", m_fMetersMinPixelValue);
11147 sprintf(buf, "Height maximum pixel: %.4fmeters\r\n", m_fMetersMaxPixelValue);
11148
11149 sDescription += "\r\nImage Data:\r\n";
11150
11151 for (int i = 0; i<(int)m_nSize; i++) {
11152 if (!(i & 0x1f))
11153 sDescription += "\r\n";
11154 sprintf(buf, "%02X", m_pData[i]);
11155 sDescription += buf;
11156 }
11157 sDescription += "\r\n";
11158}
11159
11160/**
11161****************************************************************************
11162* Name: CIccTagEmbeddedHeightImage::SetSize
11163*
11164* Purpose: Sets the size of the data array.
11165*
11166* Args:
11167* nSize - number of data entries,
11168* bZeroNew - flag to zero newly formed values
11169*****************************************************************************
11170*/
11171bool CIccTagEmbeddedHeightImage::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
11172{
11173 if (m_nSize == nSize)
11174 return true;
11175
11176 m_pData = (icUInt8Number*)icRealloc(m_pData, nSize * sizeof(icUInt8Number));
11177
11178 if (!m_pData) {
11179 m_nSize = 0;
11180 return false;
11181 }
11182
11183 if (bZeroNew && nSize > m_nSize) {
11184 memset(&m_pData[m_nSize], 0, (nSize - m_nSize) * sizeof(icUInt8Number));
11185 }
11186 m_nSize = nSize;
11187
11188 return true;
11189}
11190
11191
11192/**
11193******************************************************************************
11194* Name: CIccTagEmbeddedHeightImage::Validate
11195*
11196* Purpose: Check tag data validity.
11197*
11198* Args:
11199* sig = signature of tag being validated,
11200* sReport = String to add report information to
11201*
11202* Return:
11203* icValidateStatusOK if valid, or other error status.
11204******************************************************************************
11205*/
11206icValidateStatus CIccTagEmbeddedHeightImage::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
11207{
11208 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
11209
11210 CIccInfo Info;
11211 std::string sSigPathName = Info.GetSigPathName(sigPath);
11212
11213 switch (m_nSeamlesIndicator) {
11214 case 0:
11215 case 1:
11216 break;
11217 default:
11218 sReport += icMsgValidateNonCompliant;
11219 sReport += sSigPathName;
11220 sReport += " - Invalid data flag Seamless Indicator.\r\n";
11221 rv = icMaxStatus(rv, icValidateNonCompliant);
11222 }
11223
11224 switch (m_nEncodingFormat) {
11225 case icPngImageType:
11226 case icTiffImageType:
11227 break;
11228 default:
11229 sReport += icMsgValidateNonCompliant;
11230 sReport += sSigPathName;
11231 sReport += " - Invalid data flag Encoding Image Type.\r\n";
11232 rv = icMaxStatus(rv, icValidateNonCompliant);
11233 }
11234
11235 return rv;
11236}
11237
11238
11239
11240/**
11241****************************************************************************
11242* Name: CIccTagEmbeddedNormalImage::CIccTagEmbeddedNormalImage
11243*
11244* Purpose: Constructor
11245*
11246* Args:
11247* nSize =size of embedded image
11248*
11249*****************************************************************************
11250*/
11251CIccTagEmbeddedNormalImage::CIccTagEmbeddedNormalImage(int nSize/*=1*/)
11252{
11253 m_nSize = nSize;
11254 if (m_nSize < 1)
11255 m_nSize = 1;
11256 m_pData = (icUInt8Number*)calloc(nSize, sizeof(icUInt8Number));
11257 m_nSeamlesIndicator = 0;
11258 m_nEncodingFormat = icPngImageType;
11259}
11260
11261
11262/**
11263****************************************************************************
11264* Name: CIccTagEmbeddedNormalImage::CIccTagEmbeddedNormalImage
11265*
11266* Purpose: Copy Constructor
11267*
11268* Args:
11269* ITD = The CIccEmbeddedNormalImage object to be copied
11270*****************************************************************************
11271*/
11272CIccTagEmbeddedNormalImage::CIccTagEmbeddedNormalImage(const CIccTagEmbeddedNormalImage &IENI)
11273{
11274 m_nSeamlesIndicator = IENI.m_nSeamlesIndicator;
11275 m_nEncodingFormat = IENI.m_nEncodingFormat;
11276 m_nSize = IENI.m_nSize;
11277
11278 m_pData = (icUInt8Number*)calloc(m_nSize, sizeof(icUInt8Number));
11279 memcpy(m_pData, IENI.m_pData, sizeof(icUInt8Number)*m_nSize);
11280}
11281
11282
11283/**
11284****************************************************************************
11285* Name: CIccTagEmbeddedNormalImage::operator=
11286*
11287* Purpose: Copy Operator
11288*
11289* Args:
11290* DataTag = The CIccTagData object to be copied
11291*****************************************************************************
11292*/
11293CIccTagEmbeddedNormalImage &CIccTagEmbeddedNormalImage::operator=(const CIccTagEmbeddedNormalImage &NormalImageTag)
11294{
11295 if (&NormalImageTag == this)
11296 return *this;
11297
11298 m_nSeamlesIndicator = NormalImageTag.m_nSeamlesIndicator;
11299 m_nEncodingFormat = NormalImageTag.m_nEncodingFormat;
11300 m_nSize = NormalImageTag.m_nSize;
11301
11302 if (m_pData)
11303 free(m_pData);
11304 m_pData = (icUInt8Number*)calloc(m_nSize, sizeof(icUInt8Number));
11305 memcpy(m_pData, NormalImageTag.m_pData, sizeof(icUInt8Number)*m_nSize);
11306
11307 return *this;
11308}
11309
11310
11311/**
11312****************************************************************************
11313* Name: CIccTagEmbeddedNormalImage::~CIccTagEmbeddedNormalImage
11314*
11315* Purpose: Destructor
11316*
11317*****************************************************************************
11318*/
11319CIccTagEmbeddedNormalImage::~CIccTagEmbeddedNormalImage()
11320{
11321 if (m_pData)
11322 free(m_pData);
11323}
11324
11325
11326/**
11327****************************************************************************
11328* Name: CIccTagEmbeddedNormalImage::Read
11329*
11330* Purpose: Read in the tag contents into a data block
11331*
11332* Args:
11333* size - # of bytes in tag,
11334* pIO - IO object to read tag from
11335*
11336* Return:
11337* true = successful, false = failure
11338*****************************************************************************
11339*/
11340bool CIccTagEmbeddedNormalImage::Read(icUInt32Number size, CIccIO *pIO)
11341{
11342 icTagTypeSignature sig;
11343
11344 if (sizeof(icTagTypeSignature) +
11345 sizeof(icUInt32Number) +
11346 sizeof(icUInt32Number) +
11347 sizeof(icUInt32Number) +
11348 sizeof(icUInt8Number) > size)
11349 return false;
11350
11351 if (!pIO) {
11352 return false;
11353 }
11354
11355 if (!pIO->Read32(&sig))
11356 return false;
11357
11358 if (!pIO->Read32(&m_nReserved))
11359 return false;
11360
11361 if (!pIO->Read32(&m_nSeamlesIndicator))
11362 return false;
11363
11364 if (!pIO->Read32(&m_nEncodingFormat))
11365 return false;
11366
11367 icUInt32Number nNum = size - 4 * sizeof(icUInt32Number);
11368
11369 if (!SetSize(nNum))
11370 return false;
11371
11372 if (pIO->Read8(m_pData, nNum) != (icInt32Number)nNum)
11373 return false;
11374
11375 return true;
11376}
11377
11378
11379/**
11380****************************************************************************
11381* Name: CIccTagEmbeddedNormalImage::Write
11382*
11383* Purpose: Write the tag to a file
11384*
11385* Args:
11386* pIO - The IO object to write tag to.
11387*
11388* Return:
11389* true = succesful, false = failure
11390*****************************************************************************
11391*/
11392bool CIccTagEmbeddedNormalImage::Write(CIccIO *pIO)
11393{
11394 icTagTypeSignature sig = GetType();
11395
11396 if (!pIO)
11397 return false;
11398
11399 if (!pIO->Write32(&sig))
11400 return false;
11401
11402 if (!pIO->Write32(&m_nReserved))
11403 return false;
11404
11405 if (!pIO->Write32(&m_nSeamlesIndicator))
11406 return false;
11407
11408 if (!pIO->Write32(&m_nEncodingFormat))
11409 return false;
11410
11411 if (pIO->Write8(m_pData, m_nSize) != (icInt32Number)m_nSize)
11412 return false;
11413
11414 return true;
11415}
11416
11417
11418/**
11419****************************************************************************
11420* Name: CIccTagEmbeddedNormalImage::Describe
11421*
11422* Purpose: Dump data associated with the tag to a string
11423*
11424* Args:
11425* sDescription - string to concatenate tag dump to
11426*****************************************************************************
11427*/
11428void CIccTagEmbeddedNormalImage::Describe(std::string &sDescription)
11429{
11430 icChar buf[128];
11431
11432 sprintf(buf, "\r\nSeamlessIndicater: %d\r\n", m_nSeamlesIndicator);
11433 sDescription += buf;
11434
11435 switch (m_nEncodingFormat) {
11436 case icPngImageType:
11437 strcpy(buf, "EncodingFormat: PNG\r\n");
11438 break;
11439 case icTiffImageType:
11440 strcpy(buf, "EncodingFormat: TIFF\r\n");
11441 break;
11442 default:
11443 sprintf(buf, "EncodingFormat: %d", m_nEncodingFormat);
11444 break;
11445 }
11446 sDescription += buf;
11447
11448 sDescription += "\r\nImage Data:\r\n";
11449
11450 for (int i = 0; i < (int)m_nSize; i++) {
11451 if (!(i & 0x1f))
11452 sDescription += "\r\n";
11453 sprintf(buf, "%02X", m_pData[i]);
11454 sDescription += buf;
11455 }
11456 sDescription += "\r\n";
11457}
11458
11459/**
11460****************************************************************************
11461* Name: CIccTagEmbeddedNormalImage::SetSize
11462*
11463* Purpose: Sets the size of the data array.
11464*
11465* Args:
11466* nSize - number of data entries,
11467* bZeroNew - flag to zero newly formed values
11468*****************************************************************************
11469*/
11470bool CIccTagEmbeddedNormalImage::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
11471{
11472 if (m_nSize == nSize)
11473 return true;
11474
11475 m_pData = (icUInt8Number*)icRealloc(m_pData, nSize * sizeof(icUInt8Number));
11476
11477 if (!m_pData) {
11478 m_nSize = 0;
11479 return false;
11480 }
11481
11482 if (bZeroNew && nSize > m_nSize) {
11483 memset(&m_pData[m_nSize], 0, (nSize - m_nSize) * sizeof(icUInt8Number));
11484 }
11485 m_nSize = nSize;
11486
11487 return true;
11488}
11489
11490
11491/**
11492******************************************************************************
11493* Name: CIccTagEmbeddedNormalImage::Validate
11494*
11495* Purpose: Check tag data validity.
11496*
11497* Args:
11498* sig = signature of tag being validated,
11499* sReport = String to add report information to
11500*
11501* Return:
11502* icValidateStatusOK if valid, or other error status.
11503******************************************************************************
11504*/
11505icValidateStatus CIccTagEmbeddedNormalImage::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
11506{
11507 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
11508
11509 CIccInfo Info;
11510 std::string sSigPathName = Info.GetSigPathName(sigPath);
11511
11512 switch (m_nSeamlesIndicator) {
11513 case 0:
11514 case 1:
11515 break;
11516 default:
11517 sReport += icMsgValidateNonCompliant;
11518 sReport += sSigPathName;
11519 sReport += " - Invalid data flag Seamless Indicator.\r\n";
11520 rv = icMaxStatus(rv, icValidateNonCompliant);
11521 }
11522
11523 switch (m_nEncodingFormat) {
11524 case icPngImageType:
11525 if (m_nSize > 4 && m_pData) {
11526 unsigned char PNGhdr[] = { 'P', 'N', 'G' };
11527 if (memcmp(m_pData+1, PNGhdr, 3)) {
11528 sReport += icMsgValidateNonCompliant;
11529 sReport += sSigPathName;
11530 sReport += " - Non-PNG file stored as Embedded image.\r\n";
11531 rv = icMaxStatus(rv, icValidateNonCompliant);
11532 }
11533 }
11534 break;
11535 case icTiffImageType:
11536 if (m_nSize > 4 && m_pData) {
11537 unsigned char IIhdr[] = { 'I', 'I', 42, 0 };
11538 unsigned char MMhdr[] = { 'M', 'M', 0, 42 };
11539
11540 if (memcmp(m_pData, IIhdr, 4) && memcmp(m_pData, MMhdr, 4)) {
11541 sReport += icMsgValidateNonCompliant;
11542 sReport += sSigPathName;
11543 sReport += " - Non-TIFF file stored as Embedded image.\r\n";
11544 rv = icMaxStatus(rv, icValidateNonCompliant);
11545 }
11546 }
11547 break;
11548 default:
11549 sReport += icMsgValidateNonCompliant;
11550 sReport += sSigPathName;
11551 sReport += " - Invalid data flag Encoding Image Type.\r\n";
11552 rv = icMaxStatus(rv, icValidateNonCompliant);
11553 }
11554
11555 return rv;
11556}
11557
11558
11559
11560#ifdef USEREFICCMAXNAMESPACE
11561} //namespace refIccMAX
11562#endif