Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
IccTagBasic.cpp
Go to the documentation of this file.
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 __min
93#include <algorithm>
94using std::min;
95#define __min min
96#endif
97
98#ifdef USEREFICCMAXNAMESPACE
99namespace refIccMAX {
100#endif
101
102// For Describe() nVerboseness levels < 25, maximum length of strings
103#define BRIEF_STRING_SIZE (1024)
104
105/**
106 ****************************************************************************
107 * Name: CIccTag::CIccTag
108 *
109 * Purpose: Constructor
110 *
111 *****************************************************************************
112 */
114{
115 m_nReserved = 0;
116}
117
118/**
119 ****************************************************************************
120 * Name: CIccTag::CIccTag
121 *
122 * Purpose: Destructor
123 *
124 *****************************************************************************
125 */
127{
128
129}
130
131/**
132 ****************************************************************************
133 * Name: CIccTag::Create
134 *
135 * Purpose: This is a static tag creator based upon tag signature type
136 *
137 * Args:
138 * sig = tag type signature
139 *
140 * Return: Pointer to Allocated tag
141 *****************************************************************************
142 */
147
148
149/**
150 ******************************************************************************
151 * Name: CIccTag::Validate
152 *
153 * Purpose: Check tag data validity. In base class we only look at the
154 * tag's reserved data value
155 *
156 * Args:
157 * sig = signature of tag being validated,
158 * sReport = String to add report information to
159 *
160 * Return:
161 * icValidateStatusOK if valid, or other error status.
162 ******************************************************************************
163 */
164icValidateStatus CIccTag::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
165{
167
168 if (m_nReserved != 0) {
169 CIccInfo Info;
170 sReport += icMsgValidateNonCompliant;
171 sReport += Info.GetSigPathName(sigPath);
172 sReport += " - Reserved Value must be zero.\n";
173
175 }
176
177 return rv;
178}
179
180
181/**
182 ****************************************************************************
183 * Name: CIccTagUnknown::CIccTagUnknown
184 *
185 * Purpose: Constructor
186 *
187 *****************************************************************************
188 */
190{
191 m_nType = icSigUnknownType;
192 m_pData = NULL;
193}
194
195/**
196 ****************************************************************************
197 * Name: CIccTagUnknown::CIccTagUnknown
198 *
199 * Purpose: Copy Constructor
200 *
201 * Args:
202 * ITU = The CIccTagUnknown object to be copied
203 *****************************************************************************
204 */
206{
207 m_nSize = ITU.m_nSize;
208 m_nType = ITU.m_nType;
209
210 m_pData = new icUInt8Number[m_nSize];
211 memcpy(m_pData, ITU.m_pData, sizeof(icUInt8Number)*m_nSize);
212}
213
214/**
215 ****************************************************************************
216 * Name: CIccTagUnknown::operator=
217 *
218 * Purpose: Copy Operator
219 *
220 * Args:
221 * UnknownTag = The CIccTagUnknown object to be copied
222 *****************************************************************************
223 */
225{
226 if (&UnknownTag == this)
227 return *this;
228
229 m_nSize = UnknownTag.m_nSize;
230 m_nType = UnknownTag.m_nType;
231
232 if (m_pData)
233 delete [] m_pData;
234 m_pData = new icUInt8Number[m_nSize];
235 memcpy(m_pData, UnknownTag.m_pData, sizeof(icUInt8Number)*m_nSize);
236
237 return *this;
238}
239
240/**
241 ****************************************************************************
242 * Name: CIccTagUnknown::~CIccTagUnknown
243 *
244 * Purpose: Destructor
245 *****************************************************************************
246 */
248{
249 if (m_pData)
250 delete [] m_pData;
251}
252
253
254/**
255 ****************************************************************************
256 * Name: CIccTagUnknown::Read
257 *
258 * Purpose: Read in an unknown tag type into a data block
259 *
260 * Args:
261 * size - # of bytes in tag,
262 * pIO - IO object to read tag from
263 *
264 * Return:
265 * true = successful, false = failure
266 *****************************************************************************
267 */
269{
270 if (m_pData) {
271 delete [] m_pData;
272 m_pData = NULL;
273 }
274
275 if (size<sizeof(icTagTypeSignature) || !pIO) {
276 return false;
277 }
278
279 if (!pIO->Read32(&m_nType))
280 return false;
281
282 m_nSize = size - sizeof(icTagTypeSignature);
283
284 if (m_nSize > 0) { // size could be stored as smaller than expected value, therefore the size check
285
286 m_pData = new icUInt8Number[m_nSize];
287
288 if (pIO->Read8(m_pData, m_nSize) != (icInt32Number)m_nSize) {
289 return false;
290 }
291 } else {
292 return false;
293 }
294
295 return true;
296}
297
298
299/**
300 ****************************************************************************
301 * Name: CIccTagUnknown::Write
302 *
303 * Purpose: Write an unknown tag to a file
304 *
305 * Args:
306 * pIO - The IO object to write tag to.
307 *
308 * Return:
309 * true = succesful, false = failure
310 *****************************************************************************
311 */
313{
314 if (!pIO)
315 return false;
316
317 if (!pIO->Write32(&m_nType))
318 return false;
319
320 if (m_nSize && m_pData) {
321 if (pIO->Write8(m_pData, m_nSize) != (icInt32Number)m_nSize)
322 return false;
323 }
324
325 return true;
326}
327
328
329/**
330 ****************************************************************************
331 * Name: CIccTagUnknown::Describe
332 *
333 * Purpose: Dump data associated with unknown tag to a string
334 *
335 * Args:
336 * sDescription - string to concatenate tag dump to
337 *****************************************************************************
338 */
339void CIccTagUnknown::Describe(std::string &sDescription, int nVerboseness)
340{
341 icChar buf[128];
342
343 sDescription = "Unknown Tag Type of ";
344 sprintf(buf, "%u Bytes.", m_nSize-4);
345 sDescription += buf;
346
347 if (nVerboseness > 50) {
348 sDescription += "\n\nData Follows:\n";
349
350 icMemDump(sDescription, m_pData+4, m_nSize-4);
351 }
352}
353
354
355/**
356 ****************************************************************************
357 * Name: CIccTagText::CIccTagText
358 *
359 * Purpose: Constructor
360 *
361 *****************************************************************************
362 */
364{
365 m_szText = (icChar*)malloc(1);
366 m_szText[0] = '\0';
367 m_nBufSize = 1;
368}
369
370/**
371 ****************************************************************************
372 * Name: CIccTagText::CIccTagText
373 *
374 * Purpose: Copy Constructor
375 *
376 * Args:
377 * ITT = The CIccTagText object to be copied
378 *****************************************************************************
379 */
381{
382 m_szText = (icChar*)malloc(1);
383 m_szText[0] = '\0';
384 m_nBufSize = 1;
385 SetText(ITT.m_szText);
386}
387
388/**
389 ****************************************************************************
390 * Name: CIccTagText::operator=
391 *
392 * Purpose: Copy Operator
393 *
394 * Args:
395 * TextTag = The CIccTagText object to be copied
396 *****************************************************************************
397 */
399{
400 if (&TextTag == this)
401 return *this;
402
403 m_szText = (icChar*)malloc(1);
404 m_szText[0] = '\0';
405 m_nBufSize = 1;
406 SetText(TextTag.m_szText);
407
408 return *this;
409}
410
411/**
412 ****************************************************************************
413 * Name: CIccTagText::~CIccTagText
414 *
415 * Purpose: Destructor
416 *
417 *****************************************************************************
418 */
420{
421 free(m_szText);
422}
423
424/**
425 ****************************************************************************
426 * Name: CIccTagText::Read
427 *
428 * Purpose: Read in a text type tag into a data block
429 *
430 * Args:
431 * size - # of bytes in tag,
432 * pIO - IO object to read tag from
433 *
434 * Return:
435 * true = successful, false = failure
436 *****************************************************************************
437 */
439{
441
442 // Defensive: initialize so error paths all have valid m_szText
443 m_szText[0] = '\0';
444
445 if (size < (sizeof(icTagTypeSignature) + sizeof(icUInt32Number)) || !pIO)
446 return false;
447
448 if (!pIO->Read32(&sig))
449 return false;
450
451 if (!pIO->Read32(&m_nReserved))
452 return false;
453
454 icUInt32Number nSize = size - sizeof(icTagTypeSignature) - sizeof(icUInt32Number);
455
456 icChar *pBuf = GetBuffer(nSize);
457
458 if (nSize) {
459 if (pIO->Read8(pBuf, nSize) != (icInt32Number)nSize) {
460 return false;
461 }
462 }
463
464 Release();
465
466 return true;
467}
468
469/**
470 ****************************************************************************
471 * Name: CIccTagText::Write
472 *
473 * Purpose: Write a text type tag to a file
474 *
475 * Args:
476 * pIO - The IO object to write tag to.
477 *
478 * Return:
479 * true = succesful, false = failure
480 *****************************************************************************
481 */
483{
484 icTagTypeSignature sig = GetType();
485
486 if (!pIO)
487 return false;
488
489 if (!pIO->Write32(&sig))
490 return false;
491
492 if (!pIO->Write32(&m_nReserved))
493 return false;
494
495 if (!m_szText)
496 return false;
497
498 icUInt32Number nSize = (icUInt32Number)strlen(m_szText)+1;
499
500 if (pIO->Write8(m_szText, nSize) != (icInt32Number)nSize)
501 return false;
502
503 return true;
504}
505
506/**
507 ****************************************************************************
508 * Name: CIccTagText::Describe
509 *
510 * Purpose: Dump data associated with the tag to a string
511 *
512 * Args:
513 * sDescription - string to concatenate tag dump to
514 *****************************************************************************
515 */
516void CIccTagText::Describe(std::string &sDescription, int nVerboseness)
517{
518 sDescription += "Text Length = ";
519 if (m_szText && *m_szText) {
520 char buf[40];
521 sprintf(buf, "%zu bytes\n", strlen(m_szText));
522 sDescription += buf;
523 } else
524 sDescription += "0 (NULL)";
525
526 if (nVerboseness > 25) {
527 sDescription += "\"";
528 if (m_szText && *m_szText) {
529 if ((nVerboseness > 50) || (strlen(m_szText) < BRIEF_STRING_SIZE)) {
530 // output entire string if short or doing verbose
531 sDescription += m_szText;
532 }
533 else {
534 // copy just first part of string to keep nVerboseness under control
535 char buf[BRIEF_STRING_SIZE + 1];
536 strncpy(buf, m_szText, BRIEF_STRING_SIZE);
537 buf[BRIEF_STRING_SIZE] = '\0'; // ensure NULL termination
538 sDescription += buf;
539 sDescription += "\n... <!truncated!>";
540 }
541 }
542 sDescription += "\"\n";
543 }
544}
545
546
547/**
548 ****************************************************************************
549 * Name: CIccTagText::SetText
550 *
551 * Purpose: Allows text data associated with the tag to be set.
552 *
553 * Args:
554 * szText - zero terminated string to put in tag
555 *****************************************************************************
556 */
557void CIccTagText::SetText(const icChar *szText)
558{
559 if (!szText)
560 SetText("");
561
562 icUInt32Number len=(icUInt32Number)strlen(szText) + 1;
563 icChar *szBuf = GetBuffer(len);
564
565 strcpy(szBuf, szText);
566 Release();
567}
568
569/**
570 ****************************************************************************
571 * Name: *CIccTagText::operator=
572 *
573 * Purpose: Define assignment operator to associate text with tag.
574 *
575 * Args:
576 * szText - zero terminated string to put in the tag
577 *
578 * Return: A pointer to the string assigned to the tag.
579 *****************************************************************************
580 */
582{
583 SetText(szText);
584 return m_szText;
585}
586
587/**
588 ******************************************************************************
589 * Name: CIccTagText::GetBuffer
590 *
591 * Purpose: This function allocates room and returns pointer to data buffer to
592 * put string into
593 *
594 * Args:
595 * nSize = Requested size of data buffer.
596 *
597 * Return: The character buffer array
598 *******************************************************************************
599 */
601{
602 if (m_nBufSize < nSize) {
603 m_szText = (icChar*)icRealloc(m_szText, nSize+1);
604
605 if (m_szText) {
606 m_szText[nSize] = '\0';
607 m_nBufSize = nSize;
608 }
609 else
610 m_nBufSize = 0;
611 }
612
613 return m_szText;
614}
615
616/**
617 ****************************************************************************
618 * Name: CIccTagText::Release
619 *
620 * Purpose: This will resize the buffer to fit the zero terminated string in
621 * the buffer.
622 *****************************************************************************
623 */
625{
626 icUInt32Number nSize = (icUInt32Number)strlen(m_szText)+1;
627
628 if (nSize < m_nBufSize-1) {
629 m_szText=(icChar*)icRealloc(m_szText, nSize+1);
630 m_nBufSize = nSize+1;
631 }
632}
633
634
635/**
636******************************************************************************
637* Name: CIccTagText::Validate
638*
639* Purpose: Check tag data validity.
640*
641* Args:
642* sig = signature of tag being validated,
643* sReport = String to add report information to
644*
645* Return:
646* icValidateStatusOK if valid, or other error status.
647******************************************************************************
648*/
649icValidateStatus CIccTagText::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
650{
651 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
652
653 CIccInfo Info;
654 std::string sSigPathName = Info.GetSigPathName(sigPath);
656
657 if (m_nBufSize) {
658 switch(sig) {
660 break;
662 if (m_nBufSize<7) {
663 sReport += icMsgValidateNonCompliant;
664 sReport += sSigPathName;
665 sReport += " - Tag must have at least seven text characters.\n";
667 }
668 break;
669 default:
670 sReport += icMsgValidateWarning;
671 sReport += sSigPathName;
672 sReport += " - Unknown Tag.\n";
674 }
675 int i;
676 for (i=0; m_szText[i] && i<(int)m_nBufSize; i++) {
677 if (m_szText[i]&0x80) {
678 sReport += icMsgValidateWarning;
679 sReport += sSigPathName;
680 sReport += " - Text does not contain just 7-bit data.\n";
682 }
683 }
684 }
685 else {
686 sReport += icMsgValidateWarning;
687 sReport += sSigPathName;
688 sReport += " - Empty Tag.\n";
690 }
691
692
693 return rv;
694}
695
696
697
698/**
699 ****************************************************************************
700 * Name: CIccTagUtf8Text::CIccTagUtf8Text
701 *
702 * Purpose: Constructor
703 *
704 *****************************************************************************
705 */
707{
708 m_szText = (icUChar*)malloc(1);
709 m_szText[0] = '\0';
710 m_nBufSize = 1;
711}
712
713/**
714 ****************************************************************************
715 * Name: CIccTagUtf8Text::CIccTagUtf8Text
716 *
717 * Purpose: Copy Constructor
718 *
719 * Args:
720 * ITT = The CIccTagText object to be copied
721 *****************************************************************************
722 */
724{
725 m_szText = (icUChar*)malloc(1);
726 m_szText[0] = '\0';
727 m_nBufSize = 1;
728 SetText(ITT.m_szText);
729}
730
731/**
732 ****************************************************************************
733 * Name: CIccTagUtf8Text::operator=
734 *
735 * Purpose: Copy Operator
736 *
737 * Args:
738 * TextTag = The CIccTagText object to be copied
739 *****************************************************************************
740 */
742{
743 if (&TextTag == this)
744 return *this;
745
746 m_szText = (icUChar*)malloc(1);
747 m_szText[0] = '\0';
748 m_nBufSize = 1;
749 SetText(TextTag.m_szText);
750
751 return *this;
752}
753
754/**
755 ****************************************************************************
756 * Name: CIccTagUtf8Text::~CIccTagUtf8Text
757 *
758 * Purpose: Destructor
759 *
760 *****************************************************************************
761 */
763{
764 free(m_szText);
765}
766
767/**
768 ****************************************************************************
769 * Name: CIccTagUtf8Text::Read
770 *
771 * Purpose: Read in a text type tag into a data block
772 *
773 * Args:
774 * size - # of bytes in tag,
775 * pIO - IO object to read tag from
776 *
777 * Return:
778 * true = successful, false = failure
779 *****************************************************************************
780 */
782{
784
785 if (size<sizeof(icTagTypeSignature) || !pIO) {
786 m_szText[0] = '\0';
787 return false;
788 }
789
790 if (!pIO->Read32(&sig))
791 return false;
792
793 if (!pIO->Read32(&m_nReserved))
794 return false;
795
796 if (size < sizeof(icTagTypeSignature) + sizeof(icUInt32Number))
797 return false;
798
799 icUInt32Number nSize = size - sizeof(icTagTypeSignature) - sizeof(icUInt32Number);
800
801 icUChar *pBuf = GetBuffer(nSize);
802
803 if (nSize) {
804 if (pIO->Read8(pBuf, nSize) != (icInt32Number)nSize) {
805 return false;
806 }
807 }
808
809 Release();
810
811 return true;
812}
813
814/**
815 ****************************************************************************
816 * Name: CIccTagUtf8Text::Write
817 *
818 * Purpose: Write a text type tag to a file
819 *
820 * Args:
821 * pIO - The IO object to write tag to.
822 *
823 * Return:
824 * true = succesful, false = failure
825 *****************************************************************************
826 */
828{
829 icTagTypeSignature sig = GetType();
830
831 if (!pIO)
832 return false;
833
834 if (!pIO->Write32(&sig))
835 return false;
836
837 if (!pIO->Write32(&m_nReserved))
838 return false;
839
840 if (!m_szText)
841 return false;
842
843 icUInt32Number nSize = (icUInt32Number)strlen((icChar*)m_szText)+1;
844
845 if (pIO->Write8(m_szText, nSize) != (icInt32Number)nSize)
846 return false;
847
848 return true;
849}
850
851/**
852 ****************************************************************************
853 * Name: CIccTagUtf8Text::Describe
854 *
855 * Purpose: Dump data associated with the tag to a string
856 *
857 * Args:
858 * sDescription - string to concatenate tag dump to
859 *****************************************************************************
860 */
861void CIccTagUtf8Text::Describe(std::string &sDescription, int nVerboseness)
862{
863 sDescription += "UTF8 Length = ";
864 if (m_szText && *m_szText) {
865 char buf[40];
866 sprintf(buf, "%d bytes\n", m_nBufSize);
867 sDescription += buf;
868 }
869 else
870 sDescription += "0 (NULL)";
871
872 if (nVerboseness > 25) {
873 sDescription += "\"";
874 if (m_szText && *m_szText) {
875 if ((nVerboseness > 50) || (m_nBufSize < BRIEF_STRING_SIZE)) {
876 // output entire string if short or doing verbose output
877 sDescription += (icChar*)m_szText;
878 }
879 else {
880 // copy just first part of string to keep nVerboseness under control
881 char buf[BRIEF_STRING_SIZE + 1];
882 strncpy(buf, (icChar*)m_szText, BRIEF_STRING_SIZE);
883 buf[BRIEF_STRING_SIZE] = '\0'; // ensure NULL termination
884 sDescription += buf;
885 sDescription += "\n... <!truncated!>";
886 }
887 }
888 sDescription += "\"\n";
889 }
890}
891
892
893/**
894 ****************************************************************************
895 * Name: CIccTagUtf8Text::SetText
896 *
897 * Purpose: Allows text data associated with the tag to be set.
898 *
899 * Args:
900 * szText - zero terminated string to put in tag
901 *****************************************************************************
902 */
904{
905 if (!szText)
906 SetText("");
907
908 icUInt32Number len=(icUInt32Number)strlen((icChar*)szText) + 1;
909 icUChar *szBuf = GetBuffer(len);
910
911 strcpy((icChar*)szBuf, (icChar*)szText);
912 Release();
913}
914
915
916/**
917 ****************************************************************************
918 * Name: CIccTagUtf8Text::SetText
919 *
920 * Purpose: Allows text data associated with the tag to be set.
921 *
922 * Args:
923 * szText - zero terminated string to put in tag
924 *****************************************************************************
925 */
927{
928 if (!szText)
929 SetText("");
930
931 icUtf8Vector text;
932 icUInt32Number len;
933 for (len=0; szText[len]; len++);
934
935 icConvertUTF16toUTF8(szText, &szText[len], text, lenientConversion);
936
937 SetText((const icUChar*)&text[0]);
938}
939
940/**
941 ****************************************************************************
942 * Name: *CIccTagUtf8Text::operator=
943 *
944 * Purpose: Define assignment operator to associate text with tag.
945 *
946 * Args:
947 * szText - zero terminated string to put in the tag
948 *
949 * Return: A pointer to the string assigned to the tag.
950 *****************************************************************************
951 */
953{
954 SetText(szText);
955 return (icUChar*)m_szText;
956}
957
958/**
959 ******************************************************************************
960 * Name: CIccTagUtf8Text::GetBuffer
961 *
962 * Purpose: This function allocates room and returns pointer to data buffer to
963 * put string into
964 *
965 * Args:
966 * nSize = Requested size of data buffer.
967 *
968 * Return: The character buffer array
969 *******************************************************************************
970 */
972{
973 if (m_nBufSize < nSize) {
974 m_szText = (icUChar*)icRealloc(m_szText, nSize+1);
975
976 if (m_szText) {
977 m_szText[nSize] = '\0';
978 m_nBufSize = nSize;
979 }
980 else {
981 m_nBufSize = 0;
982 }
983 }
984
985 return m_szText;
986}
987
988/**
989 ****************************************************************************
990 * Name: CIccTagUtf8Text::Release
991 *
992 * Purpose: This will resize the buffer to fit the zero terminated string in
993 * the buffer.
994 *****************************************************************************
995 */
997{
998 icUInt32Number nSize = (icUInt32Number)strlen((icChar*)m_szText)+1;
999
1000 if (nSize < m_nBufSize-1) {
1001 m_szText=(icUChar*)icRealloc(m_szText, nSize+1);
1002 m_nBufSize = nSize+1;
1003 }
1004}
1005
1006
1007/**
1008******************************************************************************
1009* Name: CIccTagUtf8Text::Validate
1010*
1011* Purpose: Check tag data validity.
1012*
1013* Args:
1014* sig = signature of tag being validated,
1015* sReport = String to add report information to
1016*
1017* Return:
1018* icValidateStatusOK if valid, or other error status.
1019******************************************************************************
1020*/
1021icValidateStatus CIccTagUtf8Text::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
1022{
1023 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
1024
1025 CIccInfo Info;
1026 std::string sSigPathName = Info.GetSigPathName(sigPath);
1027
1028 if (!m_nBufSize) {
1029 sReport += icMsgValidateWarning;
1030 sReport += sSigPathName;
1031 sReport += " - Empty Tag.\n";
1033 }
1034
1035
1036 return rv;
1037}
1038
1039
1040static unsigned char icFaultyXmlZipData[4] = { 0,0,0,1 };
1041
1042/**
1043 ****************************************************************************
1044 * Name: CIccTagZipUtf8Text::CIccTagZipUtf8Text
1045 *
1046 * Purpose: Constructor
1047 *
1048 *****************************************************************************
1049 */
1051{
1052 m_pZipBuf = NULL;
1053 m_nBufSize = 0;
1054}
1055
1056/**
1057 ****************************************************************************
1058 * Name: CIccTagZipUtf8Text::CIccTagZipUtf8Text
1059 *
1060 * Purpose: Copy Constructor
1061 *
1062 * Args:
1063 * ITT = The CIccTagText object to be copied
1064 *****************************************************************************
1065 */
1067{
1068 m_pZipBuf = NULL;
1069 m_nBufSize = 0;
1070 AllocBuffer(ITT.BufferSize());
1071 if (m_pZipBuf) {
1072 memcpy(m_pZipBuf, ITT.GetBuffer(), m_nBufSize);
1073 }
1074}
1075
1076/**
1077 ****************************************************************************
1078 * Name: CIccTagZipUtf8Text::operator=
1079 *
1080 * Purpose: Copy Operator
1081 *
1082 * Args:
1083 * TextTag = The CIccTagText object to be copied
1084 *****************************************************************************
1085 */
1087{
1088 if (&ITT == this)
1089 return *this;
1090
1091 AllocBuffer(ITT.BufferSize());
1092 if (m_pZipBuf) {
1093 memcpy(m_pZipBuf, ITT.GetBuffer(), m_nBufSize);
1094 }
1095
1096 return *this;
1097}
1098
1099/**
1100 ****************************************************************************
1101 * Name: CIccTagZipUtf8Text::~CIccTagZipUtf8Text
1102 *
1103 * Purpose: Destructor
1104 *
1105 *****************************************************************************
1106 */
1108{
1109 if (m_pZipBuf)
1110 free(m_pZipBuf);
1111}
1112
1113/**
1114 ****************************************************************************
1115 * Name: CIccTagZipUtf8Text::Read
1116 *
1117 * Purpose: Read in a text type tag into a data block
1118 *
1119 * Args:
1120 * size - # of bytes in tag,
1121 * pIO - IO object to read tag from
1122 *
1123 * Return:
1124 * true = successful, false = failure
1125 *****************************************************************************
1126 */
1128{
1130
1131 if (size<sizeof(icTagTypeSignature) || !pIO) {
1132 AllocBuffer(0);
1133 return false;
1134 }
1135
1136 if (!pIO->Read32(&sig))
1137 return false;
1138
1139 if (!pIO->Read32(&m_nReserved))
1140 return false;
1141
1142 icUInt32Number nSize = size - sizeof(icTagTypeSignature) - sizeof(icUInt32Number);
1143
1144 icUChar *pBuf = AllocBuffer(nSize);
1145
1146 if (m_nBufSize && pBuf) {
1147 if (pIO->Read8(pBuf, m_nBufSize) != (icInt32Number)m_nBufSize) {
1148 return false;
1149 }
1150 }
1151
1152 return true;
1153}
1154
1155/**
1156 ****************************************************************************
1157 * Name: CIccTagZipUtf8Text::Write
1158 *
1159 * Purpose: Write a text type tag to a file
1160 *
1161 * Args:
1162 * pIO - The IO object to write tag to.
1163 *
1164 * Return:
1165 * true = succesful, false = failure
1166 *****************************************************************************
1167 */
1169{
1170 icTagTypeSignature sig = GetType();
1171
1172 if (!pIO)
1173 return false;
1174
1175 if (!pIO->Write32(&sig))
1176 return false;
1177
1178 if (!pIO->Write32(&m_nReserved))
1179 return false;
1180
1181 if (m_pZipBuf) {
1182 if (pIO->Write8(m_pZipBuf, m_nBufSize) != (icInt32Number)m_nBufSize)
1183 return false;
1184 }
1185 return true;
1186}
1187
1188/**
1189 ****************************************************************************
1190 * Name: CIccTagZipUtf8Text::Describe
1191 *
1192 * Purpose: Dump data associated with the tag to a string
1193 *
1194 * Args:
1195 * sDescription - string to concatenate tag dump to
1196 *****************************************************************************
1197 */
1198void CIccTagZipUtf8Text::Describe(std::string &sDescription, int nVerboseness)
1199{
1200 std::string str;
1201#ifdef ICC_USE_ZLIB
1202 if (!GetText(str)) {
1203 sDescription += "Error! - Unable to decompress text data.\n";
1204 }
1205 else if (m_nBufSize > 4 && !memcmp(m_pZipBuf, icFaultyXmlZipData, 4)) {
1206 sDescription += "Warning! - Correcting for improperly encoded ";
1207 sDescription += CIccTagCreator::GetTagTypeSigName(GetType());
1208 sDescription += " tag.\n\n";
1209 }
1210
1211 sDescription += "ZLib Compressed String=\"";
1212 sDescription += str;
1213 sDescription += "\"\n";
1214#else
1215 char size[30];
1216 sprintf(size, "%d", m_nBufSize);
1217 sDescription += "BEGIN_COMPESSED_DATA[\"";
1218 sDescription += size;
1219 sDescription += "]\n";
1220 if (m_nBufSize) {
1221 icMemDump(str, m_pZipBuf, m_nBufSize);
1222 sDescription += str;
1223 sDescription += "\n";
1224 }
1225 sDescription += "END_COMPRESSED_DATA\n";
1226#endif
1227}
1228
1229/**
1230 ****************************************************************************
1231 * Name: CIccTagZipUtf8Text::GetText
1232 *
1233 * Purpose: Allows text data associated with the tag to be set.
1234 *
1235 * Args:
1236 * text - string to put uncompressed text into
1237 *****************************************************************************
1238 */
1239bool CIccTagZipUtf8Text::GetText(std::string &str) const
1240{
1241#ifndef ICC_USE_ZLIB
1242 str="";
1243 return false;
1244#else
1245 int zstat;
1246 z_stream zstr;
1247 memset(&zstr, 0, sizeof(zstr));
1248 unsigned char buf[32767] = { 0 };
1249
1250 zstat = inflateInit(&zstr);
1251
1252 if (zstat != Z_OK) {
1253 return false;
1254 }
1255
1256 zstat = inflateReset(&zstr);
1257
1258 if (zstat != Z_OK) {
1259 return false;
1260 }
1261
1262 if (m_nBufSize > 4 && !memcmp(m_pZipBuf, icFaultyXmlZipData, 4)) {
1263 //xrite creates invalid zipXMLType tags
1264 zstr.next_in = m_pZipBuf+4;
1265 zstr.avail_in = m_nBufSize-4;
1266 }
1267 else {
1268 zstr.next_in = m_pZipBuf;
1269 zstr.avail_in = m_nBufSize;
1270 }
1271
1272 do {
1273 unsigned int i, n;
1274
1275 zstr.next_out = buf;
1276 zstr.avail_out = sizeof(buf);
1277
1278 zstat = inflate(&zstr, Z_SYNC_FLUSH);
1279
1280 if (zstat != Z_OK && zstat != Z_STREAM_END) {
1281 inflateEnd(&zstr);
1282 return false;
1283 }
1284
1285 n = sizeof(buf) - zstr.avail_out;
1286
1287 for (i = 0; i < n; i++) {
1288 str += buf[i];
1289 }
1290 } while (zstat != Z_STREAM_END);
1291
1292 inflateEnd(&zstr);
1293
1294 return true;
1295#endif
1296}
1297
1298
1299/**
1300 ****************************************************************************
1301 * Name: CIccTagZipUtf8Text::SetText
1302 *
1303 * Purpose: Allows text data associated with the tag to be set.
1304 *
1305 * Args:
1306 * szText - zero terminated string to put in tag
1307 *****************************************************************************
1308 */
1310{
1311#ifndef ICC_USE_ZLIB
1312 return false;
1313#else
1314 icUInt32Number nSize = (icUInt32Number)strlen((const char*)szText) + 1;
1315 icUtf8Vector compress;
1316 int i;
1317
1318 int zstat;
1319 z_stream zstr;
1320 unsigned char buf[32767];
1321 memset(&zstr, 0, sizeof(zstr));
1322
1323 zstat = deflateInit(&zstr, Z_DEFAULT_COMPRESSION);
1324
1325 if (zstat != Z_OK) {
1326 return false;
1327 }
1328
1329 zstat = deflateReset(&zstr);
1330 zstr.next_in = (Bytef*)szText;
1331 zstr.avail_in = nSize;
1332
1333 if (zstat != Z_OK) {
1334 return false;
1335 }
1336
1337
1338 do {
1339 int n;
1340 zstr.next_out = buf;
1341 zstr.avail_out = sizeof(buf);
1342
1343 zstat = deflate(&zstr, Z_FINISH);
1344
1345 if (zstat != Z_OK && zstat != Z_STREAM_END) {
1346 deflateEnd(&zstr);
1347 return false;
1348 }
1349
1350 n = sizeof(buf) - zstr.avail_out;
1351
1352 for (i = 0; i < n; i++) {
1353 compress.push_back(buf[i]);
1354 }
1355 } while (zstat != Z_STREAM_END);
1356
1357 deflateEnd(&zstr);
1358
1359 icUChar *pBuf = AllocBuffer((icUInt32Number)compress.size());
1360
1361 if (pBuf) {
1362 for (i = 0; i < (int)m_nBufSize; i++) {
1363 pBuf[i] = compress[i];
1364}
1365 }
1366
1367 return true;
1368#endif
1369}
1370
1371/**
1372 ****************************************************************************
1373 * Name: CIccTagZipUtf8Text::SetText
1374 *
1375 * Purpose: Allows text data associated with the tag to be set.
1376 *
1377 * Args:
1378 * szText - zero terminated string to put in tag
1379 *****************************************************************************
1380 */
1382{
1383 if (!szText)
1384 return SetText("");
1385
1386 icUtf8Vector text;
1387 icUInt32Number len;
1388 for (len=0; szText[len]; len++);
1389
1390 icConvertUTF16toUTF8(szText, &szText[len], text, lenientConversion);
1391
1392 return SetText((const icUChar*)&text[0]);
1393}
1394
1395
1396
1397/**
1398 ******************************************************************************
1399 * Name: CIccTagZipUtf8Text::AllocBuffer
1400 *
1401 * Purpose: This function allocates room and returns pointer to data buffer to
1402 * put string into
1403 *
1404 * Args:
1405 * nSize = Requested size of data buffer.
1406 *
1407 * Return: The character buffer array
1408 *******************************************************************************
1409 */
1411{
1412 if (m_nBufSize != nSize) {
1413 if (!nSize) {
1414 if (m_pZipBuf)
1415 free(m_pZipBuf);
1416
1417 m_nBufSize = nSize;
1418 return NULL;
1419 }
1420
1421 if (!m_nBufSize)
1422 m_pZipBuf = (icUChar*)malloc(nSize);
1423 else
1424 m_pZipBuf = (icUChar*)icRealloc(m_pZipBuf, nSize);
1425
1426 m_nBufSize = nSize;
1427
1428 }
1429
1430 return m_pZipBuf;
1431}
1432
1433
1434/**
1435******************************************************************************
1436* Name: CIccTagZipUtf8Text::Validate
1437*
1438* Purpose: Check tag data validity.
1439*
1440* Args:
1441* sig = signature of tag being validated,
1442* sReport = String to add report information to
1443*
1444* Return:
1445* icValidateStatusOK if valid, or other error status.
1446******************************************************************************
1447*/
1448icValidateStatus CIccTagZipUtf8Text::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
1449{
1450 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
1451
1452 CIccInfo Info;
1453 std::string sSigPathName = Info.GetSigPathName(sigPath);
1454
1455 if (!m_nBufSize) {
1456 sReport += icMsgValidateWarning;
1457 sReport += sSigPathName;
1458 sReport += " - Empty Tag.\n";
1460 }
1461 else {
1462#ifdef ICC_USE_ZLIB
1463 std::string sText;
1464 if (!GetText(sText)) {
1465 sReport += icMsgValidateNonCompliant;
1466 sReport += sSigPathName;
1467 sReport += " - Unable to get text for tag (possibly corrupt compressed data).\n";
1469 }
1470 else if (m_nBufSize > 4 && !memcmp(m_pZipBuf, icFaultyXmlZipData, 4)) {
1471 sReport += icMsgValidateNonCompliant;
1472 sReport += sSigPathName;
1473 sReport += " - Improperly encoded ";
1474 sReport += CIccTagCreator::GetTagTypeSigName(GetType());
1475 sReport += " tag.\n";
1477 }
1478#else
1479 sReport += icMsgValidateWarning;
1480 sReport += sSigPathName;
1481 sReport += " - Zip compression not supported by CMM - unable to validate text compression.\n";
1483#endif
1484 }
1485
1486 return rv;
1487}
1488
1489
1490
1491/**
1492 ****************************************************************************
1493 * Name: CIccTagUtf16Text::CIccTagUtf16Text
1494 *
1495 * Purpose: Constructor
1496 *
1497 *****************************************************************************
1498 */
1500{
1501 m_szText = (icUChar16*)malloc(1*sizeof(icUChar16));
1502 m_szText[0] = 0;
1503 m_nBufSize = 1;
1504}
1505
1506/**
1507 ****************************************************************************
1508 * Name: CIccTagUtf16Text::CIccTagUtf16Text
1509 *
1510 * Purpose: Copy Constructor
1511 *
1512 * Args:
1513 * ITT = The CIccTagText object to be copied
1514 *****************************************************************************
1515 */
1517{
1518 m_szText = (icUChar16*)malloc(1*sizeof(icUChar16));
1519 m_szText[0] = 0;
1520 m_nBufSize = 1;
1521 SetText(ITT.m_szText);
1522}
1523
1524/**
1525 ****************************************************************************
1526 * Name: CIccTagUtf16Text::operator=
1527 *
1528 * Purpose: Copy Operator
1529 *
1530 * Args:
1531 * TextTag = The CIccTagText object to be copied
1532 *****************************************************************************
1533 */
1535{
1536 if (&TextTag == this)
1537 return *this;
1538
1539 m_szText = (icUChar16*)malloc(1*sizeof(icUChar16));
1540 m_szText[0] = '\0';
1541 m_nBufSize = 1;
1542 SetText(TextTag.m_szText);
1543
1544 return *this;
1545}
1546
1547/**
1548 ****************************************************************************
1549 * Name: CIccTagUtf16Text::~CIccTagUtf16Text
1550 *
1551 * Purpose: Destructor
1552 *
1553 *****************************************************************************
1554 */
1556{
1557 free(m_szText);
1558}
1559
1560/**
1561 ****************************************************************************
1562 * Name: CIccTagUtf16Text::GetLength
1563 *
1564 * Purpose: Get length of utf16 string
1565 *
1566 *****************************************************************************
1567 */
1569{
1571 if (!m_szText || !m_nBufSize)
1572 return 0;
1573
1574 for (n=0; n<m_nBufSize && m_szText[n]; n++);
1575
1576 return n;
1577}
1578
1579/**
1580 ****************************************************************************
1581 * Name: CIccTagUtf16Text::Read
1582 *
1583 * Purpose: Read in a text type tag into a data block
1584 *
1585 * Args:
1586 * size - # of bytes in tag,
1587 * pIO - IO object to read tag from
1588 *
1589 * Return:
1590 * true = successful, false = failure
1591 *****************************************************************************
1592 */
1594{
1596
1597 if (size<sizeof(icTagTypeSignature) || !pIO) {
1598 m_szText[0] = '\0';
1599 return false;
1600 }
1601
1602 if (!pIO->Read32(&sig))
1603 return false;
1604
1605 if (!pIO->Read32(&m_nReserved))
1606 return false;
1607
1608 icUInt32Number nSize = (size - sizeof(icTagTypeSignature) - sizeof(icUInt32Number))/sizeof(icUChar16);
1609
1610 icUChar16 *pBuf = GetBuffer(nSize);
1611
1612 if (nSize) {
1613 if (pIO->Read16(pBuf, nSize) != (icInt32Number)nSize) {
1614 return false;
1615 }
1616 }
1617
1618 Release();
1619
1620 return true;
1621}
1622
1623/**
1624 ****************************************************************************
1625 * Name: CIccTagUtf16Text::Write
1626 *
1627 * Purpose: Write a text type tag to a file
1628 *
1629 * Args:
1630 * pIO - The IO object to write tag to.
1631 *
1632 * Return:
1633 * true = succesful, false = failure
1634 *****************************************************************************
1635 */
1637{
1638 icTagTypeSignature sig = GetType();
1639
1640 if (!pIO)
1641 return false;
1642
1643 if (!pIO->Write32(&sig))
1644 return false;
1645
1646 if (!pIO->Write32(&m_nReserved))
1647 return false;
1648
1649 if (!m_szText)
1650 return false;
1651
1652 icUInt32Number nSize = GetLength();
1653
1654 if (nSize) {
1655 if (pIO->Write16(m_szText, nSize) != (icInt32Number)nSize)
1656 return false;
1657 }
1658
1659 return true;
1660}
1661
1662/**
1663 ****************************************************************************
1664 * Name: CIccTagUtf16Text::Describe
1665 *
1666 * Purpose: Dump data associated with the tag to a string
1667 *
1668 * Args:
1669 * sDescription - string to concatenate tag dump to
1670 *****************************************************************************
1671 */
1672void CIccTagUtf16Text::Describe(std::string &sDescription, int nVerboseness)
1673{
1674 sDescription += "UTF16 Length = ";
1675 if (m_szText && *m_szText) {
1676 char buf[40];
1677 sprintf(buf, "%d bytes\n", m_nBufSize);
1678 sDescription += buf;
1679 }
1680 else
1681 sDescription += "0 (NULL)";
1682
1683 if (nVerboseness > 25) {
1684 sDescription += "\"";
1685 if (m_szText && *m_szText) {
1686 std::string s;
1687 if ((nVerboseness > 50) || (m_nBufSize < BRIEF_STRING_SIZE)) {
1688 // output entire string if short or doing verbose
1689 sDescription += GetText(s);
1690 }
1691 else {
1692 // copy just first part of string to keep nVerboseness under control
1693 char buf[BRIEF_STRING_SIZE + 1];
1694 strncpy(buf, GetText(s), BRIEF_STRING_SIZE);
1695 buf[BRIEF_STRING_SIZE] = '\0'; // ensure NULL termination
1696 sDescription += buf;
1697 sDescription += "\n... <!truncated!>";
1698 }
1699 }
1700 sDescription += "\"\n";
1701 }
1702
1703}
1704
1705/**
1706 ****************************************************************************
1707 * Name: CIccTagUtf16Text::GetText
1708 *
1709 * Purpose: Allows text data associated with the tag to be fetched.
1710 *
1711 * Args:
1712 * buf - buffer to put tag data into.
1713 * Returns: buf.c_str()
1714 *****************************************************************************
1715 */
1716const icChar *CIccTagUtf16Text::GetText(std::string &buf) const
1717{
1718 icUtf8Vector str;
1719
1720 icConvertUTF16toUTF8(m_szText, &m_szText[GetLength()], str, lenientConversion);
1721
1722 buf.clear();
1723 icUtf8Vector::iterator c;
1724 c=str.begin();
1725 if (str.size()>2 && (str[0]==0xff && str[1]==0xfe)) {
1726 c++; c++;
1727 }
1728 for (; c!=str.end(); c++)
1729 buf.push_back(*c);
1730
1731 return buf.c_str();
1732}
1733
1734
1735/**
1736 ****************************************************************************
1737 * Name: CIccTagUtf16Text::SetText
1738 *
1739 * Purpose: Allows text data associated with the tag to be set.
1740 *
1741 * Args:
1742 * szText - zero terminated string to put in tag
1743 *****************************************************************************
1744 */
1746{
1747 if (!szText) {
1748 icUChar16 c=0;
1749 SetText(&c);
1750 }
1751
1753 for (n=0; szText[n]; n++);
1754
1755 icUInt32Number len=n + 1;
1756 icUChar16 *szBuf = GetBuffer(len);
1757
1758 memcpy(szBuf, szText, len*sizeof(icUChar16));
1759 Release();
1760}
1761
1762/**
1763 ****************************************************************************
1764 * Name: CIccTagUtf16Text::SetText
1765 *
1766 * Purpose: Allows text data associated with the tag to be set.
1767 *
1768 * Args:
1769 * szText - zero terminated string to put in tag
1770 *****************************************************************************
1771 */
1773{
1774 if (!szText) {
1775 icUChar16 c=0;
1776 SetText(&c);
1777 }
1778
1779 icUtf16Vector str;
1780 icConvertUTF8toUTF16(szText, szText+strlen((icChar*)szText)+1, str, lenientConversion);
1781
1782 int pos = 0;
1783 if (str[0]==0xfeff) {
1784 pos = 1;
1785 }
1786
1787 icUInt32Number nSize = (icUInt32Number)(str.size()-pos);
1788 icUChar16 *szBuf = GetBuffer(nSize);
1789
1790 if (nSize)
1791 memcpy(m_szText, &str[pos], nSize*sizeof(icUChar));
1792 Release();
1793}
1794
1795/**
1796 ****************************************************************************
1797 * Name: *CIccTagUtf16Text::operator=
1798 *
1799 * Purpose: Define assignment operator to associate text with tag.
1800 *
1801 * Args:
1802 * szText - zero terminated string to put in the tag
1803 *
1804 * Return: A pointer to the string assigned to the tag.
1805 *****************************************************************************
1806 */
1808{
1809 SetText(szText);
1810 return (icUChar16*)m_szText;
1811}
1812
1813/**
1814 ******************************************************************************
1815 * Name: CIccTagUtf16Text::GetBuffer
1816 *
1817 * Purpose: This function allocates room and returns pointer to data buffer to
1818 * put string into
1819 *
1820 * Args:
1821 * nSize = Requested size of data buffer.
1822 *
1823 * Return: The utf16 character buffer array
1824 *******************************************************************************
1825 */
1827{
1828 if (m_nBufSize < nSize) {
1829 m_szText = (icUChar16*)icRealloc(m_szText, (nSize+1)*sizeof(icUChar16));
1830
1831 m_szText[nSize] = 0;
1832
1833 m_nBufSize = nSize;
1834 }
1835
1836 return m_szText;
1837}
1838
1839/**
1840 ****************************************************************************
1841 * Name: CIccTagUtf16Text::Release
1842 *
1843 * Purpose: This will resize the buffer to fit the zero terminated string in
1844 * the buffer.
1845 *****************************************************************************
1846 */
1848{
1849 icUInt32Number nSize = GetLength()+1;
1850
1851 if (nSize < m_nBufSize-1) {
1852 m_szText=(icUChar16*)icRealloc(m_szText, (nSize+1)*sizeof(icUChar16));
1853 m_nBufSize = nSize+1;
1854 }
1855}
1856
1857
1858/**
1859******************************************************************************
1860* Name: CIccTagUtf16Text::Validate
1861*
1862* Purpose: Check tag data validity.
1863*
1864* Args:
1865* sig = signature of tag being validated,
1866* sReport = String to add report information to
1867*
1868* Return:
1869* icValidateStatusOK if valid, or other error status.
1870******************************************************************************
1871*/
1872icValidateStatus CIccTagUtf16Text::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
1873{
1874 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
1875
1876 CIccInfo Info;
1877 std::string sSigPathName = Info.GetSigPathName(sigPath);
1878
1879 if (!m_nBufSize) {
1880 sReport += icMsgValidateWarning;
1881 sReport += sSigPathName;
1882 sReport += " - Empty Tag.\n";
1884 }
1885
1886 return rv;
1887}
1888
1889
1890
1891/**
1892 ****************************************************************************
1893 * Name: CIccTagTextDescription::CIccTagTextDescription
1894 *
1895 * Purpose: Constructor
1896 *
1897 *****************************************************************************
1898 */
1900{
1901 m_szText = (icChar*)malloc(1);
1902 m_szText[0] = '\0';
1903 m_nASCIISize = 1;
1904
1905 m_uzUnicodeText = (icUInt16Number*)malloc(sizeof(icUInt16Number));
1906 m_uzUnicodeText[0] = 0;
1907 m_nUnicodeSize = 1;
1908 m_nUnicodeLanguageCode = 0;
1909
1910 m_nScriptSize = 0;
1911 m_nScriptCode = 0;
1912 memset(m_szScriptText, 0, sizeof(m_szScriptText));
1913
1914 m_bInvalidScript = false;
1915}
1916
1917/**
1918 ****************************************************************************
1919 * Name: CIccTagTextDescription::CIccTagTextDescription
1920 *
1921 * Purpose: Copy Constructor
1922 *
1923 * Args:
1924 * ITTD = The CIccTagTextDescription object to be copied
1925 *****************************************************************************
1926 */
1928{
1929 m_nASCIISize = ITTD.m_nASCIISize;
1930 m_nUnicodeSize = ITTD.m_nUnicodeSize;
1931 m_nUnicodeLanguageCode = ITTD.m_nUnicodeLanguageCode;
1932 m_nScriptSize = ITTD.m_nScriptSize;
1933 m_nScriptCode = ITTD.m_nScriptCode;
1934
1935 if (m_nASCIISize) {
1936 m_szText = (icChar*)malloc(m_nASCIISize * sizeof(icChar));
1937 memcpy(m_szText, ITTD.m_szText, m_nASCIISize*sizeof(icChar));
1938 }
1939 else {
1940 m_nASCIISize = 1;
1941 m_szText = (icChar*)calloc(m_nASCIISize, sizeof(icChar));
1942 m_szText[0] = '\0';
1943 }
1944
1945 if (m_nUnicodeSize) {
1946 m_uzUnicodeText = (icUInt16Number*)malloc((m_nUnicodeSize) * sizeof(icUInt16Number));
1947 memcpy(m_uzUnicodeText, ITTD.m_uzUnicodeText, m_nUnicodeSize*sizeof(icUInt16Number));
1948 }
1949 else {
1950 m_nUnicodeSize = 1;
1951 m_uzUnicodeText = (icUInt16Number*)calloc(m_nUnicodeSize, sizeof(icUInt16Number));
1952 m_uzUnicodeText[0] = 0;
1953 }
1954
1955 memcpy(m_szScriptText, ITTD.m_szScriptText, sizeof(m_szScriptText));
1956
1957 m_bInvalidScript = ITTD.m_bInvalidScript;
1958}
1959
1960
1961/**
1962 ****************************************************************************
1963 * Name: CIccTagTextDescription::operator=
1964 *
1965 * Purpose: Copy Operator
1966 *
1967 * Args:
1968 * TextDescTag = The CIccTagTextDescription object to be copied
1969 *****************************************************************************
1970 */
1972{
1973 if (&TextDescTag == this)
1974 return *this;
1975
1976 m_nASCIISize = TextDescTag.m_nASCIISize;
1977 m_nUnicodeSize = TextDescTag.m_nUnicodeSize;
1978 m_nUnicodeLanguageCode = TextDescTag.m_nUnicodeLanguageCode;
1979 m_nScriptSize = TextDescTag.m_nScriptSize;
1980 m_nScriptCode = TextDescTag.m_nScriptCode;
1981
1982 if (m_szText)
1983 free(m_szText);
1984 if (m_nASCIISize) {
1985 m_szText = (icChar*)calloc(m_nASCIISize, sizeof(icChar));
1986 memcpy(m_szText, TextDescTag.m_szText, m_nASCIISize*sizeof(icChar));
1987 }
1988 else {
1989 m_nASCIISize = 1;
1990 m_szText = (icChar*)calloc(m_nASCIISize, sizeof(icChar));
1991 m_szText[0] = '\0';
1992 }
1993
1994 if (m_uzUnicodeText)
1995 free(m_uzUnicodeText);
1996 if (m_nUnicodeSize) {
1997 m_uzUnicodeText = (icUInt16Number*)calloc(m_nUnicodeSize, sizeof(icUInt16Number));
1998 memcpy(m_uzUnicodeText, TextDescTag.m_uzUnicodeText, m_nUnicodeSize*sizeof(icUInt16Number));
1999 }
2000 else {
2001 m_nUnicodeSize = 1;
2002 m_uzUnicodeText = (icUInt16Number*)calloc(m_nUnicodeSize, sizeof(icUInt16Number));
2003 m_uzUnicodeText[0] = 0;
2004 }
2005
2006 memcpy(m_szScriptText, TextDescTag.m_szScriptText, sizeof(m_szScriptText));
2007
2008 m_bInvalidScript = TextDescTag.m_bInvalidScript;
2009
2010 return *this;
2011}
2012
2013/**
2014 ****************************************************************************
2015 * Name: CIccTagTextDescription::~CIccTagTextDescription
2016 *
2017 * Purpose: Destructor
2018 *
2019 *****************************************************************************
2020 */
2022{
2023 free(m_szText);
2024 free(m_uzUnicodeText);
2025}
2026
2027/**
2028 ****************************************************************************
2029 * Name: CIccTagTextDescription::Read
2030 *
2031 * Purpose: Read in the tag contents into a data block
2032 *
2033 * Args:
2034 * size - # of bytes in tag,
2035 * pIO - IO object to read tag from
2036 *
2037 * Return:
2038 * true = successful, false = failure
2039 *****************************************************************************
2040 */
2042{
2044 icUInt32Number nEnd;
2045
2046 m_szText[0] = '\0';
2047 nEnd = pIO->Tell() + size;
2048
2049 if (size<3*sizeof(icUInt32Number) || !pIO)
2050 return false;
2051
2052 icUInt32Number nSize;
2053
2054 if (!pIO->Read32(&sig) ||
2055 !pIO->Read32(&m_nReserved) ||
2056 !pIO->Read32(&nSize))
2057 return false;
2058
2059 if (3*sizeof(icUInt32Number) + nSize > size)
2060 return false;
2061
2062 icChar *pBuf = GetBuffer(nSize);
2063
2064 if (nSize) {
2065 if (pIO->Read8(pBuf, nSize) != (icInt32Number)nSize) {
2066 return false;
2067 }
2068 }
2069 else
2070 m_szText[0] = '\0';
2071
2072 Release();
2073
2074 if (pIO->Tell() + 2 * sizeof(icUInt32Number) > nEnd)
2075 return false;
2076
2077 if (!pIO->Read32(&m_nUnicodeLanguageCode) ||
2078 !pIO->Read32(&nSize))
2079 return false;
2080
2081 // Calculations in GetUnicodeBuffer() can cause wrap-around error
2082 if (nSize == 0xFFFFFFFF)
2083 return false;
2084
2085 icUInt16Number *pBuf16 = GetUnicodeBuffer(nSize);
2086
2087 if (nSize) {
2088 if (pIO->Read16(pBuf16, nSize) != (icInt32Number)nSize) {
2089 return false;
2090 }
2091 }
2092 else
2093 pBuf16[0] = 0;
2094
2095 ReleaseUnicode();
2096
2097 if (pIO->Tell()+3 > (icInt32Number)nEnd)
2098 return false;
2099
2100 if (!pIO->Read16(&m_nScriptCode) ||
2101 !pIO->Read8(&m_nScriptSize))
2102 return false;
2103
2104 if (pIO->Tell() + m_nScriptSize> (icInt32Number)nEnd ||
2105 m_nScriptSize > sizeof(m_szScriptText))
2106 return false;
2107
2108 int nScriptLen = pIO->Read8(m_szScriptText, 67);
2109
2110 if (!nScriptLen)
2111 return false;
2112
2113 if (nScriptLen<67) {
2114 memset(&m_szScriptText[0], 0, 67-nScriptLen);
2115 m_bInvalidScript = true;
2116 }
2117
2118 return true;
2119}
2120
2121/**
2122 ****************************************************************************
2123 * Name: CIccTagTextDescription::Write
2124 *
2125 * Purpose: Write the tag to a file
2126 *
2127 * Args:
2128 * pIO - The IO object to write tag to.
2129 *
2130 * Return:
2131 * true = succesful, false = failure
2132 *****************************************************************************
2133 */
2135{
2136 icTagTypeSignature sig = GetType();
2137 icUInt32Number zero = 0;
2138
2139 if (!pIO)
2140 return false;
2141
2142 if (!pIO->Write32(&sig) ||
2143 !pIO->Write32(&m_nReserved) ||
2144 !pIO->Write32(&m_nASCIISize))
2145 return false;
2146
2147 if (m_nASCIISize) {
2148 if (pIO->Write8(m_szText, m_nASCIISize) != (icInt32Number)m_nASCIISize)
2149 return false;
2150 }
2151
2152 if (!pIO->Write32(&m_nUnicodeLanguageCode))
2153 return false;
2154
2155 if (m_nUnicodeSize > 1) {
2156 if (!pIO->Write32(&m_nUnicodeSize) ||
2157 pIO->Write16(m_uzUnicodeText, m_nUnicodeSize) != (icInt32Number)m_nUnicodeSize)
2158 return false;
2159 }
2160 else {
2161 if (!pIO->Write32(&zero))
2162 return false;
2163 }
2164
2165 if (!pIO->Write16(&m_nScriptCode) ||
2166 !pIO->Write8(&m_nScriptSize) ||
2167 pIO->Write8(m_szScriptText, 67)!= 67)
2168 return false;
2169
2170 m_bInvalidScript = false;
2171
2172 return true;
2173}
2174
2175/**
2176 ****************************************************************************
2177 * Name: CIccTagTextDescription::Describe
2178 *
2179 * Purpose: Dump data associated with the tag to a string
2180 *
2181 * Args:
2182 * sDescription - string to concatenate tag dump to
2183 *****************************************************************************
2184 */
2185void CIccTagTextDescription::Describe(std::string &sDescription, int nVerboseness)
2186{
2187 sDescription += "TextDescription Length = ";
2188 if (m_szText && *m_szText) {
2189 char buf[40];
2190 sprintf(buf, "%zu bytes\n", strlen(m_szText));
2191 sDescription += buf;
2192 }
2193 else
2194 sDescription += "0 (NULL)";
2195
2196 if (nVerboseness > 25) {
2197 sDescription += "\"";
2198 if (m_szText && *m_szText) {
2199 if ((nVerboseness > 50) || (strlen(m_szText) < BRIEF_STRING_SIZE)) {
2200 // output entire string if short or doing verbose
2201 sDescription += m_szText;
2202 }
2203 else {
2204 // copy just first part of string to keep nVerboseness under control
2205 char buf[BRIEF_STRING_SIZE+1];
2206 strncpy(buf, m_szText, BRIEF_STRING_SIZE);
2207 buf[BRIEF_STRING_SIZE] = '\0'; // ensure NULL termination
2208 sDescription += buf;
2209 sDescription += "\n... <!truncated!>";
2210 }
2211 }
2212 sDescription += "\"\n";
2213 }
2214}
2215
2216
2217/**
2218 ****************************************************************************
2219 * Name: CIccTagTextDescription::SetText
2220 *
2221 * Purpose: Allows text data associated with the tag to be set.
2222 *
2223 * Args:
2224 * szText - zero terminated string to put in tag
2225 *****************************************************************************
2226 */
2228{
2229 m_bInvalidScript = false;
2230
2231 if (!szText)
2232 SetText("");
2233
2234 icUInt32Number len=(icUInt32Number)strlen(szText) + 1;
2235 icChar *szBuf = GetBuffer(len);
2236
2237 strcpy(szBuf, szText);
2238 Release();
2239}
2240
2241/**
2242 ****************************************************************************
2243 * Name: CIccTagTextDescription::operator=
2244 *
2245 * Purpose: Define assignment operator to associate text with tag.
2246 *
2247 * Args:
2248 * szText - zero terminated string to put in the tag
2249 *
2250 * Return: A pointer to the string assigned to the tag.
2251 *****************************************************************************
2252 */
2254{
2255 SetText(szText);
2256 return m_szText;
2257}
2258
2259/**
2260 ****************************************************************************
2261 * Name: CIccTagTextDescription::GetBuffer
2262 *
2263 * Purpose: This function allocates room and returns pointer to data buffer to
2264 * put string into
2265 *
2266 * Args:
2267 * nSize = Requested size of data buffer.
2268 *
2269 * Return:
2270 *****************************************************************************
2271 */
2273{
2274 if (m_nASCIISize < nSize) {
2275 m_szText = (icChar*)icRealloc(m_szText, nSize+1);
2276
2277 m_szText[nSize] = '\0';
2278
2279 m_nASCIISize = nSize;
2280 }
2281
2282 return m_szText;
2283}
2284
2285/**
2286 ****************************************************************************
2287 * Name: CIccTagTextDescription::Release
2288 *
2289 * Purpose: This will resize the buffer to fit the zero terminated string in
2290 * the buffer.
2291 *****************************************************************************
2292 */
2294{
2295 icUInt32Number nSize = (icUInt32Number)strlen(m_szText);
2296
2297 if (nSize < m_nASCIISize-1) {
2298 m_szText=(icChar*)icRealloc(m_szText, nSize+1);
2299 m_nASCIISize = nSize+1;
2300 }
2301}
2302
2303/**
2304 ****************************************************************************
2305 * Name: CIccTagTextDescription::GetUnicodeBuffer
2306 *
2307 * Purpose: This function allocates room and returns pointer to data buffer to
2308 * put string into
2309 *
2310 * Args:
2311 * nSize = Requested size of data buffer.
2312 *
2313 * Return:
2314 *****************************************************************************
2315 */
2317{
2318 if (m_nUnicodeSize < nSize) {
2319 m_uzUnicodeText = (icUInt16Number*)icRealloc(m_uzUnicodeText, (nSize+1)*sizeof(icUInt16Number));
2320
2321 m_uzUnicodeText[nSize] = 0;
2322
2323 m_nUnicodeSize = nSize;
2324 }
2325
2326 return m_uzUnicodeText;
2327}
2328
2329/**
2330 ****************************************************************************
2331 * Name: CIccTagTextDescription::ReleaseUnicode
2332 *
2333 * Purpose: This will resize the buffer to fit the zero terminated string in
2334 * the buffer.
2335 *****************************************************************************
2336 */
2338{
2339 int i;
2340 for (i=0; m_uzUnicodeText[i]; i++);
2341
2342 icUInt32Number nSize = i+1;
2343
2344 if (nSize < m_nUnicodeSize-1) {
2345 m_uzUnicodeText=(icUInt16Number*)icRealloc(m_uzUnicodeText, (nSize+1)*sizeof(icUInt16Number));
2346 m_nUnicodeSize = nSize+1;
2347 }
2348}
2349
2350
2351/**
2352******************************************************************************
2353* Name: CIccTagTextDescription::Validate
2354*
2355* Purpose: Check tag data validity.
2356*
2357* Args:
2358* sig = signature of tag being validated,
2359* sReport = String to add report information to
2360*
2361* Return:
2362* icValidateStatusOK if valid, or other error status.
2363******************************************************************************
2364*/
2365icValidateStatus CIccTagTextDescription::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
2366{
2367 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
2368
2369 CIccInfo Info;
2370 std::string sSigPathName = Info.GetSigPathName(sigPath);
2371
2372 if (m_nScriptSize>67) {
2373 sReport += icMsgValidateNonCompliant;
2374 sReport += sSigPathName;
2375 sReport += " - ScriptCode count must not be greater than 67.\n";
2376
2378 }
2379
2380 if (m_bInvalidScript) {
2381 sReport += icMsgValidateNonCompliant;
2382 sReport += sSigPathName;
2383 sReport += " - ScriptCode must contain 67 bytes.\n";
2384
2386 }
2387
2388 return rv;
2389}
2390
2391/**
2392 ****************************************************************************
2393 * Name: CIccTagSignature::CIccTagSignature
2394 *
2395 * Purpose: Constructor
2396 *
2397 *****************************************************************************
2398 */
2400{
2401 m_nSig = 0x3f3f3f3f; //'????';
2402}
2403
2404
2405
2406/**
2407 ****************************************************************************
2408 * Name: CIccTagSignature::CIccTagSignature
2409 *
2410 * Purpose: Copy Constructor
2411 *
2412 * Args:
2413 * ITS = The CIccTagSignature object to be copied
2414 *****************************************************************************
2415 */
2417{
2418 m_nSig = ITS.m_nSig;
2419}
2420
2421
2422
2423/**
2424 ****************************************************************************
2425 * Name: CIccTagSignature::operator=
2426 *
2427 * Purpose: Copy Operator
2428 *
2429 * Args:
2430 * SignatureTag = The CIccTagSignature object to be copied
2431 *****************************************************************************
2432 */
2434{
2435 if (&SignatureTag == this)
2436 return *this;
2437
2438 m_nSig = SignatureTag.m_nSig;
2439
2440 return *this;
2441}
2442
2443
2444/**
2445 ****************************************************************************
2446 * Name: CIccTagSignature::~CIccTagSignature
2447 *
2448 * Purpose: Destructor
2449 *
2450 *****************************************************************************
2451 */
2455
2456/**
2457 ****************************************************************************
2458 * Name: CIccTagSignature::Read
2459 *
2460 * Purpose: Read in the tag contents into a data block
2461 *
2462 * Args:
2463 * size - # of bytes in tag,
2464 * pIO - IO object to read tag from
2465 *
2466 * Return:
2467 * true = successful, false = failure
2468 *****************************************************************************
2469 */
2471{
2473
2474 if (sizeof(icTagTypeSignature) + 2*sizeof(icUInt32Number) > size)
2475 return false;
2476
2477 if (!pIO) {
2478 m_nSig = 0x3f3f3f3f; //'????';
2479 return false;
2480 }
2481
2482 if (!pIO->Read32(&sig))
2483 return false;
2484
2485 if (!pIO->Read32(&m_nReserved))
2486 return false;
2487
2488 if (!pIO->Read32(&m_nSig))
2489 return false;
2490
2491 return true;
2492}
2493
2494/**
2495 ****************************************************************************
2496 * Name: CIccTagSignature::Write
2497 *
2498 * Purpose: Write the tag to a file
2499 *
2500 * Args:
2501 * pIO - The IO object to write tag to.
2502 *
2503 * Return:
2504 * true = succesful, false = failure
2505 *****************************************************************************
2506 */
2508{
2509 icTagTypeSignature sig = GetType();
2510
2511 if (!pIO)
2512 return false;
2513
2514 if (!pIO->Write32(&sig))
2515 return false;
2516
2517 if (!pIO->Write32(&m_nReserved))
2518 return false;
2519
2520 if (!pIO->Write32(&m_nSig))
2521 return false;
2522
2523 return true;
2524}
2525
2526
2527/**
2528 ****************************************************************************
2529 * Name: CIccTagSignature::Describe
2530 *
2531 * Purpose: Dump data associated with the tag to a string
2532 *
2533 * Args:
2534 * sDescription - string to concatenate tag dump to
2535 *****************************************************************************
2536 */
2537void CIccTagSignature::Describe(std::string &sDescription, int nVerboseness)
2538{
2539 CIccInfo Fmt;
2540
2541 sDescription += Fmt.GetSigName(m_nSig);
2542 sDescription += "\n";
2543}
2544
2545
2546/**
2547******************************************************************************
2548* Name: CIccTagSignature::Validate
2549*
2550* Purpose: Check tag data validity.
2551*
2552* Args:
2553* sig = signature of tag being validated,
2554* sReport = String to add report information to
2555*
2556* Return:
2557* icValidateStatusOK if valid, or other error status.
2558******************************************************************************
2559*/
2560icValidateStatus CIccTagSignature::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
2561{
2562 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
2563
2564 CIccInfo Info;
2565 std::string sSigPathName = Info.GetSigPathName(sigPath);
2567 char buf[128];
2568
2569 if (sig==icSigTechnologyTag) {
2570 switch(m_nSig) {
2571 case icSigFilmScanner:
2572 case icSigDigitalCamera:
2574 case icSigInkJetPrinter:
2580 case icSigFilmWriter:
2581 case icSigVideoMonitor:
2582 case icSigVideoCamera:
2584 case icSigCRTDisplay:
2585 case icSigPMDisplay:
2586 case icSigAMDisplay:
2587 case icSigPhotoCD:
2589 case icSigGravure:
2591 case icSigSilkscreen:
2592 case icSigFlexography:
2597 break;
2598
2599 default:
2600 {
2601 sReport += icMsgValidateNonCompliant;
2602 sReport += sSigPathName;
2603 sprintf(buf, " - %s: Unknown Technology.\n", Info.GetSigName(m_nSig));
2604 sReport += buf;
2606 }
2607 }
2608 }
2611 switch(m_nSig) {
2613 break;
2614
2615 default:
2616 {
2617 sReport += icMsgValidateNonCompliant;
2618 sReport += sSigPathName;
2619 sprintf(buf, " - %s: Unknown Reference Medium Gamut.\n", Info.GetSigName(m_nSig));
2620 sReport += buf;
2622 }
2623 }
2624 }
2626 switch(m_nSig) {
2632 break;
2633
2634 default:
2635 {
2636 sReport += icMsgValidateNonCompliant;
2637 sReport += sSigPathName;
2638 sprintf(buf, " - %s: Unknown Colorimetric Intent Image State.\n", Info.GetSigName(m_nSig));
2639 sReport += buf;
2641 }
2642 }
2643 }
2644
2645
2646 return rv;
2647}
2648
2649/**
2650 ****************************************************************************
2651 * Name: CIccTagNamedColor2::CIccTagNamedColor2
2652 *
2653 * Purpose: Constructor
2654 *
2655 * Args:
2656 * nSize = number of named color entries,
2657 * nDeviceCoords = number of device channels
2658 *****************************************************************************
2659 */
2660CIccTagNamedColor2::CIccTagNamedColor2(int nSize/*=1*/, int nDeviceCoords/*=0*/)
2661{
2662 m_nSize = nSize <1 ? 1 : nSize;
2663 m_nVendorFlags = 0;
2664 m_nDeviceCoords = nDeviceCoords;
2665 if (nDeviceCoords<0)
2666 m_nDeviceCoords = nDeviceCoords = 0;
2667
2668 if (nDeviceCoords>0)
2669 nDeviceCoords--;
2670
2671 m_szPrefix[0] = '\0';
2672 m_szSufix[0] = '\0';
2673 m_csPCS = icSigUnknownData;
2674 m_csDevice = icSigUnknownData;
2675
2676 m_nColorEntrySize = 32/*rootName*/ + (3/*PCS*/ + 1/*iAny*/ + nDeviceCoords)*sizeof(icFloatNumber);
2677
2678 m_NamedColor = (SIccNamedColorEntry*)calloc(nSize, m_nColorEntrySize);
2679
2680 m_NamedLab = NULL;
2681}
2682
2683
2684/**
2685 ****************************************************************************
2686 * Name: CIccTagNamedColor2::CIccTagNamedColor2
2687 *
2688 * Purpose: Copy Constructor
2689 *
2690 * Args:
2691 * ITNC = The CIccTagNamedColor2 object to be copied
2692 *****************************************************************************
2693 */
2695{
2696 m_nColorEntrySize = ITNC.m_nColorEntrySize;
2697 m_nVendorFlags = ITNC.m_nVendorFlags;
2698 m_nDeviceCoords = ITNC.m_nDeviceCoords;
2699 m_nSize = ITNC.m_nSize;
2700
2701 m_csPCS = ITNC.m_csPCS;
2702 m_csDevice = ITNC.m_csDevice;
2703
2704 memcpy(m_szPrefix, ITNC.m_szPrefix, sizeof(m_szPrefix));
2705 memcpy(m_szSufix, ITNC.m_szSufix, sizeof(m_szSufix));
2706
2707 m_NamedColor = (SIccNamedColorEntry*)calloc(m_nSize, m_nColorEntrySize);
2708 memcpy(m_NamedColor, ITNC.m_NamedColor, m_nColorEntrySize*m_nSize);
2709
2710 m_NamedLab = NULL;
2711}
2712
2713
2714/**
2715 ****************************************************************************
2716 * Name: CIccTagNamedColor2::operator=
2717 *
2718 * Purpose: Copy Operator
2719 *
2720 * Args:
2721 * NamedColor2Tag = The CIccTagNamedColor2 object to be copied
2722 *****************************************************************************
2723 */
2725{
2726 if (&NamedColor2Tag == this)
2727 return *this;
2728
2729 m_nColorEntrySize = NamedColor2Tag.m_nColorEntrySize;
2730 m_nVendorFlags = NamedColor2Tag.m_nVendorFlags;
2731 m_nDeviceCoords = NamedColor2Tag.m_nDeviceCoords;
2732 m_nSize = NamedColor2Tag.m_nSize;
2733
2734 m_csPCS = NamedColor2Tag.m_csPCS;
2735 m_csDevice = NamedColor2Tag.m_csDevice;
2736
2737 memcpy(m_szPrefix, NamedColor2Tag.m_szPrefix, sizeof(m_szPrefix));
2738 memcpy(m_szSufix, NamedColor2Tag.m_szSufix, sizeof(m_szSufix));
2739
2740 if (m_NamedColor)
2741 free(m_NamedColor);
2742 m_NamedColor = (SIccNamedColorEntry*)calloc(m_nSize, m_nColorEntrySize);
2743 memcpy(m_NamedColor, NamedColor2Tag.m_NamedColor, m_nColorEntrySize*m_nSize);
2744
2745 m_NamedLab = NULL;
2746
2747 return *this;
2748}
2749
2750
2751/**
2752 ****************************************************************************
2753 * Name: CIccTagNamedColor2::~CIccTagNamedColor2
2754 *
2755 * Purpose: Destructor
2756 *
2757 *****************************************************************************
2758 */
2760{
2761 if (m_NamedColor)
2762 free(m_NamedColor);
2763
2764 if (m_NamedLab)
2765 delete [] m_NamedLab;
2766}
2767
2768/**
2769 ****************************************************************************
2770 * Name: CIccTagNamedColor2::SetSize
2771 *
2772 * Purpose: Sets the size of the named color array.
2773 *
2774 * Args:
2775 * nSize - number of named color entries,
2776 * nDeviceCoords - number of device channels
2777 *****************************************************************************
2778 */
2780{
2781 if (nSize <1)
2782 nSize = 1;
2783 if (nDeviceCoords<0)
2784 nDeviceCoords = m_nDeviceCoords;
2785
2786 icInt32Number nNewCoords=nDeviceCoords;
2787
2788 if (nDeviceCoords>0)
2789 nDeviceCoords--;
2790
2791 icUInt32Number nColorEntrySize = 32/*rootName*/ + (3/*PCS*/ + 1/*iAny*/ + nDeviceCoords)*sizeof(icFloatNumber);
2792
2793 SIccNamedColorEntry* pNamedColor = (SIccNamedColorEntry*)calloc(nSize, nColorEntrySize);
2794
2795 if (!pNamedColor)
2796 return false;
2797
2798 icUInt32Number i, nCopy = __min(nSize, m_nSize);
2799 icUInt32Number j, nCoords = __min(nNewCoords, (icInt32Number)m_nDeviceCoords);
2800
2801 for (i=0; i<nCopy; i++) {
2802 SIccNamedColorEntry *pFrom = (SIccNamedColorEntry*)((icChar*)m_NamedColor + i*m_nColorEntrySize);
2803 SIccNamedColorEntry *pTo = (SIccNamedColorEntry*)((icChar*)pNamedColor + i*nColorEntrySize);
2804
2805 strcpy(pTo->rootName, pFrom->rootName);
2806 for (j=0; j<3; j++)
2807 pTo->pcsCoords[j] = pFrom->pcsCoords[j];
2808
2809 for (j=0; j<nCoords; j++) {
2810 pTo->deviceCoords[j] = pFrom->deviceCoords[j];
2811 }
2812 }
2813 free(m_NamedColor);
2814
2815 m_nColorEntrySize = nColorEntrySize;
2816
2817 m_NamedColor = pNamedColor;
2818 m_nSize = nSize;
2819 m_nDeviceCoords = nNewCoords;
2820
2821 ResetPCSCache();
2822
2823 return true;
2824}
2825
2826
2827/**
2828****************************************************************************
2829* Name: CIccTagNamedColor2::SetPrefix
2830*
2831* Purpose: Set contents of suffix member field
2832*
2833* Args:
2834* szPrefix - string to set prefix to
2835*****************************************************************************
2836*/
2838{
2839 strncpy(m_szPrefix, szPrefix, sizeof(m_szPrefix));
2840 m_szPrefix[sizeof(m_szPrefix)-1]='\0';
2841}
2842
2843
2844/**
2845****************************************************************************
2846* Name: CIccTagNamedColor2::SetSufix
2847*
2848* Purpose: Set contents of suffix member field
2849*
2850* Args:
2851* szPrefix - string to set prefix to
2852*****************************************************************************
2853*/
2855{
2856 strncpy(m_szSufix, szSufix, sizeof(m_szSufix));
2857 m_szSufix[sizeof(m_szSufix)-1]='\0';
2858}
2859
2860
2861/**
2862 ****************************************************************************
2863 * Name: CIccTagNamedColor2::Read
2864 *
2865 * Purpose: Read in the tag contents into a data block
2866 *
2867 * Args:
2868 * size - # of bytes in tag,
2869 * pIO - IO object to read tag from
2870 *
2871 * Return:
2872 * true = successful, false = failure
2873 *****************************************************************************
2874 */
2876{
2878 icUInt32Number nNum, nCoords;
2879
2880 icUInt32Number nTagHdrSize = sizeof(icTagTypeSignature) +
2881 sizeof(icUInt32Number) + //m_nReserved=0
2882 sizeof(icUInt32Number) + //VendorFlags
2883 sizeof(icUInt32Number) + //Num Colors
2884 sizeof(icUInt32Number) + //Num Device Coords
2885 sizeof(m_szPrefix) +
2886 sizeof(m_szSufix);
2887 if (nTagHdrSize > size)
2888 return false;
2889
2890 if (!pIO) {
2891 return false;
2892 }
2893
2894 if (!pIO->Read32(&sig) ||
2895 !pIO->Read32(&m_nReserved) ||
2896 !pIO->Read32(&m_nVendorFlags) ||
2897 !pIO->Read32(&nNum) ||
2898 !pIO->Read32(&nCoords) ||
2899 pIO->Read8(m_szPrefix, sizeof(m_szPrefix))!=sizeof(m_szPrefix) ||
2900 pIO->Read8(m_szSufix, sizeof(m_szSufix))!=sizeof(m_szSufix)) {
2901 return false;
2902 }
2903
2904 size -= nTagHdrSize;
2905
2906 icUInt32Number nCount = size / (32+(3+nCoords)*sizeof(icUInt16Number));
2907
2908 if (nCount < nNum)
2909 return false;
2910
2911 if (!SetSize(nNum, nCoords))
2912 return false;
2913
2915 SIccNamedColorEntry *pNamedColor=m_NamedColor;
2916
2917 for (i=0; i<nNum; i++) {
2918 if (pIO->Read8(&pNamedColor->rootName, sizeof(pNamedColor->rootName))!=sizeof(pNamedColor->rootName) ||
2919 pIO->ReadUInt16Float(&pNamedColor->pcsCoords, 3)!=3)
2920 return false;
2921 if (nCoords) {
2922 if (pIO->ReadUInt16Float(&pNamedColor->deviceCoords, nCoords)!=(icInt32Number)nCoords)
2923 return false;
2924 }
2925 pNamedColor = (SIccNamedColorEntry*)((icChar*)pNamedColor + m_nColorEntrySize);
2926 }
2927
2928 return true;
2929}
2930
2931
2932/**
2933 ****************************************************************************
2934 * Name: CIccTagNamedColor2::Write
2935 *
2936 * Purpose: Write the tag to a file
2937 *
2938 * Args:
2939 * pIO - The IO object to write tag to.
2940 *
2941 * Return:
2942 * true = succesful, false = failure
2943 *****************************************************************************
2944 */
2946{
2947 icTagTypeSignature sig = GetType();
2948
2949 if (!pIO)
2950 return false;
2951
2952 if (!pIO->Write32(&sig))
2953 return false;
2954
2955 if (!pIO->Write32(&m_nReserved))
2956 return false;
2957
2958 if (!pIO->Write32(&m_nVendorFlags))
2959 return false;
2960
2961 if (!pIO->Write32(&m_nSize))
2962 return false;
2963
2964 if (!pIO->Write32(&m_nDeviceCoords))
2965 return false;
2966
2967 if (!pIO->Write8(m_szPrefix, sizeof(m_szPrefix)))
2968 return false;
2969
2970 if (!pIO->Write8(m_szSufix, sizeof(m_szSufix)))
2971 return false;
2972
2974 SIccNamedColorEntry *pNamedColor=m_NamedColor;
2975
2976 for (i=0; i<m_nSize; i++) {
2977 if (pIO->Write8(&pNamedColor->rootName, sizeof(pNamedColor->rootName))!=sizeof(pNamedColor->rootName) ||
2978 pIO->WriteUInt16Float(&pNamedColor->pcsCoords, 3)!=3)
2979 return false;
2980 if (m_nDeviceCoords) {
2981 if (pIO->WriteUInt16Float(&pNamedColor->deviceCoords, m_nDeviceCoords) != (icInt32Number)m_nDeviceCoords)
2982 return false;
2983 }
2984 pNamedColor = (SIccNamedColorEntry*)((icChar*)pNamedColor + m_nColorEntrySize);
2985 }
2986
2987 return true;
2988}
2989
2990
2991/**
2992 ****************************************************************************
2993 * Name: CIccTagNamedColor2::Describe
2994 *
2995 * Purpose: Dump data associated with the tag to a string
2996 *
2997 * Args:
2998 * sDescription - string to concatenate tag dump to
2999 *****************************************************************************
3000 */
3001void CIccTagNamedColor2::Describe(std::string &sDescription, int nVerboseness)
3002{
3003 icChar buf[128], szColorVal[40], szColor[40];
3004
3005 icUInt32Number i, j;
3006 SIccNamedColorEntry *pNamedColor=m_NamedColor;
3007
3008 sDescription.reserve(sDescription.size() + m_nSize*79);
3009
3010 sprintf(buf, "BEGIN_NAMED_COLORS flags=%08x %u %u\n", m_nVendorFlags, m_nSize, m_nDeviceCoords);
3011 sDescription += buf;
3012
3013 sprintf(buf, "Prefix=\"%s\"\n", m_szPrefix);
3014 sDescription += buf;
3015
3016 sprintf(buf, "Sufix= \"%s\"\n", m_szSufix);
3017 sDescription += buf;
3018
3019 for (i=0; i<m_nSize; i++) {
3020 sprintf(buf, "Color[%u]: %s :", i, pNamedColor->rootName);
3021 sDescription += buf;
3022
3023 icFloatNumber pcsCoord[3] ={0};
3024 for (j=0; j<3; j++)
3025 pcsCoord[j] = pNamedColor->pcsCoords[j];
3026
3027 if (m_csPCS==icSigLabData) {
3028 for (j=0; j<3; j++)
3029 pcsCoord[j] = (icFloatNumber)(pcsCoord[j] * 65535.0 / 65280.0);
3030 }
3031
3032 for (j=0; j<3; j++) {
3033 icColorIndexName(szColor, m_csPCS, j, 3, "P");
3034 icColorValue(szColorVal, pcsCoord[j], m_csPCS, j);
3035 sprintf(buf, " %s=%s", szColor, szColorVal);
3036 sDescription += buf;
3037 }
3038 if (m_nDeviceCoords) {
3039 sDescription += " :";
3040 for (j=0; j<m_nDeviceCoords; j++) {
3041 icColorIndexName(szColor, m_csDevice, j, m_nDeviceCoords, "D");
3042 icColorValue(szColorVal, pNamedColor->deviceCoords[j], m_csDevice, j);
3043 sprintf(buf, " %s=%s", szColor, szColorVal);
3044 sDescription += buf;
3045 }
3046 }
3047 sDescription += "\n";
3048
3049 pNamedColor = (SIccNamedColorEntry*)((icChar*)pNamedColor + m_nColorEntrySize);
3050 }
3051}
3052
3053/**
3054 ****************************************************************************
3055 * Name: CIccTagNamedColor2::SetColorSpaces
3056 *
3057 * Purpose: Set the device and PCS color space of the tag
3058 *
3059 * Args:
3060 * csPCS = PCS color space signature,
3061 * csDevice = Device color space signature
3062 *
3063 *****************************************************************************
3064 */
3066{
3067 m_csPCS = csPCS;
3068 m_csDevice = csDevice;
3069}
3070
3071/**
3072 ****************************************************************************
3073 * Name: CIccTagNamedColor2::FindRootColor
3074 *
3075 * Purpose: Find the root color name
3076 *
3077 * Args:
3078 * szRootColor = string containing the root color name to be found
3079 *
3080 * Return: Index of the named color array where the root color name was found,
3081 * if the color was not found -1 is returned
3082 *****************************************************************************
3083 */
3085{
3086 for (icUInt32Number i=0; i<m_nSize; i++) {
3087 if (stricmp(m_NamedColor[i].rootName,szRootColor) == 0)
3088 return i;
3089 }
3090
3091 return -1;
3092}
3093
3094/**
3095 ****************************************************************************
3096 * Name: CIccTagNamedColor2::ResetPCSCache
3097 *
3098 * Purpose: This function is called if entry values change between calls
3099 * to FindPCSColor()
3100 *
3101 *****************************************************************************
3102 */
3104{
3105 if (m_NamedLab) {
3106 delete [] m_NamedLab;
3107 m_NamedLab = NULL;
3108 }
3109}
3110
3111/**
3112****************************************************************************
3113* Name: CIccTagNamedColor2::InitFindPCSColor
3114*
3115* Purpose: Initialization needed for using FindPCSColor
3116*
3117* Return:
3118* true if successfull, false if failure
3119*****************************************************************************
3120*/
3122{
3123 icFloatNumber *pXYZ, *pLab;
3124
3125 if (!m_NamedLab) {
3126 m_NamedLab = new SIccNamedLabEntry[m_nSize];
3127 if (!m_NamedLab)
3128 return false;
3129
3130 if (m_csPCS != icSigLabData) {
3131 for (icUInt32Number i=0; i<m_nSize; i++) {
3132 pLab = m_NamedLab[i].lab;
3133 pXYZ = m_NamedColor[i].pcsCoords;
3134 icXyzFromPcs(pXYZ);
3135 icXYZtoLab(pLab, pXYZ);
3136 }
3137 }
3138 else {
3139 for (icUInt32Number i=0; i<m_nSize; i++) {
3140 pLab = m_NamedLab[i].lab;
3141 Lab2ToLab4(pLab, m_NamedColor[i].pcsCoords);
3142 icLabFromPcs(pLab);
3143 }
3144 }
3145 }
3146
3147 return true;
3148}
3149
3150/**
3151 ****************************************************************************
3152 * Name: CIccTagNamedColor2::FindPCSColor
3153 *
3154 * Purpose: Find the PCS color within the specified deltaE
3155 *
3156 * Args:
3157 * pPCS = PCS co-ordinates,
3158 * dMinDE = the minimum deltaE (tolerance)
3159 *
3160 * Return: Index of the named color array where the PCS color was found,
3161 * if the color was not found within the tolerance -1 is returned
3162 *****************************************************************************
3163 */
3165{
3166 icFloatNumber dCalcDE, dLeastDE=0.0;
3167 icFloatNumber pLabIn[3];
3168 icFloatNumber *pXYZ, *pLab;
3169 icInt32Number leastDEindex = -1;
3170 if (m_csPCS != icSigLabData) {
3171 pXYZ = pPCS;
3172 icXyzFromPcs(pXYZ);
3173 icXYZtoLab(pLabIn,pXYZ);
3174 }
3175 else {
3176 Lab2ToLab4(pLabIn, pPCS);
3177 icLabFromPcs(pLabIn);
3178 }
3179
3180 if (!m_NamedLab)
3181 return -1;
3182
3183 for (icUInt32Number i=0; i<m_nSize; i++) {
3184 pLab = m_NamedLab[i].lab;
3185
3186 dCalcDE = icDeltaE(pLabIn, pLab);
3187
3188 if (i==0) {
3189 dLeastDE = dCalcDE;
3190 leastDEindex = i;
3191 }
3192
3193 if (dCalcDE<dMinDE) {
3194 if (dCalcDE<dLeastDE) {
3195 dLeastDE = dCalcDE;
3196 leastDEindex = i;
3197 }
3198 }
3199 }
3200
3201 return leastDEindex;
3202}
3203
3204/**
3205****************************************************************************
3206* Name: CIccTagNamedColor2::FindPCSColor
3207*
3208* Purpose: Find the PCS color within the specified deltaE
3209*
3210* Args:
3211* pPCS = PCS co-ordinates,
3212* dMinDE = the minimum deltaE (tolerance)
3213*
3214* Return: Index of the named color array where the PCS color was found,
3215* if the color was not found within the tolerance -1 is returned
3216*****************************************************************************
3217*/
3219{
3220 if (!m_NamedLab)
3221 InitFindCachedPCSColor();
3222
3223 return FindCachedPCSColor(pPCS, dMinDE);
3224}
3225
3226/**
3227 ****************************************************************************
3228 * Name: CIccTagNamedColor2::FindColor
3229 *
3230 * Purpose: Find the color with given name
3231 *
3232 * Args:
3233 * szColor = the color name
3234 *
3235 * Return: Index of the named color array where the color name was found,
3236 * if the color was not found -1 is returned
3237 *****************************************************************************
3238 */
3240{
3241 std::string sColorName;
3242 icInt32Number i, j;
3243
3244 j = (icInt32Number)strlen(m_szPrefix);
3245 if (j != 0) {
3246 if (strncmp(szColor, m_szPrefix, j))
3247 return -1;
3248 }
3249
3250 j = (icInt32Number)strlen(m_szSufix);
3251 i = (icInt32Number)strlen(szColor);
3252 if (j != 0) {
3253 if (strncmp(szColor+(i-j), m_szSufix, j))
3254 return -1;
3255 }
3256
3257
3258 for ( i=0; i<(icInt32Number)m_nSize; i++) {
3259 sColorName = m_szPrefix;
3260 sColorName += m_NamedColor[i].rootName;
3261 sColorName += m_szSufix;
3262
3263 if (strcmp(sColorName.c_str(),szColor) == 0)
3264 return i;
3265 }
3266
3267 return -1;
3268}
3269
3270/**
3271 ****************************************************************************
3272 * Name: CIccTagNamedColor2::FindDeviceColor
3273 *
3274 * Purpose: Find the device color
3275 *
3276 * Args:
3277 * pDevColor = device color co-ordinates
3278 *
3279 * Return: Index of the named color array where the closest device color
3280 * was found, if device representation is absent -1 is returned.
3281 *****************************************************************************
3282 */
3284{
3285 if (!m_nDeviceCoords)
3286 return -1;
3287
3288 icFloatNumber dCalcDiff=0.0, dLeastDiff=0.0;
3289 icFloatNumber *pDevOut;
3290 icInt32Number leastDiffindex = -1;
3291
3292
3293 for (icUInt32Number i=0; i<m_nSize; i++) {
3294 pDevOut = m_NamedColor[i].deviceCoords;
3295
3296 for (icUInt32Number j=0; j<m_nDeviceCoords; j++) {
3297 dCalcDiff += (pDevColor[j]-pDevOut[j])*(pDevColor[j]-pDevOut[j]);
3298 }
3299 dCalcDiff = (icFloatNumber)sqrt(dCalcDiff);
3300
3301 if (i==0) {
3302 dLeastDiff = dCalcDiff;
3303 leastDiffindex = i;
3304 }
3305
3306 if (dCalcDiff<dLeastDiff) {
3307 dLeastDiff = dCalcDiff;
3308 leastDiffindex = i;
3309 }
3310
3311 dCalcDiff = 0.0;
3312 }
3313
3314 return leastDiffindex;
3315}
3316
3317/**
3318 ****************************************************************************
3319 * Name: CIccTagNamedColor2::GetColorName
3320 *
3321 * Purpose: Extracts the color name from the named color array
3322 *
3323 * Args:
3324 * sColorName = string where color name will be stored,
3325 * index = array index of the color name
3326 *
3327 * Return:
3328 * true = if the index is within range,
3329 * false = index out of range
3330 *****************************************************************************
3331 */
3332bool CIccTagNamedColor2::GetColorName(std::string &sColorName, icInt32Number index) const
3333{
3334 if (index > (icInt32Number)m_nSize-1)
3335 return false;
3336
3337 sColorName += m_szPrefix;
3338 SIccNamedColorEntry * pNamedColor = (SIccNamedColorEntry*)((icChar*)m_NamedColor + m_nColorEntrySize * index);
3339 sColorName += pNamedColor->rootName;
3340 sColorName += m_szSufix;
3341
3342 return true;
3343}
3344
3345/**
3346 ****************************************************************************
3347 * Name: CIccTagNamedColor2::UnitClip
3348 *
3349 * Purpose: Clip number so that its between 0-1
3350 *
3351 * Args:
3352 * v = number to be clipped
3353 *
3354 * Return: Clipped number
3355 *
3356 *****************************************************************************
3357 */
3359{
3360 if (v<0)
3361 v = 0;
3362 if (v>1.0)
3363 v = 1.0;
3364
3365 return v;
3366}
3367
3368/**
3369 ****************************************************************************
3370 * Name: CIccTagNamedColor2::NegClip
3371 *
3372 * Purpose: Negative numbers are clipped to zero
3373 *
3374 * Args:
3375 * v = number to be clipped
3376 *
3377 * Return: Clipped number
3378 *
3379 *****************************************************************************
3380 */
3382{
3383 if (v<0)
3384 v=0;
3385
3386 return v;
3387}
3388
3389
3390/**
3391 ****************************************************************************
3392 * Name: CIccTagNamedColor2::Lab2ToLab4
3393 *
3394 * Purpose: Convert version 2 Lab to version 4 Lab
3395 *
3396 * Args:
3397 * Dst = array to store version 4 Lab coordinates,
3398 * Src = array containing version 2 Lab coordinates
3399 *
3400 *****************************************************************************
3401 */
3403{
3404 Dst[0] = UnitClip((icFloatNumber)(Src[0] * 65535.0 / 65280.0));
3405 Dst[1] = UnitClip((icFloatNumber)(Src[1] * 65535.0 / 65280.0));
3406 Dst[2] = UnitClip((icFloatNumber)(Src[2] * 65535.0 / 65280.0));
3407}
3408
3409/**
3410 ****************************************************************************
3411 * Name: CIccTagNamedColor2::Lab4ToLab2
3412 *
3413 * Purpose: Convert version 4 Lab to version 2 Lab
3414 *
3415 * Args:
3416 * Dst = array to store version 2 Lab coordinates,
3417 * Src = array containing version 4 Lab coordinates
3418 *
3419 *****************************************************************************
3420 */
3422{
3423 Dst[0] = (icFloatNumber)(Src[0] * 65280.0 / 65535.0);
3424 Dst[1] = (icFloatNumber)(Src[1] * 65280.0 / 65535.0);
3425 Dst[2] = (icFloatNumber)(Src[2] * 65280.0 / 65535.0);
3426}
3427
3428
3429/**
3430******************************************************************************
3431* Name: CIccTagNamedColor2::Validate
3432*
3433* Purpose: Check tag data validity.
3434*
3435* Args:
3436* sig = signature of tag being validated,
3437* sReport = String to add report information to
3438*
3439* Return:
3440* icValidateStatusOK if valid, or other error status.
3441******************************************************************************
3442*/
3443icValidateStatus CIccTagNamedColor2::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
3444{
3445 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
3446
3447 CIccInfo Info;
3448 std::string sSigPathName = Info.GetSigPathName(sigPath);
3449
3450 if (!m_nSize) {
3451 sReport += icMsgValidateWarning;
3452 sReport += sSigPathName;
3453 sReport += " - Empty tag!\n";
3455 }
3456
3457 if (m_nDeviceCoords) {
3458 if (pProfile) {
3459 icUInt32Number nCoords = icGetSpaceSamples(pProfile->m_Header.colorSpace);
3460 if (m_nDeviceCoords != nCoords) {
3461 sReport += icMsgValidateNonCompliant;
3462 sReport += sSigPathName;
3463 sReport += " - Incorrect number of device co-ordinates.\n";
3465 }
3466 }
3467 else {
3468 sReport += icMsgValidateWarning;
3469 sReport += sSigPathName;
3470 sReport += " - Tag validation incomplete: Pointer to profile unavailable.\n";
3472 }
3473 }
3474
3475
3476 return rv;
3477}
3478
3479
3480/**
3481 ****************************************************************************
3482 * Name: CIccTagXYZ::CIccTagXYZ
3483 *
3484 * Purpose: Constructor
3485 *
3486 * Args:
3487 * nSize = number of XYZ entries
3488 *
3489 *****************************************************************************
3490 */
3492{
3493 m_nSize = nSize;
3494 if (m_nSize <1)
3495 m_nSize = 1;
3496 m_XYZ = (icXYZNumber*)calloc(nSize, sizeof(icXYZNumber));
3497}
3498
3499
3500/**
3501 ****************************************************************************
3502 * Name: CIccTagXYZ::CIccTagXYZ
3503 *
3504 * Purpose: Copy Constructor
3505 *
3506 * Args:
3507 * ITXYZ = The CIccTagXYZ object to be copied
3508 *****************************************************************************
3509 */
3511{
3512 m_nSize = ITXYZ.m_nSize;
3513
3514 m_XYZ = (icXYZNumber*)calloc(m_nSize, sizeof(icXYZNumber));
3515 memcpy(m_XYZ, ITXYZ.m_XYZ, sizeof(icXYZNumber)*m_nSize);
3516}
3517
3518
3519
3520/**
3521 ****************************************************************************
3522 * Name: CIccTagXYZ::operator=
3523 *
3524 * Purpose: Copy Operator
3525 *
3526 * Args:
3527 * XYZTag = The CIccTagXYZ object to be copied
3528 *****************************************************************************
3529 */
3531{
3532 if (&XYZTag == this)
3533 return *this;
3534
3535 m_nSize = XYZTag.m_nSize;
3536
3537 if (m_XYZ)
3538 free(m_XYZ);
3539 m_XYZ = (icXYZNumber*)calloc(m_nSize, sizeof(icXYZNumber));
3540 memcpy(m_XYZ, XYZTag.m_XYZ, sizeof(icXYZNumber)*m_nSize);
3541
3542 return *this;
3543}
3544
3545
3546/**
3547 ****************************************************************************
3548 * Name: CIccTagXYZ::~CIccTagXYZ
3549 *
3550 * Purpose: Destructor
3551 *
3552 *****************************************************************************
3553 */
3555{
3556 if (m_XYZ)
3557 free(m_XYZ);
3558}
3559
3560
3561/**
3562 ****************************************************************************
3563 * Name: CIccTagXYZ::Read
3564 *
3565 * Purpose: Read in the tag contents into a data block
3566 *
3567 * Args:
3568 * size - # of bytes in tag,
3569 * pIO - IO object to read tag from
3570 *
3571 * Return:
3572 * true = successful, false = failure
3573 *****************************************************************************
3574 */
3576{
3578
3579 if (sizeof(icTagTypeSignature) +
3580 sizeof(icUInt32Number) +
3581 sizeof(icXYZNumber) > size)
3582 return false;
3583
3584 if (!pIO) {
3585 return false;
3586 }
3587
3588 if (!pIO->Read32(&sig))
3589 return false;
3590
3591 if (!pIO->Read32(&m_nReserved))
3592 return false;
3593
3594 icUInt32Number nNum=((size-2*sizeof(icUInt32Number)) / sizeof(icXYZNumber));
3595 icUInt32Number nNum32 = nNum*sizeof(icXYZNumber)/sizeof(icUInt32Number);
3596
3597 if (!SetSize(nNum))
3598 return false;
3599
3600 if (pIO->Read32(m_XYZ, nNum32) != (icInt32Number)nNum32 )
3601 return false;
3602
3603 return true;
3604}
3605
3606
3607/**
3608 ****************************************************************************
3609 * Name: CIccTagXYZ::Write
3610 *
3611 * Purpose: Write the tag to a file
3612 *
3613 * Args:
3614 * pIO - The IO object to write tag to.
3615 *
3616 * Return:
3617 * true = succesful, false = failure
3618 *****************************************************************************
3619 */
3621{
3622 icTagTypeSignature sig = GetType();
3623
3624 if (!pIO)
3625 return false;
3626
3627 if (!pIO->Write32(&sig))
3628 return false;
3629
3630 if (!pIO->Write32(&m_nReserved))
3631 return false;
3632
3633 icUInt32Number nNum32 = m_nSize * sizeof(icXYZNumber)/sizeof(icUInt32Number);
3634
3635 if (
3636 pIO->Write32(m_XYZ, nNum32) != (icInt32Number)nNum32)
3637 return false;
3638
3639 return true;
3640}
3641
3642
3643/**
3644 ****************************************************************************
3645 * Name: CIccTagXYZ::Describe
3646 *
3647 * Purpose: Dump data associated with the tag to a string
3648 *
3649 * Args:
3650 * sDescription - string to concatenate tag dump to
3651 *****************************************************************************
3652 */
3653void CIccTagXYZ::Describe(std::string &sDescription, int nVerboseness)
3654{
3655 icChar buf[128];
3656
3657 if (m_nSize == 1 ) {
3658 sprintf(buf, "X=%.4lf, Y=%.4lf, Z=%.4lf\n", icFtoD(m_XYZ[0].X), icFtoD(m_XYZ[0].Y), icFtoD(m_XYZ[0].Z));
3659 sDescription += buf;
3660 }
3661 else {
3663 sDescription.reserve(sDescription.size() + m_nSize*79);
3664
3665 for (i=0; i<m_nSize; i++) {
3666 sprintf(buf, "value[%u]: X=%.4lf, Y=%.4lf, Z=%.4lf\n", i, icFtoD(m_XYZ[i].X), icFtoD(m_XYZ[i].Y), icFtoD(m_XYZ[i].Z));
3667 sDescription += buf;
3668 }
3669 }
3670}
3671
3672/**
3673 ****************************************************************************
3674 * Name: CIccTagXYZ::SetSize
3675 *
3676 * Purpose: Sets the size of the XYZ array.
3677 *
3678 * Args:
3679 * nSize - number of XYZ entries,
3680 * bZeroNew - flag to zero newly formed values
3681 *****************************************************************************
3682 */
3683bool CIccTagXYZ::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
3684{
3685 if (nSize==m_nSize)
3686 return true;
3687
3688 m_XYZ = (icXYZNumber*)icRealloc(m_XYZ, nSize*sizeof(icXYZNumber));
3689
3690 if (!m_XYZ) {
3691 m_nSize = 0;
3692 return false;
3693 }
3694
3695 if (bZeroNew && m_nSize < nSize) {
3696 memset(&m_XYZ[m_nSize], 0, (nSize-m_nSize)*sizeof(icXYZNumber));
3697 }
3698 m_nSize = nSize;
3699
3700 return true;
3701}
3702
3703
3704/**
3705******************************************************************************
3706* Name: CIccTagXYZ::Validate
3707*
3708* Purpose: Check tag data validity.
3709*
3710* Args:
3711* sig = signature of tag being validated,
3712* sReport = String to add report information to
3713*
3714* Return:
3715* icValidateStatusOK if valid, or other error status.
3716******************************************************************************
3717*/
3718icValidateStatus CIccTagXYZ::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
3719{
3720 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
3721
3722 CIccInfo Info;
3723 std::string sSigPathName = Info.GetSigPathName(sigPath);
3724
3725 if (!m_nSize) {
3726 sReport += icMsgValidateWarning;
3727 sReport += sSigPathName;
3728 sReport += " - Empty tag.\n";
3729
3731 return rv;
3732 }
3733
3734 for (int i=0; i<(int)m_nSize; i++) {
3735 rv = icMaxStatus(rv, Info.CheckData(sReport, m_XYZ[i], sSigPathName + ":XYZ"));
3736 }
3737
3738 return rv;
3739}
3740
3741
3742/**
3743 ****************************************************************************
3744 * Name: CIccTagChromaticity::CIccTagChromaticity
3745 *
3746 * Purpose: Constructor
3747 *
3748 * Args:
3749 * nSize = number of xy entries
3750 *
3751 *****************************************************************************
3752 */
3754{
3755 m_nChannels = nSize;
3756 if (m_nChannels <3)
3757 m_nChannels = 3;
3758 m_xy = (icChromaticityNumber*)calloc(nSize, sizeof(icChromaticityNumber));
3759}
3760
3761
3762/**
3763 ****************************************************************************
3764 * Name: CIccTagChromaticity::CIccTagChromaticity
3765 *
3766 * Purpose: Copy Constructor
3767 *
3768 * Args:
3769 * ITCh = The CIccTagChromaticity object to be copied
3770 *****************************************************************************
3771 */
3773{
3774 m_nChannels = ITCh.m_nChannels;
3775
3776 m_xy = (icChromaticityNumber*)calloc(m_nChannels, sizeof(icChromaticityNumber));
3777 memcpy(m_xy, ITCh.m_xy, sizeof(icChromaticityNumber)*m_nChannels);
3778}
3779
3780
3781/**
3782 ****************************************************************************
3783 * Name: CIccTagChromaticity::operator=
3784 *
3785 * Purpose: Copy Operator
3786 *
3787 * Args:
3788 * ChromTag = The CIccTagChromaticity object to be copied
3789 *****************************************************************************
3790 */
3792{
3793 if (&ChromTag == this)
3794 return *this;
3795
3796 m_nChannels = ChromTag.m_nChannels;
3797
3798 if (m_xy)
3799 free(m_xy);
3800 m_xy = (icChromaticityNumber*)calloc(m_nChannels, sizeof(icChromaticityNumber));
3801 memcpy(m_xy, ChromTag.m_xy, sizeof(icChromaticityNumber)*m_nChannels);
3802
3803 return *this;
3804}
3805
3806
3807/**
3808 ****************************************************************************
3809 * Name: CIccTagChromaticity::~CIccTagChromaticity
3810 *
3811 * Purpose: Destructor
3812 *
3813 *****************************************************************************
3814 */
3816{
3817 if (m_xy)
3818 free(m_xy);
3819}
3820
3821
3822/**
3823 ****************************************************************************
3824 * Name: CIccTagChromaticity::Read
3825 *
3826 * Purpose: Read in the tag contents into a data block
3827 *
3828 * Args:
3829 * size - # of bytes in tag,
3830 * pIO - IO object to read tag from
3831 *
3832 * Return:
3833 * true = successful, false = failure
3834 *****************************************************************************
3835 */
3837{
3839 icUInt16Number nChannels;
3840
3841 if (sizeof(icTagTypeSignature) +
3842 sizeof(icUInt32Number) +
3843 sizeof(icUInt32Number) +
3844 sizeof(icChromaticityNumber) > size)
3845 return false;
3846
3847 if (!pIO) {
3848 return false;
3849 }
3850
3851 if (!pIO->Read32(&sig))
3852 return false;
3853
3854 if (!pIO->Read32(&m_nReserved))
3855 return false;
3856
3857 if (!pIO->Read16(&nChannels) ||
3858 !pIO->Read16(&m_nColorantType))
3859 return false;
3860
3861 icUInt32Number nNum = (size-3*sizeof(icUInt32Number)) / sizeof(icChromaticityNumber);
3862 icUInt32Number nNum32 = (nNum*sizeof(icChromaticityNumber)) / sizeof(icU16Fixed16Number);
3863
3864 if (nNum < nChannels)
3865 return false;
3866
3867 // SetSize casts from icUInt32Number down to icUInt16Number. Check for overflow
3868 if (nNum > (icUInt16Number)nNum)
3869 return false;
3870
3871 if (!SetSize((icUInt16Number)nNum))
3872 return false;
3873
3874 if (pIO->Read32(&m_xy[0], nNum32) != (icInt32Number)nNum32 )
3875 return false;
3876
3877 return true;
3878}
3879
3880
3881/**
3882 ****************************************************************************
3883 * Name: CIccTagChromaticity::Write
3884 *
3885 * Purpose: Write the tag to a file
3886 *
3887 * Args:
3888 * pIO - The IO object to write tag to.
3889 *
3890 * Return:
3891 * true = succesful, false = failure
3892 *****************************************************************************
3893 */
3895{
3896 icTagTypeSignature sig = GetType();
3897
3898 if (!pIO)
3899 return false;
3900
3901 if (!pIO->Write32(&sig))
3902 return false;
3903
3904 if (!pIO->Write32(&m_nReserved))
3905 return false;
3906
3907 if (!pIO->Write16(&m_nChannels))
3908 return false;
3909
3910 if (!pIO->Write16(&m_nColorantType))
3911 return false;
3912
3913 icUInt32Number nNum32 = m_nChannels*sizeof(icChromaticityNumber)/sizeof(icU16Fixed16Number);
3914
3915 if (pIO->Write32(&m_xy[0], nNum32) != (icInt32Number)nNum32)
3916 return false;
3917
3918 return true;
3919}
3920
3921
3922/**
3923 ****************************************************************************
3924 * Name: CIccTagChromaticity::Describe
3925 *
3926 * Purpose: Dump data associated with the tag to a string
3927 *
3928 * Args:
3929 * sDescription - string to concatenate tag dump to
3930 *****************************************************************************
3931 */
3932void CIccTagChromaticity::Describe(std::string &sDescription, int nVerboseness)
3933{
3934 icChar buf[128];
3935 CIccInfo Fmt;
3936
3938 //sDescription.reserve(sDescription.size() + m_nChannels*79);
3939 sprintf(buf, "Number of Channels : %u\n", m_nChannels);
3940 sDescription += buf;
3941
3942 sprintf(buf, "Colorant Encoding : %s\n", Fmt.GetColorantEncoding((icColorantEncoding)m_nColorantType));
3943 sDescription += buf;
3944
3945 for (i=0; i<m_nChannels; i++) {
3946 sprintf(buf, "value[%u]: x=%.3lf, y=%.3lf\n", i, icUFtoD(m_xy[i].x), icUFtoD(m_xy[i].y));
3947 sDescription += buf;
3948 }
3949
3950}
3951
3952/**
3953 ****************************************************************************
3954 * Name: CIccTagChromaticity::SetSize
3955 *
3956 * Purpose: Sets the size of the xy chromaticity array.
3957 *
3958 * Args:
3959 * nSize - number of xy entries,
3960 * bZeroNew - flag to zero newly formed values
3961 *****************************************************************************
3962 */
3963bool CIccTagChromaticity::SetSize(icUInt16Number nSize, bool bZeroNew/*=true*/)
3964{
3965 if (m_nChannels == nSize)
3966 return true;
3967
3968 m_xy = (icChromaticityNumber*)icRealloc(m_xy, nSize*sizeof(icChromaticityNumber));
3969
3970 if (!m_xy) {
3971 m_nChannels = 0;
3972 return false;
3973 }
3974
3975 if (bZeroNew && nSize > m_nChannels) {
3976 memset(&m_xy[m_nChannels], 0, (nSize - m_nChannels)*sizeof(icChromaticityNumber));
3977 }
3978
3979 m_nChannels = nSize;
3980 return true;
3981}
3982
3983
3984/**
3985******************************************************************************
3986* Name: CIccTagChromaticity::Validate
3987*
3988* Purpose: Check tag data validity.
3989*
3990* Args:
3991* sig = signature of tag being validated,
3992* sReport = String to add report information to
3993*
3994* Return:
3995* icValidateStatusOK if valid, or other error status.
3996******************************************************************************
3997*/
3998icValidateStatus CIccTagChromaticity::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
3999{
4000 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
4001
4002 CIccInfo Info;
4003 std::string sSigPathName = Info.GetSigPathName(sigPath);
4004
4005 if (m_nColorantType) {
4006
4007 if (m_nChannels!=3) {
4008 sReport += icMsgValidateCriticalError;
4009 sReport += sSigPathName;
4010 sReport += " - Number of device channels must be three.\n";
4012 }
4013
4014 switch(m_nColorantType) {
4015 case icColorantITU:
4016 {
4017 if ( (m_xy[0].x != icDtoUF((icFloatNumber)0.640)) || (m_xy[0].y != icDtoUF((icFloatNumber)0.330)) ||
4018 (m_xy[1].x != icDtoUF((icFloatNumber)0.300)) || (m_xy[1].y != icDtoUF((icFloatNumber)0.600)) ||
4019 (m_xy[2].x != icDtoUF((icFloatNumber)0.150)) || (m_xy[2].y != icDtoUF((icFloatNumber)0.060)) ) {
4020 sReport += icMsgValidateNonCompliant;
4021 sReport += sSigPathName;
4022 sReport += " - Chromaticity data does not match specification.\n";
4024 }
4025 break;
4026 }
4027
4028 case icColorantSMPTE:
4029 {
4030 if ( (m_xy[0].x != icDtoUF((icFloatNumber)0.630)) || (m_xy[0].y != icDtoUF((icFloatNumber)0.340)) ||
4031 (m_xy[1].x != icDtoUF((icFloatNumber)0.310)) || (m_xy[1].y != icDtoUF((icFloatNumber)0.595)) ||
4032 (m_xy[2].x != icDtoUF((icFloatNumber)0.155)) || (m_xy[2].y != icDtoUF((icFloatNumber)0.070)) ) {
4033 sReport += icMsgValidateNonCompliant;
4034 sReport += sSigPathName;
4035 sReport += " - Chromaticity data does not match specification.\n";
4037 }
4038 break;
4039 }
4040
4041 case icColorantEBU:
4042 {
4043 if ( (m_xy[0].x != icDtoUF((icFloatNumber)0.64)) || (m_xy[0].y != icDtoUF((icFloatNumber)0.33)) ||
4044 (m_xy[1].x != icDtoUF((icFloatNumber)0.29)) || (m_xy[1].y != icDtoUF((icFloatNumber)0.60)) ||
4045 (m_xy[2].x != icDtoUF((icFloatNumber)0.15)) || (m_xy[2].y != icDtoUF((icFloatNumber)0.06)) ) {
4046 sReport += icMsgValidateNonCompliant;
4047 sReport += sSigPathName;
4048 sReport += " - Chromaticity data does not match specification.\n";
4050 }
4051 break;
4052 }
4053
4054 case icColorantP22:
4055 {
4056 if ( (m_xy[0].x != icDtoUF((icFloatNumber)0.625)) || (m_xy[0].y != icDtoUF((icFloatNumber)0.340)) ||
4057 (m_xy[1].x != icDtoUF((icFloatNumber)0.280)) || (m_xy[1].y != icDtoUF((icFloatNumber)0.605)) ||
4058 (m_xy[2].x != icDtoUF((icFloatNumber)0.155)) || (m_xy[2].y != icDtoUF((icFloatNumber)0.070)) ) {
4059 sReport += icMsgValidateNonCompliant;
4060 sReport += sSigPathName;
4061 sReport += " - Chromaticity data does not match specification.\n";
4063 }
4064 break;
4065 }
4066
4067 default:
4068 {
4069 sReport += icMsgValidateNonCompliant;
4070 sReport += sSigPathName;
4071 sReport += " - Invalid colorant type encoding.\n";
4073 }
4074 }
4075 }
4076
4077 return rv;
4078}
4079
4080
4081/**
4082 ****************************************************************************
4083 * Name: CIccTagCicp::CIccTagCicp
4084 *
4085 * Purpose: Constructor
4086 *
4087 * Args:
4088 * nSize = number of XYZ entries
4089 *
4090 *****************************************************************************
4091 */
4093{
4094 m_nColorPrimaries = 0;
4095 m_nTransferCharacteristics = 0;
4096 m_nMatrixCoefficients = 0;
4097 m_nVideoFullRangeFlag = 0;
4098}
4099
4100
4101/**
4102 ****************************************************************************
4103 * Name: CIccTagCicp::CIccTagCicp
4104 *
4105 * Purpose: Copy Constructor
4106 *
4107 * Args:
4108 * ITCICP = The CIccTagCicp object to be copied
4109 *****************************************************************************
4110 */
4112{
4113}
4114
4115
4116
4117/**
4118 ****************************************************************************
4119 * Name: CIccTagCicp::operator=
4120 *
4121 * Purpose: Copy Operator
4122 *
4123 * Args:
4124 * cicpTag = The CIccTagCicp object to be copied
4125 *****************************************************************************
4126 */
4128{
4129 if (&cicpTag == this)
4130 return *this;
4131
4132 m_nColorPrimaries = cicpTag.m_nColorPrimaries;
4133 m_nTransferCharacteristics = cicpTag.m_nTransferCharacteristics;
4134 m_nMatrixCoefficients = cicpTag.m_nMatrixCoefficients;
4135 m_nVideoFullRangeFlag = cicpTag.m_nVideoFullRangeFlag;
4136
4137 return *this;
4138}
4139
4140
4141/**
4142 ****************************************************************************
4143 * Name: CIccTagCicp::~CIccTagCicp
4144 *
4145 * Purpose: Destructor
4146 *
4147 *****************************************************************************
4148 */
4152
4153
4154/**
4155 ****************************************************************************
4156 * Name: CIccTagCicp::Read
4157 *
4158 * Purpose: Read in the tag contents into a data block
4159 *
4160 * Args:
4161 * size - # of bytes in tag,
4162 * pIO - IO object to read tag from
4163 *
4164 * Return:
4165 * true = successful, false = failure
4166 *****************************************************************************
4167 */
4169{
4171
4172 if (sizeof(icTagTypeSignature) +
4173 sizeof(icUInt32Number) +
4174 sizeof(icUInt8Number)*4 > size)
4175 return false;
4176
4177 if (!pIO) {
4178 return false;
4179 }
4180
4181 if (!pIO->Read32(&sig))
4182 return false;
4183
4184 if (!pIO->Read32(&m_nReserved))
4185 return false;
4186
4187 if (!pIO->Read8(&m_nColorPrimaries) ||
4188 !pIO->Read8(&m_nTransferCharacteristics) ||
4189 !pIO->Read8(&m_nMatrixCoefficients) ||
4190 !pIO->Read8(&m_nVideoFullRangeFlag))
4191 return false;
4192
4193 return true;
4194}
4195
4196
4197/**
4198 ****************************************************************************
4199 * Name: CIccTagCicp::Write
4200 *
4201 * Purpose: Write the tag to a file
4202 *
4203 * Args:
4204 * pIO - The IO object to write tag to.
4205 *
4206 * Return:
4207 * true = succesful, false = failure
4208 *****************************************************************************
4209 */
4211{
4212 icTagTypeSignature sig = GetType();
4213
4214 if (!pIO)
4215 return false;
4216
4217 if (!pIO->Write32(&sig))
4218 return false;
4219
4220 if (!pIO->Write32(&m_nReserved))
4221 return false;
4222
4223 if (!pIO->Write8(&m_nColorPrimaries) ||
4224 !pIO->Write8(&m_nTransferCharacteristics) ||
4225 !pIO->Write8(&m_nMatrixCoefficients) ||
4226 !pIO->Write8(&m_nVideoFullRangeFlag))
4227 return false;
4228
4229 return true;
4230}
4231
4232
4233static struct {
4234 const char* code;
4235 const char* interp;
4236} icExampleCicpCodes[] = {
4237 { "1-1-0-0", "RGB narrow range representation specified in Recommendation ITU-R BT.709-6, Item 3.4"},
4238 { "1-13-0-1", "RGB full range representation specified in IEC 61966-2-1 sRGB"},
4239 { "9-14-0-0", "R’G’B’ narrow range representation specified in Recommendation ITU-R BT.2020-2, Table 5"},
4240 { "9-16-0-0", "PQ R’G’B’ narrow range representation specified in Recommendation ITU-R BT.2100-2, Table 9"},
4241 { "9-16-0-1", "PQ R’G’B’ full range representation specified in Recommendation ITU-R BT.2100-2, Table 9"},
4242 { "9-18-0-0 ", "HLG R’G’B’ narrow range representation specified in Recommendation ITU-R BT.2100-2 "},
4243 { "9-18-0-1", "HLG R’G’B’ full range representation specified in Recommendation ITU-R BT.2100-2"},
4244 { "1-1-1-0 ", "YCbCr representation specified in Recommendation ITU-R BT.709-6, Item 3.4"},
4245 { "9-14-9-0", "Y’Cb’Cr’ narrow range representation specified in Recommendation ITU-R BT.2020-2, Table 5"},
4246 { "9-16-9-0", "PQ Y’Cb’Cr’ narrow range representation specified in Recommendation ITU-R BT.2100-2, Table 9"},
4247 { "9-16-14-0", "PQ ICtCp narrow range representation specified in Recommendation ITU-R BT.2100-2, Table 9"},
4248 { "9-18-9-0", "HLG Y’Cb’Cr’ narrow range representation specified in Recommendation ITU-R BT.2100-2"},
4249 { "9-18-14-0 ", "HLG ICtCp narrow range representation specified in Recommendation ITU-R BT.2100-2"},
4250 { NULL, NULL},
4252
4253/**
4254 ****************************************************************************
4255 * Name: CIccTagCicp::Describe
4256 *
4257 * Purpose: Dump data associated with the tag to a string
4258 *
4259 * Args:
4260 * sDescription - string to concatenate tag dump to
4261 *****************************************************************************
4262 */
4263void CIccTagCicp::Describe(std::string& sDescription, int nVerboseness)
4264{
4265 icChar buf[256], code[128];
4266 sprintf(code, "%u-%u-%u-%u", m_nColorPrimaries, m_nTransferCharacteristics, m_nMatrixCoefficients, m_nVideoFullRangeFlag);
4267
4268 sprintf(buf, "ColorPrimaries=%u\r\n", m_nColorPrimaries);
4269 sDescription += buf;
4270
4271 sprintf(buf, "TransferCharacteristics=%u\r\n", m_nTransferCharacteristics);
4272 sDescription += buf;
4273
4274 sprintf(buf, "MatrixCoefficients=%u\r\n", m_nMatrixCoefficients);
4275 sDescription += buf;
4276
4277 sprintf(buf, "VideoFullRangeFlag=%u\r\n\r\n", m_nVideoFullRangeFlag);
4278 sDescription += buf;
4279
4280 sprintf(buf, "Combined Code: %s\r\n", code);
4281 sDescription += buf;
4282
4283 int i;
4284 for (i = 0; icExampleCicpCodes[i].code; i++)
4285 if (!strcmp(code, icExampleCicpCodes[i].code))
4286 break;
4287
4288 sDescription += "Interpretation: ";
4289 if (icExampleCicpCodes[i].code) {
4290 sDescription += icExampleCicpCodes[i].interp;
4291 }
4292 else {
4293 sDescription += "unknown";
4294 }
4295 sDescription += "\r\n";
4296}
4297
4298
4299/**
4300 ****************************************************************************
4301 * Name: CIccTagCicp::GetFields
4302 *
4303 * Purpose: gets the ITU-T H.273 field values
4304 *
4305 * Args:
4306 * meaning of args as named
4307 *****************************************************************************
4308 */
4310 icUInt8Number &transferCharacteristics,
4311 icUInt8Number &matrixCoefficients,
4312 icUInt8Number &videoFullRangeFlag)
4313{
4314 colorPrimaries = m_nColorPrimaries;
4315 transferCharacteristics = m_nTransferCharacteristics;
4316 matrixCoefficients = m_nMatrixCoefficients;
4317 videoFullRangeFlag = m_nVideoFullRangeFlag;
4318}
4319
4320
4321/**
4322 ****************************************************************************
4323 * Name: CIccTagCicp::SetFields
4324 *
4325 * Purpose: Sets the ITU-T H.273 field values
4326 *
4327 * Args:
4328 * meaning of args as named
4329 *****************************************************************************
4330 */
4332 icUInt8Number transferCharacteristics,
4333 icUInt8Number matrixCoefficients,
4334 icUInt8Number videoFullRangeFlag)
4335{
4336 m_nColorPrimaries = colorPrimaries;
4337 m_nTransferCharacteristics = transferCharacteristics;
4338 m_nMatrixCoefficients =matrixCoefficients;
4339 m_nVideoFullRangeFlag = videoFullRangeFlag;
4340}
4341
4342
4343/**
4344******************************************************************************
4345* Name: CIccTagCicp::Validate
4346*
4347* Purpose: Check tag data validity.
4348*
4349* Args:
4350* sig = signature of tag being validated,
4351* sReport = String to add report information to
4352* pProfile = profile containing tag
4353*
4354* Return:
4355* icValidateStatusOK if valid, or other error status.
4356******************************************************************************
4357*/
4358icValidateStatus CIccTagCicp::Validate(std::string sigPath, std::string& sReport, const CIccProfile* pProfile/*=NULL*/) const
4359{
4360 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
4361
4362 CIccInfo Info;
4363 std::string sSigPathName = Info.GetSigPathName(sigPath);
4364
4365 if (!pProfile)
4366 return rv;
4367
4368 if ((pProfile->m_Header.colorSpace == icSigRgbData || pProfile->m_Header.colorSpace == icSigXYZData) && m_nMatrixCoefficients) {
4369 sReport += icMsgValidateNonCompliant;
4370 sReport += sSigPathName;
4371 sReport += " - CICP MatrixCoefficients not zero for RGB or XYZ colour space data.\r\n";
4373 }
4374
4375 if (pProfile->m_Header.colorSpace == icSigYCbCrData && !m_nMatrixCoefficients) {
4376 sReport += icMsgValidateNonCompliant;
4377 sReport += sSigPathName;
4378 sReport += " - CICP MatrixCoefficients zero for YCbCr colour space data.\r\n";
4380 }
4381
4382 return rv;
4383}
4384
4385
4386
4387/**
4388 ****************************************************************************
4389 * Name: CIccTagSparseMatrixArray::CIccTagSparseMatrixArray
4390 *
4391 * Purpose: CIccTagSparseMatrixArray Constructor
4392 *
4393 * Args:
4394 * nSize = number of data entries
4395 *
4396 *****************************************************************************
4397 */
4398CIccTagSparseMatrixArray::CIccTagSparseMatrixArray(int nNumMatrices/* =1 */, int nChannelsPerMatrix/* =4 */)
4399{
4400 m_nSize = nNumMatrices;
4401 m_nChannelsPerMatrix = nChannelsPerMatrix;
4402 m_nMatrixType = icSparseMatrixFloat32;
4403
4404 if (m_nSize <1)
4405 m_nSize = 1;
4406 if (nChannelsPerMatrix<4)
4407 m_nChannelsPerMatrix = 4;
4408
4409 m_RawData = (icUInt8Number*)calloc(m_nSize, GetBytesPerMatrix());
4410
4411 m_bNonZeroPadding = false;
4412}
4413
4414
4415/**
4416 ****************************************************************************
4417 * Name: CIccTagSparseMatrixArray::CIccTagSparseMatrixArray
4418 *
4419 * Purpose: Copy Constructor
4420 *
4421 * Args:
4422 * ITFN = The CIccTagFixedNum object to be copied
4423 *****************************************************************************
4424 */
4426{
4427 m_nSize = ITSMA.m_nSize;
4428 m_nChannelsPerMatrix = ITSMA.m_nChannelsPerMatrix;
4429 m_nMatrixType = ITSMA.m_nMatrixType;
4430
4431 m_RawData = (icUInt8Number*)calloc(m_nSize, GetBytesPerMatrix());
4432 memcpy(m_RawData, ITSMA.m_RawData, m_nSize*GetBytesPerMatrix());
4433
4434 m_bNonZeroPadding = ITSMA.m_bNonZeroPadding;
4435}
4436
4437
4438/**
4439 ****************************************************************************
4440 * Name: CIccTagSparseMatrixArray::operator=
4441 *
4442 * Purpose: Copy Operator
4443 *
4444 * Args:
4445 * ITFN = The CIccTagSparseMatrixArray object to be copied
4446 *****************************************************************************
4447 */
4449{
4450 if (&ITSMA == this)
4451 return *this;
4452
4453 m_nSize = ITSMA.m_nSize;
4454 m_nChannelsPerMatrix = ITSMA.m_nChannelsPerMatrix;
4455
4456 if (m_RawData)
4457 free(m_RawData);
4458 m_RawData = (icUInt8Number*)calloc(m_nSize, m_nChannelsPerMatrix);
4459 memcpy(m_RawData, ITSMA.m_RawData, m_nSize*GetBytesPerMatrix());
4460
4461 m_bNonZeroPadding = ITSMA.m_bNonZeroPadding;
4462
4463 return *this;
4464}
4465
4466
4467
4468/**
4469 ****************************************************************************
4470 * Name: CIccTagSparseMatrixArray::~CIccTagSparseMatrixArray
4471 *
4472 * Purpose: Destructor
4473 *
4474 *****************************************************************************
4475 */
4477{
4478 if (m_RawData)
4479 free(m_RawData);
4480}
4481
4482
4483/**
4484 ****************************************************************************
4485 * Name: CIccTagSparseMatrixArray::Read
4486 *
4487 * Purpose: Read in the tag contents into a data block
4488 *
4489 * Args:
4490 * size - # of bytes in tag,
4491 * pIO - IO object to read tag from
4492 *
4493 * Return:
4494 * true = successful, false = failure
4495 *****************************************************************************
4496 */
4498{
4500 icUInt16Number nChannels;
4501 icUInt16Number nMatrixType;
4502 icUInt32Number nBytesPerMatrix;
4503 icUInt32Number nNumMatrices;
4504
4505 icUInt32Number nHdrSize = sizeof(icTagTypeSignature) +
4506 sizeof(icUInt32Number) +
4507 2*sizeof(icUInt16Number) +
4508 sizeof(icUInt32Number);
4509
4510 if (nHdrSize +sizeof(icUInt16Number) > size)
4511 return false;
4512
4513 if (!pIO) {
4514 return false;
4515 }
4516
4517 if (!pIO->Read32(&sig) ||
4518 !pIO->Read32(&m_nReserved) ||
4519 !pIO->Read16(&nChannels) ||
4520 !pIO->Read16(&nMatrixType) ||
4521 !pIO->Read32(&nNumMatrices))
4522 return false;
4523
4524 m_nMatrixType = (icSparseMatrixType)nMatrixType;
4525
4526 icUInt32Number nSizeLeft = size - nHdrSize;
4527
4528 Reset(nNumMatrices, nChannels);
4529 nBytesPerMatrix = GetBytesPerMatrix();
4530
4531 if (m_nSize) {
4532 icUInt32Number pos;
4533 icUInt16Number nRows;
4534
4535 int i, j;
4536 icUInt32Number n, nAligned;
4537 CIccSparseMatrix mtx;
4538
4539 m_bNonZeroPadding = false;
4540
4541 pos = nHdrSize;
4542 for (i=0; i<(int)m_nSize; i++) {
4543 icUInt8Number *pMatrix = m_RawData + i*nBytesPerMatrix;
4544
4545 n=2*sizeof(icUInt16Number);
4546
4547 if (nSizeLeft<n)
4548 return false;
4549 if (pIO->Read16(pMatrix, 2)!=2) {
4550 return false;
4551 }
4552
4553 nSizeLeft -= n;
4554 pos += n;
4555
4556 nRows = *((icUInt16Number*)pMatrix);
4557
4558 n=(nRows+1)*sizeof(icUInt16Number);
4559
4560 if (nSizeLeft<n)
4561 return false;
4562 if (pIO->Read16(pMatrix+2*sizeof(icUInt16Number), nRows+1)!=nRows+1) {
4563 return false;
4564 }
4565
4566 nSizeLeft -= n;
4567 pos += n;
4568 mtx.Reset(pMatrix, nBytesPerMatrix, icSparseMatrixFloatNum, true);
4569
4570 if (mtx.GetNumEntries()>mtx.MaxEntries(nChannels*sizeof(icFloatNumber), mtx.Rows(), sizeof(icFloatNumber)))
4571 return false;
4572
4573 n=mtx.GetNumEntries()*sizeof(icUInt16Number);
4574
4575 if (nSizeLeft<n)
4576 return false;
4577
4578 if (pIO->Read16(mtx.GetColumnsForRow(0), mtx.GetNumEntries())!=mtx.GetNumEntries())
4579 return false;
4580
4581 nSizeLeft -= n;
4582 pos += n;
4583
4584 nAligned = ((pos+3)/4)*4;
4585 if (nAligned != pos) {
4586 n = nAligned - pos;
4587 if (nSizeLeft < n)
4588 return false;
4589
4590 char zbuf[3] = { 0 };
4591 if (pIO->Read8(&zbuf[0], n)!=n)
4592 return false;
4593 for (j=0; j<(int)n; j++) {
4594 if (zbuf[j])
4595 m_bNonZeroPadding = true;
4596 }
4597
4598 nSizeLeft -= n;
4599 pos += n;
4600 }
4601
4602 switch(m_nMatrixType) {
4604 n=mtx.GetNumEntries()*sizeof(icUInt8Number);
4605 if (nSizeLeft<n)
4606 return false;
4607
4608 if (pIO->ReadUInt8Float(mtx.GetData()->getPtr(0), mtx.GetNumEntries())!=mtx.GetNumEntries())
4609 return false;
4610
4611 break;
4612
4614 n=mtx.GetNumEntries()*sizeof(icUInt16Number);
4615 if (nSizeLeft<n)
4616 return false;
4617
4618 if (pIO->ReadUInt16Float(mtx.GetData()->getPtr(0), mtx.GetNumEntries())!=mtx.GetNumEntries())
4619 return false;
4620
4621 break;
4622
4624 n=mtx.GetNumEntries()*sizeof(icFloat16Number);
4625 if (nSizeLeft<n)
4626 return false;
4627
4628 if (pIO->ReadFloat16Float(mtx.GetData()->getPtr(0), mtx.GetNumEntries())!=mtx.GetNumEntries())
4629 return false;
4630
4631 break;
4632
4634 n=mtx.GetNumEntries()*sizeof(icFloat32Number);
4635 if (nSizeLeft<n)
4636 return false;
4637
4638 if (pIO->ReadFloat32Float(mtx.GetData()->getPtr(0), mtx.GetNumEntries())!=mtx.GetNumEntries())
4639 return false;
4640
4641 break;
4642
4643 default:
4644 return false;
4645 }
4646 nSizeLeft -= n;
4647 pos += n;
4648
4649 nAligned = ((pos+3)/4)*4;
4650 if (nAligned != pos) {
4651 n = nAligned - pos;
4652 if (nSizeLeft < n)
4653 return false;
4654
4655 icUInt8Number zbuf[3] = { 0 };
4656 if (pIO->Read8(&zbuf[0], n)!=n)
4657 return false;
4658 for (j=0; j<(int)n; j++) {
4659 if (zbuf[j])
4660 m_bNonZeroPadding = true;
4661 }
4662
4663 nSizeLeft -= n;
4664 pos += n;
4665 }
4666 }
4667 if (nSizeLeft) {
4668 icUInt8Number b;
4669 for (i=0; i<(int)nSizeLeft; i++) {
4670 if (!pIO->Read8(&b))
4671 return false;
4672 if (b)
4673 m_bNonZeroPadding = true;
4674 }
4675 }
4676 }
4677
4678 return true;
4679}
4680
4681
4682/**
4683 ****************************************************************************
4684 * Name: CIccTagSparseMatrixArray::Write
4685 *
4686 * Purpose: Write the tag to a file
4687 *
4688 * Args:
4689 * pIO - The IO object to write tag to.
4690 *
4691 * Return:
4692 * true = succesful, false = failure
4693 *****************************************************************************
4694 */
4696{
4697 icTagTypeSignature sig = GetType();
4698 icUInt16Number nTemp = m_nMatrixType;
4699
4700 if (!pIO)
4701 return false;
4702
4703 if (!pIO->Write32(&sig) ||
4704 !pIO->Write32(&m_nReserved) ||
4705 !pIO->Write16(&m_nChannelsPerMatrix) ||
4706 !pIO->Write16(&nTemp) ||
4707 !pIO->Write32(&m_nSize))
4708 return false;
4709
4710 icUInt32Number nBytesPerMatrix = m_nChannelsPerMatrix * sizeof(icFloatNumber);
4711 CIccSparseMatrix mtx;
4712 icUInt16Number nRows;
4713 int i, n;
4714
4715 for (i=0; i<(int)m_nSize; i++) {
4716 icUInt8Number *pMatrix = m_RawData + i*nBytesPerMatrix;
4717 mtx.Reset(pMatrix, nBytesPerMatrix, icSparseMatrixFloatNum, true);
4718 nRows = mtx.Rows();
4719
4720 n=(nRows+3)*sizeof(icUInt16Number);
4721
4722 if (pIO->Write16(pMatrix, nRows+3)!=nRows+3 ||
4723 pIO->Write16(mtx.GetColumnsForRow(0), mtx.GetNumEntries())!=mtx.GetNumEntries()) {
4724 return false;
4725 }
4726
4727 if (!pIO->Align32())
4728 return false;
4729
4730 switch(m_nMatrixType) {
4732 if (pIO->WriteUInt8Float(mtx.GetData()->getPtr(), mtx.GetNumEntries())!=mtx.GetNumEntries()) {
4733 return false;
4734 }
4735 break;
4737 if (pIO->WriteUInt16Float(mtx.GetData()->getPtr(), mtx.GetNumEntries())!=mtx.GetNumEntries()) {
4738 return false;
4739 }
4740 break;
4742 if (pIO->WriteFloat16Float(mtx.GetData()->getPtr(), mtx.GetNumEntries())!=mtx.GetNumEntries()) {
4743 return false;
4744 }
4745 break;
4747 if (pIO->WriteFloat32Float(mtx.GetData()->getPtr(), mtx.GetNumEntries())!=mtx.GetNumEntries()) {
4748 return false;
4749 }
4750 break;
4751 default:
4752 return false;
4753 }
4754
4755 if (!pIO->Align32())
4756 return false;
4757
4758 }
4759
4760 return true;
4761}
4762
4763/**
4764 ****************************************************************************
4765 * Name: CIccTagSparseMatrixArray::Describe
4766 *
4767 * Purpose: Dump data associated with the tag to a string
4768 *
4769 * Args:
4770 * sDescription - string to concatenate tag dump to
4771 *****************************************************************************
4772 */
4773void CIccTagSparseMatrixArray::Describe(std::string &sDescription, int nVerboseness)
4774{
4775 icChar buf[128];
4776
4777 sDescription += "Begin_SparseMatrix_Array\n";
4778 sprintf(buf, "OutputChannels = %d\n", m_nChannelsPerMatrix);
4779 sDescription += buf;
4780 sprintf(buf, "MatrixType = %d\n", m_nMatrixType);
4781 sDescription += buf;
4782
4783 int i, r, c;
4784 icUInt32Number nBytesPerMatrix = m_nChannelsPerMatrix * sizeof(icFloatNumber);
4785 for (i=0; i<(int)m_nSize; i++) {
4786 CIccSparseMatrix mtx(&m_RawData[i*nBytesPerMatrix], nBytesPerMatrix, icSparseMatrixFloatNum, true);
4787
4788 sprintf(buf, "\nBegin_Matrix_%d\n", i);
4789 sDescription += buf;
4790
4791 icUInt16Number *start = mtx.GetRowStart();
4792 icUInt16Number *cols = mtx.GetColumnsForRow(0);
4793 for (r=0; r<mtx.Rows(); r++) {
4794 icUInt16Number rs = start[r];
4795 icUInt16Number re = start[r+1];
4796 sprintf(buf, "Row%d:", r);
4797 sDescription += buf;
4798
4799 for (c=rs; c<re; c++) {
4800 sprintf(buf, " (%d, %.4lf)", cols[c], mtx.GetData()->get(c));
4801 sDescription += buf;
4802 }
4803 }
4804
4805 sprintf(buf, "End_Matrix_%d\n", i);
4806 sDescription += buf;
4807 }
4808 sDescription += "\nEnd_SparseMatrix_Array\n";
4809
4810}
4811
4812/**
4813 ****************************************************************************
4814 * Name: CIccTagSparseMatrixArray::Validate
4815 *
4816 * Purpose: Validates tag data
4817 *
4818 * Args:
4819 * sigPath - signature path of tag in profile to validate
4820 * sReport - string to put validation report results
4821 * profile - pointer to profile that contains the tag
4822 *****************************************************************************
4823 */
4824icValidateStatus CIccTagSparseMatrixArray::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
4825{
4827 CIccInfo Info;
4828 std::string sSigPathName = Info.GetSigPathName(sigPath);
4829
4830 switch(m_nMatrixType) {
4835 break;
4836 default:
4837 sReport += icMsgValidateCriticalError;
4838 sReport += sSigPathName;
4839 sReport += " - Invalid Sparse Matrix Type.\n";
4841
4842 }
4843
4844 bool bCheckPCS=false;
4845
4846 icSignature sig1 = icGetFirstSigPathSig(sigPath);
4847 icSignature sig2 = icGetSecondSigPathSig(sigPath);
4848
4849 if (sig1==icSigSpectralWhitePointTag) {
4850 bCheckPCS = true;
4851 }
4852
4853 if (bCheckPCS && pProfile) {
4854 if (!icIsSameColorSpaceType(pProfile->m_Header.spectralPCS, icSigSparseMatrixReflectanceData)) {
4855 sReport += icMsgValidateCriticalError;
4856 sReport += sSigPathName;
4857 sReport += " - SparseMatrix data incompatible with spectral PCS.\n";
4859 }
4860 else if (icGetSpaceSamples((icColorSpaceSignature)pProfile->m_Header.spectralPCS)!=m_nChannelsPerMatrix) {
4861 sReport += icMsgValidateCriticalError;
4862 sReport += sSigPathName;
4863 sReport += " - SparseMatrix Output channels doesn't match spectral PCS channels.\n";
4865 }
4866 }
4867
4868 if (m_bNonZeroPadding) {
4869 sReport += icMsgValidateNonCompliant;
4870 sReport += sSigPathName;
4871 sReport += " - Non zero padding in matrices used.\n";
4873 }
4874
4875 if (!m_nSize) {
4876 sReport += icMsgValidateWarning;
4877 sReport += sSigPathName;
4878 sReport += " - No Matrices Defined.\n";
4880 return rv;
4881 }
4882
4883 if (!m_RawData) {
4884 sReport += icMsgValidateCriticalError;
4885 sReport += sSigPathName;
4886 sReport += " - Data dont defined for matrices\n";
4888 return rv;
4889 }
4890
4891 icUInt16Number nRows, nCols;
4892 CIccSparseMatrix mtx;
4893 int i;
4894
4895 icUInt16Number nBytesPerMatrix = m_nChannelsPerMatrix * sizeof(icFloatNumber);
4896
4897 mtx.Reset(m_RawData, nBytesPerMatrix, icSparseMatrixFloatNum, true);
4898 nRows = mtx.Rows();
4899 nCols = mtx.Cols();
4900 icUInt32Number nMaxElements = CIccSparseMatrix::MaxEntries(nBytesPerMatrix, nRows, sizeof(icFloatNumber));
4901 char buf[128];
4902 icUInt8Number *temp = new icUInt8Number[nBytesPerMatrix];
4903
4904 for (i=0; i<(int)m_nSize; i++) {
4905 mtx.Reset(m_RawData+i*nBytesPerMatrix, nBytesPerMatrix, icSparseMatrixFloatNum, true);
4906 if (mtx.Rows() != nRows || mtx.Cols() != nCols) {
4907 sReport += icMsgValidateCriticalError;
4908 sReport += sSigPathName;
4909 sprintf(buf, " - Matrix[%d] doesn't have matching rows and columns.\n", i);
4910 sReport += buf;
4912 }
4913
4914 if (mtx.GetNumEntries()>nMaxElements) {
4915 sReport += icMsgValidateCriticalError;
4916 sReport += sSigPathName;
4917 sprintf(buf, " - Matrix[%d] entries exceeds number supported by Output channels.\n", i);
4918 sReport += buf;
4920 }
4921
4922 if (!mtx.IsValid()) {
4923 sReport += icMsgValidateCriticalError;
4924 sReport += sSigPathName;
4925 sprintf(buf, " - Matrix[%d] has an invalid matrix structure.\n", i);
4926 sReport += buf;
4928 }
4929
4930 if (i<(int)(m_nSize-1)) {
4931 CIccSparseMatrix umtx(temp, nBytesPerMatrix, icSparseMatrixFloatNum, false);
4932 CIccSparseMatrix mtx2(m_RawData+(i+1)*nBytesPerMatrix, nBytesPerMatrix, icSparseMatrixFloatNum, true);
4933
4934 umtx.Init(nRows, nCols);
4935 if (!umtx.Union(mtx, mtx2)) {
4936 sReport += icMsgValidateCriticalError;
4937 sReport += sSigPathName;
4938 sprintf(buf, " - Interpolation from Matrix[%d] exceeds number of supported Output channels.\n", i);
4939 sReport += buf;
4941 }
4942 }
4943 }
4944 delete [] temp;
4945
4946 return rv;
4947}
4948
4949
4950/**
4951 ****************************************************************************
4952 * Name: CIccTagSparseMatrixArray::Reset
4953 *
4954 * Purpose: Sets the size of the data array erasing all previous values
4955 *
4956 * Args:
4957 * nNumMatrices - number of matrices
4958 * numChannelsPerMatrix - Equivalent number of output channels that
4959 * determines the fixed block size for each matrix
4960 *****************************************************************************
4961 */
4963{
4964 if (nNumMatrices==m_nSize && nChannelsPerMatrix==m_nChannelsPerMatrix)
4965 return true;
4966
4967 m_nSize = nNumMatrices;
4968 m_nChannelsPerMatrix = nChannelsPerMatrix;
4969
4970 icUInt32Number nSize = m_nSize * GetBytesPerMatrix();
4971
4972 m_RawData = (icUInt8Number *)icRealloc(m_RawData, nSize);
4973
4974 if (!m_RawData) {
4975 m_nSize = 0;
4976 return false;
4977 }
4978
4979 memset(m_RawData, 0, nSize);
4980 return true;
4981}
4982
4983
4984/**
4985****************************************************************************
4986* Name: CIccTagSparseMatrixArray::GetValues
4987*
4988* Purpose: Gets values from the num array tag as floating point numbers
4989*
4990* Args:
4991* nSize - number of data entries,
4992* bZeroNew - flag to zero newly formed values
4993*****************************************************************************
4994*/
4995bool CIccTagSparseMatrixArray::GetSparseMatrix(CIccSparseMatrix &mtx, int nIndex, bool bInitFromData/*=true*/)
4996{
4997 if (nIndex<0 || nIndex>(int)m_nSize) {
4998 mtx.Reset(NULL, 0, icSparseMatrixFloatNum, false);
4999 return false;
5000 }
5001
5002 icUInt32Number nBytesPerMatrix = GetBytesPerMatrix();
5003
5004 mtx.Reset(m_RawData+nIndex*GetBytesPerMatrix(), nBytesPerMatrix, icSparseMatrixFloatNum, bInitFromData);
5005
5006 return true;
5007}
5008
5009bool CIccTagSparseMatrixArray::GetValues(icFloatNumber *DstVector, icUInt32Number nStart/*=0*/, icUInt32Number nVectorSize/*=1*/) const
5010{
5011 icUInt32Number nBytesPerMatrix = GetBytesPerMatrix();
5012 if (nVectorSize!=nBytesPerMatrix)
5013 return false;
5014 if (nStart % nBytesPerMatrix != 0)
5015 return false;
5016
5017 if (nStart / nBytesPerMatrix > m_nSize)
5018 return false;
5019
5020 memcpy(DstVector, m_RawData+nStart, nVectorSize);
5021 return true;
5022}
5023
5024
5025/**
5026****************************************************************************
5027* Name: CIccTagSparseMatrixArray::Interpolate
5028*
5029* Purpose: Gets values from the num array tag as floating point numbers
5030*
5031* Args:
5032* nSize - number of data entries,
5033* bZeroNew - flag to zero newly formed values
5034*****************************************************************************
5035*/
5037 icUInt32Number nVectorSize, icFloatNumber *zeroVals) const
5038{
5039 icUInt32Number nMatrix = m_nSize;
5040
5041 if (!nMatrix || nVectorSize != GetBytesPerMatrix())
5042 return false;
5043
5044 if (zeroVals)
5045 nMatrix ++;
5046 else if (nMatrix<=1)
5047 return false;
5048
5049 if (pos<0.0)
5050 pos=0.0;
5051 if (pos>1.0)
5052 pos=1.0;
5053
5054 icFloatNumber fpos = (icFloatNumber)(nMatrix-1) * pos;
5055 icUInt32Number iPos = (icUInt32Number)fpos;
5056 icFloatNumber x = fpos - iPos;
5057
5058 if (iPos == nMatrix-1) {
5059 iPos--;
5060 x = (icFloatNumber)1.0;
5061 }
5062
5063 icUInt8Number *lo, *hi;
5064
5065 if (zeroVals) {
5066 if (!iPos) {
5067 lo = (icUInt8Number*)zeroVals;
5068 hi = m_RawData;
5069 }
5070 else {
5071 lo = &m_RawData[(iPos-1)*nVectorSize];
5072 hi = &lo[nVectorSize];
5073 }
5074 }
5075 else {
5076 lo = &m_RawData[iPos*nVectorSize];
5077 hi = &lo[nVectorSize];
5078 }
5079
5080 CIccSparseMatrix mlo(lo, nVectorSize, icSparseMatrixFloatNum, true);
5081 CIccSparseMatrix mhi(hi, nVectorSize, icSparseMatrixFloatNum, true);
5082 CIccSparseMatrix dst((icUInt8Number*)DstVector, nVectorSize, icSparseMatrixFloatNum, false);
5083
5084 if (mlo.Rows()!=mhi.Rows() || mlo.Cols()!=mhi.Cols())
5085 return false;
5086
5087 if (!dst.Interp(1.0f-x, mlo, x, mhi))
5088 return false;
5089
5090 return true;
5091}
5092
5093
5094/**
5095****************************************************************************
5096* Name: CIccTagSparseMatrixArray::ValuePos
5097*
5098* Purpose: Gets position of a value int the num array tag
5099*
5100* Args:
5101* DstPos - position of val in array
5102* val - value to look for in array.
5103* bNoZero - flag indicating whether first entry is zero
5104*****************************************************************************
5105*/
5107{
5108 //ValuePos not supported for Sparse Matrices
5109 return false;
5110}
5111
5112
5113/**
5114 ****************************************************************************
5115 * Name: CIccTagFixedNum::CIccTagFixedNum
5116 *
5117 * Purpose: CIccTagFixedNumConstructor
5118 *
5119 * Args:
5120 * nSize = number of data entries
5121 *
5122 *****************************************************************************
5123 */
5124template <class T, icTagTypeSignature Tsig>
5126{
5127 m_nSize = nSize;
5128 if (m_nSize <1)
5129 m_nSize = 1;
5130 m_Num = (T*)calloc(nSize, sizeof(T));
5131}
5132
5133
5134/**
5135 ****************************************************************************
5136 * Name: CIccTagFixedNum::CIccTagFixedNum
5137 *
5138 * Purpose: Copy Constructor
5139 *
5140 * Args:
5141 * ITFN = The CIccTagFixedNum object to be copied
5142 *****************************************************************************
5143 */
5144template <class T, icTagTypeSignature Tsig>
5146{
5147 m_nSize = ITFN.m_nSize;
5148 m_Num = (T*)calloc(m_nSize, sizeof(T));
5149 memcpy(m_Num, ITFN.m_Num, m_nSize*sizeof(T));
5150}
5151
5152
5153/**
5154 ****************************************************************************
5155 * Name: CIccTagFixedNum::operator=
5156 *
5157 * Purpose: Copy Operator
5158 *
5159 * Args:
5160 * ITFN = The CIccTagFixedNum object to be copied
5161 *****************************************************************************
5162 */
5163template <class T, icTagTypeSignature Tsig>
5165{
5166 if (&ITFN == this)
5167 return *this;
5168
5169 m_nSize = ITFN.m_nSize;
5170
5171 if (m_Num)
5172 free(m_Num);
5173 m_Num = (T*)calloc(m_nSize, sizeof(T));
5174 memcpy(m_Num, ITFN.m_Num, m_nSize*sizeof(T));
5175
5176 return *this;
5177}
5178
5179
5180
5181/**
5182 ****************************************************************************
5183 * Name: CIccTagFixedNum::~CIccTagFixedNum
5184 *
5185 * Purpose: Destructor
5186 *
5187 *****************************************************************************
5188 */
5189template <class T, icTagTypeSignature Tsig>
5191{
5192 if (m_Num)
5193 free(m_Num);
5194}
5195
5196/**
5197 ****************************************************************************
5198 * Name: CIccTagFixedNum::GetClassName
5199 *
5200 * Purpose: Returns the tag type class name
5201 *
5202 *****************************************************************************
5203 */
5204template <class T, icTagTypeSignature Tsig>
5206{
5207 if (Tsig==icSigS15Fixed16ArrayType)
5208 return "CIccTagS15Fixed16";
5209 else
5210 return "CIccTagU16Fixed16";
5211}
5212
5213
5214/**
5215 ****************************************************************************
5216 * Name: CIccTagFixedNum::Read
5217 *
5218 * Purpose: Read in the tag contents into a data block
5219 *
5220 * Args:
5221 * size - # of bytes in tag,
5222 * pIO - IO object to read tag from
5223 *
5224 * Return:
5225 * true = successful, false = failure
5226 *****************************************************************************
5227 */
5228template <class T, icTagTypeSignature Tsig>
5230{
5232
5233 if (sizeof(icTagTypeSignature) +
5234 sizeof(icUInt32Number) +
5235 sizeof(T) > size)
5236 return false;
5237
5238 if (!pIO) {
5239 return false;
5240 }
5241
5242 if (!pIO->Read32(&sig))
5243 return false;
5244
5245 if (!pIO->Read32(&m_nReserved))
5246 return false;
5247
5248 icUInt32Number nSize=((size-2*sizeof(icUInt32Number)) / sizeof(T));
5249
5250 if (!SetSize(nSize))
5251 return false;
5252
5253 if (pIO->Read32(m_Num, nSize) != (icInt32Number)nSize )
5254 return false;
5255
5256 return true;
5257}
5258
5259
5260/**
5261 ****************************************************************************
5262 * Name: CIccTagFixedNum::Write
5263 *
5264 * Purpose: Write the tag to a file
5265 *
5266 * Args:
5267 * pIO - The IO object to write tag to.
5268 *
5269 * Return:
5270 * true = succesful, false = failure
5271 *****************************************************************************
5272 */
5273template <class T, icTagTypeSignature Tsig>
5275{
5276 icTagTypeSignature sig = GetType();
5277
5278 if (!pIO)
5279 return false;
5280
5281 if (!pIO->Write32(&sig))
5282 return false;
5283
5284 if (!pIO->Write32(&m_nReserved))
5285 return false;
5286
5287 if (pIO->Write32(m_Num, m_nSize) != (icInt32Number)m_nSize)
5288 return false;
5289
5290 return true;
5291}
5292
5293/**
5294 ****************************************************************************
5295 * Name: CIccTagFixedNum::Describe
5296 *
5297 * Purpose: Dump data associated with the tag to a string
5298 *
5299 * Args:
5300 * sDescription - string to concatenate tag dump to
5301 *****************************************************************************
5302 */
5303template <class T, icTagTypeSignature Tsig>
5304void CIccTagFixedNum<T, Tsig>::Describe(std::string &sDescription, int nVerboseness)
5305{
5306 icChar buf[128] = { 0 };
5307
5308 if (m_nSize == 1 ) {
5309 if (Tsig==icSigS15Fixed16ArrayType)
5310 sprintf(buf, "Value = %.4lf\n", icFtoD(m_Num[0]));
5311 else
5312 sprintf(buf, "Value = %.4lf\n", icUFtoD(m_Num[0]));
5313 sDescription += buf;
5314 }
5315 else {
5317
5318 if (Tsig==icSigS15Fixed16ArrayType && m_nSize==9) {
5319 sDescription += "Matrix Form:\n";
5320 icMatrixDump(sDescription, (icS15Fixed16Number*)m_Num);
5321
5322 sDescription += "\nArrayForm:\n";
5323 }
5324 sDescription.reserve(sDescription.size() + m_nSize*79);
5325
5326 for (i=0; i<m_nSize; i++) {
5327 if (Tsig==icSigS15Fixed16ArrayType)
5328 sprintf(buf, "Value[%u] = %8.4lf\n", i, icFtoD(m_Num[i]));
5329 else
5330 sprintf(buf, "Value[%u] = %8.4lf\n", i, icUFtoD(m_Num[i]));
5331 sDescription += buf;
5332 }
5333 }
5334}
5335
5336/**
5337 ****************************************************************************
5338 * Name: CIccTagFixedNum::SetSize
5339 *
5340 * Purpose: Sets the size of the data array.
5341 *
5342 * Args:
5343 * nSize - number of data entries,
5344 * bZeroNew - flag to zero newly formed values
5345 *****************************************************************************
5346 */
5347template <class T, icTagTypeSignature Tsig>
5348bool CIccTagFixedNum<T, Tsig>::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
5349{
5350 if (nSize==m_nSize)
5351 return true;
5352
5353 m_Num = (T*)icRealloc(m_Num, nSize*sizeof(T));
5354
5355 if (!m_Num) {
5356 m_nSize = 0;
5357 return false;
5358 }
5359
5360 if (bZeroNew && m_nSize < nSize) {
5361 memset(&m_Num[m_nSize], 0, (nSize-m_nSize)*sizeof(T));
5362 }
5363 m_nSize = nSize;
5364
5365 return true;
5366}
5367
5368/**
5369****************************************************************************
5370* Name: CIccTagFixedNum::GetValues
5371*
5372* Purpose: Gets values from the num array tag as floating point numbers
5373*
5374* Args:
5375* nSize - number of data entries,
5376* bZeroNew - flag to zero newly formed values
5377*****************************************************************************
5378*/
5379template <class T, icTagTypeSignature Tsig>
5381{
5382 if (nVectorSize+nStart >m_nSize)
5383 return false;
5384
5386
5387 switch (Tsig) {
5389 for (i=0; i<m_nSize; i++) {
5390 DstVector[i] = (icFloatNumber)icFtoD(m_Num[i+nStart]);
5391 }
5392 break;
5394 for (i=0; i<m_nSize; i++) {
5395 DstVector[i] = (icFloatNumber)icUFtoD(m_Num[i+nStart]);
5396 }
5397 break;
5398 default:
5399 return false;
5400 }
5401 return true;
5402}
5403
5404
5405/**
5406****************************************************************************
5407* Name: CIccTagFixedNum::Interpolate
5408*
5409* Purpose: Gets values from the num array tag as floating point numbers
5410*
5411* Args:
5412* nSize - number of data entries,
5413* bZeroNew - flag to zero newly formed values
5414*****************************************************************************
5415*/
5416template <class T, icTagTypeSignature Tsig>
5418 icUInt32Number nVectorSize, icFloatNumber *zeroVals) const
5419{
5420 icUInt32Number nVector = m_nSize / nVectorSize;
5421
5422 if (!nVector)
5423 return false;
5424
5425 if (zeroVals)
5426 nVector ++;
5427 else if (nVector<=1)
5428 return false;
5429
5430 if (pos<0.0)
5431 pos=0.0;
5432 if (pos>1.0)
5433 pos=1.0;
5434
5435 icFloatNumber fpos = (icFloatNumber)(nVector-1) * pos;
5436 icUInt32Number iPos = (icUInt32Number)fpos;
5437 icFloatNumber x = fpos - iPos;
5438
5439 if (iPos == nVector-1) {
5440 iPos--;
5441 x = (icFloatNumber)1.0;
5442 }
5443
5444 T *lo, *hi;
5445
5446 if (zeroVals) {
5447 if (!iPos) {
5448 lo = NULL;
5449 hi = m_Num;
5450 }
5451 else {
5452 lo = &m_Num[(iPos-1)*nVectorSize];
5453 hi = &lo[nVectorSize];
5454 }
5455 }
5456 else {
5457 lo = &m_Num[iPos*nVectorSize];
5458 hi = &lo[nVectorSize];
5459 }
5460
5462
5463 switch (Tsig) {
5465 if (!lo) {
5466 for (i=0; i<m_nSize; i++) {
5467 DstVector[i] = (icFloatNumber)(zeroVals[i]*(1.0f-x) + icFtoD(hi[i])*x);
5468 }
5469 }
5470 else {
5471 for (i=0; i<m_nSize; i++) {
5472 DstVector[i] = (icFloatNumber)(icFtoD(lo[i])*(1.0-x) + icFtoD(hi[i])*x);
5473 }
5474 }
5475 break;
5477 if (!lo) {
5478 for (i=0; i<m_nSize; i++) {
5479 DstVector[i] = (icFloatNumber)(zeroVals[i]*(1.0-x) + icUFtoD(hi[i])*x);
5480 }
5481 }
5482 else {
5483 for (i=0; i<m_nSize; i++) {
5484 DstVector[i] = (icFloatNumber)(icUFtoD(lo[i])*(1.0-x) + icUFtoD(hi[i])*x);
5485 }
5486 }
5487 break;
5488 default:
5489 return false;
5490 }
5491 return true;
5492}
5493
5494/**
5495****************************************************************************
5496* Name: CIccTagFixedNum::ValuePos
5497*
5498* Purpose: Gets position of a value int the num array tag
5499*
5500* Args:
5501* DstPos - position of val in array
5502* val - value to look for in array.
5503* bNoZero - flag indicating whether first entry is zero
5504*****************************************************************************
5505*/
5506template <class T, icTagTypeSignature Tsig>
5508{
5509 if(val<0.0)
5510 return false;
5511
5512 icFloatNumber nv = 0.0;
5513 icFloatNumber lv = 0.0;
5514 switch (Tsig) {
5516 lv = icFtoD(m_Num[0]);
5517 break;
5519 lv = icUFtoD(m_Num[0]);
5520 break;
5521 default:
5522 return false;
5523 }
5524 bNoZero = (lv!=0.0);
5525
5526 if (val<lv) {
5527 DstPos = val/lv - 1.0f;
5528 return true;
5529 }
5530
5532 for (i=1; i<m_nSize; i++, lv=nv) {
5533 switch (Tsig) {
5535 nv = icFtoD(m_Num[i]);
5536 break;
5538 nv = icUFtoD(m_Num[i]);
5539 break;
5540 default:
5541 return false;
5542 }
5543 if (val<=nv) {
5544 DstPos = (val-lv)/(nv-lv) + i - 1.0f;
5545 return true;
5546 }
5547 }
5548
5549 return false;
5550}
5551
5552
5553//Make sure typedef classes get built
5556
5557
5558/**
5559 ****************************************************************************
5560 * Name: CIccTagNum::CIccTagNum
5561 *
5562 * Purpose: Constructor
5563 *
5564 * Args:
5565 * nSize = number of data entries
5566 *****************************************************************************
5567 */
5568template <class T, icTagTypeSignature Tsig>
5570{
5571 m_nSize = nSize;
5572 if (m_nSize <1)
5573 m_nSize = 1;
5574 m_Num = (T*)calloc(nSize, sizeof(T));
5575}
5576
5577
5578/**
5579 ****************************************************************************
5580 * Name: CIccTagNum::CIccTagNum
5581 *
5582 * Purpose: Copy Constructor
5583 *
5584 * Args:
5585 * ITNum = The CIccTagNum object to be copied
5586 *****************************************************************************
5587 */
5588template <class T, icTagTypeSignature Tsig>
5590{
5591 m_nSize = ITNum.m_nSize;
5592
5593 m_Num = (T*)calloc(m_nSize, sizeof(T));
5594 memcpy(m_Num, ITNum.m_Num, m_nSize * sizeof(T));
5595}
5596
5597
5598/**
5599 ****************************************************************************
5600 * Name: CIccTagNum::operator=
5601 *
5602 * Purpose: Copy Operator
5603 *
5604 * Args:
5605 * ITNum = The CIccTagNum object to be copied
5606 *****************************************************************************
5607 */
5608template <class T, icTagTypeSignature Tsig>
5610{
5611 if (&ITNum == this)
5612 return *this;
5613
5614 m_nSize = ITNum.m_nSize;
5615
5616 m_Num = (T*)calloc(m_nSize, sizeof(T));
5617 memcpy(m_Num, ITNum.m_Num, m_nSize * sizeof(T));
5618
5619 return *this;
5620}
5621
5622
5623
5624/**
5625 ****************************************************************************
5626 * Name: CIccTagNum::~CIccTagNum
5627 *
5628 * Purpose: Destructor
5629 *
5630 *****************************************************************************
5631 */
5632template <class T, icTagTypeSignature Tsig>
5634{
5635 if (m_Num)
5636 free(m_Num);
5637}
5638
5639/**
5640 ****************************************************************************
5641 * Name: CIccTagNum::GetClassName
5642 *
5643 * Purpose: Returns the tag type class name
5644 *
5645 *****************************************************************************
5646 */
5647template <class T, icTagTypeSignature Tsig>
5649{
5650 if (sizeof(T)==sizeof(icUInt8Number))
5651 return "CIccTagUInt8";
5652 else if (sizeof(T)==sizeof(icUInt16Number))
5653 return "CIccTagUInt16";
5654 else if (sizeof(T)==sizeof(icUInt32Number))
5655 return "CIccTagUInt32";
5656 else if (sizeof(T)==sizeof(icUInt64Number))
5657 return "CIccTagUInt64";
5658 else
5659 return "CIccTagNum<>";
5660}
5661
5662
5663/**
5664 ****************************************************************************
5665 * Name: CIccTagNum::Read
5666 *
5667 * Purpose: Read in the tag contents into a data block
5668 *
5669 * Args:
5670 * size - # of bytes in tag,
5671 * pIO - IO object to read tag from
5672 *
5673 * Return:
5674 * true = successful, false = failure
5675 *****************************************************************************
5676 */
5677template <class T, icTagTypeSignature Tsig>
5679{
5681
5682 if (sizeof(icTagTypeSignature) +
5683 sizeof(icUInt32Number) +
5684 sizeof(T) > size)
5685 return false;
5686
5687 if (!pIO) {
5688 return false;
5689 }
5690
5691 if (!pIO->Read32(&sig))
5692 return false;
5693
5694 if (!pIO->Read32(&m_nReserved))
5695 return false;
5696
5697 icUInt32Number nSize=((size-2*sizeof(icUInt32Number)) / sizeof(T));
5698
5699 if (!SetSize(nSize))
5700 return false;
5701
5702 if (sizeof(T)==sizeof(icUInt8Number)) {
5703 if (pIO->Read8(m_Num, nSize) != (icInt32Number)nSize )
5704 return false;
5705 }
5706 else if (sizeof(T)==sizeof(icUInt16Number)) {
5707 if (pIO->Read16(m_Num, nSize) != (icInt32Number)nSize )
5708 return false;
5709 }
5710 else if (sizeof(T)==sizeof(icUInt32Number)) {
5711 if (pIO->Read32(m_Num, nSize) != (icInt32Number)nSize )
5712 return false;
5713 }
5714 else if (sizeof(T)==sizeof(icUInt64Number)) {
5715 if (pIO->Read64(m_Num, nSize) != (icInt32Number)nSize )
5716 return false;
5717 }
5718 else
5719 return false;
5720
5721 return true;
5722}
5723
5724
5725/**
5726 ****************************************************************************
5727 * Name: CIccTagNum::Write
5728 *
5729 * Purpose: Write the tag to a file
5730 *
5731 * Args:
5732 * pIO - The IO object to write tag to.
5733 *
5734 * Return:
5735 * true = succesful, false = failure
5736 *****************************************************************************
5737 */
5738template <class T, icTagTypeSignature Tsig>
5740{
5741 icTagTypeSignature sig = GetType();
5742
5743 if (!pIO)
5744 return false;
5745
5746 if (!pIO->Write32(&sig))
5747 return false;
5748
5749 if (!pIO->Write32(&m_nReserved))
5750 return false;
5751
5752 if (sizeof(T)==sizeof(icUInt8Number)) {
5753 if (pIO->Write8(m_Num, m_nSize) != (icInt32Number)m_nSize)
5754 return false;
5755 }
5756 else if (sizeof(T)==sizeof(icUInt16Number)) {
5757 if (pIO->Write16(m_Num, m_nSize) != (icInt32Number)m_nSize)
5758 return false;
5759 }
5760 else if (sizeof(T)==sizeof(icUInt32Number)) {
5761 if (pIO->Write32(m_Num, m_nSize) != (icInt32Number)m_nSize)
5762 return false;
5763 }
5764 else if (sizeof(T)==sizeof(icUInt64Number)) {
5765 if (pIO->Write64(m_Num, m_nSize) != (icInt32Number)m_nSize)
5766 return false;
5767 }
5768 else
5769 return false;
5770
5771 return true;
5772}
5773
5774
5775/**
5776 ****************************************************************************
5777 * Name: CIccTagNum::Describe
5778 *
5779 * Purpose: Dump data associated with the tag to a string
5780 *
5781 * Args:
5782 * sDescription - string to concatenate tag dump to
5783 *****************************************************************************
5784 */
5785template <class T, icTagTypeSignature Tsig>
5786void CIccTagNum<T, Tsig>::Describe(std::string &sDescription, int nVerboseness)
5787{
5788 icChar buf[128] = {0};
5789
5790 if (m_nSize == 1 ) {
5791 switch (sizeof(T)) {
5792 case 1:
5793 sprintf(buf, "Value = %u (0x02%x)\n", m_Num[0], m_Num[0]);
5794 break;
5795 case 2:
5796 sprintf(buf, "Value = %u (0x04%x)\n", m_Num[0], m_Num[0]);
5797 break;
5798 case 4:
5799 sprintf(buf, "Value = %u (0x08%x)\n", m_Num[0], m_Num[0]);
5800 break;
5801 case 8:
5802 sprintf(buf, "Value = %u (0x016%x)\n", m_Num[0], m_Num[0]);
5803 break;
5804 default:
5805 sprintf(buf, "Value = %u (0x%x)\n", m_Num[0], m_Num[0]);
5806 break;
5807 }
5808 sDescription += buf;
5809 }
5810 else {
5812 sDescription.reserve(sDescription.size() + m_nSize*79);
5813
5814 for (i=0; i<m_nSize; i++) {
5815 switch (sizeof(T)) {
5816 case 1:
5817 sprintf(buf, "Value = %u (0x02%x)\n", m_Num[i], m_Num[i]);
5818 break;
5819 case 2:
5820 sprintf(buf, "Value = %u (0x04%x)\n", m_Num[i], m_Num[i]);
5821 break;
5822 case 4:
5823 sprintf(buf, "Value = %u (0x08%x)\n", m_Num[i], m_Num[i]);
5824 break;
5825 case 8:
5826 sprintf(buf, "Value = %u (0x016%x)\n", m_Num[i], m_Num[i]);
5827 break;
5828 default:
5829 sprintf(buf, "Value = %u (0x%x)\n", m_Num[i], m_Num[i]);
5830 break;
5831 }
5832 sDescription += buf;
5833 }
5834 }
5835}
5836
5837template <class T, icTagTypeSignature Tsig>
5838icValidateStatus CIccTagNum<T, Tsig>::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile) const
5839{
5841 //Check # of channels
5843 pProfile &&
5844 m_nSize != icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs)) {
5845 CIccInfo Info;
5846 std::string sSigPathName = Info.GetSigPathName(sigPath);
5847
5848 sReport += icMsgValidateCriticalError;
5849 sReport += sSigPathName;
5850 sReport += " - Number of material default values does not match MCS in header.\n";
5852 }
5853
5854 rv = icMaxStatus(rv, CIccTagNumArray::Validate(sigPath, sReport, pProfile));
5855
5856 return rv;
5857}
5858
5859// template function specialization to handle need for %llu and %llx for 64-bit ints
5860template <>
5861void CIccTagNum<icUInt64Number, icSigUInt64ArrayType>::Describe(std::string &sDescription, int nVerboseness)
5862{
5863 icChar buf[128];
5864
5865 if (m_nSize == 1 ) {
5866 sprintf(buf, "Value = %llu (0x016%llx)\n", m_Num[0], m_Num[0]);
5867 sDescription += buf;
5868 }
5869 else {
5871 sDescription.reserve(sDescription.size() + m_nSize*79);
5872
5873 for (i=0; i<m_nSize; i++) {
5874 sprintf(buf, "Value = %llu (0x016%llx)\n", m_Num[i], m_Num[i]);
5875 sDescription += buf;
5876 }
5877 }
5878}
5879
5880
5881
5882
5883/**
5884 ****************************************************************************
5885 * Name: CIccTagNum::SetSize
5886 *
5887 * Purpose: Sets the size of the data array.
5888 *
5889 * Args:
5890 * nSize - number of data entries,
5891 * bZeroNew - flag to zero newly formed values
5892 *****************************************************************************
5893 */
5894template <class T, icTagTypeSignature Tsig>
5895bool CIccTagNum<T, Tsig>::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
5896{
5897 if (nSize==m_nSize)
5898 return true;
5899
5900 m_Num = (T*)icRealloc(m_Num, nSize*sizeof(T));
5901
5902 if (!m_Num) {
5903 m_nSize = 0;
5904 return false;
5905 }
5906
5907 if (bZeroNew && m_nSize < nSize) {
5908 memset(&m_Num[m_nSize], 0, (nSize-m_nSize)*sizeof(T));
5909 }
5910 m_nSize = nSize;
5911
5912 return true;
5913}
5914
5915/**
5916****************************************************************************
5917* Name: CIccTagNum::GetValues
5918*
5919* Purpose: Gets values from the num array tag as floating point numbers
5920*
5921* Args:
5922* nSize - number of data entries,
5923* bZeroNew - flag to zero newly formed values
5924*****************************************************************************
5925*/
5926template <class T, icTagTypeSignature Tsig>
5928{
5929 if (nVectorSize+nStart >m_nSize)
5930 return false;
5931
5933
5934 switch (Tsig) {
5936 for (i=0; i<m_nSize; i++) {
5937 DstVector[i] = icU8toF((icUInt8Number)(m_Num[i+nStart]));
5938 }
5939 break;
5941 for (i=0; i<m_nSize; i++) {
5942 DstVector[i] = icU16toF((icUInt16Number)(m_Num[i+nStart]));
5943 }
5944 break;
5945 case icSigUInt32ArrayType: //Not Supported
5946 case icSigUInt64ArrayType: //Not Supported
5947 default:
5948 return false;
5949 }
5950 return true;
5951}
5952
5953//Avoid casting warnings for 32 and 64 bit numbers
5954template <>
5956{
5957 return false;
5958}
5959template <>
5961{
5962 return false;
5963}
5964
5965/**
5966****************************************************************************
5967* Name: CIccTagNum::Interpolate
5968*
5969* Purpose: Gets values from the num array tag as floating point numbers
5970*
5971* Args:
5972* nSize - number of data entries,
5973* bZeroNew - flag to zero newly formed values
5974*****************************************************************************
5975*/
5976template <class T, icTagTypeSignature Tsig>
5978 icUInt32Number nVectorSize, icFloatNumber *zeroVals) const
5979{
5980 icUInt32Number nVector = m_nSize / nVectorSize;
5981
5982 if (!nVector)
5983 return false;
5984
5985 if (zeroVals)
5986 nVector ++;
5987 else if (nVector<=1)
5988 return false;
5989
5990 if (pos<0.0)
5991 pos=0.0;
5992 if (pos>1.0)
5993 pos=1.0;
5994
5995 icFloatNumber fpos = (icFloatNumber)(nVector-1) * pos;
5996 icUInt32Number iPos = (icUInt32Number)fpos;
5997 icFloatNumber x = fpos - iPos;
5998
5999 if (iPos == nVector-1) {
6000 iPos--;
6001 x = (icFloatNumber)1.0;
6002 }
6003
6004 T *lo, *hi;
6005
6006 if (!zeroVals) {
6007 if (!iPos) {
6008 lo = NULL;
6009 hi = m_Num;
6010 }
6011 else {
6012 lo = &m_Num[(iPos-1)*nVectorSize];
6013 hi = &lo[nVectorSize];
6014 }
6015 }
6016 else {
6017 lo = &m_Num[iPos*nVectorSize];
6018 hi = &lo[nVectorSize];
6019 }
6020
6022
6023 switch (Tsig) {
6025 if (!lo) {
6026 for (i=0; i<m_nSize; i++) {
6027 DstVector[i] = zeroVals[i]*(1.0f-x) + icU8toF((icUInt8Number)hi[i])*x;
6028 }
6029 }
6030 else {
6031 for (i=0; i<m_nSize; i++) {
6032 DstVector[i] = icU8toF((icUInt8Number)lo[i])*(1.0f-x) + icU8toF((icUInt8Number)hi[i])*x;
6033 }
6034 }
6035 break;
6037 if (!lo) {
6038 for (i=0; i<m_nSize; i++) {
6039 DstVector[i] = zeroVals[i]*(1.0f-x) + icU16toF((icUInt16Number)hi[i])*x;
6040 }
6041 }
6042 else {
6043 for (i=0; i<m_nSize; i++) {
6044 DstVector[i] = icU16toF((icUInt16Number)lo[i])*(1.0f-x) + icU16toF((icUInt16Number)hi[i])*x;
6045 }
6046 }
6047 break;
6050 default:
6051 return false;
6052 }
6053 return true;
6054}
6055
6056
6057/**
6058****************************************************************************
6059* Name: CIccTagNum::ValuePos
6060*
6061* Purpose: Gets position of a value int the num array tag
6062*
6063* Args:
6064* DstPos - position of val in array
6065* val - value to look for in array.
6066* bNoZero - flag indicating whether first entry is zero
6067*****************************************************************************
6068*/
6069template <class T, icTagTypeSignature Tsig>
6070bool CIccTagNum<T, Tsig>::ValuePos(icFloatNumber &DstPos, icFloatNumber val, bool &bNoZero) const
6071{
6072 if(val<0.0)
6073 return false;
6074
6075 icFloatNumber nv = 0.0;
6076 icFloatNumber lv = 0.0;
6077 switch (Tsig) {
6079 lv = icU8toF((icUInt8Number)m_Num[0]);
6080 break;
6082 lv = icU16toF((icUInt16Number)m_Num[0]);
6083 break;
6086 default:
6087 return false;
6088 }
6089 bNoZero = (lv!=0.0);
6090
6091 if (val<lv) {
6092 DstPos = val/lv - 1.0f;
6093 return true;
6094 }
6095
6097 for (i=1; i<m_nSize; i++, lv=nv) {
6098 switch (Tsig) {
6100 nv = icU8toF((icUInt8Number)m_Num[i]);
6101 break;
6103 nv = icU16toF((icUInt16Number)m_Num[i]);
6104 break;
6107 default:
6108 return false;
6109 }
6110 if (val<=nv) {
6111 DstPos = (val-lv)/(nv-lv) + i - 1.0f;
6112 return true;
6113 }
6114 }
6115
6116 return false;
6117}
6118
6119//Avoid casting warnings for 32 and 64 bit numbers
6120template <>
6122 icUInt32Number nVectorSize, icFloatNumber *zeroVals) const
6123{
6124 return false;
6125}
6126template <>
6128 icUInt32Number nVectorSize, icFloatNumber *zeroVals) const
6129{
6130 return false;
6131}
6132
6133template <>
6135{
6136 return false;
6137}
6138template <>
6140{
6141 return false;
6142}
6143
6144//Make sure typedef classes get built
6149
6150
6151/**
6152 ****************************************************************************
6153 * Name: CIccTagFloatNum::CIccTagFloatNum
6154 *
6155 * Purpose: Constructor
6156 *
6157 * Args:
6158 * nSize = number of data entries
6159 *****************************************************************************
6160 */
6161template <class T, icTagTypeSignature Tsig>
6163{
6164 m_nSize = nSize;
6165 if (m_nSize <1)
6166 m_nSize = 1;
6167 m_Num = (T*)calloc(nSize, sizeof(T));
6168}
6169
6170
6171/**
6172 ****************************************************************************
6173 * Name: CIccTagFloatNum::CIccTagFloatNum
6174 *
6175 * Purpose: Copy Constructor
6176 *
6177 * Args:
6178 * ITNum = The CIccTagNum object to be copied
6179 *****************************************************************************
6180 */
6181template <class T, icTagTypeSignature Tsig>
6183{
6184 m_nSize = ITNum.m_nSize;
6185
6186 m_Num = (T*)calloc(m_nSize, sizeof(T));
6187 memcpy(m_Num, ITNum.m_Num, m_nSize * sizeof(T));
6188}
6189
6190
6191/**
6192 ****************************************************************************
6193 * Name: CIccTagFloatNum::operator=
6194 *
6195 * Purpose: Copy Operator
6196 *
6197 * Args:
6198 * ITNum = The CIccTagNum object to be copied
6199 *****************************************************************************
6200 */
6201template <class T, icTagTypeSignature Tsig>
6203{
6204 if (&ITNum == this)
6205 return *this;
6206
6207 m_nSize = ITNum.m_nSize;
6208
6209 m_Num = (T*)calloc(m_nSize, sizeof(T));
6210 memcpy(m_Num, ITNum.m_Num, m_nSize * sizeof(T));
6211
6212 return *this;
6213}
6214
6215
6216
6217/**
6218 ****************************************************************************
6219 * Name: CIccTagFloatNum::~CIccTagFloatNum
6220 *
6221 * Purpose: Destructor
6222 *
6223 *****************************************************************************
6224 */
6225template <class T, icTagTypeSignature Tsig>
6227{
6228 if (m_Num)
6229 free(m_Num);
6230}
6231
6232/**
6233 ****************************************************************************
6234 * Name: CIccTagFloatNum::GetClassName
6235 *
6236 * Purpose: Returns the tag type class name
6237 *
6238 *****************************************************************************
6239 */
6240template <class T, icTagTypeSignature Tsig>
6242{
6243 if (Tsig==icSigFloat16ArrayType)
6244 return "CIccFlaot16";
6245 if (Tsig==icSigFloat32ArrayType)
6246 return "CIccFloat32";
6247 else if (Tsig==icSigFloat64ArrayType)
6248 return "CIccFloat64";
6249 else
6250 return "CIccTagFloatNum<>";
6251}
6252
6253
6254/**
6255 ****************************************************************************
6256 * Name: CIccTagFloatNum::Read
6257 *
6258 * Purpose: Read in the tag contents into a data block
6259 *
6260 * Args:
6261 * size - # of bytes in tag,
6262 * pIO - IO object to read tag from
6263 *
6264 * Return:
6265 * true = successful, false = failure
6266 *****************************************************************************
6267 */
6268template <class T, icTagTypeSignature Tsig>
6270{
6272
6273 if (Tsig==icSigFloat16ArrayType) {
6274 if (sizeof(icTagTypeSignature) +
6275 sizeof(icUInt32Number) +
6276 sizeof(icFloat16Number) > size)
6277 return false;
6278 }
6279 else {
6280 if (sizeof(icTagTypeSignature) +
6281 sizeof(icUInt32Number) +
6282 sizeof(T) > size)
6283 return false;
6284 }
6285
6286 if (!pIO) {
6287 return false;
6288 }
6289
6290 if (!pIO->Read32(&sig))
6291 return false;
6292
6293 if (!pIO->Read32(&m_nReserved))
6294 return false;
6295
6296 if (Tsig==icSigFloat16ArrayType) {
6297 icUInt32Number nSize=((size-2*sizeof(icUInt32Number)) / sizeof(icFloat16Number));
6298
6299 if (!SetSize(nSize))
6300 return false;
6301
6302 if (pIO->ReadFloat16Float(&m_Num[0], nSize) != (icInt32Number)nSize)
6303 return false;
6304 }
6305 else if (Tsig==icSigFloat32ArrayType) {
6306 icUInt32Number nSize=((size-2*sizeof(icUInt32Number)) / sizeof(icFloat32Number));
6307
6308 if (!SetSize(nSize))
6309 return false;
6310
6311 if (pIO->Read32(m_Num, nSize) != (icInt32Number)nSize )
6312 return false;
6313 }
6314 else if (Tsig==icSigFloat64ArrayType) {
6315 icUInt32Number nSize=((size-2*sizeof(icUInt32Number)) / sizeof(icFloat64Number));
6316
6317 if (!SetSize(nSize))
6318 return false;
6319
6320 if (pIO->Read64(m_Num, nSize) != (icInt32Number)nSize )
6321 return false;
6322 }
6323 else
6324 return false;
6325
6326 return true;
6327}
6328
6329
6330/**
6331 ****************************************************************************
6332 * Name: CIccTagFloatNum::Write
6333 *
6334 * Purpose: Write the tag to a file
6335 *
6336 * Args:
6337 * pIO - The IO object to write tag to.
6338 *
6339 * Return:
6340 * true = succesful, false = failure
6341 *****************************************************************************
6342 */
6343template <class T, icTagTypeSignature Tsig>
6345{
6346 icTagTypeSignature sig = GetType();
6347
6348 if (!pIO)
6349 return false;
6350
6351 if (!pIO->Write32(&sig))
6352 return false;
6353
6354 if (!pIO->Write32(&m_nReserved))
6355 return false;
6356
6357 if (Tsig==icSigFloat16ArrayType) {
6358 if (pIO->WriteFloat16Float(m_Num, m_nSize) != (icInt32Number)m_nSize)
6359 return false;
6360 }
6361 else if (Tsig == icSigFloat32ArrayType) {
6362 if (pIO->Write32(m_Num, m_nSize) != (icInt32Number)m_nSize)
6363 return false;
6364 }
6365 else if (Tsig == icSigFloat64ArrayType) {
6366 if (pIO->Write64(m_Num, m_nSize) != (icInt32Number)m_nSize)
6367 return false;
6368 }
6369 else
6370 return false;
6371
6372 return true;
6373}
6374
6375
6376/**
6377 ****************************************************************************
6378 * Name: CIccTagFloatNum::Describe
6379 *
6380 * Purpose: Dump data associated with the tag to a string
6381 *
6382 * Args:
6383 * sDescription - string to concatenate tag dump to
6384 *****************************************************************************
6385 */
6386template <class T, icTagTypeSignature Tsig>
6387void CIccTagFloatNum<T, Tsig>::Describe(std::string &sDescription, int nVerboseness)
6388{
6389 icChar buf[128] = {0};
6390
6391 if (m_nSize == 1 ) {
6392 switch (sizeof(T)) {
6393 case 4:
6394 sprintf(buf, "Value = %.8f\n", m_Num[0]);
6395 break;
6396 case 8:
6397 sprintf(buf, "Value = %.16f\n", m_Num[0]);
6398 break;
6399 default:
6400 sprintf(buf, "Value = %.f\n", m_Num[0]);
6401 break;
6402 }
6403 sDescription += buf;
6404 }
6405 else {
6406 icUInt32Number i, n;
6407 sDescription.reserve(sDescription.size() + m_nSize*79);
6408
6409 sprintf(buf, "Begin_Value_Array[%d]\n", m_nSize);
6410 sDescription += buf;
6411
6412 if (sizeof(T)!=8)
6413 n=8;
6414 else
6415 n=4;
6416
6417 for (i=0; i<m_nSize; i++) {
6418 if (i&& !(i%n))
6419 sDescription += "\n";
6420
6421 switch (sizeof(T)) {
6422 case 4:
6423 sprintf(buf, " %.8f", m_Num[i]);
6424 break;
6425 case 8:
6426 sprintf(buf, " %.16f", m_Num[i]);
6427 break;
6428 default:
6429 sprintf(buf, " %f", m_Num[i]);
6430 }
6431 sDescription += buf;
6432 }
6433 if ((i%n)!=1)
6434 sDescription += "\n";
6435 sDescription += "End_Value_Array\n";
6436 }
6437}
6438
6439
6440/**
6441 ****************************************************************************
6442 * Name: CIccTagFloatNum::SetSize
6443 *
6444 * Purpose: Sets the size of the data array.
6445 *
6446 * Args:
6447 * nSize - number of data entries,
6448 * bZeroNew - flag to zero newly formed values
6449 *****************************************************************************
6450 */
6451template <class T, icTagTypeSignature Tsig>
6452bool CIccTagFloatNum<T, Tsig>::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
6453{
6454 if (nSize==m_nSize)
6455 return true;
6456
6457 m_Num = (T*)icRealloc(m_Num, nSize*sizeof(T));
6458
6459 if (!m_Num) {
6460 m_nSize = 0;
6461 return false;
6462 }
6463
6464 if (bZeroNew && m_nSize < nSize) {
6465 memset(&m_Num[m_nSize], 0, (nSize-m_nSize)*sizeof(T));
6466 }
6467 m_nSize = nSize;
6468
6469 return true;
6470}
6471
6472/**
6473****************************************************************************
6474* Name: CIccTagFloatNum::GetValues
6475*
6476* Purpose: Gets values from the num array tag as floating point numbers
6477*
6478* Args:
6479* nSize - number of data entries,
6480* bZeroNew - flag to zero newly formed values
6481*****************************************************************************
6482*/
6483template <class T, icTagTypeSignature Tsig>
6485{
6486 if (nVectorSize >m_nSize)
6487 return false;
6488
6490
6491 for (i=0; i<m_nSize; i++) {
6492 DstVector[i] = (icFloatNumber)m_Num[i+nStart];
6493 }
6494 return true;
6495}
6496
6497
6498/**
6499****************************************************************************
6500* Name: CIccTagFloatNum::Interpolate
6501*
6502* Purpose: Gets values from the num array tag as floating point numbers
6503*
6504* Args:
6505* nSize - number of data entries,
6506* bZeroNew - flag to zero newly formed values
6507*****************************************************************************
6508*/
6509template <class T, icTagTypeSignature Tsig>
6510icValidateStatus CIccTagFloatNum<T, Tsig>::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile) const
6511{
6513 //Check # of channels
6515 pProfile &&
6516 m_nSize != icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs)) {
6517 CIccInfo Info;
6518 std::string sSigPathName = Info.GetSigPathName(sigPath);
6519
6520 sReport += icMsgValidateCriticalError;
6521 sReport += sSigPathName;
6522 sReport += " - Number of material default values does not match MCS in header.\n";
6524 }
6525
6526 rv = icMaxStatus(rv, CIccTagNumArray::Validate(sigPath, sReport, pProfile));
6527
6528 return rv;
6529}
6530
6531
6532
6533/**
6534****************************************************************************
6535* Name: CIccTagFloatNum::Interpolate
6536*
6537* Purpose: Gets values from the num array tag as floating point numbers
6538*
6539* Args:
6540* nSize - number of data entries,
6541* bZeroNew - flag to zero newly formed values
6542*****************************************************************************
6543*/
6544template <class T, icTagTypeSignature Tsig>
6546 icUInt32Number nVectorSize, icFloatNumber *zeroVals) const
6547{
6548 icUInt32Number nVector = m_nSize / nVectorSize;
6549
6550 if (!nVector)
6551 return false;
6552
6553 if (zeroVals)
6554 nVector ++;
6555 else if (nVector<=1)
6556 return false;
6557
6558 if (pos<0.0)
6559 pos=0.0;
6560 if (pos>1.0)
6561 pos=1.0;
6562
6563 icFloatNumber fpos = (icFloatNumber)(nVector-1) * pos;
6564 icUInt32Number iPos = (icUInt32Number)fpos;
6565 icFloatNumber x = fpos - iPos;
6566 icFloatNumber invx = (1.0f - x);
6567
6568 if (iPos == nVector-1) {
6569 iPos--;
6570 x = (icFloatNumber)1.0f;
6571 invx = (icFloatNumber)0.0f;
6572 }
6573
6574 T *lo, *hi;
6575
6576 if (zeroVals) {
6577 if (!iPos) {
6578 lo = NULL;
6579 hi = m_Num;
6580 }
6581 else {
6582 lo = &m_Num[(iPos-1)*nVectorSize];
6583 hi = &lo[nVectorSize];
6584 }
6585 }
6586 else {
6587 lo = &m_Num[iPos*nVectorSize];
6588 hi = &lo[nVectorSize];
6589 }
6590
6592
6593 if (!lo) {
6594 for (i=0; i<nVectorSize; i++) {
6595 DstVector[i] = (icFloatNumber)(zeroVals[i]*invx + hi[i]*x);
6596 }
6597 }
6598 else {
6599 for (i=0; i<nVectorSize; i++) {
6600 DstVector[i] = (icFloatNumber)(lo[i]*invx + hi[i]*x);
6601 }
6602 }
6603 return true;
6604}
6605
6606
6607/**
6608****************************************************************************
6609* Name: CIccTagFloatNum::ValuePos
6610*
6611* Purpose: Gets position of a value int the num array tag
6612*
6613* Args:
6614* DstPos - position of val in array
6615* val - value to look for in array.
6616* bNoZero - flag indicating whether first entry is zero
6617*****************************************************************************
6618*/
6619template <class T, icTagTypeSignature Tsig>
6621{
6622 if(val<0.0)
6623 return false;
6624
6625 icFloatNumber nv = 0.0;
6626 icFloatNumber lv = 0.0;
6627
6628 lv = (icFloatNumber)m_Num[0];
6629
6630 bNoZero = (lv!=0.0);
6631
6632 if (val<lv) {
6633 DstPos = val/lv - 1.0f;
6634 return true;
6635 }
6636
6638 for (i=1; i<m_nSize; i++, lv=nv) {
6639 nv = (icFloatNumber)m_Num[i];
6640
6641 if (val<=nv) {
6642 DstPos = (val-lv)/(nv-lv) + i - 1.0f;
6643 return true;
6644 }
6645 }
6646
6647 return false;
6648}
6649
6650
6651//Make sure typedef classes get built
6655
6656/**
6657 ****************************************************************************
6658 * Name: CIccTagMeasurement::CIccTagMeasurement
6659 *
6660 * Purpose: Constructor
6661 *
6662 *****************************************************************************
6663 */
6665{
6666 memset(&m_Data, 0, sizeof(m_Data));
6667}
6668
6669
6670/**
6671 ****************************************************************************
6672 * Name: CIccTagMeasurement::CIccTagMeasurement
6673 *
6674 * Purpose: Copy Constructor
6675 *
6676 * Args:
6677 * ITM = The CIccTagMeasurement object to be copied
6678 *****************************************************************************
6679 */
6681{
6682 memcpy(&m_Data, &ITM.m_Data, sizeof(m_Data));
6683}
6684
6685
6686/**
6687 ****************************************************************************
6688 * Name: CIccTagMeasurement::operator=
6689 *
6690 * Purpose: Copy Operator
6691 *
6692 * Args:
6693 * MeasTag = The CIccTagMeasurement object to be copied
6694 *****************************************************************************
6695 */
6697{
6698 if (&MeasTag == this)
6699 return *this;
6700
6701 memcpy(&m_Data, &MeasTag.m_Data, sizeof(m_Data));
6702
6703 return *this;
6704}
6705
6706
6707
6708/**
6709 ****************************************************************************
6710 * Name: CIccTagMeasurement::~CIccTagMeasurement
6711 *
6712 * Purpose: Destructor
6713 *
6714 *****************************************************************************
6715 */
6719
6720
6721/**
6722 ****************************************************************************
6723 * Name: CIccTagMeasurement::Read
6724 *
6725 * Purpose: Read in the tag contents into a data block
6726 *
6727 * Args:
6728 * size - # of bytes in tag,
6729 * pIO - IO object to read tag from
6730 *
6731 * Return:
6732 * true = successful, false = failure
6733 *****************************************************************************
6734 */
6736{
6738
6739 if (sizeof(icTagTypeSignature) +
6740 sizeof(icUInt32Number) +
6741 sizeof(m_Data) > size)
6742 return false;
6743
6744 if (!pIO) {
6745 return false;
6746 }
6747
6748 if (!pIO->Read32(&sig))
6749 return false;
6750
6751 if (!pIO->Read32(&m_nReserved))
6752 return false;
6753
6754 icUInt32Number nSize=sizeof(m_Data)/sizeof(icUInt32Number);
6755
6756 if (pIO->Read32(&m_Data,nSize) != (icInt32Number)nSize)
6757 return false;
6758
6759 return true;
6760}
6761
6762
6763/**
6764 ****************************************************************************
6765 * Name: CIccTagMeasurement::Write
6766 *
6767 * Purpose: Write the tag to a file
6768 *
6769 * Args:
6770 * pIO - The IO object to write tag to.
6771 *
6772 * Return:
6773 * true = succesful, false = failure
6774 *****************************************************************************
6775 */
6777{
6778 icTagTypeSignature sig = GetType();
6779
6780 if (!pIO)
6781 return false;
6782
6783 if (!pIO->Write32(&sig))
6784 return false;
6785
6786 if (!pIO->Write32(&m_nReserved))
6787 return false;
6788
6789 icUInt32Number nSize=sizeof(m_Data)/sizeof(icUInt32Number);
6790
6791 if (pIO->Write32(&m_Data,nSize) != (icInt32Number)nSize)
6792 return false;
6793
6794 return true;
6795}
6796
6797
6798/**
6799 ****************************************************************************
6800 * Name: CIccTagMeasurement::Describe
6801 *
6802 * Purpose: Dump data associated with the tag to a string
6803 *
6804 * Args:
6805 * sDescription - string to concatenate tag dump to
6806 *****************************************************************************
6807 */
6808void CIccTagMeasurement::Describe(std::string &sDescription, int nVerboseness)
6809{
6810 CIccInfo Fmt;
6811 icChar buf[128];
6812
6813 sDescription += Fmt.GetStandardObserverName(m_Data.stdObserver); sDescription += "\n";
6814 sprintf(buf, "Backing measurement: X=%.4lf, Y=%.4lf, Z=%.4lf\n",
6815 icFtoD(m_Data.backing.X),
6816 icFtoD(m_Data.backing.Y),
6817 icFtoD(m_Data.backing.Z));
6818 sDescription += buf;
6819 sDescription += Fmt.GetMeasurementGeometryName(m_Data.geometry); sDescription += "\n";
6820 sDescription += Fmt.GetMeasurementFlareName(m_Data.flare); sDescription += "\n";
6821 sDescription += Fmt.GetIlluminantName(m_Data.illuminant); sDescription += "\n";
6822}
6823
6824
6825/**
6826******************************************************************************
6827* Name: CIccTagMeasurement::Validate
6828*
6829* Purpose: Check tag data validity.
6830*
6831* Args:
6832* sig = signature of tag being validated,
6833* sReport = String to add report information to
6834*
6835* Return:
6836* icValidateStatusOK if valid, or other error status.
6837******************************************************************************
6838*/
6839icValidateStatus CIccTagMeasurement::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
6840{
6841 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
6842
6843 CIccInfo Info;
6844 std::string sSigPathName = Info.GetSigPathName(sigPath);
6845
6846 switch(m_Data.stdObserver) {
6847 case icStdObsUnknown:
6850 break;
6851
6852 default:
6853 sReport += icMsgValidateNonCompliant;
6854 sReport += sSigPathName;
6855 sReport += " - Invalid standard observer encoding.\n";
6857 }
6858
6859 switch(m_Data.geometry) {
6860 case icGeometryUnknown:
6861 case icGeometry045or450:
6862 case icGeometry0dord0:
6863 break;
6864
6865 default:
6866 sReport += icMsgValidateNonCompliant;
6867 sReport += sSigPathName;
6868 sReport += " - Invalid measurement geometry encoding.\n";
6870 }
6871
6872 switch(m_Data.illuminant) {
6874 case icIlluminantD50:
6875 case icIlluminantD65:
6876 case icIlluminantD93:
6877 case icIlluminantF2:
6878 case icIlluminantD55:
6879 case icIlluminantA:
6881 case icIlluminantF8:
6882 break;
6883
6884 default:
6885 sReport += icMsgValidateNonCompliant;
6886 sReport += sSigPathName;
6887 sReport += " - Invalid standard illuminant encoding.\n";
6889 }
6890
6891 return rv;
6892}
6893
6894
6895/**
6896 ****************************************************************************
6897 * Name: CIccLocalizedUnicode::CIccLocalizedUnicode
6898 *
6899 * Purpose: Constructor
6900 *
6901 *****************************************************************************
6902 */
6904{
6905 m_pBuf = (icUInt16Number*)malloc(1*sizeof(icUInt16Number));
6906 *m_pBuf = 0;
6907 m_nLength = 0;
6908}
6909
6910
6911/**
6912 ****************************************************************************
6913 * Name: CIccLocalizedUnicode::CIccLocalizedUnicode
6914 *
6915 * Purpose: Copy Constructor
6916 *
6917 * Args:
6918 * ILU = The CIccLocalizedUnicode object to be copied
6919 *****************************************************************************
6920 */
6922{
6923 m_nLength = ILU.GetLength();
6924 m_pBuf = (icUInt16Number*)malloc((m_nLength+1) * sizeof(icUInt16Number));
6925 if (m_nLength)
6926 memcpy(m_pBuf, ILU.GetBuf(), m_nLength*sizeof(icUInt16Number));
6927 m_pBuf[m_nLength] = 0;
6928 m_nLanguageCode = ILU.m_nLanguageCode;
6929 m_nCountryCode = ILU.m_nCountryCode;
6930}
6931
6932
6933/**
6934 ****************************************************************************
6935 * Name: CIccLocalizedUnicode::operator=
6936 *
6937 * Purpose: Copy Operator
6938 *
6939 * Args:
6940 * UnicodeText = The CIccLocalizedUnicode object to be copied
6941 *****************************************************************************
6942 */
6944{
6945 if (&UnicodeText == this)
6946 return *this;
6947
6948 if (SetSize(UnicodeText.GetLength())) {
6949 memcpy(m_pBuf, UnicodeText.GetBuf(), m_nLength*sizeof(icUInt16Number));
6950 }
6951 m_nLanguageCode = UnicodeText.m_nLanguageCode;
6952 m_nCountryCode = UnicodeText.m_nCountryCode;
6953
6954 return *this;
6955}
6956
6957
6958/**
6959 ****************************************************************************
6960 * Name: CIccLocalizedUnicode::~CIccLocalizedUnicode
6961 *
6962 * Purpose: Destructor
6963 *
6964 *****************************************************************************
6965 */
6967{
6968 if (m_pBuf)
6969 free(m_pBuf);
6970}
6971
6972/**
6973 ****************************************************************************
6974 * Name: CIccLocalizedUnicode::GetUtf8Size
6975 *
6976 * Purpose: Returns the size of the ANSI data buffer
6977 *
6978 *****************************************************************************
6979 */
6981{
6982 std::string str;
6983 GetText(str);
6984
6985 return (icUInt32Number)str.size()+1;
6986}
6987
6988/**
6989 ****************************************************************************
6990 * Name: CIccLocalizedUnicode::GetUtf8
6991 *
6992 * Purpose: Extracts the ANSI data buffer (from UTF-16BE)
6993 *
6994 * Args:
6995 * szBuf = pointer where the returned string buffer is to be stored
6996 * nBufSize = size of the buffer to be extracted
6997 *
6998 * Return:
6999 * Pointer to the ANSI data string
7000 *****************************************************************************
7001 */
7003{
7004 if (!szBuf || !nBufSize)
7005 return NULL;
7006
7007 std::string str;
7008 GetText(str);
7009
7010 if (nBufSize - 1 < str.size()) {
7011 memcpy(szBuf, str.c_str(), nBufSize - 1);
7012 szBuf[nBufSize] = 0;
7013 }
7014 else {
7015 strcpy(szBuf, str.c_str());
7016 }
7017
7018 return szBuf;
7019}
7020
7021/**
7022****************************************************************************
7023* Name: CIccLocalizedUnicode::GetText
7024*
7025* Purpose: Gets text as a UTF-8 string
7026*
7027* Args:
7028* sText - string to put results in
7029*
7030*****************************************************************************
7031*/
7032bool CIccLocalizedUnicode::GetText(std::string &sText)
7033{
7034 sText.clear();
7035
7036 icUInt16Number* str = m_pBuf;
7037 while (*str) {
7038 icUInt32Number code32 = 0x0;
7039
7040 //UTF-16 to UTF-32
7041
7042 if (*str <= 0xD7FF) {
7043 code32 = *str;
7044 str++;
7045 }
7046 else if (*str <= 0xDBFF) {
7047 icUInt16Number high = (*str - 0xD800) * 0x400;
7048 icUInt16Number low = *(str + 1) - 0xDC00;
7049 code32 = (low | high) + 0x10000;
7050 str += 2;
7051 }
7052
7053 //UTF-32 to UTF-8 -------
7054
7055 if (code32 <= 0x007F) {
7056 sText += (unsigned char)code32;
7057 }
7058 else if (code32 <= 0x07FF) {
7059 sText += (unsigned char)(((code32 >> 6) & 0x1F) | 0xC0);
7060 sText += (unsigned char)((code32 & 0x3F) | 0x80);
7061 }
7062 else if (code32 <= 0xFFFF) {
7063 sText += (unsigned char)(((code32 >> 12) & 0x0F) | 0xE0);
7064 sText += (unsigned char)(((code32 >> 6) & 0x3F) | 0x80);
7065 sText += (unsigned char)(((code32) & 0x3F) | 0x80);
7066 }
7067 else if (code32 <= 0x10FFFF) {
7068 sText += (unsigned char)(((code32 >> 18) & 0x07) | 0xF0);
7069 sText += (unsigned char)(((code32 >> 12) & 0x3F) | 0x80);
7070 sText += (unsigned char)(((code32 >> 6) & 0x3F) | 0x80);
7071 sText += (unsigned char)(((code32) & 0x3F) | 0x80);
7072 }
7073 }
7074
7075 return true;
7076}
7077
7078
7079/**
7080 ****************************************************************************
7081 * Name: CIccLocalizedUnicode::SetSize
7082 *
7083 * Purpose: Sets the size of the string buffer.
7084 *
7085 * Args:
7086 * nSize - length of the string
7087 *
7088 *****************************************************************************
7089 */
7091{
7092 if (nSize == m_nLength)
7093 return true;
7094
7095 m_pBuf = (icUInt16Number*)icRealloc(m_pBuf, (nSize+1)*sizeof(icUInt16Number));
7096
7097 if (!m_pBuf) {
7098 m_nLength = 0;
7099 return false;
7100 }
7101
7102 m_nLength = nSize;
7103
7104 m_pBuf[nSize]=0;
7105
7106 return true;
7107}
7108
7109/**
7110 ****************************************************************************
7111 * Name: CIccLocalizedUnicode::SetText
7112 *
7113 * Purpose: Allows text data associated with the tag to be set.
7114 *
7115 * Args:
7116 * szText = zero terminated utf8 string to put in tag,
7117 * nLanguageCode = the language code type as defined by icLanguageCode,
7118 * nRegionCode = the region code type as defined by icCountryCode
7119 *****************************************************************************
7120 */
7122 icLanguageCode nLanguageCode/* = icLanguageCodeEnglish*/,
7123 icCountryCode nRegionCode/* = icCountryCodeUSA*/)
7124{
7125 //first convert utf8 to unicode
7126 std::vector<unsigned long> unicode;
7127 size_t i = 0;
7128 while (szText[i])
7129 {
7130 unsigned long uni;
7131 size_t todo;
7132 bool error = false;
7133 unsigned char ch = szText[i++];
7134 if (ch <= 0x7F)
7135 {
7136 uni = ch;
7137 todo = 0;
7138 }
7139 else if (ch <= 0xBF)
7140 {
7141 //not a UTF-8 string so use question mark
7142 uni = '?';
7143 todo = 0;
7144 }
7145 else if (ch <= 0xDF)
7146 {
7147 uni = ch & 0x1F;
7148 todo = 1;
7149 }
7150 else if (ch <= 0xEF)
7151 {
7152 uni = ch & 0x0F;
7153 todo = 2;
7154 }
7155 else if (ch <= 0xF7)
7156 {
7157 uni = ch & 0x07;
7158 todo = 3;
7159 }
7160 else
7161 {
7162 //not a UTF-8 string so use question mark
7163 uni = '?';
7164 todo = 0;;
7165 }
7166 for (size_t j = 0; j < todo; ++j)
7167 {
7168 if (!szText[i]) {
7169 uni = '?';
7170 break;
7171 }
7172 else {
7173 unsigned char ch = szText[i];
7174 if (ch < 0x80 || ch > 0xBF) {
7175 //not a UTF-8 string so use question mark
7176 uni = '?';
7177 break;
7178 }
7179 else {
7180 uni <<= 6;
7181 uni += ch & 0x3F;
7182 }
7183 }
7184 }
7185 if (uni >= 0xD800 && uni <= 0xDFFF) {
7186 //not a UTF-8 string so use question mark
7187 uni = '?';
7188 }
7189 else if (uni > 0x10FFFF) {
7190 //not a UTF-8 string so use question mark
7191 uni = '?';
7192 }
7193 unicode.push_back(uni);
7194 }
7195
7196 //now convert unicode to utf16
7197 std::vector<unsigned short> utf16;
7198 for (i = 0; i < unicode.size(); ++i)
7199 {
7200 unsigned long uni = unicode[i];
7201 if (uni <= 0xFFFF)
7202 {
7203 utf16.push_back((unsigned short)uni);
7204 }
7205 else
7206 {
7207 uni -= 0x10000;
7208 utf16.push_back((unsigned short)((uni >> 10) + 0xD800));
7209 utf16.push_back((unsigned short)((uni & 0x3FF) + 0xDC00));
7210 }
7211 }
7212
7213 icUInt16Number *pBuf;
7214
7215 size_t len = utf16.size();
7216 if (!SetSize((icUInt32Number)len+1))
7217 return false;
7218
7219 pBuf = m_pBuf;
7220 for (i=0; i<len; i++) {
7221 *pBuf++ = utf16[i];
7222 }
7223 *pBuf = 0;
7224
7225 m_nLanguageCode = nLanguageCode;
7226 m_nCountryCode = nRegionCode;
7227
7228 return true;
7229}
7230
7231/**
7232 ****************************************************************************
7233 * Name: CIccLocalizedUnicode::SetText
7234 *
7235 * Purpose: Allows text data associated with the tag to be set.
7236 *
7237 * Args:
7238 * sszUnicode16Text = Unicode16 text to be set,
7239 * nLanguageCode = the language code type as defined by icLanguageCode,
7240 * nRegionCode = the region code type as defined by icCountryCode
7241 *****************************************************************************
7242 */
7244 icLanguageCode nLanguageCode/* = icLanguageCodeEnglish*/,
7245 icCountryCode nRegionCode/* = icCountryCodeUSA*/)
7246{
7247 const icUInt16Number *pBuf=sszUnicode16Text;
7248 int len;
7249
7250 for (len=0; *pBuf; len++, pBuf++);
7251
7252 if (!SetSize(len))
7253 return false;
7254 memcpy(m_pBuf, sszUnicode16Text, (len+1)*sizeof(icUInt16Number));
7255
7256 m_nLanguageCode = nLanguageCode;
7257 m_nCountryCode = nRegionCode;
7258
7259 return true;
7260}
7261
7262/**
7263****************************************************************************
7264* Name: CIccLocalizedUnicode::SetText
7265*
7266* Purpose: Allows text data associated with the tag to be set.
7267*
7268* Args:
7269* sszUnicode32Text = Unicode32 text to be set,
7270* nLanguageCode = the language code type as defined by icLanguageCode,
7271* nRegionCode = the region code type as defined by icCountryCode
7272*****************************************************************************
7273*/
7275 icLanguageCode nLanguageCode/* = icLanguageCodeEnglish*/,
7276 icCountryCode nRegionCode/* = icCountryCodeUSA*/)
7277{
7278 const icUInt32Number *pBuf=sszUnicode32Text;
7279 int len;
7280
7281 for (len=0; *pBuf; len++, pBuf++);
7282 if (*pBuf)
7283 pBuf--;
7284
7285 if (!SetSize(len*2))
7286 return false;
7287
7288 const icUInt32Number *srcStart = sszUnicode32Text;
7289 icUInt16Number *dstStart = m_pBuf;
7290 icConvertUTF32toUTF16(&srcStart, &srcStart[len], &dstStart, &dstStart[len*2], lenientConversion);
7291
7292 *dstStart=0;
7293 if (!SetSize((icUInt32Number)(dstStart - m_pBuf)))
7294 return false;
7295
7296 m_nLanguageCode = nLanguageCode;
7297 m_nCountryCode = nRegionCode;
7298
7299 return true;
7300}
7301
7302
7303/**
7304 ****************************************************************************
7305 * Name: CIccTagMultiLocalizedUnicode::CIccTagMultiLocalizedUnicode
7306 *
7307 * Purpose: Constructor
7308 *
7309 *****************************************************************************
7310 */
7315
7316
7317/**
7318 ****************************************************************************
7319 * Name: CIccTagMultiLocalizedUnicode::CIccTagMultiLocalizedUnicode
7320 *
7321 * Purpose: Copy Constructor
7322 *
7323 * Args:
7324 * ITMLU = The CIccTagMultiLocalizedUnicode object to be copied
7325 *****************************************************************************
7326 */
7332
7333
7334/**
7335 ****************************************************************************
7336 * Name: CIccTagMultiLocalizedUnicode::operator=
7337 *
7338 * Purpose: Copy Operator
7339 *
7340 * Args:
7341 * MultiLocalizedTag = The CIccTagMultiLocalizedUnicode object to be copied
7342 *****************************************************************************
7343 */
7345{
7346 if (&MultiLocalizedTag == this)
7347 return *this;
7348
7349 m_Strings->clear();
7350 *m_Strings = *MultiLocalizedTag.m_Strings;
7351
7352 return *this;
7353}
7354
7355
7356/**
7357 ****************************************************************************
7358 * Name: CIccTagMultiLocalizedUnicode::~CIccTagMultiLocalizedUnicode
7359 *
7360 * Purpose: Destructor
7361 *
7362 *****************************************************************************
7363 */
7368
7369
7370/**
7371 ****************************************************************************
7372 * Name: CIccTagMultiLocalizedUnicode::Read
7373 *
7374 * Purpose: Read in the tag contents into a data block
7375 *
7376 * Since MultiLocalizedUnicode tags can be embedded in other tags
7377 * this function ensures that the current read pointer will be set to the
7378 * position just after the last name record.
7379 *
7380 * Args:
7381 * size - # of bytes in tag,
7382 * pIO - IO object to read tag from
7383 *
7384 * Return:
7385 * true = successful, false = failure
7386 *****************************************************************************
7387 */
7389{
7391 icUInt32Number nNumRec, nRecSize;
7392 icLanguageCode nLanguageCode;
7393 icCountryCode nRegionCode;
7394 icUInt32Number nLength, nOffset, nNumChar;
7395
7396 if (!m_Strings->empty())
7397 m_Strings->clear();
7398
7399 if (sizeof(icTagTypeSignature) +
7400 sizeof(icUInt32Number)*3 > size)
7401 return false;
7402
7403 if (!pIO) {
7404 return false;
7405 }
7406
7407 icUInt32Number nTagPos = pIO->Tell();
7408
7409 if (!pIO->Read32(&sig) ||
7410 !pIO->Read32(&m_nReserved) ||
7411 !pIO->Read32(&nNumRec) ||
7412 !pIO->Read32(&nRecSize))
7413 return false;
7414
7415
7416 if (nRecSize!=12) { //Recognized version name records are 12 bytes each
7417 return false;
7418 }
7419
7420 icUInt32Number i;
7421 CIccLocalizedUnicode Unicode;
7422 icUInt32Number nLastPos = 0;
7423
7424 for (i=0; i<nNumRec; i++) {
7425 if (4*sizeof(icUInt32Number) + (i+1)*12 > size)
7426 return false;
7427
7428 pIO->Seek(nTagPos+4*sizeof(icUInt32Number) + i*12, icSeekSet);
7429
7430 if (!pIO->Read16(&nLanguageCode) ||
7431 !pIO->Read16(&nRegionCode) ||
7432 !pIO->Read32(&nLength) ||
7433 !pIO->Read32(&nOffset))
7434 return false;
7435
7436 if (nOffset+nLength > size)
7437 return false;
7438
7439 //Find out position of the end of last named record
7440 if (nOffset+nLength > nLastPos)
7441 nLastPos = nOffset + nLength;
7442
7443 nNumChar = nLength / sizeof(icUInt16Number);
7444
7445 if (!Unicode.SetSize(nNumChar))
7446 return false;
7447
7448 Unicode.m_nLanguageCode = nLanguageCode;
7449 Unicode.m_nCountryCode = nRegionCode;
7450
7451 pIO->Seek(nTagPos+nOffset, icSeekSet);
7452
7453 if (pIO->Read16(Unicode.GetBuf(), nNumChar) != (icInt32Number)nNumChar)
7454 return false;
7455
7456 m_Strings->push_back(Unicode);
7457 }
7458
7459 //Now seek past the last named record
7460 if (nLastPos > 0)
7461 pIO->Seek(nTagPos+nLastPos, icSeekSet);
7462
7463 return true;
7464}
7465
7466
7467/**
7468 ****************************************************************************
7469 * Name: CIccTagMultiLocalizedUnicode::Write
7470 *
7471 * Purpose: Write the tag to a file
7472 *
7473 * Args:
7474 * pIO - The IO object to write tag to.
7475 *
7476 * Return:
7477 * true = succesful, false = failure
7478 *****************************************************************************
7479 */
7481{
7482 icTagTypeSignature sig = GetType();
7483 icUInt32Number nNumRec=(icUInt32Number)m_Strings->size(), nRecSize=12;
7484 icUInt32Number nLength;
7485
7486 if (!pIO) {
7487 return false;
7488 }
7489
7490 if (!pIO->Write32(&sig) ||
7491 !pIO->Write32(&m_nReserved) ||
7492 !pIO->Write32(&nNumRec) ||
7493 !pIO->Write32(&nRecSize))
7494 return false;
7495
7496
7497 icUInt32Number nPos = 4*sizeof(icUInt32Number) + nNumRec*12;
7498
7499 CIccMultiLocalizedUnicode::iterator i;
7500
7501 for (i=m_Strings->begin(); i!=m_Strings->end(); i++) {
7502 nLength = i->GetLength() * sizeof(icUInt16Number);
7503
7504 if (!pIO->Write16(&i->m_nLanguageCode) ||
7505 !pIO->Write16(&i->m_nCountryCode) ||
7506 !pIO->Write32(&nLength) ||
7507 !pIO->Write32(&nPos))
7508 return false;
7509 nPos += nLength;
7510 }
7511
7512 for (i=m_Strings->begin(); i!=m_Strings->end(); i++) {
7513 nLength = i->GetLength();
7514
7515 if (nLength) {
7516 if (pIO->Write16(i->GetBuf(), nLength) != (icInt32Number)nLength)
7517 return false;
7518 }
7519 }
7520
7521 return true;
7522}
7523
7524
7525/**
7526 ****************************************************************************
7527 * Name: CIccTagMultiLocalizedUnicode::Describe
7528 *
7529 * Purpose: Dump data associated with the tag to a string
7530 *
7531 * Args:
7532 * sDescription - string to concatenate tag dump to
7533 *****************************************************************************
7534 */
7535void CIccTagMultiLocalizedUnicode::Describe(std::string &sDescription, int nVerboseness)
7536{
7537 char szBuf[128];
7538 std::string utf8;
7539 int nSize = 127;
7540 CIccMultiLocalizedUnicode::iterator i;
7541
7542 for (i=m_Strings->begin(); i!=m_Strings->end(); i++) {
7543 if (i!=m_Strings->begin())
7544 sDescription += "\n";
7545
7546 // Bad ICCs can have unprintables...
7547 sDescription += "Language = ";
7548 if (isprint(i->m_nLanguageCode >> 8) && isprint(i->m_nLanguageCode & 0x00FF)) {
7549 sprintf(szBuf, "'%c%c'", i->m_nLanguageCode >> 8, i->m_nLanguageCode & 0x00FF);
7550 }
7551 else {
7552 sprintf(szBuf, "'\?\?' (0x%04X)", i->m_nLanguageCode);
7553 }
7554 sDescription += szBuf;
7555
7556 if (i->m_nCountryCode) {
7557 // Region Codes are optional according to ISO
7558 sDescription += ", Region = ";
7559 if (isprint(i->m_nCountryCode >> 8) && isprint(i->m_nCountryCode & 0x00FF)) {
7560 sprintf(szBuf, "'%c%c'", i->m_nCountryCode>>8, i->m_nCountryCode & 0x00FF);
7561 }
7562 else {
7563 sprintf(szBuf, "'\?\?' (0x%04X)", i->m_nCountryCode);
7564 }
7565 sDescription += szBuf;
7566 }
7567 sDescription += "\n";
7568
7569 i->GetText(utf8);
7570 sDescription += "\"";
7571 sDescription += utf8;
7572 sDescription += "\"\n";
7573 }
7574}
7575
7576
7577/**
7578******************************************************************************
7579* Name: CIccTagMultiLocalizedUnicode::Validate
7580*
7581* Purpose: Check tag data validity.
7582*
7583* Args:
7584* sig = signature of tag being validated,
7585* sReport = String to add report information to
7586*
7587* Return:
7588* icValidateStatusOK if valid, or other error status.
7589******************************************************************************
7590*/
7591icValidateStatus CIccTagMultiLocalizedUnicode::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
7592{
7593 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
7594
7595 CIccInfo Info;
7596 std::string sSigPathName = Info.GetSigPathName(sigPath);
7597
7598 if (!m_Strings->size()) {
7599 sReport += icMsgValidateWarning;
7600 sReport += sSigPathName;
7601 sReport += " - Empty tag!\n";
7603 }
7604
7605 CIccMultiLocalizedUnicode::iterator i;
7606 for (i=m_Strings->begin(); i!=m_Strings->end(); i++) {
7607 // TODO: Validate ISO-639 Language Codes and and ISO-3166 Country codes.
7608 // Needs to be done against a full set of codes or many false warnings.
7609 }
7610
7611 return rv;
7612}
7613
7614/**
7615****************************************************************************
7616* Name: refIccMAX::CIccTagMultiLocalizedUnicode::Find
7617*
7618* Purpose:
7619*
7620* Args:
7621* nLanguageCode
7622* nRegionCode
7623*
7624* Return:
7625* Pointer to CIccLocalizedUnicode object associated with the nLanguageCode
7626* and nRegionCode or NULL if not found
7627*****************************************************************************
7628*/
7630 icCountryCode nRegionCode /* = icCountryCodeUSA */)
7631{
7632 CIccMultiLocalizedUnicode::iterator i;
7633
7634 for (i=m_Strings->begin(); i!=m_Strings->end(); i++) {
7635 if (i->m_nLanguageCode == nLanguageCode &&
7636 i->m_nCountryCode == nRegionCode) {
7637 return &(*i);
7638 }
7639 }
7640
7641 return NULL;
7642}
7643
7644/**
7645****************************************************************************
7646* Name: refIccMAX::CIccTagMultiLocalizedUnicode::SetText
7647*
7648* Purpose:
7649*
7650* Args:
7651* sszUnicodeText
7652* nLanguageCode
7653* RegionCode
7654*****************************************************************************
7655*/
7657 icLanguageCode nLanguageCode /* = icLanguageCodeEnglish */,
7658 icCountryCode nRegionCode /* = icCountryCodeUSA */)
7659{
7660 CIccLocalizedUnicode *pText = Find(nLanguageCode, nRegionCode);
7661
7662 if (!pText) {
7663 CIccLocalizedUnicode newText;
7664 newText.SetText(szText, nLanguageCode, nRegionCode);
7665 m_Strings->push_back(newText);
7666 }
7667 else {
7668 pText->SetText(szText, nLanguageCode, nRegionCode);
7669 }
7670}
7671
7672
7673/**
7674****************************************************************************
7675* Name: refIccMAX::CIccTagMultiLocalizedUnicode::SetText
7676*
7677* Purpose:
7678*
7679* Args:
7680* sszUnicodeText
7681* nLanguageCode
7682* RegionCode
7683*****************************************************************************
7684*/
7686 icLanguageCode nLanguageCode /* = icLanguageCodeEnglish */,
7687 icCountryCode nRegionCode /* = icCountryCodeUSA */)
7688{
7689 CIccLocalizedUnicode *pText = Find(nLanguageCode, nRegionCode);
7690
7691 if (!pText) {
7692 CIccLocalizedUnicode newText;
7693 newText.SetText(sszUnicode16Text, nLanguageCode, nRegionCode);
7694 m_Strings->push_back(newText);
7695 }
7696 else {
7697 pText->SetText(sszUnicode16Text, nLanguageCode, nRegionCode);
7698 }
7699}
7700
7701/**
7702****************************************************************************
7703* Name: refIccMAX::CIccTagMultiLocalizedUnicode::SetText
7704*
7705* Purpose:
7706*
7707* Args:
7708* sszUnicodeText
7709* nLanguageCode
7710* RegionCode
7711*****************************************************************************
7712*/
7714 icLanguageCode nLanguageCode /* = icLanguageCodeEnglish */,
7715 icCountryCode nRegionCode /* = icCountryCodeUSA */)
7716{
7717 CIccLocalizedUnicode *pText = Find(nLanguageCode, nRegionCode);
7718
7719 if (!pText) {
7720 CIccLocalizedUnicode newText;
7721 newText.SetText(sszUnicode32Text, nLanguageCode, nRegionCode);
7722 m_Strings->push_back(newText);
7723 }
7724 else {
7725 pText->SetText(sszUnicode32Text, nLanguageCode, nRegionCode);
7726 }
7727}
7728
7729//
7730// MD: Moved Curve and LUT tags to IccTagLut.cpp (4-30-05)
7731//
7732
7733
7734/**
7735 ****************************************************************************
7736 * Name: CIccTagData::CIccTagData
7737 *
7738 * Purpose: Constructor
7739 *
7740 * Args:
7741 * nSize = number of data entries
7742 *
7743 *****************************************************************************
7744 */
7746{
7747 m_nSize = nSize;
7748 if (m_nSize <1)
7749 m_nSize = 1;
7750 m_pData = (icUInt8Number*)calloc(nSize, sizeof(icUInt8Number));
7751}
7752
7753
7754/**
7755 ****************************************************************************
7756 * Name: CIccTagData::CIccTagData
7757 *
7758 * Purpose: Copy Constructor
7759 *
7760 * Args:
7761 * ITD = The CIccTagData object to be copied
7762 *****************************************************************************
7763 */
7765{
7766 m_nDataFlag = ITD.m_nDataFlag;
7767 m_nSize = ITD.m_nSize;
7768
7769 m_pData = (icUInt8Number*)calloc(m_nSize, sizeof(icUInt8Number));
7770 memcpy(m_pData, ITD.m_pData, sizeof(icUInt8Number)*m_nSize);
7771}
7772
7773
7774/**
7775 ****************************************************************************
7776 * Name: CIccTagData::operator=
7777 *
7778 * Purpose: Copy Operator
7779 *
7780 * Args:
7781 * DataTag = The CIccTagData object to be copied
7782 *****************************************************************************
7783 */
7785{
7786 if (&DataTag == this)
7787 return *this;
7788
7789 m_nDataFlag = DataTag.m_nDataFlag;
7790 m_nSize = DataTag.m_nSize;
7791
7792 if (m_pData)
7793 free(m_pData);
7794 m_pData = (icUInt8Number*)calloc(m_nSize, sizeof(icUInt8Number));
7795 memcpy(m_pData, DataTag.m_pData, sizeof(icUInt8Number)*m_nSize);
7796
7797 return *this;
7798}
7799
7800
7801/**
7802 ****************************************************************************
7803 * Name: CIccTagData::~CIccTagData
7804 *
7805 * Purpose: Destructor
7806 *
7807 *****************************************************************************
7808 */
7810{
7811 if (m_pData)
7812 free(m_pData);
7813}
7814
7815
7816/**
7817 ****************************************************************************
7818 * Name: CIccTagData::Read
7819 *
7820 * Purpose: Read in the tag contents into a data block
7821 *
7822 * Args:
7823 * size - # of bytes in tag,
7824 * pIO - IO object to read tag from
7825 *
7826 * Return:
7827 * true = successful, false = failure
7828 *****************************************************************************
7829 */
7831{
7833
7834 if (sizeof(icTagTypeSignature) +
7835 sizeof(icUInt32Number) +
7836 sizeof(icUInt32Number) +
7837 sizeof(icUInt8Number) > size)
7838 return false;
7839
7840 if (!pIO) {
7841 return false;
7842 }
7843
7844 if (!pIO->Read32(&sig))
7845 return false;
7846
7847 if (!pIO->Read32(&m_nReserved))
7848 return false;
7849
7850 if (!pIO->Read32(&m_nDataFlag))
7851 return false;
7852
7853 icUInt32Number nNum = size-3*sizeof(icUInt32Number);
7854
7855 if (!SetSize(nNum))
7856 return false;
7857
7858 if (pIO->Read8(m_pData, nNum) != (icInt32Number)nNum)
7859 return false;
7860
7861 if (IsTypeCompressed()) {
7862 //Uncompress data here
7863 }
7864
7865 return true;
7866}
7867
7868
7869/**
7870 ****************************************************************************
7871 * Name: CIccTagData::Write
7872 *
7873 * Purpose: Write the tag to a file
7874 *
7875 * Args:
7876 * pIO - The IO object to write tag to.
7877 *
7878 * Return:
7879 * true = succesful, false = failure
7880 *****************************************************************************
7881 */
7883{
7884 icTagTypeSignature sig = GetType();
7885
7886 if (!pIO)
7887 return false;
7888
7889 if (!pIO->Write32(&sig))
7890 return false;
7891
7892 if (!pIO->Write32(&m_nReserved))
7893 return false;
7894
7895 if (!pIO->Write32(&m_nDataFlag))
7896 return false;
7897
7898 if (IsTypeCompressed()) {
7899 icUInt32Number *pData = NULL;
7900 icInt32Number nSize = 0;
7901 //Compress data here
7902
7903 if (pIO->Write8(pData, nSize) != (icInt32Number)nSize)
7904 return false;
7905 }
7906 else {
7907 if (pIO->Write8(m_pData, m_nSize) != (icInt32Number)m_nSize)
7908 return false;
7909 }
7910
7911 return true;
7912}
7913
7914
7915/**
7916 ****************************************************************************
7917 * Name: CIccTagData::Describe
7918 *
7919 * Purpose: Dump data associated with the tag to a string
7920 *
7921 * Args:
7922 * sDescription - string to concatenate tag dump to
7923 *****************************************************************************
7924 */
7925void CIccTagData::Describe(std::string &sDescription, int nVerboseness)
7926{
7927 icChar buf[128];
7928
7929 sDescription = "\n";
7930 if (IsTypeCompressed())
7931 sDescription += "Compressed "; // If data is compressed, prepend appropriate text
7932
7933 if (IsTypeAscii()) {
7934 sDescription = "Ascii Data:\n";
7935
7936 for (int i=0; i<(int)m_nSize; i++)
7937 sDescription += (icChar)m_pData[i];
7938 }
7939 else if (IsTypeUtf()) {
7940 if (m_nSize>2 &&
7941 ((m_pData[0]==0xff && m_pData[1]==0xfe) || //UTF-16LE
7942 (m_pData[0]==0xfe && m_pData[1]==0xff))) { //UTF-16BE
7943 sprintf(buf, "UTF-16%s Data:", m_pData[0]==0xff ? "LE" : "BE" );
7944 sDescription = buf;
7945
7946 icMemDump(sDescription, m_pData, m_nSize);
7947 }
7948 else { //UTF-8
7949 sDescription = "UTF-8 Data:\n";
7950
7951 for (int i=0; i<(int)m_nSize; i++)
7952 sDescription += (icChar)m_pData[i];
7953 }
7954 }
7955 else {
7956 if (IsTypeBinary()) {
7957 sDescription = "Binary Data:\n";
7958 }
7959 else {
7960 sDescription = "Other Data:\n";
7961 }
7962
7963 icMemDump(sDescription, m_pData, m_nSize);
7964 }
7965 sDescription += "\n";
7966}
7967
7968/**
7969 ****************************************************************************
7970 * Name: CIccTagData::SetSize
7971 *
7972 * Purpose: Sets the size of the data array.
7973 *
7974 * Args:
7975 * nSize - number of data entries,
7976 * bZeroNew - flag to zero newly formed values
7977 *****************************************************************************
7978 */
7979bool CIccTagData::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
7980{
7981 if (m_nSize == nSize)
7982 return true;
7983
7984 m_pData = (icUInt8Number*)icRealloc(m_pData, nSize*sizeof(icUInt8Number));
7985
7986 if (!m_pData) {
7987 m_nSize = 0;
7988 return false;
7989 }
7990
7991 if (bZeroNew && nSize > m_nSize) {
7992 memset(&m_pData[m_nSize], 0, (nSize-m_nSize)*sizeof(icUInt8Number));
7993 }
7994 m_nSize = nSize;
7995
7996 return true;
7997}
7998
7999
8000/**
8001******************************************************************************
8002* Name: CIccTagData::Validate
8003*
8004* Purpose: Check tag data validity.
8005*
8006* Args:
8007* sig = signature of tag being validated,
8008* sReport = String to add report information to
8009*
8010* Return:
8011* icValidateStatusOK if valid, or other error status.
8012******************************************************************************
8013*/
8014icValidateStatus CIccTagData::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
8015{
8016 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
8017
8018 CIccInfo Info;
8019 std::string sSigPathName = Info.GetSigPathName(sigPath);
8020
8021 // Mask bits to match processing in Describe() so warnings are appropriate
8022 switch(m_nDataFlag&(icCompressedData|icDataTypeMask)) {
8023 case icAsciiData:
8024 for (int i = 0; i < (int)m_nSize; i++) {
8025 if (m_pData[i] & 0x80) {
8026 sReport += icMsgValidateWarning;
8027 sReport += sSigPathName;
8028 sReport += " - Ascii Data is not just 7-bit data.\n";
8030 break;
8031 }
8032 }
8033 break;
8034 case icBinaryData:
8035 case icUtfData:
8039 break;
8040 default:
8041 sReport += icMsgValidateNonCompliant;
8042 sReport += sSigPathName;
8043 sReport += " - Invalid data flag encoding.\n";
8045 }
8046
8047 if (m_nDataFlag & ~(icCompressedData | icDataTypeMask)) {
8048 sReport += icMsgValidateNonCompliant;
8049 sReport += sSigPathName;
8050 sReport += " - Invalid data flag encoding (reserved high order bits).\n";
8052 }
8053
8054 return rv;
8055}
8056
8057
8058/**
8059 ****************************************************************************
8060 * Name: CIccTagDateTime::CIccTagDateTime
8061 *
8062 * Purpose: Constructor
8063 *
8064 *****************************************************************************
8065 */
8067{
8068 memset(&m_DateTime, 0, sizeof(m_DateTime));
8069}
8070
8071
8072/**
8073 ****************************************************************************
8074 * Name: CIccTagDateTime::CIccTagDateTime
8075 *
8076 * Purpose: Copy Constructor
8077 *
8078 * Args:
8079 * ITDT = The CIccTagDateTime object to be copied
8080 *****************************************************************************
8081 */
8083{
8084 memcpy(&m_DateTime, &ITDT.m_DateTime, sizeof(m_DateTime));
8085}
8086
8087
8088/**
8089 ****************************************************************************
8090 * Name: CIccTagDateTime::operator=
8091 *
8092 * Purpose: Copy Operator
8093 *
8094 * Args:
8095 * DateTimeTag = The CIccTagDateTime object to be copied
8096 *****************************************************************************
8097 */
8099{
8100 if (&DateTimeTag == this)
8101 return *this;
8102
8103 memcpy(&m_DateTime, &DateTimeTag.m_DateTime, sizeof(m_DateTime));
8104
8105 return *this;
8106}
8107
8108
8109/**
8110 ****************************************************************************
8111 * Name: CIccTagDateTime::~CIccTagDateTime
8112 *
8113 * Purpose: Destructor
8114 *
8115 *****************************************************************************
8116 */
8120
8121
8122
8123/**
8124 ****************************************************************************
8125 * Name: CIccTagDateTime::Read
8126 *
8127 * Purpose: Read in the tag contents into a data block
8128 *
8129 * Args:
8130 * size - # of bytes in tag,
8131 * pIO - IO object to read tag from
8132 *
8133 * Return:
8134 * true = successful, false = failure
8135 *****************************************************************************
8136 */
8138{
8140
8141 if (sizeof(icTagTypeSignature) +
8142 sizeof(icUInt32Number) +
8143 sizeof(icDateTimeNumber) > size)
8144 return false;
8145
8146 if (!pIO) {
8147 return false;
8148 }
8149
8150 if (!pIO->Read32(&sig))
8151 return false;
8152
8153 if (!pIO->Read32(&m_nReserved))
8154 return false;
8155
8156
8157 icUInt32Number nsize = (size-2*sizeof(icUInt32Number))/sizeof(icUInt16Number);
8158
8159 if (nsize > sizeof(m_DateTime) / sizeof(icUInt16Number))
8160 return false;
8161
8162 if (pIO->Read16(&m_DateTime,nsize) != (icInt32Number)nsize)
8163 return false;
8164
8165 return true;
8166}
8167
8168
8169
8170/**
8171 ****************************************************************************
8172 * Name: CIccTagDateTime::Write
8173 *
8174 * Purpose: Write the tag to a file
8175 *
8176 * Args:
8177 * pIO - The IO object to write tag to.
8178 *
8179 * Return:
8180 * true = succesful, false = failure
8181 *****************************************************************************
8182 */
8184{
8185 icTagTypeSignature sig = GetType();
8186
8187 if (!pIO)
8188 return false;
8189
8190 if (!pIO->Write32(&sig))
8191 return false;
8192
8193 if (!pIO->Write32(&m_nReserved))
8194 return false;
8195
8196 if (pIO->Write16(&m_DateTime,6) != 6)
8197 return false;
8198
8199 return true;
8200}
8201
8202
8203
8204/**
8205 ****************************************************************************
8206 * Name: CIccTagDateTime::Describe
8207 *
8208 * Purpose: Dump data associated with the tag to a string
8209 *
8210 * Args:
8211 * sDescription - string to concatenate tag dump to
8212 *****************************************************************************
8213 */
8214void CIccTagDateTime::Describe(std::string &sDescription, int nVerboseness)
8215{
8216 icChar buf[128];
8217
8218 sDescription = "Date = ";
8219 sprintf(buf, "%u-%u-%u\n", m_DateTime.month, m_DateTime.day, m_DateTime.year);
8220 sDescription += buf;
8221
8222 sDescription += "Time = ";
8223 sprintf(buf, "%u:%u:%u\n", m_DateTime.hours, m_DateTime.minutes, m_DateTime.seconds);
8224 sDescription += buf;
8225}
8226
8227
8228/**
8229******************************************************************************
8230* Name: CIccTagDateTime::Validate
8231*
8232* Purpose: Check tag data validity.
8233*
8234* Args:
8235* sig = signature of tag being validated,
8236* sReport = String to add report information to
8237*
8238* Return:
8239* icValidateStatusOK if valid, or other error status.
8240******************************************************************************
8241*/
8242icValidateStatus CIccTagDateTime::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
8243{
8244 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
8245 CIccInfo Info;
8246
8247 rv = icMaxStatus(rv, Info.CheckData(sReport, m_DateTime));
8248
8249 return rv;
8250}
8251
8252
8253
8254/**
8255 ****************************************************************************
8256 * Name: CIccTagColorantOrder::CIccTagColorantOrder
8257 *
8258 * Purpose: Constructor
8259 *
8260 * Args:
8261 * nSize = number of channels
8262 *
8263 *****************************************************************************
8264 */
8266{
8267 m_nCount = nsize;
8268 if (m_nCount <1)
8269 m_nCount = 1;
8270 m_pData = (icUInt8Number*)calloc(nsize, sizeof(icUInt8Number));
8271}
8272
8273
8274
8275/**
8276 ****************************************************************************
8277 * Name: CIccTagColorantOrder::CIccTagColorantOrder
8278 *
8279 * Purpose: Copy Constructor
8280 *
8281 * Args:
8282 * ITCO = The CIccTagColorantOrder object to be copied
8283 *****************************************************************************
8284 */
8286{
8287 m_nCount = ITCO.m_nCount;
8288
8289 m_pData = (icUInt8Number*)calloc(m_nCount, sizeof(icUInt8Number));
8290 memcpy(m_pData, ITCO.m_pData, sizeof(icUInt8Number)*m_nCount);
8291}
8292
8293
8294/**
8295 ****************************************************************************
8296 * Name: CIccTagColorantOrder::operator=
8297 *
8298 * Purpose: Copy Operator
8299 *
8300 * Args:
8301 * ColorantOrderTag = The CIccTagColorantOrder object to be copied
8302 *****************************************************************************
8303 */
8305{
8306 if (&ColorantOrderTag == this)
8307 return *this;
8308
8309 m_nCount = ColorantOrderTag.m_nCount;
8310
8311 if (m_pData)
8312 free(m_pData);
8313 m_pData = (icUInt8Number*)calloc(m_nCount, sizeof(icUInt8Number));
8314 memcpy(m_pData, ColorantOrderTag.m_pData, sizeof(icUInt8Number)*m_nCount);
8315
8316 return *this;
8317}
8318
8319
8320/**
8321 ****************************************************************************
8322 * Name: CIccTagColorantOrder::~CIccTagColorantOrder
8323 *
8324 * Purpose: Destructor
8325 *
8326 *****************************************************************************
8327 */
8329{
8330 if (m_pData)
8331 free(m_pData);
8332}
8333
8334
8335
8336/**
8337 ****************************************************************************
8338 * Name: CIccTagColorantOrder::Read
8339 *
8340 * Purpose: Read in the tag contents into a data block
8341 *
8342 * Args:
8343 * size - # of bytes in tag,
8344 * pIO - IO object to read tag from
8345 *
8346 * Return:
8347 * true = successful, false = failure
8348 *****************************************************************************
8349 */
8351{
8353 icUInt32Number nCount;
8354
8355 if (sizeof(icTagTypeSignature) +
8356 sizeof(icUInt32Number) +
8357 sizeof(icUInt32Number) > size)
8358 return false;
8359
8360 if (!pIO) {
8361 return false;
8362 }
8363
8364 if (!pIO->Read32(&sig))
8365 return false;
8366
8367 if (!pIO->Read32(&m_nReserved))
8368 return false;
8369
8370 if (!pIO->Read32(&nCount))
8371 return false;
8372
8373 icUInt32Number nNum = (size - 3*sizeof(icUInt32Number))/sizeof(icUInt8Number);
8374
8375 if (nNum < nCount)
8376 return false;
8377
8378 if (!SetSize((icUInt16Number)nCount))
8379 return false;
8380
8381 if (pIO->Read8(&m_pData[0], m_nCount) != (icInt32Number)m_nCount)
8382 return false;
8383
8384 return true;
8385}
8386
8387
8388
8389/**
8390 ****************************************************************************
8391 * Name: CIccTagColorantOrder::Write
8392 *
8393 * Purpose: Write the tag to a file
8394 *
8395 * Args:
8396 * pIO - The IO object to write tag to.
8397 *
8398 * Return:
8399 * true = succesful, false = failure
8400 *****************************************************************************
8401 */
8403{
8404 icTagTypeSignature sig = GetType();
8405
8406 if (!pIO)
8407 return false;
8408
8409 if (!pIO->Write32(&sig))
8410 return false;
8411
8412 if (!pIO->Write32(&m_nReserved))
8413 return false;
8414
8415 if (!pIO->Write32(&m_nCount))
8416 return false;
8417
8418 if (pIO->Write8(&m_pData[0], m_nCount) != (icInt32Number)m_nCount)
8419 return false;
8420
8421 return true;
8422}
8423
8424
8425
8426/**
8427 ****************************************************************************
8428 * Name: CIccTagColorantOrder::Describe
8429 *
8430 * Purpose: Dump data associated with the tag to a string
8431 *
8432 * Args:
8433 * sDescription - string to concatenate tag dump to
8434 *****************************************************************************
8435 */
8436void CIccTagColorantOrder::Describe(std::string &sDescription, int nVerboseness)
8437{
8438 icChar buf[128];
8439
8440 sprintf(buf, "Colorant Count : %u\n", m_nCount);
8441 sDescription += buf;
8442 sDescription += "Order of Colorants:\n";
8443
8444 for (int i=0; i<(int)m_nCount; i++) {
8445 sprintf(buf, "%u\n", m_pData[i]);
8446 sDescription += buf;
8447 }
8448}
8449
8450
8451/**
8452 ****************************************************************************
8453 * Name: CIccTagColorantOrder::SetSize
8454 *
8455 * Purpose: Sets the size of the data array.
8456 *
8457 * Args:
8458 * nSize - number of channels,
8459 * bZeroNew - flag to zero newly formed values
8460 *****************************************************************************
8461 */
8462bool CIccTagColorantOrder::SetSize(icUInt16Number nSize, bool bZeroNew/*=true*/)
8463{
8464 if (m_nCount == nSize)
8465 return true;
8466
8467 m_pData = (icUInt8Number*)icRealloc(m_pData, nSize*sizeof(icUInt8Number));
8468
8469 if (!m_pData) {
8470 m_nCount = 0;
8471 return false;
8472 }
8473
8474 if (bZeroNew && nSize > m_nCount) {
8475 memset(&m_pData[m_nCount], 0, (nSize - m_nCount)*sizeof(icUInt8Number));
8476 }
8477
8478 m_nCount = nSize;
8479
8480 return true;
8481}
8482
8483
8484/**
8485******************************************************************************
8486* Name: CIccTagColorantOrder::Validate
8487*
8488* Purpose: Check tag data validity.
8489*
8490* Args:
8491* sig = signature of tag being validated,
8492* sReport = String to add report information to
8493*
8494* Return:
8495* icValidateStatusOK if valid, or other error status.
8496******************************************************************************
8497*/
8498icValidateStatus CIccTagColorantOrder::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
8499{
8500 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
8501
8502 CIccInfo Info;
8503 std::string sSigPathName = Info.GetSigPathName(sigPath);
8504
8505 if (!pProfile) {
8506 sReport += icMsgValidateWarning;
8507 sReport += sSigPathName;
8508 sReport += " - Tag validation incomplete: Pointer to profile unavailable.\n";
8510 return rv;
8511 }
8512
8513 if (sigPath==icGetSigPath(icSigColorantTableTag)) {
8514 if (m_nCount != icGetSpaceSamples(pProfile->m_Header.colorSpace)) {
8515 sReport += icMsgValidateNonCompliant;
8516 sReport += sSigPathName;
8517 sReport += " - Incorrect number of colorants.\n";
8519 }
8520 }
8521 else if (sigPath==icGetSigPath(icSigColorantTableOutTag)) {
8522 if (m_nCount != icGetSpaceSamples(pProfile->m_Header.pcs)) {
8523 sReport += icMsgValidateNonCompliant;
8524 sReport += sSigPathName;
8525 sReport += " - Incorrect number of colorants.\n";
8527 }
8528 }
8529 else {
8530 sReport += icMsgValidateWarning;
8531 sReport += sSigPathName;
8532 sReport += " - Unknown number of required colorants.\n";
8534 }
8535
8536 return rv;
8537}
8538
8539
8540
8541/**
8542 ****************************************************************************
8543 * Name: CIccTagColorantTable::CIccTagColorantTable
8544 *
8545 * Purpose: Constructor
8546 *
8547 * Args:
8548 * nSize = number of entries
8549 *
8550 *****************************************************************************
8551 */
8553{
8554 m_nCount = nSize;
8555 if (m_nCount<1)
8556 m_nCount = 1;
8557
8558 m_pData = (icColorantTableEntry*)calloc(nSize, sizeof(icColorantTableEntry));
8559}
8560
8561
8562/**
8563 ****************************************************************************
8564 * Name: CIccTagColorantTable::CIccTagColorantTable
8565 *
8566 * Purpose: Copy Constructor
8567 *
8568 * Args:
8569 * ITCT = The CIccTagUnknown object to be copied
8570 *****************************************************************************
8571 */
8573{
8574 m_PCS = ITCT.m_PCS;
8575 m_nCount = ITCT.m_nCount;
8576
8577 m_pData = (icColorantTableEntry*)calloc(m_nCount, sizeof(icColorantTableEntry));
8578 memcpy(m_pData, ITCT.m_pData, m_nCount*sizeof(icColorantTableEntry));
8579}
8580
8581
8582/**
8583 ****************************************************************************
8584 * Name: CIccTagColorantTable::operator=
8585 *
8586 * Purpose: Copy Operator
8587 *
8588 * Args:
8589 * ColorantTableTag = The CIccTagColorantTable object to be copied
8590 *****************************************************************************
8591 */
8593{
8594 if (&ColorantTableTag == this)
8595 return *this;
8596
8597 m_PCS = ColorantTableTag.m_PCS;
8598 m_nCount = ColorantTableTag.m_nCount;
8599
8600 if (m_pData)
8601 free(m_pData);
8602 m_pData = (icColorantTableEntry*)calloc(m_nCount, sizeof(icColorantTableEntry));
8603 memcpy(m_pData, ColorantTableTag.m_pData, m_nCount*sizeof(icColorantTableEntry));
8604
8605 return *this;
8606}
8607
8608
8609/**
8610 ****************************************************************************
8611 * Name: CIccTagColorantTable::~CIccTagColorantTable
8612 *
8613 * Purpose: Destructor
8614 *
8615 *****************************************************************************
8616 */
8618{
8619 if (m_pData)
8620 free(m_pData);
8621}
8622
8623
8624/**
8625 ****************************************************************************
8626 * Name: CIccTagColorantTable::Read
8627 *
8628 * Purpose: Read in the tag contents into a data block
8629 *
8630 * Args:
8631 * size - # of bytes in tag,
8632 * pIO - IO object to read tag from
8633 *
8634 * Return:
8635 * true = successful, false = failure
8636 *****************************************************************************
8637 */
8639{
8641 icUInt32Number nCount;
8642
8643 if (sizeof(icTagTypeSignature) +
8644 sizeof(icUInt32Number) +
8645 sizeof(icUInt32Number) +
8646 sizeof(icColorantTableEntry) > size)
8647 return false;
8648
8649 if (!pIO) {
8650 return false;
8651 }
8652
8653 if (!pIO->Read32(&sig))
8654 return false;
8655
8656 if (!pIO->Read32(&m_nReserved))
8657 return false;
8658
8659 if (!pIO->Read32(&nCount))
8660 return false;
8661
8662 icUInt32Number nNum = (size - 3*sizeof(icUInt32Number))/sizeof(icColorantTableEntry);
8663 icUInt32Number nNum8 = sizeof(m_pData->name);
8664 icUInt32Number nNum16 = sizeof(m_pData->data)/sizeof(icUInt16Number);
8665
8666 if (nNum < nCount || nCount > 0xffff)
8667 return false;
8668
8669 if (!SetSize((icUInt16Number)nCount))
8670 return false;
8671
8672 for (icUInt32Number i=0; i<nCount; i++) {
8673 if (pIO->Read8(&m_pData[i].name[0], nNum8) != (icInt32Number)nNum8)
8674 return false;
8675
8676 if (pIO->Read16(&m_pData[i].data[0], nNum16) != (icInt32Number)nNum16)
8677 return false;
8678 }
8679
8680 return true;
8681}
8682
8683
8684/**
8685 ****************************************************************************
8686 * Name: CIccTagColorantTable::Write
8687 *
8688 * Purpose: Write the tag to a file
8689 *
8690 * Args:
8691 * pIO - The IO object to write tag to.
8692 *
8693 * Return:
8694 * true = succesful, false = failure
8695 *****************************************************************************
8696 */
8698{
8699 icTagTypeSignature sig = GetType();
8700
8701 if (!pIO)
8702 return false;
8703
8704 if (!pIO->Write32(&sig))
8705 return false;
8706
8707 if (!pIO->Write32(&m_nReserved))
8708 return false;
8709
8710 if (!pIO->Write32(&m_nCount))
8711 return false;
8712
8713 icUInt32Number nNum8 = sizeof(m_pData->name);
8714 icUInt32Number nNum16 = sizeof(m_pData->data)/sizeof(icUInt16Number);
8715
8716 for (icUInt32Number i=0; i<m_nCount; i++) {
8717 if (pIO->Write8(&m_pData[i].name[0],nNum8) != (icInt32Number)nNum8)
8718 return false;
8719
8720 if (pIO->Write16(&m_pData[i].data[0],nNum16) != (icInt32Number)nNum16)
8721 return false;
8722 }
8723
8724 return true;
8725}
8726
8727
8728/**
8729 ****************************************************************************
8730 * Name: CIccTagColorantTable::Describe
8731 *
8732 * Purpose: Dump data associated with the tag to a string
8733 *
8734 * Args:
8735 * sDescription - string to concatenate tag dump to
8736 *****************************************************************************
8737 */
8738void CIccTagColorantTable::Describe(std::string &sDescription, int nVerboseness)
8739{
8740 icChar buf[128];
8741
8742 icUInt32Number i, nLen, nMaxLen=0;
8743 icFloatNumber Lab[3] = {0};
8744
8745 sprintf(buf, "BEGIN_COLORANTS %u\n", m_nCount);
8746 sDescription += buf;
8747
8748 for (i=0; i<m_nCount; i++) {
8749 nLen = (icUInt32Number)strlen(m_pData[i].name);
8750 if (nLen>nMaxLen)
8751 nMaxLen =nLen;
8752 }
8753 sDescription += "# NAME ";
8754
8755 if (m_PCS == icSigXYZData) {
8756 sprintf(buf, "XYZ_X XYZ_Y XYZ_Z\n");
8757 sDescription += buf;
8758 }
8759 else {
8760 sprintf(buf, "Lab_L Lab_a Lab_b\n");
8761 sDescription += buf;
8762 }
8763 for (i=0; i<m_nCount; i++) {
8764 sprintf(buf, "%2u \"%s\"", i, m_pData[i].name);
8765 sDescription += buf;
8766 memset(buf, ' ', 128);
8767 buf[nMaxLen + 1 - strlen(m_pData[i].name)] ='\0';
8768 sDescription += buf;
8769
8770 if (m_PCS == icSigXYZData) {
8771 sprintf(buf, "%7.4lf %7.4lf %7.4lf\n", icUSFtoD(m_pData[i].data[0]), icUSFtoD(m_pData[i].data[1]), icUSFtoD(m_pData[i].data[2]));
8772 sDescription += buf;
8773 }
8774 else {
8775 Lab[0] = icU16toF(m_pData[i].data[0]);
8776 Lab[1] = icU16toF(m_pData[i].data[1]);
8777 Lab[2] = icU16toF(m_pData[i].data[2]);
8778 icLabFromPcs(Lab);
8779 sprintf(buf, "%7.4lf %8.4lf %8.4lf\n", Lab[0], Lab[1], Lab[2]);
8780 sDescription += buf;
8781 }
8782 }
8783
8784}
8785
8786/**
8787 ****************************************************************************
8788 * Name: CIccTagColorantTable::SetSize
8789 *
8790 * Purpose: Sets the size of the data array.
8791 *
8792 * Args:
8793 * nSize - number of entries,
8794 * bZeroNew - flag to zero newly formed values
8795 *****************************************************************************
8796 */
8797bool CIccTagColorantTable::SetSize(icUInt16Number nSize, bool bZeroNew/*=true*/)
8798{
8799 if (m_nCount == nSize)
8800 return true;
8801
8802 m_pData = (icColorantTableEntry*)icRealloc(m_pData, nSize*sizeof(icColorantTableEntry));
8803
8804 if (!m_pData) {
8805 m_nCount = 0;
8806 return false;
8807 }
8808
8809 if (bZeroNew && nSize > m_nCount) {
8810 memset(&m_pData[m_nCount], 0, (nSize-m_nCount)*sizeof(icColorantTableEntry));
8811 }
8812 m_nCount = nSize;
8813
8814 return true;
8815}
8816
8817
8818/**
8819******************************************************************************
8820* Name: CIccTagColorantTable::Validate
8821*
8822* Purpose: Check tag data validity.
8823*
8824* Args:
8825* sig = signature of tag being validated,
8826* sReport = String to add report information to
8827*
8828* Return:
8829* icValidateStatusOK if valid, or other error status.
8830******************************************************************************
8831*/
8832icValidateStatus CIccTagColorantTable::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
8833{
8834 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
8835
8836 CIccInfo Info;
8837 std::string sSigPathName = Info.GetSigPathName(sigPath);
8839
8840 if (!pProfile) {
8841 sReport += icMsgValidateWarning;
8842 sReport += sSigPathName;
8843 sReport += " - Tag validation incomplete: Pointer to profile unavailable.\n";
8845 return rv;
8846 }
8847
8848
8850 if (pProfile->m_Header.deviceClass!=icSigLinkClass) {
8851 sReport += icMsgValidateNonCompliant;
8852 sReport += sSigPathName;
8853 sReport += " - Use of this tag is allowed only in DeviceLink Profiles.\n";
8855 }
8856 if (m_nCount != icGetSpaceSamples(pProfile->m_Header.pcs)) {
8857 sReport += icMsgValidateNonCompliant;
8858 sReport += sSigPathName;
8859 sReport += " - Incorrect number of colorants.\n";
8861 }
8862 }
8863 else {
8864 if (m_nCount != icGetSpaceSamples(pProfile->m_Header.colorSpace)) {
8865 sReport += icMsgValidateNonCompliant;
8866 sReport += sSigPathName;
8867 sReport += " - Incorrect number of colorants.\n";
8869 }
8870 }
8871
8872 return rv;
8873}
8874
8875
8876/**
8877 ****************************************************************************
8878 * Name: CIccTagViewingConditions::CIccTagViewingConditions
8879 *
8880 * Purpose: Constructor
8881 *
8882 *****************************************************************************
8883 */
8885{
8886 m_XYZIllum.X = 0;
8887 m_XYZIllum.Y = 0;
8888 m_XYZIllum.Z = 0;
8889
8890 m_XYZSurround.X = 0;
8891 m_XYZSurround.Y = 0;
8892 m_XYZSurround.Z = 0;
8893
8894 m_illumType = icIlluminantUnknown;
8895}
8896
8897
8898/**
8899 ****************************************************************************
8900 * Name: CIccTagViewingConditions::CIccTagViewingConditions
8901 *
8902 * Purpose: Copy Constructor
8903 *
8904 * Args:
8905 * ITVC = The CIccTagViewingConditions object to be copied
8906 *****************************************************************************
8907 */
8909{
8910 m_illumType = ITVC.m_illumType;
8911
8912 memcpy(&m_XYZIllum, &ITVC.m_XYZIllum, sizeof(icXYZNumber));
8913 memcpy(&m_XYZSurround, &ITVC.m_XYZSurround, sizeof(icXYZNumber));
8914}
8915
8916
8917/**
8918 ****************************************************************************
8919 * Name: CIccTagViewingConditions::operator=
8920 *
8921 * Purpose: Copy Operator
8922 *
8923 * Args:
8924 * ViewCondTag = The CIccTagViewingConditions object to be copied
8925 *****************************************************************************
8926 */
8928{
8929 if (&ViewCondTag == this)
8930 return *this;
8931
8932 m_illumType = ViewCondTag.m_illumType;
8933
8934 memcpy(&m_XYZIllum, &ViewCondTag.m_XYZIllum, sizeof(icXYZNumber));
8935 memcpy(&m_XYZSurround, &ViewCondTag.m_XYZSurround, sizeof(icXYZNumber));
8936
8937 return *this;
8938}
8939
8940
8941/**
8942 ****************************************************************************
8943 * Name: CIccTagViewingConditions::~CIccTagViewingConditions
8944 *
8945 * Purpose: Destructor
8946 *
8947 *****************************************************************************
8948 */
8952
8953
8954/**
8955 ****************************************************************************
8956 * Name: CIccTagViewingConditions::Read
8957 *
8958 * Purpose: Read in the tag contents into a data block
8959 *
8960 * Args:
8961 * size - # of bytes in tag,
8962 * pIO - IO object to read tag from
8963 *
8964 * Return:
8965 * true = successful, false = failure
8966 *****************************************************************************
8967 */
8969{
8971
8972 if (sizeof(icTagTypeSignature) +
8973 2*sizeof(icUInt32Number) +
8974 2*sizeof(icXYZNumber) > size)
8975 return false;
8976
8977 if (!pIO) {
8978 return false;
8979 }
8980
8981 if (!pIO->Read32(&sig))
8982 return false;
8983
8984 if (!pIO->Read32(&m_nReserved))
8985 return false;
8986
8987 if (pIO->Read32(&m_XYZIllum.X, 3) != 3)
8988 return false;
8989
8990 if (pIO->Read32(&m_XYZSurround.X, 3) != 3)
8991 return false;
8992
8993 if (!pIO->Read32(&m_illumType))
8994 return false;
8995
8996 return true;
8997}
8998
8999
9000/**
9001 ****************************************************************************
9002 * Name: CIccTagViewingConditions::Write
9003 *
9004 * Purpose: Write the tag to a file
9005 *
9006 * Args:
9007 * pIO - The IO object to write tag to.
9008 *
9009 * Return:
9010 * true = succesful, false = failure
9011 *****************************************************************************
9012 */
9014{
9015 icTagTypeSignature sig = GetType();
9016
9017 if (!pIO)
9018 return false;
9019
9020 if (!pIO->Write32(&sig))
9021 return false;
9022
9023 if (!pIO->Write32(&m_nReserved))
9024 return false;
9025
9026 if (pIO->Write32(&m_XYZIllum.X, 3) !=3)
9027 return false;
9028
9029 if (pIO->Write32(&m_XYZSurround.X, 3) !=3)
9030 return false;
9031
9032 if (!pIO->Write32(&m_illumType))
9033 return false;
9034
9035 return true;
9036}
9037
9038
9039/**
9040 ****************************************************************************
9041 * Name: CIccTagViewingConditions::Describe
9042 *
9043 * Purpose: Dump data associated with the tag to a string
9044 *
9045 * Args:
9046 * sDescription - string to concatenate tag dump to
9047 *****************************************************************************
9048 */
9049void CIccTagViewingConditions::Describe(std::string &sDescription, int nVerboseness)
9050{
9051 icChar buf[128];
9052 CIccInfo Fmt;
9053
9054 sprintf(buf, "Illuminant Tristimulus values: X = %.4lf, Y = %.4lf, Z = %.4lf\n",
9055 icFtoD(m_XYZIllum.X),
9056 icFtoD(m_XYZIllum.Y),
9057 icFtoD(m_XYZIllum.Z));
9058 sDescription += buf;
9059
9060 sprintf(buf, "Surround Tristimulus values: X = %.4lf, Y = %.4lf, Z = %.4lf\n",
9061 icFtoD(m_XYZSurround.X),
9062 icFtoD(m_XYZSurround.Y),
9063 icFtoD(m_XYZSurround.Z));
9064 sDescription += buf;
9065
9066 sDescription += "Illuminant Type: ";
9067
9068 sDescription += Fmt.GetIlluminantName(m_illumType);
9069 sDescription += "\n";
9070
9071}
9072
9073
9074/**
9075******************************************************************************
9076* Name: CIccTagViewingConditions::Validate
9077*
9078* Purpose: Check tag data validity.
9079*
9080* Args:
9081* sig = signature of tag being validated,
9082* sReport = String to add report information to
9083*
9084* Return:
9085* icValidateStatusOK if valid, or other error status.
9086******************************************************************************
9087*/
9088icValidateStatus CIccTagViewingConditions::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
9089{
9090 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
9091
9092 CIccInfo Info;
9093 std::string sSigPathName = Info.GetSigPathName(sigPath);
9094
9095 rv = icMaxStatus(rv, Info.CheckData(sReport, m_XYZIllum, "XYZ Illuminant"));
9096 rv = icMaxStatus(rv, Info.CheckData(sReport, m_XYZSurround, "XYZ Surround"));
9097
9098 return rv;
9099}
9100
9101
9102/**
9103 ****************************************************************************
9104 * Name: CIccProfileDescText::CIccProfileDescText
9105 *
9106 * Purpose: Constructor
9107 *
9108 *****************************************************************************
9109 */
9111{
9112 m_pTag = NULL;
9113 m_bNeedsPading = false;
9114}
9115
9116
9117/**
9118 ****************************************************************************
9119 * Name: CIccProfileDescText::CIccProfileDescText
9120 *
9121 * Purpose: Copy Constructor
9122 *
9123 * Args:
9124 * IPDC = The CIccTagUnknown object to be copied
9125 *****************************************************************************
9126 */
9128{
9129 if (IPDC.m_pTag) {
9130 m_pTag = IPDC.m_pTag->NewCopy();
9131 m_bNeedsPading = IPDC.m_bNeedsPading;
9132 }
9133 else {
9134 m_pTag = NULL;
9135 m_bNeedsPading = false;
9136 }
9137}
9138
9139
9140/**
9141 ****************************************************************************
9142 * Name: CIccProfileDescText::operator=
9143 *
9144 * Purpose: Copy Operator
9145 *
9146 * Args:
9147 * ProfDescText = The CIccProfileDescText object to be copied
9148 *****************************************************************************
9149 */
9151{
9152 if (&ProfDescText == this)
9153 return *this;
9154
9155 if (m_pTag)
9156 delete m_pTag;
9157
9158 if (ProfDescText.m_pTag) {
9159 m_pTag = ProfDescText.m_pTag->NewCopy();
9160 m_bNeedsPading = ProfDescText.m_bNeedsPading;
9161 }
9162 else {
9163 m_pTag = NULL;
9164 m_bNeedsPading = false;
9165 }
9166
9167 return *this;
9168}
9169
9170
9171/**
9172 ****************************************************************************
9173 * Name: CIccProfileDescText::~CIccProfileDescText
9174 *
9175 * Purpose: Destructor
9176 *
9177 *****************************************************************************
9178 */
9180{
9181 if (m_pTag)
9182 delete m_pTag;
9183}
9184
9185
9186/**
9187 ****************************************************************************
9188 * Name: CIccProfileDescText::SetType
9189 *
9190 * Purpose: Sets the type of the profile description text. Could be either
9191 * a MultiLocalizedUnicodeType or a TextDescriptionType.
9192 *
9193 * Args:
9194 * nType = the tag type signature
9195 *
9196 * Return:
9197 * true = successful, false = failure
9198 *****************************************************************************
9199 */
9201{
9202 if (m_pTag) {
9203 if (m_pTag->GetType() == nType)
9204 return true;
9205
9206 delete m_pTag;
9207 }
9208
9209 if (nType == icSigMultiLocalizedUnicodeType ||
9210 nType == icSigTextDescriptionType)
9211 m_pTag = CIccTag::Create(nType);
9212 else
9213 m_pTag = NULL;
9214
9215 return(m_pTag != NULL);
9216}
9217
9218
9219/**
9220 ****************************************************************************
9221 * Name: CIccProfileDescText::SetType
9222 *
9223 * Purpose: Gets the type of the profile description text. Could be either
9224 * a MultiLocalizedUnicodeType or a TextDescriptionType.
9225 *
9226 *****************************************************************************
9227 */
9229{
9230 if (m_pTag)
9231 return m_pTag->GetType();
9232
9233 return icSigUnknownType;
9234}
9235
9236
9237/**
9238 ****************************************************************************
9239 * Name: CIccProfileDescText::Describe
9240 *
9241 * Purpose: Dump data associated with the tag to a string
9242 *
9243 * Args:
9244 * sDescription - string to concatenate tag dump to
9245 *****************************************************************************
9246 */
9247void CIccProfileDescText::Describe(std::string &sDescription, int nVerboseness)
9248{
9249 if (m_pTag)
9250 m_pTag->Describe(sDescription, nVerboseness);
9251}
9252
9253
9254/**
9255 ****************************************************************************
9256 * Name: CIccProfileDescText::Read
9257 *
9258 * Purpose: Read in the tag contents into a data block
9259 *
9260 * Args:
9261 * size - # of bytes in tag,
9262 * pIO - IO object to read tag from
9263 *
9264 * Return:
9265 * true = successful, false = failure
9266 *****************************************************************************
9267 */
9269{
9271 icUInt32Number nPos;
9272
9273 //Check for description tag type signature
9274 nPos = pIO->Tell();
9275
9276 if ((nPos&0x03) != 0)
9277 m_bNeedsPading = true;
9278
9279 if (!pIO->Read32(&sig))
9280 return false;
9281 pIO->Seek(nPos, icSeekSet);
9282
9284 m_bNeedsPading = false;
9285
9286 if (!SetType(sig)) {
9287 //We couldn't find it, but we may be looking in the wrong place
9288 //Re-Sync to a 4 byte boundary
9289 pIO->Sync32();
9290
9291 nPos = pIO->Tell();
9292 if (!pIO->Read32(&sig))
9293 return false;
9294 pIO->Seek(nPos, icSeekSet);
9295
9296 if (!SetType(sig)) {
9297 return false;
9298 }
9299 }
9300
9301 if (m_pTag) {
9302 return m_pTag->Read(size, pIO);
9303 }
9304
9305 return false;
9306}
9307
9308
9309/**
9310 ****************************************************************************
9311 * Name: CIccProfileDescText::Write
9312 *
9313 * Purpose: Write the tag to a file
9314 *
9315 * Args:
9316 * pIO - The IO object to write tag to.
9317 *
9318 * Return:
9319 * true = succesful, false = failure
9320 *****************************************************************************
9321 */
9323{
9324 if (!m_pTag)
9325 return false;
9326
9327 if (m_pTag->Write(pIO)) {
9328 if (m_pTag->GetType() != icSigTextDescriptionType)
9329 return pIO->Align32();
9330 else
9331 return true;
9332 }
9333
9334 return false;
9335}
9336
9337
9338
9339/**
9340 ****************************************************************************
9341 * Name: CIccProfileDescStruct::CIccProfileDescStruct
9342 *
9343 * Purpose: Constructor
9344 *
9345 *****************************************************************************
9346 */
9350
9351
9352/**
9353 ****************************************************************************
9354 * Name: CIccProfileDescStruct::CIccProfileDescStruct
9355 *
9356 * Purpose: Copy Constructor
9357 *
9358 * Args:
9359 * IPDS = The CIccProfileDescStruct object to be copied
9360 *****************************************************************************
9361 */
9363{
9364 m_deviceMfg = IPDS.m_deviceMfg;
9365 m_deviceModel = IPDS.m_deviceModel;
9366 m_attributes = IPDS.m_attributes;
9367 m_technology = IPDS.m_technology;
9368 m_deviceMfgDesc = IPDS.m_deviceMfgDesc;
9369 m_deviceModelDesc = IPDS.m_deviceModelDesc;
9370}
9371
9372
9373
9374/**
9375 ****************************************************************************
9376 * Name: CIccProfileDescStruct::operator=
9377 *
9378 * Purpose: Copy Operator
9379 *
9380 * Args:
9381 * ProfDescStruct = The CIccProfileDescStruct object to be copied
9382 *****************************************************************************
9383 */
9385{
9386 if (&ProfDescStruct == this)
9387 return *this;
9388
9389 m_deviceMfg = ProfDescStruct.m_deviceMfg;
9390 m_deviceModel = ProfDescStruct.m_deviceModel;
9391 m_attributes = ProfDescStruct.m_attributes;
9392 m_technology = ProfDescStruct.m_technology;
9393 m_deviceMfgDesc = ProfDescStruct.m_deviceMfgDesc;
9394 m_deviceModelDesc = ProfDescStruct.m_deviceModelDesc;
9395
9396 return *this;
9397}
9398
9399
9400
9401/**
9402 ****************************************************************************
9403 * Name: CIccTagProfileSeqDesc::CIccTagProfileSeqDesc
9404 *
9405 * Purpose: Constructor
9406 *
9407 *****************************************************************************
9408 */
9413
9414
9415/**
9416 ****************************************************************************
9417 * Name: CIccTagProfileSeqDesc::CIccTagProfileSeqDesc
9418 *
9419 * Purpose: Copy Constructor
9420 *
9421 * Args:
9422 * ITPSD = The CIccTagProfileSeqDesc object to be copied
9423 *****************************************************************************
9424 */
9426{
9427 m_Descriptions = new(CIccProfileSeqDesc);
9428 *m_Descriptions = *ITPSD.m_Descriptions;
9429}
9430
9431
9432/**
9433 ****************************************************************************
9434 * Name: CIccTagProfileSeqDesc::operator=
9435 *
9436 * Purpose: Copy Operator
9437 *
9438 * Args:
9439 * ProfSeqDescTag = The CIccTagProfileSeqDesc object to be copied
9440 *****************************************************************************
9441 */
9443{
9444 if (&ProfSeqDescTag == this)
9445 return *this;
9446
9447 *m_Descriptions = *ProfSeqDescTag.m_Descriptions;
9448
9449 return *this;
9450}
9451
9452
9453/**
9454 ****************************************************************************
9455 * Name: CIccTagProfileSeqDesc::~CIccTagProfileSeqDesc
9456 *
9457 * Purpose: Destructor
9458 *
9459 *****************************************************************************
9460 */
9462{
9463 delete m_Descriptions;
9464}
9465
9466
9467/**
9468 ****************************************************************************
9469 * Name: CIccTagProfileSeqDesc::Read
9470 *
9471 * Purpose: Read in the tag contents into a data block
9472 *
9473 * Args:
9474 * size - # of bytes in tag,
9475 * pIO - IO object to read tag from
9476 *
9477 * Return:
9478 * true = successful, false = failure
9479 *****************************************************************************
9480 */
9482{
9484 icUInt32Number nCount, nEnd;
9485
9486 nEnd = pIO->Tell() + size;
9487
9488 if (sizeof(icTagTypeSignature) +
9489 sizeof(icUInt32Number)*2 > size)
9490 return false;
9491
9492 if (!pIO) {
9493 return false;
9494 }
9495
9496 if (!pIO->Read32(&sig) ||
9497 !pIO->Read32(&m_nReserved) ||
9498 !pIO->Read32(&nCount))
9499 return false;
9500
9501 if (!nCount)
9502 return true;
9503
9504 if (sizeof(icTagTypeSignature) +
9505 sizeof(icUInt32Number)*2 +
9506 sizeof(CIccProfileDescStruct) > size)
9507 return false;
9508
9509 icUInt32Number i, nPos;
9510 CIccProfileDescStruct ProfileDescStruct;
9511
9512 for (i=0; i<nCount; i++) {
9513
9514 if (!pIO->Read32(&ProfileDescStruct.m_deviceMfg) ||
9515 !pIO->Read32(&ProfileDescStruct.m_deviceModel) ||
9516 !pIO->Read64(&ProfileDescStruct.m_attributes) ||
9517 !pIO->Read32(&ProfileDescStruct.m_technology))
9518 return false;
9519
9520 nPos = pIO->Tell();
9521
9522 if (!ProfileDescStruct.m_deviceMfgDesc.Read(nEnd - nPos, pIO))
9523 return false;
9524
9525 nPos = pIO->Tell();
9526 if (!ProfileDescStruct.m_deviceModelDesc.Read(nEnd - nPos, pIO))
9527 return false;
9528
9529 m_Descriptions->push_back(ProfileDescStruct);
9530 }
9531
9532 return true;
9533}
9534
9535
9536/**
9537 ****************************************************************************
9538 * Name: CIccTagProfileSeqDesc::Write
9539 *
9540 * Purpose: Write the tag to a file
9541 *
9542 * Args:
9543 * pIO - The IO object to write tag to.
9544 *
9545 * Return:
9546 * true = succesful, false = failure
9547 *****************************************************************************
9548 */
9550{
9551 icTagTypeSignature sig = GetType();
9552 icUInt32Number nCount=(icUInt32Number)m_Descriptions->size();
9553
9554 if (!pIO) {
9555 return false;
9556 }
9557
9558 if (!pIO->Write32(&sig) ||
9559 !pIO->Write32(&m_nReserved) ||
9560 !pIO->Write32(&nCount))
9561 return false;
9562
9563 CIccProfileSeqDesc::iterator i;
9564
9565 for (i=m_Descriptions->begin(); i!=m_Descriptions->end(); i++) {
9566
9567 if (!pIO->Write32(&i->m_deviceMfg) ||
9568 !pIO->Write32(&i->m_deviceModel) ||
9569 !pIO->Write64(&i->m_attributes) ||
9570 !pIO->Write32(&i->m_technology))
9571 return false;
9572
9573 if (!i->m_deviceMfgDesc.Write(pIO) ||
9574 !i->m_deviceModelDesc.Write(pIO))
9575 return false;
9576 }
9577
9578 return true;
9579}
9580
9581
9582/**
9583 ****************************************************************************
9584 * Name: CIccTagProfileSeqDesc::Describe
9585 *
9586 * Purpose: Dump data associated with the tag to a string
9587 *
9588 * Args:
9589 * sDescription - string to concatenate tag dump to
9590 *****************************************************************************
9591 */
9592void CIccTagProfileSeqDesc::Describe(std::string &sDescription, int nVerboseness)
9593{
9594 CIccProfileSeqDesc::iterator i;
9595 icChar buf[128], buf2[28];
9596 icUInt32Number count=0;
9597
9598 sprintf(buf, "Number of Profile Description Structures: %u\n", (icUInt32Number)m_Descriptions->size());
9599 sDescription += buf;
9600
9601 for (i=m_Descriptions->begin(); i!=m_Descriptions->end(); i++, count++) {
9602 sDescription += "\n";
9603
9604 sprintf(buf, "Profile Description Structure Number [%u] follows:\n", count+1);
9605 sDescription += buf;
9606
9607 sprintf(buf, "Device Manufacturer Signature: %s\n", icGetSig(buf2, i->m_deviceMfg, false));
9608 sDescription += buf;
9609
9610 sprintf(buf, "Device Model Signature: %s\n", icGetSig(buf2, i->m_deviceModel, false));
9611 sDescription += buf;
9612
9613 sprintf(buf, "Device Attributes: %08x%08x\n", (icUInt32Number)(i->m_attributes >> 32), (icUInt32Number)(i->m_attributes));
9614 sDescription += buf;
9615
9616 sprintf(buf, "Device Technology Signature: %s\n", icGetSig(buf2, i->m_technology, false));
9617 sDescription += buf;
9618
9619 sprintf(buf, "Description of device manufacturer: \n");
9620 sDescription += buf;
9621 i->m_deviceMfgDesc.Describe(sDescription, nVerboseness);
9622
9623 sprintf(buf, "Description of device model: \n");
9624 sDescription += buf;
9625 i->m_deviceModelDesc.Describe(sDescription, nVerboseness);
9626 }
9627}
9628
9629
9630/**
9631******************************************************************************
9632* Name: CIccTagProfileSeqDesc::Validate
9633*
9634* Purpose: Check tag data validity.
9635*
9636* Args:
9637* sig = signature of tag being validated,
9638* sReport = String to add report information to
9639*
9640* Return:
9641* icValidateStatusOK if valid, or other error status.
9642******************************************************************************
9643*/
9644icValidateStatus CIccTagProfileSeqDesc::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
9645{
9646 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
9647
9648 CIccInfo Info;
9649 char buf[128];
9650 std::string sSigPathName = Info.GetSigPathName(sigPath);
9651
9652 CIccProfileSeqDesc::iterator i;
9653 for (i=m_Descriptions->begin(); i!=m_Descriptions->end(); i++) {
9654 switch(i->m_technology) {
9655 case 0x00000000: //Technology not defined
9656 case icSigFilmScanner:
9657 case icSigDigitalCamera:
9659 case icSigInkJetPrinter:
9665 case icSigFilmWriter:
9666 case icSigVideoMonitor:
9667 case icSigVideoCamera:
9669 case icSigCRTDisplay:
9670 case icSigPMDisplay:
9671 case icSigAMDisplay:
9672 case icSigPhotoCD:
9674 case icSigGravure:
9676 case icSigSilkscreen:
9677 case icSigFlexography:
9678 break;
9679
9680 default:
9681 {
9682 sReport += icMsgValidateNonCompliant;
9683 sReport += sSigPathName;
9684 sprintf(buf, " - %s: Unknown Technology.\n", Info.GetSigName(i->m_technology));
9685 sReport += buf;
9687 }
9688 }
9689
9690 if (i->m_deviceMfgDesc.m_bNeedsPading) {
9691 sReport += icMsgValidateNonCompliant;
9692 sReport += sSigPathName;
9693
9694 sReport += " Contains non-aligned deviceMfgDesc text tag information\n";
9695
9697 }
9698
9699 if (i->m_deviceModelDesc.m_bNeedsPading) {
9700 sReport += icMsgValidateNonCompliant;
9701 sReport += sSigPathName;
9702
9703 sReport += " Contains non-aligned deviceModelDesc text tag information\n";
9704
9706 }
9707
9708 rv = icMaxStatus(rv, i->m_deviceMfgDesc.GetTag()->Validate(sigPath+icGetSigPath(GetType()), sReport, pProfile));
9709 rv = icMaxStatus(rv, i->m_deviceModelDesc.GetTag()->Validate(sigPath+icGetSigPath(GetType()), sReport, pProfile));
9710 }
9711
9712 return rv;
9713}
9714
9715
9716/**
9717 ****************************************************************************
9718 * Name: CIccResponseCurveStruct::CIccResponseCurveStruct
9719 *
9720 * Purpose: Constructor
9721 *
9722 * Args:
9723 * nChannels = number of channels
9724 *
9725 *****************************************************************************
9726 */
9728{
9729 m_nChannels = nChannels;
9730 m_maxColorantXYZ = (icXYZNumber*)calloc(nChannels, sizeof(icXYZNumber));
9731 m_Response16ListArray = new CIccResponse16List[nChannels];
9732}
9733
9734
9735/**
9736 ****************************************************************************
9737 * Name: CIccResponseCurveStruct::CIccResponseCurveStruct
9738 *
9739 * Purpose: Constructor
9740 *
9741 * Args:
9742 * sig = measurement unit signature indicating the type of measurement data,
9743 * nChannels = number of channels
9744 *****************************************************************************
9745 */
9747{
9748 m_nChannels = nChannels;
9749 m_measurementUnitSig = sig;
9750 m_maxColorantXYZ = (icXYZNumber*)calloc(nChannels, sizeof(icXYZNumber));
9751 m_Response16ListArray = new CIccResponse16List[nChannels];
9752}
9753
9754/**
9755 ****************************************************************************
9756 * Name: CIccResponseCurveStruct::CIccResponseCurveStruct
9757 *
9758 * Purpose: Copy Constructor
9759 *
9760 * Args:
9761 * IRCS = The CIccTagUnknown object to be copied
9762 *****************************************************************************
9763 */
9765{
9766 m_nChannels = IRCS.m_nChannels;
9767 m_measurementUnitSig = IRCS.m_measurementUnitSig;
9768
9769 m_maxColorantXYZ = (icXYZNumber*)calloc(m_nChannels, sizeof(icXYZNumber));
9770 memcpy(m_maxColorantXYZ, IRCS.m_maxColorantXYZ, m_nChannels*sizeof(icXYZNumber));
9771
9772 m_Response16ListArray = new CIccResponse16List[m_nChannels];
9773 for (icUInt32Number i=0; i<m_nChannels; i++)
9774 m_Response16ListArray[i] = IRCS.m_Response16ListArray[i];
9775}
9776
9777
9778/**
9779 ****************************************************************************
9780 * Name: CIccResponseCurveStruct::operator=
9781 *
9782 * Purpose: Copy Operator
9783 *
9784 * Args:
9785 * RespCurveStruct = The CIccResponseCurveStruct object to be copied
9786 *****************************************************************************
9787 */
9789{
9790 if (&RespCurveStruct == this)
9791 return *this;
9792
9793 m_nChannels = RespCurveStruct.m_nChannels;
9794 m_measurementUnitSig = RespCurveStruct.m_measurementUnitSig;
9795
9796 if (m_maxColorantXYZ)
9797 free(m_maxColorantXYZ);
9798
9799 m_maxColorantXYZ = (icXYZNumber*)calloc(m_nChannels, sizeof(icXYZNumber));
9800 memcpy(m_maxColorantXYZ, RespCurveStruct.m_maxColorantXYZ, m_nChannels*sizeof(icXYZNumber));
9801
9802 if (m_Response16ListArray)
9803 delete [] m_Response16ListArray;
9804 m_Response16ListArray = new CIccResponse16List[m_nChannels];
9805 for (icUInt32Number i=0; i<m_nChannels; i++)
9806 m_Response16ListArray[i] = RespCurveStruct.m_Response16ListArray[i];
9807
9808 return *this;
9809}
9810
9811
9812/**
9813 ****************************************************************************
9814 * Name: CIccResponseCurveStruct::~CIccResponseCurveStruct
9815 *
9816 * Purpose: Destructor
9817 *
9818 *****************************************************************************
9819 */
9821{
9822 if (m_maxColorantXYZ)
9823 free(m_maxColorantXYZ);
9824
9825 if (m_Response16ListArray)
9826 delete [] m_Response16ListArray;
9827}
9828
9829
9830/**
9831 ****************************************************************************
9832 * Name: CIccResponseCurveStruct::Read
9833 *
9834 * Purpose: Read in the tag contents into a data block
9835 *
9836 * Args:
9837 * size - # of bytes in tag,
9838 * pIO - IO object to read tag from
9839 *
9840 * Return:
9841 * true = successful, false = failure
9842 *****************************************************************************
9843 */
9845{
9846 if (!m_nChannels)
9847 return false;
9848
9849 if (sizeof(icTagTypeSignature) +
9850 m_nChannels * (sizeof(icUInt32Number) +
9851 sizeof(icXYZNumber) +
9852 sizeof(icResponse16Number)) > size)
9853 return false;
9854
9855 if (!pIO) {
9856 return false;
9857 }
9858
9859 if (!pIO->Read32(&m_measurementUnitSig))
9860 return false;
9861
9862 icUInt32Number* nMeasurements = new icUInt32Number[m_nChannels];
9863
9864 if (pIO->Read32(&nMeasurements[0],m_nChannels) != m_nChannels) {
9865 delete[] nMeasurements;
9866 return false;
9867 }
9868
9869 icUInt32Number nNum32 = m_nChannels*sizeof(icXYZNumber)/sizeof(icS15Fixed16Number);
9870 if (pIO->Read32(&m_maxColorantXYZ[0], nNum32) != (icInt32Number)nNum32) {
9871 delete[] nMeasurements;
9872 return false;
9873 }
9874
9875 icResponse16Number nResponse16 = {};
9876 CIccResponse16List nResponseList;
9877
9878 for (int i = 0; i<m_nChannels; i++) {
9879 if (!nResponseList.empty())
9880 nResponseList.clear();
9881 for (int j=0; j<(int)nMeasurements[i]; j++) {
9882 if (!pIO->Read16(&nResponse16.deviceCode) ||
9883 !pIO->Read16(&nResponse16.reserved) ||
9884 !pIO->Read32(&nResponse16.measurementValue)) {
9885 delete[] nMeasurements;
9886 return false;
9887 }
9888 nResponseList.push_back(nResponse16);
9889 }
9890 m_Response16ListArray[i] = nResponseList;
9891 }
9892
9893 delete [] nMeasurements;
9894 return true;
9895}
9896
9897
9898/**
9899 ****************************************************************************
9900 * Name: CIccResponseCurveStruct::Write
9901 *
9902 * Purpose: Write the tag to a file
9903 *
9904 * Args:
9905 * pIO - The IO object to write tag to.
9906 *
9907 * Return:
9908 * true = succesful, false = failure
9909 *****************************************************************************
9910 */
9912{
9913 if (!m_nChannels)
9914 return false;
9915
9916 icMeasurementUnitSig sig = GetMeasurementType();
9917
9918 if (!pIO) {
9919 return false;
9920 }
9921
9922 if (!pIO->Write32(&sig))
9923 return false;
9924
9925 if (m_nChannels) {
9926
9927 icUInt32Number* nMeasurements = new icUInt32Number[m_nChannels];
9928 for (int i=0; i<m_nChannels; i++)
9929 nMeasurements[i] = (icUInt32Number)m_Response16ListArray[i].size();
9930
9931 if (pIO->Write32(&nMeasurements[0],m_nChannels) != m_nChannels)
9932 return false;
9933 delete [] nMeasurements;
9934
9935 icUInt32Number nNum32 = m_nChannels*sizeof(icXYZNumber)/sizeof(icS15Fixed16Number);
9936 if (pIO->Write32(&m_maxColorantXYZ[0], nNum32) != (icInt32Number)nNum32)
9937 return false;
9938 }
9939 else
9940 return false;
9941
9942 CIccResponse16List nResponseList;
9943 CIccResponse16List::iterator j;
9944
9945 for (int i = 0; i<m_nChannels; i++) {
9946 nResponseList = m_Response16ListArray[i];
9947 for (j=nResponseList.begin(); j!=nResponseList.end(); j++) {
9948 if (!pIO->Write16(&j->deviceCode) ||
9949 !pIO->Write16(&j->reserved) ||
9950 !pIO->Write32(&j->measurementValue))
9951 return false;
9952 }
9953 nResponseList.clear();
9954 }
9955
9956 return true;
9957}
9958
9959
9960/**
9961 ****************************************************************************
9962 * Name: CIccResponseCurveStruct::Describe
9963 *
9964 * Purpose: Dump data associated with the tag to a string
9965 *
9966 * Args:
9967 * sDescription - string to concatenate tag dump to
9968 *****************************************************************************
9969 */
9970void CIccResponseCurveStruct::Describe(std::string &sDescription, int nVerboseness)
9971{
9972 icChar buf[128];
9973 CIccInfo Fmt;
9974 CIccResponse16List nResponseList;
9975 CIccResponse16List::iterator j;
9976
9977 sDescription += "Measurement Unit: ";
9978 sDescription += Fmt.GetMeasurementUnit((icSignature)GetMeasurementType()); sDescription += "\n";
9979
9980
9981 for (int i=0; i<m_nChannels; i++) {
9982 nResponseList = m_Response16ListArray[i];
9983
9984 sDescription += "\n";
9985 sprintf(buf, "Maximum Colorant XYZ Measurement for Channel-%u : X=%.4lf, Y=%.4lf, Z=%.4lf\n", i+1,
9986 icFtoD(m_maxColorantXYZ[i].X), icFtoD(m_maxColorantXYZ[i].Y), icFtoD(m_maxColorantXYZ[i].Z));
9987 sDescription += buf;
9988
9989 sprintf(buf, "Number of Measurements for Channel-%u : %u\n", i+1, (icUInt32Number)nResponseList.size());
9990 sDescription += buf;
9991
9992 sprintf(buf, "Measurement Data for Channel-%u follows:\n", i+1);
9993 sDescription += buf;
9994
9995 for (j=nResponseList.begin(); j!=nResponseList.end(); j++) {
9996 sprintf(buf, "Device Value= %u : Measurement Value= %.4lf\n", j->deviceCode, icFtoD(j->measurementValue));
9997 sDescription += buf;
9998 }
9999 }
10000}
10001
10002
10003/**
10004******************************************************************************
10005* Name: CIccResponseCurveStruct::Validate
10006*
10007* Purpose: Check tag data validity.
10008*
10009* Args:
10010* sig = signature of tag being validated,
10011* sReport = String to add report information to
10012*
10013* Return:
10014* icValidateStatusOK if valid, or other error status.
10015******************************************************************************
10016*/
10018{
10020
10021 CIccInfo Info;
10022 std::string sSigName = Info.GetSigName(m_measurementUnitSig);
10023 switch(m_measurementUnitSig) {
10024 case icSigStatusA:
10025 case icSigStatusE:
10026 case icSigStatusI:
10027 case icSigStatusT:
10028 case icSigStatusM:
10029 case icSigDN:
10030 case icSigDNP:
10031 case icSigDNN:
10032 case icSigDNNP:
10033 break;
10034
10035 default:
10036 sReport += icMsgValidateNonCompliant;
10037 sReport += sSigName;
10038 sReport += " - Unknown measurement unit signature.\n";
10040 }
10041
10042 if (!m_nChannels) {
10043 sReport += icMsgValidateNonCompliant;
10044 sReport += sSigName;
10045 sReport += " - Incorrect number of channels.\n";
10047 return rv;
10048 }
10049 for (int i=0; i<m_nChannels; i++) {
10050 rv = icMaxStatus(rv, Info.CheckData(sReport, m_maxColorantXYZ[i], "Max Colorant XYZ"));
10051 }
10052
10053 return rv;
10054}
10055
10056
10057
10058/**
10059 ****************************************************************************
10060 * Name: CIccTagResponseCurveSet16::CIccTagResponseCurveSet16
10061 *
10062 * Purpose: Constructor
10063 *
10064 *****************************************************************************
10065 */
10067{
10068 m_nChannels = 0;
10069
10070 m_ResponseCurves = new(CIccResponseCurveSet);
10071 m_Curve = new(CIccResponseCurveSetIter);
10072 m_Curve->inited = false;
10073}
10074
10075
10076/**
10077 ****************************************************************************
10078 * Name: CIccTagResponseCurveSet16::CIccTagResponseCurveSet16
10079 *
10080 * Purpose: Copy Constructor
10081 *
10082 * Args:
10083 * ITRCS = The CIccTagResponseCurveSet16 object to be copied
10084 *****************************************************************************
10085 */
10087{
10088 m_nChannels = ITRCS.m_nChannels;
10089 m_ResponseCurves = new(CIccResponseCurveSet);
10090 *m_ResponseCurves = *ITRCS.m_ResponseCurves;
10091 m_Curve = new(CIccResponseCurveSetIter);
10092 *m_Curve = *ITRCS.m_Curve;
10093}
10094
10095
10096/**
10097 ****************************************************************************
10098 * Name: CIccTagResponseCurveSet16::operator=
10099 *
10100 * Purpose: Copy Operator
10101 *
10102 * Args:
10103 * RespCurveSet16Tag = The CIccTagResponseCurveSet16 object to be copied
10104 *****************************************************************************
10105 */
10107{
10108 if (&RespCurveSet16Tag == this)
10109 return *this;
10110
10111 if (!m_ResponseCurves->empty())
10112 m_ResponseCurves->clear();
10113
10114 m_nChannels = RespCurveSet16Tag.m_nChannels;
10115 *m_ResponseCurves = *RespCurveSet16Tag.m_ResponseCurves;
10116 *m_Curve = *RespCurveSet16Tag.m_Curve;
10117
10118 return *this;
10119}
10120
10121
10122/**
10123 ****************************************************************************
10124 * Name: CIccTagResponseCurveSet16::~CIccTagResponseCurveSet16
10125 *
10126 * Purpose: Destructor
10127 *
10128 *****************************************************************************
10129 */
10131{
10132 if (!m_ResponseCurves->empty())
10133 m_ResponseCurves->clear();
10134
10135 delete m_ResponseCurves;
10136 delete m_Curve;
10137}
10138
10139
10140/**
10141 ****************************************************************************
10142 * Name: CIccTagResponseCurveSet16::Read
10143 *
10144 * Purpose: Read in the tag contents into a data block
10145 *
10146 * Args:
10147 * size - # of bytes in tag,
10148 * pIO - IO object to read tag from
10149 *
10150 * Return:
10151 * true = successful, false = failure
10152 *****************************************************************************
10153 */
10155{
10157
10158 icUInt32Number startPos = pIO->Tell();
10159
10160 unsigned long headerSize = sizeof(icTagTypeSignature) +
10161 sizeof(icUInt32Number) +
10162 sizeof(icUInt16Number) * 2;
10163 if (headerSize > size)
10164 return false;
10165
10166 if (!pIO) {
10167 return false;
10168 }
10169
10170 if (!pIO->Read32(&sig) ||
10171 !pIO->Read32(&m_nReserved))
10172 return false;
10173
10174 icUInt16Number nCountMeasmntTypes;
10175
10176 if (!pIO->Read16(&m_nChannels) ||
10177 !pIO->Read16(&nCountMeasmntTypes))
10178 return false;
10179
10180 if ((icUInt32Number)nCountMeasmntTypes * sizeof(icUInt32Number) > size - headerSize)
10181 return false;
10182
10183 icUInt32Number* nOffset = new icUInt32Number[nCountMeasmntTypes];
10184
10185 if (pIO->Read32(&nOffset[0], nCountMeasmntTypes) != nCountMeasmntTypes) {
10186 delete[] nOffset;
10187 return false;
10188 }
10189
10191
10192 for (icUInt16Number i=0; i<nCountMeasmntTypes; i++) {
10193 if (nOffset[i] + 4 > size) {
10194 delete[] nOffset;
10195 return false;
10196 }
10197 pIO->Seek(startPos + nOffset[i], icSeekSet);
10198 entry = CIccResponseCurveStruct(m_nChannels);
10199 if (!entry.Read(size-nOffset[i], pIO)) {
10200 delete[] nOffset;
10201 return false;
10202 }
10203
10204 m_ResponseCurves->push_back(entry);
10205 }
10206 delete[] nOffset;
10207
10208
10209 m_Curve->inited = false;
10210
10211 return true;
10212}
10213
10214
10215/**
10216 ****************************************************************************
10217 * Name: CIccTagResponseCurveSet16::Write
10218 *
10219 * Purpose: Write the tag to a file
10220 *
10221 * Args:
10222 * pIO - The IO object to write tag to.
10223 *
10224 * Return:
10225 * true = succesful, false = failure
10226 *****************************************************************************
10227 */
10229{
10230 icTagTypeSignature sig = GetType();
10231 icUInt16Number nCountMeasmntTypes = (icUInt16Number)m_ResponseCurves->size();
10232
10233 if (!pIO) {
10234 return false;
10235 }
10236
10237 icUInt32Number startPos = pIO->GetLength();
10238
10239 if (!pIO->Write32(&sig) ||
10240 !pIO->Write32(&m_nReserved))
10241 return false;
10242
10243
10244 if (!pIO->Write16(&m_nChannels) ||
10245 !pIO->Write16(&nCountMeasmntTypes))
10246 return false;
10247
10248 icUInt32Number offsetPos = pIO->GetLength();
10249 icUInt32Number* nOffset = new icUInt32Number[nCountMeasmntTypes];
10250
10251
10252 int j;
10253 for (j=0; j<nCountMeasmntTypes; j++) {
10254 nOffset[j] = 0;
10255 if (!pIO->Write32(&nOffset[j]))
10256 return false;
10257 }
10258
10259 CIccResponseCurveSet::iterator i;
10260
10261 for (i=m_ResponseCurves->begin(), j=0; i!=m_ResponseCurves->end(); i++, j++) {
10262 nOffset[j] = pIO->GetLength() - startPos;
10263 if (!i->Write(pIO))
10264 return false;
10265 }
10266
10267 icUInt32Number curPOs = pIO->GetLength();
10268
10269 pIO->Seek(offsetPos,icSeekSet);
10270
10271 for (j=0; j<nCountMeasmntTypes; j++) {
10272 if (!pIO->Write32(&nOffset[j]))
10273 return false;
10274 }
10275
10276 pIO->Seek(curPOs,icSeekSet);
10277 delete [] nOffset;
10278
10279 return true;
10280}
10281
10282
10283/**
10284 ****************************************************************************
10285 * Name: CIccTagResponseCurveSet16::Describe
10286 *
10287 * Purpose: Dump data associated with the tag to a string
10288 *
10289 * Args:
10290 * sDescription - string to concatenate tag dump to
10291 *****************************************************************************
10292 */
10293void CIccTagResponseCurveSet16::Describe(std::string &sDescription, int nVerboseness)
10294{
10295 CIccResponseCurveSet::iterator i;
10296 icChar buf[128];
10297
10298 sprintf(buf, "Number of Channels: %u\n", m_nChannels);
10299 sDescription += buf;
10300
10301 sprintf(buf, "Number of Measurement Types used: %u\n", (icUInt32Number)m_ResponseCurves->size());
10302 sDescription += buf;
10303
10304 int count = 0;
10305 for (i=m_ResponseCurves->begin(); i!=m_ResponseCurves->end(); i++, count++) {
10306 sDescription += "\n";
10307
10308 sprintf(buf, "Response Curve for measurement type [%u] follows:\n", count+1);
10309 sDescription += buf;
10310
10311 i->Describe(sDescription, nVerboseness);
10312 }
10313}
10314
10315
10316/**
10317 ****************************************************************************
10318 * Name: CIccTagResponseCurveSet16::SetNumChannels
10319 *
10320 * Purpose: Sets the number of channels. This will delete any prior Response
10321 * curves from the set.
10322 *
10323 * Args:
10324 * nChannels = number of channels
10325 *****************************************************************************
10326 */
10328{
10329 m_nChannels = nChannels;
10330
10331 if (!m_ResponseCurves->empty())
10332 m_ResponseCurves->clear();
10333}
10334
10335
10336/**
10337 ****************************************************************************
10338 * Name: CIccTagResponseCurveSet16::NewResponseCurves
10339 *
10340 * Purpose: Creates and adds a new set of response curves to the list.
10341 * SetNumChannels() must be called before calling this function.
10342 *
10343 * Args:
10344 * sig = measurement unit signature
10345 *****************************************************************************
10346 */
10348{
10349 if (!m_nChannels)
10350 return NULL;
10351
10352 CIccResponseCurveStruct *pResponseCurveStruct;
10353 pResponseCurveStruct = GetResponseCurves(sig);
10354
10355 if (pResponseCurveStruct)
10356 return pResponseCurveStruct;
10357
10359 entry = CIccResponseCurveStruct(sig, m_nChannels);
10360 m_ResponseCurves->push_back(entry);
10361 m_Curve->inited = false;
10362
10363 return GetResponseCurves(sig);
10364}
10365
10366
10367/**
10368 ****************************************************************************
10369 * Name: CIccTagResponseCurveSet16::GetResponseCurves
10370 *
10371 * Purpose: Returns pointer to the requested set of response curves
10372 *
10373 * Args:
10374 * sig = measurement unit signature of the response curve set desired
10375 *****************************************************************************
10376 */
10378{
10379 if (!m_nChannels)
10380 return NULL;
10381
10382 CIccResponseCurveSet::iterator i;
10383
10384 for (i=m_ResponseCurves->begin(); i!=m_ResponseCurves->end(); i++) {
10385 if (i->GetMeasurementType() == sig)
10386 return (i->GetThis());
10387 }
10388
10389 return NULL;
10390}
10391
10392
10393/**
10394 ****************************************************************************
10395 * Name: CIccTagResponseCurveSet16::GetFirstCurves
10396 *
10397 * Purpose: Returns pointer to the first set of response curves in the list.
10398 *
10399 *****************************************************************************
10400 */
10402{
10403 if (!m_Curve)
10404 return NULL;
10405
10406 m_Curve->item = m_ResponseCurves->begin();
10407 if (m_Curve->item == m_ResponseCurves->end()) {
10408 m_Curve->inited = false;
10409 return NULL;
10410 }
10411 m_Curve->inited = true;
10412 return m_Curve->item->GetThis();
10413}
10414
10415
10416/**
10417 ****************************************************************************
10418 * Name: CIccTagResponseCurveSet16::GetNextCurves
10419 *
10420 * Purpose: Serves as an iterator for the list containing response curves.
10421 * GetFirstCurves() must be called before calling this function.
10422 *
10423 *****************************************************************************
10424 */
10426{
10427 if (!m_Curve || !m_Curve->inited)
10428 return NULL;
10429
10430 m_Curve->item++;
10431 if (m_Curve->item==m_ResponseCurves->end()) {
10432 m_Curve->inited = false;
10433 return NULL;
10434 }
10435 return m_Curve->item->GetThis();
10436}
10437
10438
10439/**
10440 ****************************************************************************
10441 * Name: CIccTagResponseCurveSet16::GetNumResponseCurveTypes
10442 *
10443 * Purpose: Get the number of response curve types.
10444 *
10445 *****************************************************************************
10446 */
10448{
10449 return(icUInt16Number) m_ResponseCurves->size();
10450}
10451
10452
10453/**
10454******************************************************************************
10455* Name: CIccTagResponseCurveSet16::Validate
10456*
10457* Purpose: Check tag data validity.
10458*
10459* Args:
10460* sig = signature of tag being validated,
10461* sReport = String to add report information to
10462*
10463* Return:
10464* icValidateStatusOK if valid, or other error status.
10465******************************************************************************
10466*/
10467icValidateStatus CIccTagResponseCurveSet16::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
10468{
10469 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
10470
10471 CIccInfo Info;
10472 std::string sSigPathName = Info.GetSigPathName(sigPath);
10473
10474 if (!pProfile) {
10475 sReport += icMsgValidateWarning;
10476 sReport += sSigPathName;
10477 sReport += " - Tag validation incomplete: Pointer to profile unavailable.\n";
10479 return rv;
10480 }
10481
10482 if (m_nChannels!=icGetSpaceSamples(pProfile->m_Header.colorSpace)) {
10483 sReport += icMsgValidateWarning;
10484 sReport += sSigPathName;
10485 sReport += " - Incorrect number of channels.\n";
10486 }
10487
10488 if (!GetNumResponseCurveTypes()) {
10489 sReport += icMsgValidateWarning;
10490 sReport += sSigPathName;
10491 sReport += " - Empty Tag!.\n";
10493 }
10494 else {
10495 CIccResponseCurveSet::iterator i;
10496 for (i=m_ResponseCurves->begin(); i!=m_ResponseCurves->end(); i++) {
10497 rv = icMaxStatus(rv, i->Validate(sReport));
10498 }
10499 }
10500
10501 return rv;
10502}
10503
10504
10505/**
10506 ****************************************************************************
10507 * Name: CIccTagSpectralDataInfo::CIccTagSpectralDataInfo
10508 *
10509 * Purpose: Constructor
10510 *
10511 *****************************************************************************
10512 */
10514{
10515 m_nSig = 0;
10516 memset(&m_spectralRange, 0, sizeof(m_spectralRange));
10517 memset(&m_biSpectralRange, 0, sizeof(m_biSpectralRange));
10518}
10519
10520
10521
10522/**
10523 ****************************************************************************
10524 * Name: CIccTagSpectralDataInfo::CIccTagSpectralDataInfo
10525 *
10526 * Purpose: Copy Constructor
10527 *
10528 * Args:
10529 * ITS = The CIccTagSpectralDataInfo object to be copied
10530 *****************************************************************************
10531 */
10533{
10534 m_nSig = ITS.m_nSig;
10535 m_spectralRange = ITS.m_spectralRange;
10536 m_biSpectralRange = ITS.m_biSpectralRange;
10537}
10538
10539
10540
10541/**
10542 ****************************************************************************
10543 * Name: CIccTagSpectralDataInfo::operator=
10544 *
10545 * Purpose: Copy Operator
10546 *
10547 * Args:
10548 * SignatureTag = The CIccTagSignature object to be copied
10549 *****************************************************************************
10550 */
10552{
10553 if (&ITS == this)
10554 return *this;
10555
10556 m_nSig = ITS.m_nSig;
10557 m_spectralRange = ITS.m_spectralRange;
10558 m_biSpectralRange = ITS.m_biSpectralRange;
10559
10560 return *this;
10561}
10562
10563
10564/**
10565 ****************************************************************************
10566 * Name: CIccTagSpectralDataInfo::~CIccTagSpectralDataInfo
10567 *
10568 * Purpose: Destructor
10569 *
10570 *****************************************************************************
10571 */
10575
10576/**
10577 ****************************************************************************
10578 * Name: CIccTagSpectralDataInfo::Read
10579 *
10580 * Purpose: Read in the tag contents into a data block
10581 *
10582 * Args:
10583 * size - # of bytes in tag,
10584 * pIO - IO object to read tag from
10585 *
10586 * Return:
10587 * true = successful, false = failure
10588 *****************************************************************************
10589 */
10591{
10593
10594 if (sizeof(icTagTypeSignature) + 2*sizeof(icUInt32Number) + 6*sizeof(icUInt16Number) > size)
10595 return false;
10596
10597 if (!pIO) {
10598 m_nSig = 0;
10599 memset(&m_spectralRange, 0, sizeof(m_spectralRange));
10600 memset(&m_biSpectralRange, 0, sizeof(m_biSpectralRange));
10601 return false;
10602 }
10603
10604 if (!pIO->Read32(&sig))
10605 return false;
10606
10607 if (!pIO->Read32(&m_nReserved))
10608 return false;
10609
10610 if (!pIO->Read32(&m_nSig))
10611 return false;
10612
10613 if (!pIO->Read16(&m_spectralRange.start))
10614 return false;
10615
10616 if (!pIO->Read16(&m_spectralRange.end))
10617 return false;
10618
10619 if (!pIO->Read16(&m_spectralRange.steps))
10620 return false;
10621
10622 if (!pIO->Read16(&m_biSpectralRange.start))
10623 return false;
10624
10625 if (!pIO->Read16(&m_biSpectralRange.end))
10626 return false;
10627
10628 if (!pIO->Read16(&m_biSpectralRange.steps))
10629 return false;
10630
10631 return true;
10632}
10633
10634/**
10635 ****************************************************************************
10636 * Name: CIccTagSpectralDataInfo::Write
10637 *
10638 * Purpose: Write the tag to a file
10639 *
10640 * Args:
10641 * pIO - The IO object to write tag to.
10642 *
10643 * Return:
10644 * true = succesful, false = failure
10645 *****************************************************************************
10646 */
10648{
10649 icTagTypeSignature sig = GetType();
10650
10651 if (!pIO)
10652 return false;
10653
10654 if (!pIO->Write32(&sig))
10655 return false;
10656
10657 if (!pIO->Write32(&m_nReserved))
10658 return false;
10659
10660 if (!pIO->Write32(&m_nSig))
10661 return false;
10662
10663 if (!pIO->Write16(&m_spectralRange.start))
10664 return false;
10665
10666 if (!pIO->Write16(&m_spectralRange.end))
10667 return false;
10668
10669 if (!pIO->Write16(&m_spectralRange.steps))
10670 return false;
10671
10672 if (!pIO->Write16(&m_biSpectralRange.start))
10673 return false;
10674
10675 if (!pIO->Write16(&m_biSpectralRange.end))
10676 return false;
10677
10678 if (!pIO->Write16(&m_biSpectralRange.steps))
10679 return false;
10680 return true;
10681}
10682
10683
10684/**
10685 ****************************************************************************
10686 * Name: CIccTagSpectralDataInfo::Describe
10687 *
10688 * Purpose: Dump data associated with the tag to a string
10689 *
10690 * Args:
10691 * sDescription - string to concatenate tag dump to
10692 *****************************************************************************
10693 */
10694void CIccTagSpectralDataInfo::Describe(std::string &sDescription, int nVerboseness)
10695{
10696 char buf[256];
10697
10698 sDescription += "ColorSignature: ";
10699 sDescription += icGetColorSigStr(buf, m_nSig);
10700 sDescription += "\n";
10701
10702 sprintf(buf, "SpectralRange: start %fnm end %fnm with %d steps\n", icF16toF(m_spectralRange.start), icF16toF(m_spectralRange.end), m_spectralRange.steps);
10703 sDescription += buf;
10704 if (m_biSpectralRange.steps) {
10705 sprintf(buf, "BiSpectralRange: start %fnm end %fnm with %d steps\n", icF16toF(m_spectralRange.start), icF16toF(m_spectralRange.end), m_spectralRange.steps);
10706 sDescription += buf;
10707 }
10708}
10709
10710
10711/**
10712******************************************************************************
10713* Name: CIccTagSpectralDataInfo::Validate
10714*
10715* Purpose: Check tag data validity.
10716*
10717* Args:
10718* sig = signature of tag being validated,
10719* sReport = String to add report information to
10720*
10721* Return:
10722* icValidateStatusOK if valid, or other error status.
10723******************************************************************************
10724*/
10725icValidateStatus CIccTagSpectralDataInfo::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
10726{
10727 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
10728
10729 CIccInfo Info;
10730 std::string sSigPathName = Info.GetSigPathName(sigPath);
10732
10733 if (sig==icSigSpectralDataInfoTag && pProfile->m_Header.spectralPCS) {
10734 const icHeader *pHdr = &pProfile->m_Header;
10735
10736 if (m_nSig != pHdr->spectralPCS ||
10737 memcmp(&m_spectralRange, &pHdr->spectralRange, sizeof(m_spectralRange)) ||
10738 memcmp(&m_biSpectralRange, &pHdr->biSpectralRange, sizeof(m_biSpectralRange))) {
10739 sReport += icMsgValidateCriticalError;
10740 sReport += sSigPathName;
10741 sReport += " - SpectralDataInfo should be the same as the profile spectralPCS.\n";
10743 }
10744 }
10745 rv = icMaxStatus(rv, Info.CheckData(sReport, m_spectralRange, "Spectral Range"));
10746 if (m_biSpectralRange.steps)
10747 rv = icMaxStatus(rv, Info.CheckData(sReport, m_biSpectralRange, "Bispectral Range"));
10748 return rv;
10749}
10750
10751
10752/**
10753 ****************************************************************************
10754 * Name: CIccTagSpectralViewingConditions::CIccTagSpectralViewingConditions
10755 *
10756 * Purpose: Constructor
10757 *
10758 *****************************************************************************
10759 */
10761{
10762 m_stdObserver = icStdObs1931TwoDegrees;
10763 m_observerRange.start = 0;
10764 m_observerRange.end = 0;
10765 m_observerRange.steps = 0;
10766 m_observer = NULL;
10767
10768 m_stdIlluminant = icIlluminantD50;
10769 m_colorTemperature = 5000.0f;
10770
10771 m_illuminantRange.start = 0;
10772 m_illuminantRange.end = 0;
10773 m_illuminantRange.steps = 0;
10774
10775 m_illuminant = 0;
10776
10777 m_illuminantXYZ.X = 0;
10778 m_illuminantXYZ.Y = 0;
10779 m_illuminantXYZ.Z = 0;
10780
10781 m_surroundXYZ.X = 0;
10782 m_surroundXYZ.Y = 0;
10783 m_surroundXYZ.Z = 0;
10784}
10785
10786
10787/**
10788 ****************************************************************************
10789 * Name: CIccTagSpectralViewingConditions::CIccTagSpectralViewingConditions
10790 *
10791 * Purpose: Copy Constructor
10792 *
10793 * Args:
10794 * SVCT = The CIccTagSpectralViewingConditions object to be copied
10795 *****************************************************************************
10796 */
10798{
10799 m_stdObserver = SVCT.m_stdObserver;
10800 m_observerRange.start = SVCT.m_observerRange.start;
10801 m_observerRange.end = SVCT.m_observerRange.end;
10802 m_observerRange.steps = SVCT.m_observerRange.steps;
10803
10804 if (SVCT.m_observer && SVCT.m_observerRange.steps) {
10805 m_observer = new icFloat32Number[SVCT.m_observerRange.steps*3];
10806 if (m_observer) {
10807 memcpy(m_observer, SVCT.m_observer, SVCT.m_observerRange.steps*3*sizeof(icFloat32Number));
10808 }
10809 }
10810 else {
10811 m_observer = NULL;
10812 }
10813
10814 m_stdIlluminant = SVCT.m_stdIlluminant;
10815 m_colorTemperature = SVCT.m_colorTemperature;
10816
10817 m_illuminantRange.start = 0;
10818 m_illuminantRange.end = 0;
10819 m_illuminantRange.steps = 0;
10820
10821 if (SVCT.m_illuminant && SVCT.m_illuminantRange.steps) {
10822 m_illuminant = new icFloat32Number[SVCT.m_illuminantRange.steps];
10823 if (m_illuminant) {
10824 memcpy(m_illuminant, SVCT.m_illuminant, SVCT.m_illuminantRange.steps*sizeof(icFloat32Number));
10825 }
10826 }
10827 else {
10828 m_illuminant = NULL;
10829 }
10830
10831 m_illuminantXYZ.X = 0;
10832 m_illuminantXYZ.Y = 0;
10833 m_illuminantXYZ.Z = 0;
10834
10835 m_surroundXYZ.X = 0;
10836 m_surroundXYZ.Y = 0;
10837 m_surroundXYZ.Z = 0;
10838}
10839
10840
10841/**
10842 ****************************************************************************
10843 * Name: CIccTagSpectralViewingConditions::operator=
10844 *
10845 * Purpose: Copy Operator
10846 *
10847 * Args:
10848 * specViewCondTag = The CIccTagSpectralViewingConditions object to be copied
10849 *****************************************************************************
10850 */
10852{
10853 m_stdObserver = SVCT.m_stdObserver;
10854 m_observerRange.start = SVCT.m_observerRange.start;
10855 m_observerRange.end = SVCT.m_observerRange.end;
10856 m_observerRange.steps = SVCT.m_observerRange.steps;
10857
10858 if (SVCT.m_observer && SVCT.m_observerRange.steps) {
10859 m_observer = new icFloat32Number[SVCT.m_observerRange.steps*3];
10860 if (m_observer) {
10861 memcpy(m_observer, SVCT.m_observer, SVCT.m_observerRange.steps*3*sizeof(icFloat32Number));
10862 }
10863 }
10864 else {
10865 m_observer = NULL;
10866 }
10867
10868 m_stdIlluminant = SVCT.m_stdIlluminant;
10869 m_colorTemperature = SVCT.m_colorTemperature;
10870
10871 m_illuminantRange.start = 0;
10872 m_illuminantRange.end = 0;
10873 m_illuminantRange.steps = 0;
10874
10875 if (SVCT.m_illuminant && SVCT.m_illuminantRange.steps) {
10876 m_illuminant = new icFloat32Number[SVCT.m_illuminantRange.steps];
10877 if (m_illuminant) {
10878 memcpy(m_illuminant, SVCT.m_illuminant, SVCT.m_illuminantRange.steps*sizeof(icFloat32Number));
10879 }
10880 }
10881 else {
10882 m_illuminant = NULL;
10883 }
10884
10885 m_illuminantXYZ.X = 0;
10886 m_illuminantXYZ.Y = 0;
10887 m_illuminantXYZ.Z = 0;
10888
10889 m_surroundXYZ.X = 0;
10890 m_surroundXYZ.Y = 0;
10891 m_surroundXYZ.Z = 0;
10892
10893 return *this;
10894}
10895
10896
10897/**
10898 ****************************************************************************
10899 * Name: CIccTagSpectralViewingConditions::~CIccTagResponseCurveSet16
10900 *
10901 * Purpose: Destructor
10902 *
10903 *****************************************************************************
10904 */
10906{
10907 if (m_observer)
10908 delete [] m_observer;
10909
10910 if (m_illuminant)
10911 delete [] m_illuminant;
10912}
10913
10914
10915/**
10916 ****************************************************************************
10917 * Name: CIccTagSpectralViewingConditions::Read
10918 *
10919 * Purpose: Read in the tag contents into a data block
10920 *
10921 * Args:
10922 * size - # of bytes in tag,
10923 * pIO - IO object to read tag from
10924 *
10925 * Return:
10926 * true = successful, false = failure
10927 *****************************************************************************
10928 */
10930{
10932
10933 //check size properly
10934 icUInt32Number headerSize = sizeof(icTagTypeSignature) +
10935 sizeof(icUInt32Number)*4;
10936 if (headerSize > size)
10937 return false;
10938
10939 if (!pIO) {
10940 return false;
10941 }
10942
10943 if (!pIO->Read32(&sig) ||
10944 !pIO->Read32(&m_nReserved))
10945 return false;
10946
10947
10948 if (!pIO->Read32(&m_stdObserver) ||
10949 !pIO->Read16(&m_observerRange.start) ||
10950 !pIO->Read16(&m_observerRange.end) ||
10951 !pIO->Read16(&m_observerRange.steps) ||
10952 !pIO->Read16(&m_reserved2))
10953 return false;
10954
10955 icUInt32Number vals;
10956
10957 if (m_observer) {
10958 delete [] m_observer;
10959 m_observer = NULL;
10960 }
10961
10962 icUInt32Number observerSize = 0;
10963
10964 if (m_observerRange.steps) {
10965 vals = m_observerRange.steps * 3;
10966
10967 observerSize = vals * sizeof(icFloat32Number);
10968
10969 if (headerSize + observerSize > size)
10970 return false;
10971
10972 m_observer = new icFloat32Number[vals];
10973 if (!m_observer)
10974 return false;
10975
10976 if (pIO->ReadFloat32Float(&m_observer[0], vals) != vals)
10977 return false;
10978 }
10979
10980 icUInt32Number illumInfoSize = 2 * sizeof(icUInt32Number) + 4 * sizeof(icUInt16Number);
10981 if (headerSize + observerSize +illumInfoSize > size)
10982 return false;
10983
10984 if (!pIO->Read32(&m_stdIlluminant) ||
10985 !pIO->ReadFloat32Float(&m_colorTemperature) ||
10986 !pIO->Read16(&m_illuminantRange.start) ||
10987 !pIO->Read16(&m_illuminantRange.end) ||
10988 !pIO->Read16(&m_illuminantRange.steps) ||
10989 !pIO->Read16(&m_reserved3))
10990 return false;
10991
10992
10993 if (m_illuminant) {
10994 delete [] m_illuminant;
10995 m_illuminant = NULL;
10996 }
10997
10998 icUInt32Number illuminantSize = 0;
10999
11000 if (m_illuminantRange.steps) {
11001 vals = m_illuminantRange.steps;
11002
11003 illuminantSize = vals * sizeof(icFloat32Number);
11004
11005 if (headerSize + observerSize + illumInfoSize + illuminantSize > size)
11006 return false;
11007
11008 m_illuminant = new icFloat32Number[vals];
11009 if (!m_illuminant)
11010 return false;
11011
11012 if (pIO->ReadFloat32Float(&m_illuminant[0], vals) != vals)
11013 return false;
11014 }
11015 else {
11016 setIlluminant(m_stdIlluminant, m_illuminantRange, NULL, m_colorTemperature);
11017 }
11018
11019 if (headerSize + observerSize + illumInfoSize + illuminantSize + 6*sizeof(icFloat32Number) > size)
11020 return false;
11021
11022 if (pIO->ReadFloat32Float(&m_illuminantXYZ, 3)!=3 ||
11023 pIO->ReadFloat32Float(&m_surroundXYZ, 3)!=3)
11024 return false;
11025
11026 return true;
11027}
11028
11029
11030/**
11031 ****************************************************************************
11032 * Name: CIccTagSpectralViewingConditions::Write
11033 *
11034 * Purpose: Write the tag to a file
11035 *
11036 * Args:
11037 * pIO - The IO object to write tag to.
11038 *
11039 * Return:
11040 * true = succesful, false = failure
11041 *****************************************************************************
11042 */
11044{
11045 icTagTypeSignature sig = GetType();
11046
11047 if (!pIO) {
11048 return false;
11049 }
11050
11051 if (!pIO->Write32(&sig) ||
11052 !pIO->Write32(&m_nReserved))
11053 return false;
11054
11055
11056 if (!pIO->Write32(&m_stdObserver) ||
11057 !pIO->Write16(&m_observerRange.start) ||
11058 !pIO->Write16(&m_observerRange.end) ||
11059 !pIO->Write16(&m_observerRange.steps) ||
11060 !pIO->Write16(&m_reserved2))
11061 return false;
11062
11063 icUInt32Number vals = m_observerRange.steps*3;
11064
11065 if (vals)
11066 if (pIO->WriteFloat32Float(&m_observer[0], vals) != vals)
11067 return false;
11068
11069 if (!pIO->Write32(&m_stdIlluminant) ||
11070 !pIO->WriteFloat32Float(&m_colorTemperature) ||
11071 !pIO->Write16(&m_illuminantRange.start) ||
11072 !pIO->Write16(&m_illuminantRange.end) ||
11073 !pIO->Write16(&m_illuminantRange.steps) ||
11074 !pIO->Write16(&m_reserved3))
11075 return false;
11076
11077 vals = m_illuminantRange.steps;
11078
11079 if (vals)
11080 if (pIO->WriteFloat32Float(&m_illuminant[0], vals) != vals)
11081 return false;
11082
11083 if (pIO->WriteFloat32Float(&m_illuminantXYZ, 3)!=3 ||
11084 pIO->WriteFloat32Float(&m_surroundXYZ, 3)!=3)
11085 return false;
11086
11087 return true;
11088}
11089
11090
11091/**
11092 ****************************************************************************
11093 * Name: CIccTagSpectralViewingConditions::Describe
11094 *
11095 * Purpose: Dump data associated with the tag to a string
11096 *
11097 * Args:
11098 * sDescription - string to concatenate tag dump to
11099 *****************************************************************************
11100 */
11101void CIccTagSpectralViewingConditions::Describe(std::string &sDescription, int nVerboseness)
11102{
11103 icChar buf[128];
11104 CIccInfo info;
11105
11106 sprintf(buf, "StdObserver: %s\n\n", info.GetStandardObserverName(m_stdObserver));
11107 sDescription += buf;
11108
11109 sprintf(buf, "Illuminant Tristimulus values: X = %.4lf, Y = %.4lf, Z = %.4lf\n\n",
11110 m_illuminantXYZ.X, m_illuminantXYZ.Y,m_illuminantXYZ.Z);
11111 sDescription += buf;
11112
11113 if (m_observer) {
11114 sprintf(buf, "Observer Functions: start=%.1fnm end=%.1fnm, steps=%d\n",
11115 icF16toF(m_observerRange.start), icF16toF(m_observerRange.end), m_observerRange.steps);
11116 sDescription += buf;
11117
11118 if (nVerboseness > 75) {
11119 icFloat32Number *ptr = m_observer;
11120 int i, j;
11121 for (j=0; j<3; j++) {
11122 for (i=0; i<m_observerRange.steps; i++) {
11123 sprintf(buf, " %.4f", *ptr);
11124 sDescription += buf;
11125 ptr++;
11126 }
11127 sDescription += "\n\n";
11128 }
11129 }
11130 }
11131 else {
11132 sDescription += "No custom Observer defined\n\n";
11133 }
11134
11135 sDescription += "StdIlluminant Type: ";
11136
11137 sDescription += info.GetIlluminantName(m_stdIlluminant);
11138 sDescription += "\n";
11139
11140 sprintf(buf, "Color Temperature: %.1fK\n\n", m_colorTemperature);
11141 sDescription += buf;
11142
11143 if (m_illuminant) {
11144 sprintf(buf, "Illuminant SPD: start=%.1fm end=%.1fnm, steps=%d\n",
11145 icF16toF(m_illuminantRange.start), icF16toF(m_illuminantRange.end), m_illuminantRange.steps);
11146 sDescription += buf;
11147 if (nVerboseness > 75) {
11148 icFloat32Number *ptr = m_illuminant;
11149 int i;
11150 for (i=0; i<m_illuminantRange.steps; i++) {
11151 sprintf(buf, " %.4f", *ptr);
11152 sDescription += buf;
11153 ptr++;
11154 }
11155 }
11156 sDescription += "\n\n";
11157 }
11158 else {
11159 sDescription += "No custom Observer defined\n\n";
11160 }
11161
11162 sprintf(buf, "Surround Tristimulus values: X = %.4lf, Y = %.4lf, Z = %.4lf\n",
11163 m_surroundXYZ.X, m_surroundXYZ.Y, m_surroundXYZ.Z);
11164 sDescription += buf;
11165}
11166
11167
11168
11169/**
11170******************************************************************************
11171* Name: CIccTagSpectralViewingConditions::Validate
11172*
11173* Purpose: Check tag data validity.
11174*
11175* Args:
11176* sig = signature of tag being validated,
11177* sReport = String to add report information to
11178*
11179* Return:
11180* icValidateStatusOK if valid, or other error status.
11181******************************************************************************
11182*/
11183icValidateStatus CIccTagSpectralViewingConditions::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
11184{
11185 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
11186
11187 CIccInfo Info;
11188 std::string sSigPathName = Info.GetSigPathName(sigPath);
11189
11190 rv = icMaxStatus(rv, Info.CheckData(sReport, m_illuminantXYZ, sSigPathName + ":>illuminantXYZ"));
11191 rv = icMaxStatus(rv, Info.CheckData(sReport, m_surroundXYZ, sSigPathName + ":>surroundXYZ"));
11192
11193 rv = icMaxStatus(rv, Info.CheckLuminance(sReport, m_illuminantXYZ, sSigPathName + ":>illuminantXYZ"));
11194 rv = icMaxStatus(rv, Info.CheckLuminance(sReport, m_surroundXYZ, sSigPathName + ":>surroundXYZ"));
11195
11196 icSpectralRange range;
11197
11198 if (getObserver(range)) {
11199 rv = icMaxStatus(rv, Info.CheckData(sReport, range, sSigPathName + ":>observerRange"));
11200
11201 if (!m_observer && pProfile && pProfile->m_Header.version < icVersionNumberV5_1) {
11202 sReport += icMsgValidateNonCompliant;
11203 sReport += sSigPathName;
11204 sReport += " - Missing Observer CMF not supported by profile version!\r\n";
11206 }
11207 }
11208 else {
11209 rv = icMaxStatus(rv, Info.CheckData(sReport, m_observerRange, sSigPathName + ":>observerRange"));
11210
11211 sReport += icMsgValidateCriticalError;
11212 sReport += sSigPathName;
11213 sReport += " - Missing Observer CMF!\r\n";
11215 }
11216
11217 if (getIlluminant(range)) {
11218 rv = icMaxStatus(rv, Info.CheckData(sReport, range, sSigPathName + ":>illuminantRange"));
11219
11220 if (!m_illuminant && pProfile && pProfile->m_Header.version < icVersionNumberV5_1) {
11221 sReport += icMsgValidateNonCompliant;
11222 sReport += sSigPathName;
11223 sReport += " - Missing illuminant SPD not supported by profile version!\r\n";
11225 }
11226 }
11227 else {
11228 rv = icMaxStatus(rv, Info.CheckData(sReport, m_illuminantRange, sSigPathName + ":>illuminantRange"));
11229 sReport += icMsgValidateCriticalError;
11230 sReport += sSigPathName;
11231 sReport += " - Missing Illuminant SPD!\r\n";
11233 }
11234
11235 return rv;
11236}
11237
11239{
11240 int n = newRange.steps*3;
11241 icFloatNumber *rv = (icFloatNumber*)malloc(n*sizeof(icFloatNumber));
11242
11243 CIccMatrixMath *range = CIccMatrixMath::rangeMap(m_observerRange, newRange);
11244 if (range) {
11245 range->VectorMult(rv, m_observer);
11246 range->VectorMult(&rv[newRange.steps], &m_observer[m_observerRange.steps]);
11247 range->VectorMult(&rv[newRange.steps*2], &m_observer[m_observerRange.steps*2]);
11248 delete range;
11249 }
11250 else {
11251 memcpy(rv, m_observer, m_observerRange.steps*3*sizeof(icFloatNumber));
11252 }
11253
11254 return rv;
11255}
11256
11258{
11259 CIccMatrixMath *pMtx=new CIccMatrixMath(3, newRange.steps);
11260
11261 CIccMatrixMath *range = CIccPcsXform::rangeMap(m_observerRange, newRange);
11262 if (range) {
11263 range->VectorMult(pMtx->entry(0), m_observer);
11264 range->VectorMult(pMtx->entry(1), &m_observer[m_observerRange.steps]);
11265 range->VectorMult(pMtx->entry(2), &m_observer[m_observerRange.steps*2]);
11266 delete range;
11267 }
11268 else {
11269 memcpy(pMtx->entry(0), m_observer, m_observerRange.steps*3*sizeof(icFloatNumber));
11270 }
11271
11272 return pMtx;
11273}
11274
11275typedef struct {
11278} icIllumDef;
11279
11282 { 24.457147f, 27.147280f, 29.837414f, 39.547443f, 49.257472f, 52.859364f, 56.461255f,
11283 58.222678f, 59.984100f, 58.878685f, 57.773270f, 66.274622f, 74.775973f, 80.987003f,
11284 87.198034f, 88.882488f, 90.566943f, 90.947782f, 91.328622f, 93.200755f, 95.072887f,
11285 93.503707f, 91.934527f, 93.817670f, 95.700813f, 96.147589f, 96.594366f, 96.854869f,
11286 97.115372f, 99.602130f, 102.088888f, 101.418624f, 100.748359f, 101.531110f, 102.313861f,
11287 101.156931f, 100.000000f, 98.868725f, 97.737450f, 98.330520f, 98.923589f, 96.216919f,
11288 93.510248f, 95.607997f, 97.705746f, 98.498795f, 99.291845f, 99.179895f, 99.067945f,
11289 97.409311f, 95.750676f, 97.322057f, 98.893438f, 97.299430f, 95.705421f, 96.969799f,
11290 98.234177f, 100.644248f, 103.054319f, 101.119636f, 99.184954f, 93.304566f, 87.424178f,
11291 89.538557f, 91.652935f, 92.293256f, 92.933577f, 84.912496f, 76.891415f, 81.721450f,
11292 86.551486f, 89.586840f, 92.622195f, 85.443791f, 78.265387f, 67.992302f, 57.719217f,
11293 70.340670f, 82.962124f, 80.636096f, 78.310068f }
11294 },
11296 { 49.975500f, 52.311800f, 54.648200f, 68.701500f, 82.754900f, 87.120400f, 91.486000f,
11297 92.458900f, 93.431800f, 90.057000f, 86.682300f, 95.773600f, 104.865000f, 110.936000f,
11298 117.008000f, 117.410000f, 117.812000f, 116.336000f, 114.861000f, 115.392000f, 115.923000f,
11299 112.367000f, 108.811000f, 109.082000f, 109.354000f, 108.578000f, 107.802000f, 106.296000f,
11300 104.790000f, 106.239000f, 107.689000f, 106.047000f, 104.405000f, 104.225000f, 104.046000f,
11301 102.023000f, 100.000000f, 98.167100f, 96.334200f, 96.061100f, 95.788000f, 92.236800f,
11302 88.685600f, 89.345900f, 90.006200f, 89.802600f, 89.599100f, 88.648900f, 87.698700f,
11303 85.493600f, 83.288600f, 83.493900f, 83.699200f, 81.863000f, 80.026800f, 80.120700f,
11304 80.214600f, 81.246200f, 82.277800f, 80.281000f, 78.284200f, 74.002700f, 69.721300f,
11305 70.665200f, 71.609100f, 72.979000f, 74.349000f, 67.976500f, 61.604000f, 65.744800f,
11306 69.885600f, 72.486300f, 75.087000f, 69.339800f, 63.592700f, 55.005400f, 46.418200f,
11307 56.611800f, 66.805400f, 65.094100f, 63.382800f }
11308 },
11310 { 92.424314f, 92.694368f, 92.964422f, 111.383899f, 129.803377f, 135.801152f, 141.798926f,
11311 141.447583f, 141.096240f, 133.975439f, 126.854638f, 135.602812f, 144.350987f, 149.960021f,
11312 155.569056f, 154.184112f, 152.799168f, 148.783207f, 144.767246f, 143.338753f, 141.910261f,
11313 136.139746f, 130.369231f, 128.545220f, 126.721209f, 124.329813f, 121.938418f, 117.937629f,
11314 113.936841f, 114.043847f, 114.150853f, 111.519464f, 108.888075f, 107.474441f, 106.060808f,
11315 103.030404f, 100.000000f, 97.314129f, 94.628259f, 93.347855f, 92.067450f, 88.659570f,
11316 85.251689f, 84.758623f, 84.265557f, 83.380599f, 82.495642f, 80.837162f, 79.178681f,
11317 76.519588f, 73.860495f, 73.447089f, 73.033684f, 71.360089f, 69.686495f, 69.189247f,
11318 68.692000f, 68.742482f, 68.792965f, 67.049716f, 65.306467f, 61.725711f, 58.144955f,
11319 58.497707f, 58.850460f, 60.339599f, 61.828738f, 56.573774f, 51.318811f, 54.969052f,
11320 58.619293f, 60.929241f, 63.239189f, 58.464199f, 53.689209f, 46.273925f, 38.858642f,
11321 47.398674f, 55.938706f, 54.609104f, 53.279502f,
11322 }
11323 },
11324 { icIlluminantA,
11325 { 9.7951f, 10.8996f, 12.0853f, 13.3543f, 14.7080f, 16.1480f, 17.6753f, 19.2907f,
11326 20.9950f, 22.7883f, 24.6709f, 26.6425f, 28.7027f, 30.8508f, 33.0859f, 35.4068f,
11327 37.8121f, 40.3002f, 42.8693f, 45.5174f, 48.2423f, 51.0418f, 53.9132f, 56.8539f,
11328 59.8611f, 62.9320f, 66.0635f, 69.2525f, 72.4959f, 75.7903f, 79.1326f, 82.5193f,
11329 85.9470f, 89.4124f, 92.9120f, 96.4423f, 100.0000f, 103.5820f, 107.1840f, 110.8030f,
11330 114.4360f, 118.0800f, 121.7310f, 125.3860f, 129.0430f, 132.6970f, 136.3460f, 139.9880f,
11331 143.6180f, 147.2350f, 150.8360f, 154.4180f, 157.9790f, 161.5160f, 165.0280f, 168.5100f,
11332 171.9630f, 175.3830f, 178.7690f, 182.1180f, 185.4290f, 188.7010f, 191.9310f, 195.1180f,
11333 198.2610f, 201.3590f, 204.4090f, 207.4110f, 210.3650f, 213.2680f, 216.1200f, 218.9200f,
11334 221.6670f, 224.3610f, 227.0000f, 229.5850f, 232.1150f, 234.5890f, 237.0080f, 239.3700f,
11335 241.6750f, }
11336 },
11337};
11338#define NUM_KNOWN_ILLUM (sizeof(icKnownIllums)/sizeof(icKnownIllums[0]))
11339
11341
11343{
11344 if (!m_illuminant || !m_illuminantRange.steps) {
11345 for (int i = 0; i < NUM_KNOWN_ILLUM; i++) {
11346 if (m_stdIlluminant == icKnownIllums[i].illum) {
11347 illumRange = icKnownIllumObsRange;
11348 return &icKnownIllums[i].spd[0];
11349 }
11350 }
11351 }
11352
11353 illumRange = m_illuminantRange;
11354 return m_illuminant;
11355}
11356
11357bool CIccTagSpectralViewingConditions::setIlluminant(icIlluminant illumId, const icSpectralRange &illumRange, const icFloatNumber *illum, icFloatNumber illumCCT/* = 0.0f*/)
11358{
11359 m_stdIlluminant = illumId;
11360 m_colorTemperature = illumCCT;
11361
11362 if (m_illuminant) {
11363 free(m_illuminant);
11364 }
11365
11366 m_illuminantRange = illumRange;
11367
11368 if (illumRange.steps && illum) {
11369 icUInt32Number size = illumRange.steps * sizeof(icFloatNumber);
11370 m_illuminant = (icFloatNumber *)malloc(size);
11371 if (m_illuminant)
11372 memcpy(m_illuminant, illum, size);
11373 else {
11374 memset(&m_illuminantRange, 0, sizeof(m_illuminantRange));
11375 return false;
11376 }
11377 }
11378 else {
11379 if (!illum)
11380 memset(&m_illuminantRange, 0, sizeof(m_illuminantRange));
11381
11382 m_illuminant = NULL;
11383 }
11384
11385 return true;
11386}
11387
11389{
11390 icSpectralRange zeroRange;
11391 memset(&zeroRange, 0, sizeof(zeroRange));
11392 icFloatNumber white[3] = {0};
11393 white[0] = pWhiteXYZ[0] / pWhiteXYZ[1];
11394 white[1] = 1.0;
11395 white[2] = pWhiteXYZ[2] / pWhiteXYZ[1];
11396
11397 if (!pWhiteXYZ || !icNotZero(pWhiteXYZ[1])) {
11398 setIlluminant(icIlluminantUnknown, zeroRange, NULL);
11399 return false;
11400 }
11401
11402 if (m_stdObserver == icStdObs1931TwoDegrees) {
11403 if ((icIsNear(white[0], icD50XYZ[0]) && icIsNear(white[2], icD50XYZ[2])) ||
11404 (icIsNear(white[0], 0.9642f, 0.0001f) && icIsNear(white[2], 0.8251f, 0.0001f))) {
11405 return setIlluminant(icIlluminantD50, zeroRange, NULL, 5000);
11406 }
11407 else if (icIsNear(white[0], 0.9505f, 0.0001f) && icIsNear(white[2], 1.0888f, 0.0001f)) {
11408 return setIlluminant(icIlluminantD65, zeroRange, NULL, 6504);
11409 }
11410 }
11411// else if (m_stdObserver == icStdObs1964TenDegrees) {
11412// setIlluminant(icIlluminantUnknown, zeroRange, NULL);
11413// return false;
11414// }
11415
11416 setIlluminant(icIlluminantUnknown, zeroRange, NULL);
11417 return false;
11418}
11419
11420typedef struct {
11422 icFloatNumber cmf[81*3];
11424
11427 { 0.001368f, 0.002236f, 0.004243f, 0.007650f, 0.014310f, 0.023190f, 0.043510f,
11428 0.077630f, 0.134380f, 0.214770f, 0.283900f, 0.328500f, 0.348280f, 0.348060f,
11429 0.336200f, 0.318700f, 0.290800f, 0.251100f, 0.195360f, 0.142100f, 0.095640f,
11430 0.057950f, 0.032010f, 0.014700f, 0.004900f, 0.002400f, 0.009300f, 0.029100f,
11431 0.063270f, 0.109600f, 0.165500f, 0.225750f, 0.290400f, 0.359700f, 0.433450f,
11432 0.512050f, 0.594500f, 0.678400f, 0.762100f, 0.842500f, 0.916300f, 0.978600f,
11433 1.026300f, 1.056700f, 1.062200f, 1.045600f, 1.002600f, 0.938400f, 0.854450f,
11434 0.751400f, 0.642400f, 0.541900f, 0.447900f, 0.360800f, 0.283500f, 0.218700f,
11435 0.164900f, 0.121200f, 0.087400f, 0.063600f, 0.046770f, 0.032900f, 0.022700f,
11436 0.015840f, 0.011359f, 0.008111f, 0.005790f, 0.004109f, 0.002899f, 0.002049f,
11437 0.001440f, 0.001000f, 0.000690f, 0.000476f, 0.000332f, 0.000235f, 0.000166f,
11438 0.000117f, 0.000083f, 0.000059f, 0.000042f,
11439 0.000039f, 0.000064f, 0.000120f, 0.000217f, 0.000396f, 0.000640f, 0.001210f,
11440 0.002180f, 0.004000f, 0.007300f, 0.011600f, 0.016840f, 0.023000f, 0.029800f,
11441 0.038000f, 0.048000f, 0.060000f, 0.073900f, 0.090980f, 0.112600f, 0.139020f,
11442 0.169300f, 0.208020f, 0.258600f, 0.323000f, 0.407300f, 0.503000f, 0.608200f,
11443 0.710000f, 0.793200f, 0.862000f, 0.914850f, 0.954000f, 0.980300f, 0.994950f,
11444 1.000000f, 0.995000f, 0.978600f, 0.952000f, 0.915400f, 0.870000f, 0.816300f,
11445 0.757000f, 0.694900f, 0.631000f, 0.566800f, 0.503000f, 0.441200f, 0.381000f,
11446 0.321000f, 0.265000f, 0.217000f, 0.175000f, 0.138200f, 0.107000f, 0.081600f,
11447 0.061000f, 0.044580f, 0.032000f, 0.023200f, 0.017000f, 0.011920f, 0.008210f,
11448 0.005723f, 0.004102f, 0.002929f, 0.002091f, 0.001484f, 0.001047f, 0.000740f,
11449 0.000520f, 0.000361f, 0.000249f, 0.000172f, 0.000120f, 0.000085f, 0.000060f,
11450 0.000042f, 0.000030f, 0.000021f, 0.000015f,
11451 0.006450f, 0.010550f, 0.020050f, 0.036210f, 0.067850f, 0.110200f, 0.207400f,
11452 0.371300f, 0.645600f, 1.039050f, 1.385600f, 1.622960f, 1.747060f, 1.782600f,
11453 1.772110f, 1.744100f, 1.669200f, 1.528100f, 1.287640f, 1.041900f, 0.812950f,
11454 0.616200f, 0.465180f, 0.353300f, 0.272000f, 0.212300f, 0.158200f, 0.111700f,
11455 0.078250f, 0.057250f, 0.042160f, 0.029840f, 0.020300f, 0.013400f, 0.008750f,
11456 0.005750f, 0.003900f, 0.002750f, 0.002100f, 0.001800f, 0.001650f, 0.001400f,
11457 0.001100f, 0.001000f, 0.000800f, 0.000600f, 0.000340f, 0.000240f, 0.000190f,
11458 0.000100f, 0.000050f, 0.000030f, 0.000020f, 0.000010f, 0.000000f, 0.000000f,
11459 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
11460 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
11461 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
11462 0.000000f, 0.000000f, 0.000000f, 0.000000f }
11463 },
11465 { 0.000160f, 0.000662f, 0.002362f, 0.007242f, 0.019110f, 0.043400f, 0.084736f,
11466 0.140638f, 0.204492f, 0.264737f, 0.314679f, 0.357719f, 0.383734f, 0.386726f,
11467 0.370702f, 0.342957f, 0.302273f, 0.254085f, 0.195618f, 0.132349f, 0.080507f,
11468 0.041072f, 0.016172f, 0.005132f, 0.003816f, 0.015444f, 0.037465f, 0.071358f,
11469 0.117749f, 0.172953f, 0.236491f, 0.304213f, 0.376772f, 0.451584f, 0.529826f,
11470 0.616053f, 0.705224f, 0.793832f, 0.878655f, 0.951162f, 1.014160f, 1.074300f,
11471 1.118520f, 1.134300f, 1.123990f, 1.089100f, 1.030480f, 0.950740f, 0.856297f,
11472 0.754930f, 0.647467f, 0.535110f, 0.431567f, 0.343690f, 0.268329f, 0.204300f,
11473 0.152568f, 0.112210f, 0.081261f, 0.057930f, 0.040851f, 0.028623f, 0.019941f,
11474 0.013842f, 0.009577f, 0.006605f, 0.004553f, 0.003145f, 0.002175f, 0.001506f,
11475 0.001045f, 0.000727f, 0.000508f, 0.000356f, 0.000251f, 0.000178f, 0.000126f,
11476 0.000090f, 0.000065f, 0.000046f, 0.000033f,
11477 0.000017f, 0.000072f, 0.000253f, 0.000769f, 0.002004f, 0.004509f, 0.008756f,
11478 0.014456f, 0.021391f, 0.029497f, 0.038676f, 0.049602f, 0.062077f, 0.074704f,
11479 0.089456f, 0.106256f, 0.128201f, 0.152761f, 0.185190f, 0.219940f, 0.253589f,
11480 0.297665f, 0.339133f, 0.395379f, 0.460777f, 0.531360f, 0.606741f, 0.685660f,
11481 0.761757f, 0.823330f, 0.875211f, 0.923810f, 0.961988f, 0.982200f, 0.991761f,
11482 0.999110f, 0.997340f, 0.982380f, 0.955552f, 0.915175f, 0.868934f, 0.825623f,
11483 0.777405f, 0.720353f, 0.658341f, 0.593878f, 0.527963f, 0.461834f, 0.398057f,
11484 0.339554f, 0.283493f, 0.228254f, 0.179828f, 0.140211f, 0.107633f, 0.081187f,
11485 0.060281f, 0.044096f, 0.031800f, 0.022602f, 0.015905f, 0.011130f, 0.007749f,
11486 0.005375f, 0.003718f, 0.002565f, 0.001768f, 0.001222f, 0.000846f, 0.000586f,
11487 0.000407f, 0.000284f, 0.000199f, 0.000140f, 0.000098f, 0.000070f, 0.000050f,
11488 0.000036f, 0.000025f, 0.000018f, 0.000013f,
11489 0.000705f, 0.002928f, 0.010482f, 0.032344f, 0.086011f, 0.197120f, 0.389366f,
11490 0.656760f, 0.972542f, 1.282500f, 1.553480f, 1.798500f, 1.967280f, 2.027300f,
11491 1.994800f, 1.900700f, 1.745370f, 1.554900f, 1.317560f, 1.030200f, 0.772125f,
11492 0.570060f, 0.415254f, 0.302356f, 0.218502f, 0.159249f, 0.112044f, 0.082248f,
11493 0.060709f, 0.043050f, 0.030451f, 0.020584f, 0.013676f, 0.007918f, 0.003988f,
11494 0.001091f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
11495 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
11496 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
11497 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
11498 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
11499 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
11500 0.000000f, 0.000000f, 0.000000f, 0.000000f, }
11501 },
11502};
11503#define NUM_KNOWN_OBSERVERS (sizeof(icKnownObservers)/sizeof(icKnownObservers[0]))
11504
11505
11507{
11508 if (!m_observer || !m_observerRange.steps) {
11509 for (int i = 0; i < NUM_KNOWN_OBSERVERS; i++) {
11510 if (m_stdObserver == icKnownObservers[i].obs) {
11511 observerRange = icKnownIllumObsRange;
11512 return &icKnownObservers[i].cmf[0];
11513 }
11514 }
11515 }
11516
11517 observerRange = m_observerRange;
11518 return m_observer;
11519}
11520
11522{
11523 m_stdObserver = observerId;
11524 m_observerRange = observerRange;
11525 if (m_observer) {
11526 free(m_observer);
11527 }
11528
11529 if (observerRange.steps && observer) {
11530 icUInt32Number size = observerRange.steps * sizeof(icFloatNumber) * 3;
11531 m_observer = (icFloatNumber *)malloc(size);
11532 if (m_observer)
11533 memcpy(m_observer, observer, size);
11534 else {
11535 memset(&m_observerRange, 0, sizeof(m_observerRange));
11536 return false;
11537 }
11538 }
11539 else {
11540 if (!observer)
11541 memset(&m_observerRange, 0, sizeof(m_illuminantRange));
11542
11543 m_observer = NULL;
11544 }
11545
11546 return true;
11547}
11548
11549
11550bool icGetTagText(const CIccTag *pTag, std::string &text)
11551{
11552 if (!pTag) {
11553 text = "";
11554 return false;
11555 }
11556 switch (pTag->GetType()) {
11557 case icSigTextType:
11558 {
11559 CIccTagText *pTextTag = (CIccTagText*)pTag;
11560 const char *szText = pTextTag->GetText();
11561 if (szText) {
11562 text = szText;
11563 return true;
11564 }
11565 }
11566 text = "";
11567 return false;
11568
11569 case icSigUtf8TextType:
11570 {
11571 CIccTagUtf8Text *pTextTag = (CIccTagUtf8Text*)pTag;
11572 const char *szText = (const char*)pTextTag->GetText();
11573 if (szText) {
11574 text = szText;
11575 return true;
11576 }
11577 }
11578 text = "";
11579 return false;
11580
11582 {
11583 CIccTagZipUtf8Text *pTextTag = (CIccTagZipUtf8Text*)pTag;
11584 bool rv = pTextTag->GetText(text);
11585 return rv;
11586 }
11587
11588 case icSigUtf16TextType:
11589 {
11590 CIccTagUtf16Text *pTextTag = (CIccTagUtf16Text*)pTag;
11591 const icChar *szText = pTextTag->GetText(text);
11592 if (szText)
11593 return true;
11594 }
11595 return false;
11596
11598 {
11600 const char *szText = pTextTag->GetText();
11601 if (szText) {
11602 text = szText;
11603 return true;
11604 }
11605 }
11606 text = "";
11607 return false;
11608
11610 {
11612 CIccLocalizedUnicode *pText = pTextTag->Find();
11613 if (pText) {
11614 bool rv = pText->GetText(text);
11615 return rv;
11616 }
11617 }
11618 text = "";
11619 return false;
11620
11621 default:
11622 text = "";
11623 return false;
11624 }
11625}
11626
11627
11628/**
11629****************************************************************************
11630* Name: CIccEmbeddedHeightImage::CIccEmbeddedHeightImage
11631*
11632* Purpose: Constructor
11633*
11634* Args:
11635* nSize =size of embedded image
11636*
11637*****************************************************************************
11638*/
11640{
11641 m_nSize = nSize;
11642 if (m_nSize <1)
11643 m_nSize = 1;
11644 m_pData = (icUInt8Number*)calloc(nSize, sizeof(icUInt8Number));
11645 m_nSeamlesIndicator = 0;
11646 m_nEncodingFormat = icPngImageType;
11647 m_fMetersMinPixelValue = 0;
11648 m_fMetersMaxPixelValue = 0;
11649}
11650
11651
11652/**
11653****************************************************************************
11654* Name: CIccTagEmbeddedHeightImage::CIccTagEmbeddedHeightImage
11655*
11656* Purpose: Copy Constructor
11657*
11658* Args:
11659* ITD = The CIccEmbeddedHeightImage object to be copied
11660*****************************************************************************
11661*/
11663{
11664 m_nSeamlesIndicator = IEHI.m_nSeamlesIndicator;
11665 m_nEncodingFormat = IEHI.m_nEncodingFormat;
11666 m_fMetersMinPixelValue = IEHI.m_fMetersMinPixelValue;
11667 m_fMetersMaxPixelValue = IEHI.m_fMetersMaxPixelValue;
11668 m_nSize = IEHI.m_nSize;
11669
11670 m_pData = (icUInt8Number*)calloc(m_nSize, sizeof(icUInt8Number));
11671 memcpy(m_pData, IEHI.m_pData, sizeof(icUInt8Number)*m_nSize);
11672}
11673
11674
11675/**
11676****************************************************************************
11677* Name: CIccTagEmbeddedHeightImage::operator=
11678*
11679* Purpose: Copy Operator
11680*
11681* Args:
11682* DataTag = The CIccTagData object to be copied
11683*****************************************************************************
11684*/
11686{
11687 if (&HeightImageTag == this)
11688 return *this;
11689
11690 m_nSeamlesIndicator = HeightImageTag.m_nSeamlesIndicator;
11691 m_nEncodingFormat = HeightImageTag.m_nEncodingFormat;
11692 m_fMetersMinPixelValue = HeightImageTag.m_fMetersMinPixelValue;
11693 m_fMetersMaxPixelValue = HeightImageTag.m_fMetersMaxPixelValue;
11694 m_nSize = HeightImageTag.m_nSize;
11695
11696 if (m_pData)
11697 free(m_pData);
11698 m_pData = (icUInt8Number*)calloc(m_nSize, sizeof(icUInt8Number));
11699 memcpy(m_pData, HeightImageTag.m_pData, sizeof(icUInt8Number)*m_nSize);
11700
11701 return *this;
11702}
11703
11704
11705/**
11706****************************************************************************
11707* Name: CIccTagEmbeddedHeightImage::~CIccTagEmbeddedHeightImage
11708*
11709* Purpose: Destructor
11710*
11711*****************************************************************************
11712*/
11714{
11715 if (m_pData)
11716 free(m_pData);
11717}
11718
11719
11720/**
11721****************************************************************************
11722* Name: CIccTagEmbeddedHeightImage::Read
11723*
11724* Purpose: Read in the tag contents into a data block
11725*
11726* Args:
11727* size - # of bytes in tag,
11728* pIO - IO object to read tag from
11729*
11730* Return:
11731* true = successful, false = failure
11732*****************************************************************************
11733*/
11735{
11737
11738 if (sizeof(icTagTypeSignature) +
11739 sizeof(icUInt32Number) +
11740 sizeof(icUInt32Number) +
11741 sizeof(icUInt32Number) +
11742 sizeof(icFloat32Number) +
11743 sizeof(icFloat32Number) +
11744 sizeof(icUInt8Number) > size)
11745 return false;
11746
11747 if (!pIO) {
11748 return false;
11749 }
11750
11751 if (!pIO->Read32(&sig))
11752 return false;
11753
11754 if (!pIO->Read32(&m_nReserved))
11755 return false;
11756
11757 if (!pIO->Read32(&m_nSeamlesIndicator))
11758 return false;
11759
11760 if (!pIO->Read32(&m_nEncodingFormat))
11761 return false;
11762
11763 if (!pIO->ReadFloat32Float(&m_fMetersMinPixelValue))
11764 return false;
11765
11766 if (!pIO->ReadFloat32Float(&m_fMetersMaxPixelValue))
11767 return false;
11768
11769 icUInt32Number nNum = size - 6 * sizeof(icUInt32Number);
11770
11771 if (!SetSize(nNum))
11772 return false;
11773
11774 if (pIO->Read8(m_pData, nNum) != (icInt32Number)nNum)
11775 return false;
11776
11777 return true;
11778}
11779
11780
11781/**
11782****************************************************************************
11783* Name: CIccTagEmbeddedHeightImage::Write
11784*
11785* Purpose: Write the tag to a file
11786*
11787* Args:
11788* pIO - The IO object to write tag to.
11789*
11790* Return:
11791* true = succesful, false = failure
11792*****************************************************************************
11793*/
11795{
11796 icTagTypeSignature sig = GetType();
11797
11798 if (!pIO)
11799 return false;
11800
11801 if (!pIO->Write32(&sig))
11802 return false;
11803
11804 if (!pIO->Write32(&m_nReserved))
11805 return false;
11806
11807 if (!pIO->Write32(&m_nSeamlesIndicator))
11808 return false;
11809
11810 if (!pIO->Write32(&m_nEncodingFormat))
11811 return false;
11812
11813 if (!pIO->WriteFloat32Float(&m_fMetersMinPixelValue))
11814 return false;
11815
11816 if (!pIO->WriteFloat32Float(&m_fMetersMaxPixelValue))
11817 return false;
11818
11819 if (pIO->Write8(m_pData, m_nSize) != (icInt32Number)m_nSize)
11820 return false;
11821
11822 return true;
11823}
11824
11825
11826/**
11827****************************************************************************
11828* Name: CIccTagEmbeddedHeightImage::Describe
11829*
11830* Purpose: Dump data associated with the tag to a string
11831*
11832* Args:
11833* sDescription - string to concatenate tag dump to
11834*****************************************************************************
11835*/
11836void CIccTagEmbeddedHeightImage::Describe(std::string &sDescription, int nVerboseness)
11837{
11838 icChar buf[128];
11839
11840 sprintf(buf, "\nSeamlessIndicater: %d\n", m_nSeamlesIndicator);
11841 sDescription += buf;
11842
11843 switch (m_nEncodingFormat) {
11844 case icPngImageType:
11845 strcpy(buf, "EncodingFormat: PNG\n");
11846 break;
11847 case icTiffImageType:
11848 strcpy(buf, "EncodingFormat: TIFF\n");
11849 break;
11850 default:
11851 sprintf(buf, "EncodingFormat: %d", m_nEncodingFormat);
11852 break;
11853 }
11854 sDescription += buf;
11855
11856 sprintf(buf, "Height minimum pixel: %.4fmeters\n", m_fMetersMinPixelValue);
11857 sprintf(buf, "Height maximum pixel: %.4fmeters\n", m_fMetersMaxPixelValue);
11858
11859 sDescription += "\nImage Data:\n";
11860
11861 for (int i = 0; i<(int)m_nSize; i++) {
11862 if (!(i & 0x1f))
11863 sDescription += "\n";
11864 sprintf(buf, "%02X", m_pData[i]);
11865 sDescription += buf;
11866 }
11867 sDescription += "\n";
11868}
11869
11870/**
11871****************************************************************************
11872* Name: CIccTagEmbeddedHeightImage::SetSize
11873*
11874* Purpose: Sets the size of the data array.
11875*
11876* Args:
11877* nSize - number of data entries,
11878* bZeroNew - flag to zero newly formed values
11879*****************************************************************************
11880*/
11881bool CIccTagEmbeddedHeightImage::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
11882{
11883 if (m_nSize == nSize)
11884 return true;
11885
11886 m_pData = (icUInt8Number*)icRealloc(m_pData, nSize * sizeof(icUInt8Number));
11887
11888 if (!m_pData) {
11889 m_nSize = 0;
11890 return false;
11891 }
11892
11893 if (bZeroNew && nSize > m_nSize) {
11894 memset(&m_pData[m_nSize], 0, (nSize - m_nSize) * sizeof(icUInt8Number));
11895 }
11896 m_nSize = nSize;
11897
11898 return true;
11899}
11900
11901
11902/**
11903******************************************************************************
11904* Name: CIccTagEmbeddedHeightImage::Validate
11905*
11906* Purpose: Check tag data validity.
11907*
11908* Args:
11909* sig = signature of tag being validated,
11910* sReport = String to add report information to
11911*
11912* Return:
11913* icValidateStatusOK if valid, or other error status.
11914******************************************************************************
11915*/
11916icValidateStatus CIccTagEmbeddedHeightImage::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
11917{
11918 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
11919
11920 CIccInfo Info;
11921 std::string sSigPathName = Info.GetSigPathName(sigPath);
11922
11923 switch (m_nSeamlesIndicator) {
11924 case 0:
11925 case 1:
11926 break;
11927 default:
11928 sReport += icMsgValidateNonCompliant;
11929 sReport += sSigPathName;
11930 sReport += " - Invalid data flag Seamless Indicator.\n";
11932 }
11933
11934 switch (m_nEncodingFormat) {
11935 case icPngImageType:
11936 case icTiffImageType:
11937 break;
11938 default:
11939 sReport += icMsgValidateNonCompliant;
11940 sReport += sSigPathName;
11941 sReport += " - Invalid data flag Encoding Image Type.\n";
11943 }
11944
11945 return rv;
11946}
11947
11948
11949
11950/**
11951****************************************************************************
11952* Name: CIccTagEmbeddedNormalImage::CIccTagEmbeddedNormalImage
11953*
11954* Purpose: Constructor
11955*
11956* Args:
11957* nSize =size of embedded image
11958*
11959*****************************************************************************
11960*/
11962{
11963 m_nSize = nSize;
11964 if (m_nSize < 1)
11965 m_nSize = 1;
11966 m_pData = (icUInt8Number*)calloc(nSize, sizeof(icUInt8Number));
11967 m_nSeamlesIndicator = 0;
11968 m_nEncodingFormat = icPngImageType;
11969}
11970
11971
11972/**
11973****************************************************************************
11974* Name: CIccTagEmbeddedNormalImage::CIccTagEmbeddedNormalImage
11975*
11976* Purpose: Copy Constructor
11977*
11978* Args:
11979* ITD = The CIccEmbeddedNormalImage object to be copied
11980*****************************************************************************
11981*/
11983{
11984 m_nSeamlesIndicator = IENI.m_nSeamlesIndicator;
11985 m_nEncodingFormat = IENI.m_nEncodingFormat;
11986 m_nSize = IENI.m_nSize;
11987
11988 m_pData = (icUInt8Number*)calloc(m_nSize, sizeof(icUInt8Number));
11989 memcpy(m_pData, IENI.m_pData, sizeof(icUInt8Number)*m_nSize);
11990}
11991
11992
11993/**
11994****************************************************************************
11995* Name: CIccTagEmbeddedNormalImage::operator=
11996*
11997* Purpose: Copy Operator
11998*
11999* Args:
12000* DataTag = The CIccTagData object to be copied
12001*****************************************************************************
12002*/
12004{
12005 if (&NormalImageTag == this)
12006 return *this;
12007
12008 m_nSeamlesIndicator = NormalImageTag.m_nSeamlesIndicator;
12009 m_nEncodingFormat = NormalImageTag.m_nEncodingFormat;
12010 m_nSize = NormalImageTag.m_nSize;
12011
12012 if (m_pData)
12013 free(m_pData);
12014 m_pData = (icUInt8Number*)calloc(m_nSize, sizeof(icUInt8Number));
12015 memcpy(m_pData, NormalImageTag.m_pData, sizeof(icUInt8Number)*m_nSize);
12016
12017 return *this;
12018}
12019
12020
12021/**
12022****************************************************************************
12023* Name: CIccTagEmbeddedNormalImage::~CIccTagEmbeddedNormalImage
12024*
12025* Purpose: Destructor
12026*
12027*****************************************************************************
12028*/
12030{
12031 if (m_pData)
12032 free(m_pData);
12033}
12034
12035
12036/**
12037****************************************************************************
12038* Name: CIccTagEmbeddedNormalImage::Read
12039*
12040* Purpose: Read in the tag contents into a data block
12041*
12042* Args:
12043* size - # of bytes in tag,
12044* pIO - IO object to read tag from
12045*
12046* Return:
12047* true = successful, false = failure
12048*****************************************************************************
12049*/
12051{
12053
12054 if (sizeof(icTagTypeSignature) +
12055 sizeof(icUInt32Number) +
12056 sizeof(icUInt32Number) +
12057 sizeof(icUInt32Number) +
12058 sizeof(icUInt8Number) > size)
12059 return false;
12060
12061 if (!pIO) {
12062 return false;
12063 }
12064
12065 if (!pIO->Read32(&sig))
12066 return false;
12067
12068 if (!pIO->Read32(&m_nReserved))
12069 return false;
12070
12071 if (!pIO->Read32(&m_nSeamlesIndicator))
12072 return false;
12073
12074 if (!pIO->Read32(&m_nEncodingFormat))
12075 return false;
12076
12077 icUInt32Number nNum = size - 4 * sizeof(icUInt32Number);
12078
12079 if (!SetSize(nNum))
12080 return false;
12081
12082 if (pIO->Read8(m_pData, nNum) != (icInt32Number)nNum)
12083 return false;
12084
12085 return true;
12086}
12087
12088
12089/**
12090****************************************************************************
12091* Name: CIccTagEmbeddedNormalImage::Write
12092*
12093* Purpose: Write the tag to a file
12094*
12095* Args:
12096* pIO - The IO object to write tag to.
12097*
12098* Return:
12099* true = succesful, false = failure
12100*****************************************************************************
12101*/
12103{
12104 icTagTypeSignature sig = GetType();
12105
12106 if (!pIO)
12107 return false;
12108
12109 if (!pIO->Write32(&sig))
12110 return false;
12111
12112 if (!pIO->Write32(&m_nReserved))
12113 return false;
12114
12115 if (!pIO->Write32(&m_nSeamlesIndicator))
12116 return false;
12117
12118 if (!pIO->Write32(&m_nEncodingFormat))
12119 return false;
12120
12121 if (pIO->Write8(m_pData, m_nSize) != (icInt32Number)m_nSize)
12122 return false;
12123
12124 return true;
12125}
12126
12127
12128/**
12129****************************************************************************
12130* Name: CIccTagEmbeddedNormalImage::Describe
12131*
12132* Purpose: Dump data associated with the tag to a string
12133*
12134* Args:
12135* sDescription - string to concatenate tag dump to
12136*****************************************************************************
12137*/
12138void CIccTagEmbeddedNormalImage::Describe(std::string &sDescription, int nVerboseness)
12139{
12140 icChar buf[128];
12141
12142 sprintf(buf, "\nSeamlessIndicater: %d\n", m_nSeamlesIndicator);
12143 sDescription += buf;
12144
12145 switch (m_nEncodingFormat) {
12146 case icPngImageType:
12147 strcpy(buf, "EncodingFormat: PNG\n");
12148 break;
12149 case icTiffImageType:
12150 strcpy(buf, "EncodingFormat: TIFF\n");
12151 break;
12152 default:
12153 sprintf(buf, "EncodingFormat: %d", m_nEncodingFormat);
12154 break;
12155 }
12156 sDescription += buf;
12157
12158 sDescription += "\nImage Data:\n";
12159
12160 for (int i = 0; i < (int)m_nSize; i++) {
12161 if (!(i & 0x1f))
12162 sDescription += "\n";
12163 sprintf(buf, "%02X", m_pData[i]);
12164 sDescription += buf;
12165 }
12166 sDescription += "\n";
12167}
12168
12169/**
12170****************************************************************************
12171* Name: CIccTagEmbeddedNormalImage::SetSize
12172*
12173* Purpose: Sets the size of the data array.
12174*
12175* Args:
12176* nSize - number of data entries,
12177* bZeroNew - flag to zero newly formed values
12178*****************************************************************************
12179*/
12180bool CIccTagEmbeddedNormalImage::SetSize(icUInt32Number nSize, bool bZeroNew/*=true*/)
12181{
12182 if (m_nSize == nSize)
12183 return true;
12184
12185 m_pData = (icUInt8Number*)icRealloc(m_pData, nSize * sizeof(icUInt8Number));
12186
12187 if (!m_pData) {
12188 m_nSize = 0;
12189 return false;
12190 }
12191
12192 if (bZeroNew && nSize > m_nSize) {
12193 memset(&m_pData[m_nSize], 0, (nSize - m_nSize) * sizeof(icUInt8Number));
12194 }
12195 m_nSize = nSize;
12196
12197 return true;
12198}
12199
12200
12201/**
12202******************************************************************************
12203* Name: CIccTagEmbeddedNormalImage::Validate
12204*
12205* Purpose: Check tag data validity.
12206*
12207* Args:
12208* sig = signature of tag being validated,
12209* sReport = String to add report information to
12210*
12211* Return:
12212* icValidateStatusOK if valid, or other error status.
12213******************************************************************************
12214*/
12215icValidateStatus CIccTagEmbeddedNormalImage::Validate(std::string sigPath, std::string &sReport, const CIccProfile* pProfile/*=NULL*/) const
12216{
12217 icValidateStatus rv = CIccTag::Validate(sigPath, sReport, pProfile);
12218
12219 CIccInfo Info;
12220 std::string sSigPathName = Info.GetSigPathName(sigPath);
12221
12222 switch (m_nSeamlesIndicator) {
12223 case 0:
12224 case 1:
12225 break;
12226 default:
12227 sReport += icMsgValidateNonCompliant;
12228 sReport += sSigPathName;
12229 sReport += " - Invalid data flag Seamless Indicator.\n";
12231 }
12232
12233 switch (m_nEncodingFormat) {
12234 case icPngImageType:
12235 if (m_nSize > 4 && m_pData) {
12236 unsigned char PNGhdr[] = { 'P', 'N', 'G' };
12237 if (memcmp(m_pData+1, PNGhdr, 3)) {
12238 sReport += icMsgValidateNonCompliant;
12239 sReport += sSigPathName;
12240 sReport += " - Non-PNG file stored as Embedded image.\n";
12242 }
12243 }
12244 break;
12245 case icTiffImageType:
12246 if (m_nSize > 4 && m_pData) {
12247 unsigned char IIhdr[] = { 'I', 'I', 42, 0 };
12248 unsigned char MMhdr[] = { 'M', 'M', 0, 42 };
12249
12250 if (memcmp(m_pData, IIhdr, 4) && memcmp(m_pData, MMhdr, 4)) {
12251 sReport += icMsgValidateNonCompliant;
12252 sReport += sSigPathName;
12253 sReport += " - Non-TIFF file stored as Embedded image.\n";
12255 }
12256 }
12257 break;
12258 default:
12259 sReport += icMsgValidateNonCompliant;
12260 sReport += sSigPathName;
12261 sReport += " - Invalid data flag Encoding Image Type.\n";
12263 }
12264
12265 return rv;
12266}
12267
12268
12269
12270#ifdef USEREFICCMAXNAMESPACE
12271} //namespace refIccMAX
12272#endif
#define __min
icArraySignature sig
icFloatNumber icD50XYZ[3]
Definition IccUtil.cpp:782
File: IccCmm.h.
icUtfConversionResult icConvertUTF8toUTF16(const UTF8 **sourceStart, const UTF8 *sourceEnd, UTF16 **targetStart, UTF16 *targetEnd, icUtfConversionFlags flags)
icUtfConversionResult icConvertUTF16toUTF8(const UTF16 **sourceStart, const UTF16 *sourceEnd, UTF8 **targetStart, UTF8 *targetEnd, icUtfConversionFlags flags)
icUtfConversionResult icConvertUTF32toUTF16(const UTF32 **sourceStart, const UTF32 *sourceEnd, UTF16 **targetStart, UTF16 *targetEnd, icUtfConversionFlags flags)
@ lenientConversion
unsigned char icUChar
Definition IccDefs.h:110
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
Definition IccDefs.h:100
char icChar
Definition IccDefs.h:109
unsigned short icUChar16
Definition IccDefs.h:111
icValidateStatus
Definition IccDefs.h:118
@ icValidateOK
Definition IccDefs.h:119
@ icValidateWarning
Definition IccDefs.h:120
@ icValidateCriticalError
Definition IccDefs.h:122
@ icValidateNonCompliant
Definition IccDefs.h:121
@ icSeekSet
Definition IccIO.h:83
#define stricmp
File: IccProfile.h.
File: IccSparseMatrix.h.
File: IccTag.h.
#define NUM_KNOWN_OBSERVERS
bool icGetTagText(const CIccTag *pTag, std::string &text)
#define BRIEF_STRING_SIZE
static icIllumDef icKnownIllums[]
static struct @4 icExampleCicpCodes[]
#define NUM_KNOWN_ILLUM
const char * code
static unsigned char icFaultyXmlZipData[4]
const char * interp
static icSpectralRange icKnownIllumObsRange
static icObserverDef icKnownObservers[]
std::list< icResponse16Number > CIccResponse16List
List Class: CIccResponse16List.
std::list< CIccResponseCurveStruct > CIccResponseCurveSet
List Class: CIccResponseCurveSet.
std::list< CIccProfileDescStruct > CIccProfileSeqDesc
List Class: CIccProfileSeqDesc.
std::list< CIccLocalizedUnicode > CIccMultiLocalizedUnicode
List Class: CIccMultiLocalizedUnicode.
File: IccTagFactory.h.
icValidateStatus icMaxStatus(icValidateStatus s1, icValidateStatus s2)
Name: icMaxStatus.
Definition IccUtil.cpp:244
std::string icGetSigPath(icUInt32Number nSig)
Definition IccUtil.cpp:1191
const char * icMsgValidateWarning
Definition IccUtil.cpp:90
icFloatNumber icU16toF(icUInt16Number num)
Definition IccUtil.cpp:759
icU16Fixed16Number icDtoUF(icFloatNumber num)
Definition IccUtil.cpp:566
void icXyzFromPcs(icFloatNumber *XYZ)
Floating point encoding of XYZ in PCS is in range 0.0 to 1.0 (Note: X=1.0 is encoded as about 0....
Definition IccUtil.cpp:934
icFloatNumber icUFtoD(icU16Fixed16Number num)
Definition IccUtil.cpp:580
icUInt32Number icGetSpaceSamples(icColorSpaceSignature sig)
Definition IccUtil.cpp:1303
void icMatrixDump(std::string &sDump, icS15Fixed16Number *pMatrix)
Definition IccUtil.cpp:988
bool icIsNear(icFloatNumber v1, icFloatNumber v2, icFloatNumber nearRange)
Name: icIsNear.
Definition IccUtil.cpp:142
void * icRealloc(void *ptr, size_t size)
Name: icRealloc.
Definition IccUtil.cpp:111
icFloatNumber icFtoD(icS15Fixed16Number num)
Definition IccUtil.cpp:559
const icChar * icGetColorSigStr(icChar *pBuf, icUInt32Number nSig)
Definition IccUtil.cpp:1139
icFloatNumber icU8toF(icUInt8Number num)
Definition IccUtil.cpp:738
void icLabFromPcs(icFloatNumber *Lab)
Floating point encoding of Lab in PCS is in range 0.0 to 1.0.
Definition IccUtil.cpp:919
icSignature icGetSecondSigPathSig(std::string sigPath)
Definition IccUtil.cpp:1238
void icColorValue(icChar *szValue, icFloatNumber nValue, icColorSpaceSignature csSig, int nIndex, bool bUseLegacy)
Definition IccUtil.cpp:330
icUInt32Number icGetMaterialColorSpaceSamples(icMaterialColorSignature sig)
Definition IccUtil.cpp:1391
void icMemDump(std::string &sDump, void *pBuf, icUInt32Number nNum)
Definition IccUtil.cpp:951
icFloatNumber icDeltaE(const icFloatNumber *lab1, const icFloatNumber *lab2)
Definition IccUtil.cpp:527
const char * icMsgValidateNonCompliant
Definition IccUtil.cpp:91
icFloatNumber icUSFtoD(icU1Fixed15Number num)
Definition IccUtil.cpp:601
void icColorIndexName(icChar *szName, icColorSpaceSignature csSig, int nIndex, int nColors, const icChar *szUnknown)
Definition IccUtil.cpp:295
const char * icMsgValidateCriticalError
Definition IccUtil.cpp:92
void icXYZtoLab(icFloatNumber *Lab, const icFloatNumber *XYZ, const icFloatNumber *WhiteXYZ)
Definition IccUtil.cpp:846
icFloatNumber icF16toF(icFloat16Number num)
Definition IccUtil.cpp:629
icSignature icGetFirstSigPathSig(std::string sigPath)
Definition IccUtil.cpp:1201
const icChar * icGetSig(icChar *pBuf, icUInt32Number nSig, bool bGetHexVal)
Definition IccUtil.cpp:1028
File: IccUtil.h.
#define icNotZero(v)
Definition IccUtil.h:89
icTagTypeSignature
@ icSigUInt16ArrayType
unsigned int icUInt32Number
Type: Class.
Definition IccIO.h:97
icInt32Number ReadFloat16Float(void *pBufFloat, icInt32Number nNum=1)
Definition IccIO.cpp:269
icInt32Number ReadFloat32Float(void *pBufFloat, icInt32Number nNum=1)
Definition IccIO.cpp:302
virtual icInt32Number Write8(void *pBuf8, icInt32Number nNum=1)
Definition IccIO.h:105
virtual icInt32Number GetLength()
Definition IccIO.h:130
icInt32Number Write16(void *pBuf16, icInt32Number nNum=1)
Definition IccIO.cpp:122
virtual icInt32Number Read8(void *pBuf8, icInt32Number nNum=1)
Definition IccIO.h:104
icInt32Number Read16(void *pBuf16, icInt32Number nNum=1)
Definition IccIO.cpp:114
icInt32Number WriteFloat16Float(void *pBuf16, icInt32Number nNum=1)
Definition IccIO.cpp:285
virtual icInt32Number Tell()
Definition IccIO.h:133
bool Align32()
Write operation to make sure that filelength is evenly divisible by 4.
Definition IccIO.cpp:341
icInt32Number ReadUInt8Float(void *pBufFloat, icInt32Number nNum=1)
Definition IccIO.cpp:203
icInt32Number Write32(void *pBuf32, icInt32Number nNum=1)
Definition IccIO.cpp:152
virtual icInt32Number Seek(icInt32Number nOffset, icSeekVal pos)
Definition IccIO.h:132
icInt32Number Write64(void *pBuf64, icInt32Number nNum=1)
Definition IccIO.cpp:182
icInt32Number WriteFloat32Float(void *pBufFloat, icInt32Number nNum=1)
Definition IccIO.cpp:321
icInt32Number WriteUInt8Float(void *pBuf16, icInt32Number nNum=1)
Definition IccIO.cpp:219
icInt32Number ReadUInt16Float(void *pBufFloat, icInt32Number nNum=1)
Definition IccIO.cpp:236
icInt32Number Read64(void *pBuf64, icInt32Number nNum=1)
Definition IccIO.cpp:173
icInt32Number Read32(void *pBuf32, icInt32Number nNum=1)
Definition IccIO.cpp:143
bool Sync32(icUInt32Number nOffset=0)
Operation to make sure read position is evenly divisible by 4.
Definition IccIO.cpp:357
icInt32Number WriteUInt16Float(void *pBuf16, icInt32Number nNum=1)
Definition IccIO.cpp:252
Type: Class.
Definition IccUtil.h:303
const icChar * GetColorantEncoding(icColorantEncoding colorant)
Definition IccUtil.cpp:2317
const icChar * GetIlluminantName(icIlluminant val)
Definition IccUtil.cpp:2169
const icChar * GetMeasurementUnit(icSignature sig)
Definition IccUtil.cpp:2247
const icChar * GetMeasurementGeometryName(icMeasurementGeometry val)
Definition IccUtil.cpp:2076
const icChar * GetMeasurementFlareName(icMeasurementFlare val)
Definition IccUtil.cpp:2055
const icChar * GetSigName(icUInt32Number val)
Definition IccUtil.cpp:2000
icValidateStatus CheckLuminance(std::string &sReport, const icFloatXYZNumber &XYZ, std::string sDesc="")
Definition IccUtil.cpp:2516
const icChar * GetStandardObserverName(icStandardObserver val)
Definition IccUtil.cpp:2151
std::string GetSigPathName(std::string sigPath)
Definition IccUtil.cpp:1614
icValidateStatus CheckData(std::string &sReport, const icDateTimeNumber &dateTime, std::string sDesc="")
Definition IccUtil.cpp:2414
Data Class: CIccLocalizedUnicode.
CIccLocalizedUnicode & operator=(const CIccLocalizedUnicode &UnicodeText)
Name: CIccLocalizedUnicode::operator=.
icLanguageCode m_nLanguageCode
icUInt16Number * GetBuf() const
bool SetText(const icChar *szText, icLanguageCode nLanguageCode=icLanguageCodeEnglish, icCountryCode nRegionCode=icCountryCodeUSA)
Name: CIccLocalizedUnicode::SetText.
virtual ~CIccLocalizedUnicode()
Name: CIccLocalizedUnicode::~CIccLocalizedUnicode.
icUInt32Number GetLength() const
icUInt32Number GetUtf8Size()
Name: CIccLocalizedUnicode::GetUtf8Size.
const icChar * GetUtf8(icChar *szBuf, icUInt32Number nBufSize)
Name: CIccLocalizedUnicode::GetUtf8.
bool SetSize(icUInt32Number)
Name: CIccLocalizedUnicode::SetSize.
icCountryCode m_nCountryCode
bool GetText(std::string &text)
Name: CIccLocalizedUnicode::GetText.
CIccLocalizedUnicode()
Name: CIccLocalizedUnicode::CIccLocalizedUnicode.
Type: Class.
icFloatNumber * entry(icUInt16Number nRow, icUInt16Number nCol=0)
static CIccMatrixMath * rangeMap(const icSpectralRange &from, const icSpectralRange &to)
Name: CIccMatrixMath::rangeMap.
virtual void VectorMult(icFloatNumber *pDst, const icFloatNumber *pSrc) const
Name: CIccMatrixMath::VectorMult.
Data Class: CIccProfileDescStruct.
CIccProfileDescText m_deviceMfgDesc
CIccProfileDescStruct()
Name: CIccProfileDescStruct::CIccProfileDescStruct.
icSignature m_deviceModel
icTechnologySignature m_technology
CIccProfileDescText m_deviceModelDesc
CIccProfileDescStruct & operator=(const CIccProfileDescStruct &ProfDescStruct)
Name: CIccProfileDescStruct::operator=.
icUInt64Number m_attributes
Data Class: CIccProfileDescText.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccProfileDescText::Describe.
CIccProfileDescText()
Name: CIccProfileDescText::CIccProfileDescText.
virtual icTagTypeSignature GetType() const
Name: CIccProfileDescText::SetType.
CIccProfileDescText & operator=(const CIccProfileDescText &ProfDescText)
Name: CIccProfileDescText::operator=.
bool SetType(icTagTypeSignature nType)
Name: CIccProfileDescText::SetType.
virtual bool Write(CIccIO *pIO)
Name: CIccProfileDescText::Write.
virtual ~CIccProfileDescText()
Name: CIccProfileDescText::~CIccProfileDescText.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccProfileDescText::Read.
Data Class: CIccResponseCurveStruct.
CIccResponseCurveStruct(icMeasurementUnitSig sig, icUInt16Number nChannels=0)
Name: CIccResponseCurveStruct::CIccResponseCurveStruct.
bool Write(CIccIO *pIO)
Name: CIccResponseCurveStruct::Write.
void Describe(std::string &sDescription, int nVerboseness)
Name: CIccResponseCurveStruct::Describe.
icUInt16Number m_nChannels
icXYZNumber * m_maxColorantXYZ
virtual ~CIccResponseCurveStruct()
Name: CIccResponseCurveStruct::~CIccResponseCurveStruct.
bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccResponseCurveStruct::Read.
CIccResponseCurveStruct & operator=(const CIccResponseCurveStruct &RespCurveStruct)
Name: CIccResponseCurveStruct::operator=.
CIccResponse16List * m_Response16ListArray
icValidateStatus Validate(std::string &sReport)
Name: CIccResponseCurveStruct::Validate.
icMeasurementUnitSig m_measurementUnitSig
CIccResponseCurveStruct * GetThis()
bool Union(const CIccSparseMatrix &mtx1, const CIccSparseMatrix &mtx2)
icUInt16Number * GetColumnsForRow(icUInt16Number nRow=0) const
static icUInt32Number MaxEntries(icUInt32Number nMemSize, icUInt16Number nRows, icUInt8Number nTypeSize)
bool Interp(icFloatNumber d1, const CIccSparseMatrix &mtx1, icFloatNumber d2, const CIccSparseMatrix &mtx2)
IIccSparseMatrixEntry * GetData() const
icUInt16Number Cols() const
icUInt16Number Rows() const
void Reset(void *pMatrix, icUInt32Number nSize, icSparseMatrixType nType, bool bInitFromData=true)
icUInt16Number * GetRowStart() const
icUInt16Number GetNumEntries() const
bool Init(icUInt16Number nRows, icUInt16Number nCols, bool bSetData=false)
Class: CIccTagChromaticity.
icUInt16Number m_nChannels
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagChromaticity::Validate.
virtual ~CIccTagChromaticity()
Name: CIccTagChromaticity::~CIccTagChromaticity.
virtual bool Write(CIccIO *pIO)
Name: CIccTagChromaticity::Write.
bool SetSize(icUInt16Number nSize, bool bZeroNew=true)
Name: CIccTagChromaticity::SetSize.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagChromaticity::Read.
CIccTagChromaticity(int nSize=3)
Name: CIccTagChromaticity::CIccTagChromaticity.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagChromaticity::Describe.
CIccTagChromaticity & operator=(const CIccTagChromaticity &ChromTag)
Name: CIccTagChromaticity::operator=.
icChromaticityNumber * m_xy
Class: CIccTagCicp.
CIccTagCicp()
Name: CIccTagCicp::CIccTagCicp.
icUInt8Number m_nVideoFullRangeFlag
virtual bool Write(CIccIO *pIO)
Name: CIccTagCicp::Write.
void GetFields(icUInt8Number &colorPrimaries, icUInt8Number &transferCharacteristics, icUInt8Number &matrixCoefficients, icUInt8Number &videoFullRangeFlag)
Name: CIccTagCicp::GetFields.
virtual ~CIccTagCicp()
Name: CIccTagCicp::~CIccTagCicp.
icUInt8Number m_nMatrixCoefficients
CIccTagCicp & operator=(const CIccTagCicp &XYZTag)
Name: CIccTagCicp::operator=.
icUInt8Number m_nColorPrimaries
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagCicp::Read.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagCicp::Validate.
icUInt8Number m_nTransferCharacteristics
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagCicp::Describe.
void SetFields(icUInt8Number colorPrimaries, icUInt8Number transferCharacteristics, icUInt8Number matrixCoefficients, icUInt8Number videoFullRangeFlag)
Name: CIccTagCicp::SetFields.
Class: CIccTagColorantOrder.
CIccTagColorantOrder(int nsize=1)
Name: CIccTagColorantOrder::CIccTagColorantOrder.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagColorantOrder::Validate.
CIccTagColorantOrder & operator=(const CIccTagColorantOrder &ColorantOrderTag)
Name: CIccTagColorantOrder::operator=.
virtual bool Write(CIccIO *pIO)
Name: CIccTagColorantOrder::Write.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagColorantOrder::Read.
virtual ~CIccTagColorantOrder()
Name: CIccTagColorantOrder::~CIccTagColorantOrder.
icUInt32Number m_nCount
bool SetSize(icUInt16Number nsize, bool bZeronew=true)
Name: CIccTagColorantOrder::SetSize.
icUInt8Number * m_pData
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagColorantOrder::Describe.
Class: CIccTagColorantTable.
virtual ~CIccTagColorantTable()
Name: CIccTagColorantTable::~CIccTagColorantTable.
virtual bool Write(CIccIO *pIO)
Name: CIccTagColorantTable::Write.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagColorantTable::Describe.
bool SetSize(icUInt16Number nSize, bool bZeroNew=true)
Name: CIccTagColorantTable::SetSize.
icColorantTableEntry * m_pData
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagColorantTable::Validate.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagColorantTable::Read.
icUInt32Number m_nCount
CIccTagColorantTable & operator=(const CIccTagColorantTable &ColorantTableTag)
Name: CIccTagColorantTable::operator=.
CIccTagColorantTable(int nsize=1)
Name: CIccTagColorantTable::CIccTagColorantTable.
icColorSpaceSignature m_PCS
static CIccTag * CreateTag(icTagTypeSignature tagTypeSig)
Function: CreateTag(tagTypeSig) Create a tag of type tagTypeSig.
static const icChar * GetTagTypeSigName(icTagTypeSignature tagTypeSig)
Function: GetTagTypeSigName(tagTypeSig) Get display name of tagTypeSig.
Class: CIccTagData.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagData::Validate.
virtual ~CIccTagData()
Name: CIccTagData::~CIccTagData.
bool SetSize(icUInt32Number nSize, bool bZeroNew=true)
Name: CIccTagData::SetSize.
CIccTagData(int nSize=1)
Name: CIccTagData::CIccTagData.
virtual bool Write(CIccIO *pIO)
Name: CIccTagData::Write.
icUInt32Number m_nSize
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagData::Describe.
icDataBlockType m_nDataFlag
icUInt8Number * m_pData
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagData::Read.
CIccTagData & operator=(const CIccTagData &DataTag)
Name: CIccTagData::operator=.
Class: CIccTagDateTime.
CIccTagDateTime()
Name: CIccTagDateTime::CIccTagDateTime.
virtual bool Write(CIccIO *pIO)
Name: CIccTagDateTime::Write.
virtual ~CIccTagDateTime()
Name: CIccTagDateTime::~CIccTagDateTime.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagDateTime::Validate.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagDateTime::Read.
CIccTagDateTime & operator=(const CIccTagDateTime &DateTimeTag)
Name: CIccTagDateTime::operator=.
icDateTimeNumber m_DateTime
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagDateTime::Describe.
Class: CIccTagEmbeddedHeightImage.
icUInt32Number m_nSeamlesIndicator
virtual bool Write(CIccIO *pIO)
Name: CIccTagEmbeddedHeightImage::Write.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagEmbeddedHeightImage::Describe.
icFloatNumber m_fMetersMaxPixelValue
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagEmbeddedHeightImage::Read.
icImageEncodingType m_nEncodingFormat
virtual ~CIccTagEmbeddedHeightImage()
Name: CIccTagEmbeddedHeightImage::~CIccTagEmbeddedHeightImage.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagEmbeddedHeightImage::Validate.
bool SetSize(icUInt32Number nSize, bool bZeroNew=true)
Name: CIccTagEmbeddedHeightImage::SetSize.
CIccTagEmbeddedHeightImage(int nSize=1)
Name: CIccEmbeddedHeightImage::CIccEmbeddedHeightImage.
CIccTagEmbeddedHeightImage & operator=(const CIccTagEmbeddedHeightImage &HeightTag)
Name: CIccTagEmbeddedHeightImage::operator=.
icFloatNumber m_fMetersMinPixelValue
Class: CIccTagEmbeddedNormalImage.
icImageEncodingType m_nEncodingFormat
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagEmbeddedNormalImage::Read.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagEmbeddedNormalImage::Describe.
CIccTagEmbeddedNormalImage & operator=(const CIccTagEmbeddedNormalImage &NormalTag)
Name: CIccTagEmbeddedNormalImage::operator=.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagEmbeddedNormalImage::Validate.
CIccTagEmbeddedNormalImage(int nSize=1)
Name: CIccTagEmbeddedNormalImage::CIccTagEmbeddedNormalImage.
icUInt32Number m_nSeamlesIndicator
bool SetSize(icUInt32Number nSize, bool bZeroNew=true)
Name: CIccTagEmbeddedNormalImage::SetSize.
virtual ~CIccTagEmbeddedNormalImage()
Name: CIccTagEmbeddedNormalImage::~CIccTagEmbeddedNormalImage.
virtual bool Write(CIccIO *pIO)
Name: CIccTagEmbeddedNormalImage::Write.
Class: CIccTagFixedNum.
virtual bool Interpolate(icFloatNumber *DstVector, icFloatNumber val, icUInt32Number nVectorSize=1, icFloatNumber *zeroVals=NULL) const
Name: CIccTagFixedNum::Interpolate.
CIccTagFixedNum & operator=(const CIccTagFixedNum< T, Tsig > &FixedNumTag)
Name: CIccTagFixedNum::operator=.
virtual bool Write(CIccIO *pIO)
Name: CIccTagFixedNum::Write.
bool SetSize(icUInt32Number nSize, bool bZeroNew=true)
Name: CIccTagFixedNum::SetSize.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagFixedNum::Describe.
virtual const icChar * GetClassName() const
Name: CIccTagFixedNum::GetClassName.
virtual bool ValuePos(icFloatNumber &DstPos, icFloatNumber val, bool &bNoZero) const
Name: CIccTagFixedNum::ValuePos.
virtual ~CIccTagFixedNum()
Name: CIccTagFixedNum::~CIccTagFixedNum.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagFixedNum::Read.
virtual bool GetValues(icFloatNumber *DstVector, icUInt32Number nStart=0, icUInt32Number nVectorSize=1) const
Name: CIccTagFixedNum::GetValues.
CIccTagFixedNum(int nSize=1)
Name: CIccTagFixedNum::CIccTagFixedNum.
icUInt32Number m_nSize
Class: CIccTagFloatNum.
virtual bool GetValues(icFloatNumber *DstVector, icUInt32Number nStart=0, icUInt32Number nVectorSize=1) const
Name: CIccTagFloatNum::GetValues.
virtual bool ValuePos(icFloatNumber &DstPos, icFloatNumber val, bool &bNoZero) const
Name: CIccTagFloatNum::ValuePos.
virtual bool Write(CIccIO *pIO)
Name: CIccTagFloatNum::Write.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagFloatNum::Interpolate.
virtual bool Interpolate(icFloatNumber *DstVector, icFloatNumber val, icUInt32Number nVectorSize=1, icFloatNumber *zeroVals=NULL) const
Name: CIccTagFloatNum::Interpolate.
virtual const icChar * GetClassName() const
Name: CIccTagFloatNum::GetClassName.
CIccTagFloatNum(int nSize=1)
Name: CIccTagFloatNum::CIccTagFloatNum.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagFloatNum::Describe.
icUInt32Number m_nSize
virtual ~CIccTagFloatNum()
Name: CIccTagFloatNum::~CIccTagFloatNum.
CIccTagFloatNum & operator=(const CIccTagFloatNum< T, Tsig > &NumTag)
Name: CIccTagFloatNum::operator=.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagFloatNum::Read.
bool SetSize(icUInt32Number nSize, bool bZeroNew=true)
Name: CIccTagFloatNum::SetSize.
Class: CIccTag.
virtual icTagTypeSignature GetType() const
Function: GetType()
static CIccTag * Create(icTagTypeSignature sig)
Name: CIccTag::Create.
virtual ~CIccTag()
Name: CIccTag::CIccTag.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Function: Validate Each derived tag will implement it's own IsValid() function.
CIccTag()
Name: CIccTag::CIccTag.
virtual CIccTag * NewCopy() const
Function: NewCopy(sDescription) Each derived tag will implement it's own NewCopy() function.
Class: CIccTagMeasurement.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagMeasurement::Validate.
CIccTagMeasurement()
Name: CIccTagMeasurement::CIccTagMeasurement.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagMeasurement::Describe.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagMeasurement::Read.
icMeasurement m_Data
virtual bool Write(CIccIO *pIO)
Name: CIccTagMeasurement::Write.
CIccTagMeasurement & operator=(const CIccTagMeasurement &MeasTag)
Name: CIccTagMeasurement::operator=.
virtual ~CIccTagMeasurement()
Name: CIccTagMeasurement::~CIccTagMeasurement.
Class: CIccTagMultiLocalizedUnicode.
void SetText(const icChar *szText, icLanguageCode nLanguageCode=icLanguageCodeEnglish, icCountryCode nRegionCode=icCountryCodeUSA)
Name: refIccMAX::CIccTagMultiLocalizedUnicode::SetText.
CIccTagMultiLocalizedUnicode()
Name: CIccTagMultiLocalizedUnicode::CIccTagMultiLocalizedUnicode.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagMultiLocalizedUnicode::Validate.
CIccTagMultiLocalizedUnicode & operator=(const CIccTagMultiLocalizedUnicode &MultiLocalizedTag)
Name: CIccTagMultiLocalizedUnicode::operator=.
virtual ~CIccTagMultiLocalizedUnicode()
Name: CIccTagMultiLocalizedUnicode::~CIccTagMultiLocalizedUnicode.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagMultiLocalizedUnicode::Describe.
CIccLocalizedUnicode * Find(icLanguageCode nLanguageCode=icLanguageCodeEnglish, icCountryCode nRegionCode=icCountryCodeUSA)
Name: refIccMAX::CIccTagMultiLocalizedUnicode::Find.
CIccMultiLocalizedUnicode * m_Strings
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagMultiLocalizedUnicode::Read.
virtual bool Write(CIccIO *pIO)
Name: CIccTagMultiLocalizedUnicode::Write.
Class: CIccTagNamedColor2.
bool InitFindCachedPCSColor()
Name: CIccTagNamedColor2::InitFindPCSColor.
icInt32Number FindDeviceColor(icFloatNumber *pDevColor) const
Name: CIccTagNamedColor2::FindDeviceColor.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagNamedColor2::Describe.
SIccNamedColorEntry * m_NamedColor
virtual ~CIccTagNamedColor2()
Name: CIccTagNamedColor2::~CIccTagNamedColor2.
bool GetColorName(std::string &sColorName, icInt32Number index) const
Name: CIccTagNamedColor2::GetColorName.
icInt32Number FindColor(const icChar *szColor) const
Name: CIccTagNamedColor2::FindColor.
icColorSpaceSignature m_csPCS
icFloatNumber NegClip(icFloatNumber v) const
Name: CIccTagNamedColor2::NegClip.
virtual void SetColorSpaces(icColorSpaceSignature csPCS, icColorSpaceSignature csDevice)
Name: CIccTagNamedColor2::SetColorSpaces.
icUInt32Number m_nVendorFlags
icUInt32Number m_nSize
void Lab4ToLab2(icFloatNumber *Dst, const icFloatNumber *Src) const
Name: CIccTagNamedColor2::Lab4ToLab2.
CIccTagNamedColor2 & operator=(const CIccTagNamedColor2 &NamedColor2Tag)
Name: CIccTagNamedColor2::operator=.
virtual bool Write(CIccIO *pIO)
Name: CIccTagNamedColor2::Write.
icChar m_szSufix[32]
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagNamedColor2::Read.
void Lab2ToLab4(icFloatNumber *Dst, const icFloatNumber *Src) const
Name: CIccTagNamedColor2::Lab2ToLab4.
icInt32Number FindPCSColor(icFloatNumber *pPCS, icFloatNumber dMinDE=1000.0)
Name: CIccTagNamedColor2::FindPCSColor.
CIccTagNamedColor2(int nSize=1, int nDeviceCoords=0)
Name: CIccTagNamedColor2::CIccTagNamedColor2.
icUInt32Number m_nColorEntrySize
For quick response of repeated FindPCSColor.
bool SetSize(icUInt32Number nSize, icInt32Number nDeviceCoords=-1)
Name: CIccTagNamedColor2::SetSize.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagNamedColor2::Validate.
void SetPrefix(const icChar *szPrefix)
Name: CIccTagNamedColor2::SetPrefix.
icInt32Number FindCachedPCSColor(icFloatNumber *pPCS, icFloatNumber dMinDE=1000.0) const
Name: CIccTagNamedColor2::FindPCSColor.
icUInt32Number m_nDeviceCoords
icInt32Number FindRootColor(const icChar *szRootColor) const
Name: CIccTagNamedColor2::FindRootColor.
void ResetPCSCache()
Call ResetPCSCache() if entry values change between calls to FindPCSColor()
void SetSufix(const icChar *szSufix)
Name: CIccTagNamedColor2::SetSufix.
icChar m_szPrefix[32]
icFloatNumber UnitClip(icFloatNumber v) const
Name: CIccTagNamedColor2::UnitClip.
icColorSpaceSignature m_csDevice
Class: CIccTagNum.
CIccTagNum & operator=(const CIccTagNum< T, Tsig > &NumTag)
Name: CIccTagNum::operator=.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagNum::Read.
icUInt32Number m_nSize
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagNum::Describe.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Function: Validate Each derived tag will implement it's own IsValid() function.
virtual bool GetValues(icFloatNumber *DstVector, icUInt32Number nStart=0, icUInt32Number nVectorSize=1) const
Name: CIccTagNum::GetValues.
bool SetSize(icUInt32Number nSize, bool bZeroNew=true)
Name: CIccTagNum::SetSize.
virtual bool Write(CIccIO *pIO)
Name: CIccTagNum::Write.
virtual ~CIccTagNum()
Name: CIccTagNum::~CIccTagNum.
virtual bool Interpolate(icFloatNumber *DstVector, icFloatNumber val, icUInt32Number nVectorSize=1, icFloatNumber *zeroVals=NULL) const
Name: CIccTagNum::Interpolate.
CIccTagNum(int nSize=1)
Name: CIccTagNum::CIccTagNum.
virtual bool ValuePos(icFloatNumber &DstPos, icFloatNumber val, bool &bNoZero) const
Name: CIccTagNum::ValuePos.
virtual const icChar * GetClassName() const
Name: CIccTagNum::GetClassName.
Class: CIccTagProfileSeqDesc.
CIccTagProfileSeqDesc & operator=(const CIccTagProfileSeqDesc &ProfSeqDescTag)
Name: CIccTagProfileSeqDesc::operator=.
virtual ~CIccTagProfileSeqDesc()
Name: CIccTagProfileSeqDesc::~CIccTagProfileSeqDesc.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagProfileSeqDesc::Validate.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagProfileSeqDesc::Describe.
virtual bool Write(CIccIO *pIO)
Name: CIccTagProfileSeqDesc::Write.
CIccTagProfileSeqDesc()
Name: CIccTagProfileSeqDesc::CIccTagProfileSeqDesc.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagProfileSeqDesc::Read.
CIccProfileSeqDesc * m_Descriptions
Class: CIccTagResponseCurveSet16.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagResponseCurveSet16::Validate.
void SetNumChannels(icUInt16Number nChannels)
Name: CIccTagResponseCurveSet16::SetNumChannels.
CIccTagResponseCurveSet16 & operator=(const CIccTagResponseCurveSet16 &RespCurveSet16Tag)
Name: CIccTagResponseCurveSet16::operator=.
virtual ~CIccTagResponseCurveSet16()
Name: CIccTagResponseCurveSet16::~CIccTagResponseCurveSet16.
CIccResponseCurveSet * m_ResponseCurves
CIccResponseCurveSetIter * m_Curve
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagResponseCurveSet16::Read.
CIccResponseCurveStruct * GetFirstCurves()
Name: CIccTagResponseCurveSet16::GetFirstCurves.
CIccResponseCurveStruct * GetNextCurves()
Name: CIccTagResponseCurveSet16::GetNextCurves.
CIccTagResponseCurveSet16()
Name: CIccTagResponseCurveSet16::CIccTagResponseCurveSet16.
icUInt16Number GetNumResponseCurveTypes() const
Name: CIccTagResponseCurveSet16::GetNumResponseCurveTypes.
CIccResponseCurveStruct * GetResponseCurves(icMeasurementUnitSig sig)
Name: CIccTagResponseCurveSet16::GetResponseCurves.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagResponseCurveSet16::Describe.
virtual bool Write(CIccIO *pIO)
Name: CIccTagResponseCurveSet16::Write.
CIccResponseCurveStruct * NewResponseCurves(icMeasurementUnitSig sig)
Name: CIccTagResponseCurveSet16::NewResponseCurves.
Class: CIccTagSignature.
CIccTagSignature()
Name: CIccTagSignature::CIccTagSignature.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagSignature::Describe.
virtual bool Write(CIccIO *pIO)
Name: CIccTagSignature::Write.
virtual ~CIccTagSignature()
Name: CIccTagSignature::~CIccTagSignature.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagSignature::Validate.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagSignature::Read.
CIccTagSignature & operator=(const CIccTagSignature &SignatureTag)
Name: CIccTagSignature::operator=.
icUInt32Number m_nSig
Class: CIccTagSparseMatrixArray.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagSparseMatrixArray::Validate.
bool GetSparseMatrix(CIccSparseMatrix &mtx, int nIndex, bool bInitFromData=true)
Name: CIccTagSparseMatrixArray::GetValues.
virtual ~CIccTagSparseMatrixArray()
Name: CIccTagSparseMatrixArray::~CIccTagSparseMatrixArray.
icUInt8Number * m_RawData
bool Reset(icUInt32Number nNumMatrices, icUInt16Number nChannelsPerMatrix)
Name: CIccTagSparseMatrixArray::Reset.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagSparseMatrixArray::Read.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagSparseMatrixArray::Describe.
CIccTagSparseMatrixArray & operator=(const CIccTagSparseMatrixArray &ITSMA)
Name: CIccTagSparseMatrixArray::operator=.
virtual bool ValuePos(icFloatNumber &DstPos, icFloatNumber val, bool &bNoZero) const
Name: CIccTagSparseMatrixArray::ValuePos.
virtual bool GetValues(icFloatNumber *DstVector, icUInt32Number nStart=0, icUInt32Number nVectorSize=1) const
CIccTagSparseMatrixArray(int nNumMatrices=1, int nChannelsPerMatrix=4)
Name: CIccTagSparseMatrixArray::CIccTagSparseMatrixArray.
icUInt16Number m_nChannelsPerMatrix
virtual bool Write(CIccIO *pIO)
Name: CIccTagSparseMatrixArray::Write.
icSparseMatrixType m_nMatrixType
virtual bool Interpolate(icFloatNumber *DstVector, icFloatNumber val, icUInt32Number nVectorSize=1, icFloatNumber *zeroVals=NULL) const
Name: CIccTagSparseMatrixArray::Interpolate.
Class: CIccTagSpectralDataInfo.
CIccTagSpectralDataInfo()
Name: CIccTagSpectralDataInfo::CIccTagSpectralDataInfo.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagSpectralDataInfo::Validate.
virtual ~CIccTagSpectralDataInfo()
Name: CIccTagSpectralDataInfo::~CIccTagSpectralDataInfo.
icSpectralRange m_biSpectralRange
icSpectralRange m_spectralRange
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagSpectralDataInfo::Describe.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagSpectralDataInfo::Read.
virtual bool Write(CIccIO *pIO)
Name: CIccTagSpectralDataInfo::Write.
CIccTagSpectralDataInfo & operator=(const CIccTagSpectralDataInfo &RespCurveSet16Tag)
Name: CIccTagSpectralDataInfo::operator=.
Class: CIccTagSpectralViewingConditions.
CIccMatrixMath * getObserverMatrix(const icSpectralRange &newRange) const
virtual ~CIccTagSpectralViewingConditions()
Name: CIccTagSpectralViewingConditions::~CIccTagResponseCurveSet16.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagSpectralViewingConditions::Validate.
const icFloatNumber * getObserver(icSpectralRange &observerRange) const
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagSpectralViewingConditions::Read.
CIccTagSpectralViewingConditions & operator=(const CIccTagSpectralViewingConditions &RespCurveSet16Tag)
Name: CIccTagSpectralViewingConditions::operator=.
CIccTagSpectralViewingConditions()
Name: CIccTagSpectralViewingConditions::CIccTagSpectralViewingConditions.
bool setObserver(icStandardObserver observerId, const icSpectralRange &observerRange, const icFloatNumber *observer)
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagSpectralViewingConditions::Describe.
const icFloatNumber * getIlluminant(icSpectralRange &illumRange) const
icFloatNumber * applyRangeToObserver(const icSpectralRange &newRange) const
virtual bool Write(CIccIO *pIO)
Name: CIccTagSpectralViewingConditions::Write.
bool setIlluminant(icIlluminant illumId, const icSpectralRange &illumRange, const icFloatNumber *illum, icFloatNumber illumCCT=0.0f)
Class: CIccTagTextDescription()
icUInt32Number m_nUnicodeLanguageCode
icUInt16Number m_nScriptCode
icUInt16Number * m_uzUnicodeText
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagTextDescription::Read.
const icChar * GetText() const
void ReleaseUnicode()
Name: CIccTagTextDescription::ReleaseUnicode.
CIccTagTextDescription()
Name: CIccTagTextDescription::CIccTagTextDescription.
void SetText(const icChar *szText)
Name: CIccTagTextDescription::SetText.
icChar * GetBuffer(icUInt32Number nSize)
Name: CIccTagTextDescription::GetBuffer.
icUInt8Number m_szScriptText[67]
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagTextDescription::Describe.
icUInt32Number m_nUnicodeSize
virtual bool Write(CIccIO *pIO)
Name: CIccTagTextDescription::Write.
virtual ~CIccTagTextDescription()
Name: CIccTagTextDescription::~CIccTagTextDescription.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagTextDescription::Validate.
icUInt16Number * GetUnicodeBuffer(icUInt32Number nSize)
Name: CIccTagTextDescription::GetUnicodeBuffer.
void Release()
Name: CIccTagTextDescription::Release.
icUInt32Number m_nASCIISize
CIccTagTextDescription & operator=(const CIccTagTextDescription &TextDescTag)
Name: CIccTagTextDescription::operator=.
icUInt8Number m_nScriptSize
Class: CIccTagText()
const icChar * GetText() const
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagText::Validate.
virtual bool Write(CIccIO *pIO)
Name: CIccTagText::Write.
void SetText(const icChar *szText)
Name: CIccTagText::SetText.
virtual ~CIccTagText()
Name: CIccTagText::~CIccTagText.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagText::Describe.
CIccTagText()
Name: CIccTagText::CIccTagText.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagText::Read.
icChar * m_szText
CIccTagText & operator=(const CIccTagText &TextTag)
Name: CIccTagText::operator=.
icChar * GetBuffer(icUInt32Number nSize)
Name: CIccTagText::GetBuffer.
void Release()
Name: CIccTagText::Release.
Class: IccTagUnknown.
virtual bool Write(CIccIO *pIO)
Name: CIccTagUnknown::Write.
CIccTagUnknown()
Name: CIccTagUnknown::CIccTagUnknown.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagUnknown::Read.
CIccTagUnknown & operator=(const CIccTagUnknown &UnknownTag)
Name: CIccTagUnknown::operator=.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagUnknown::Describe.
icTagTypeSignature m_nType
icUInt32Number m_nSize
icUInt8Number * m_pData
virtual ~CIccTagUnknown()
Name: CIccTagUnknown::~CIccTagUnknown.
Class: CIccTagUtf16Text()
CIccTagUtf16Text()
Name: CIccTagUtf16Text::CIccTagUtf16Text.
virtual ~CIccTagUtf16Text()
Name: CIccTagUtf16Text::~CIccTagUtf16Text.
icUChar16 * GetBuffer(icUInt32Number nSize)
Name: CIccTagUtf16Text::GetBuffer.
const icUChar16 * GetText() const
virtual bool Write(CIccIO *pIO)
Name: CIccTagUtf16Text::Write.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagUtf16Text::Read.
void Release()
Name: CIccTagUtf16Text::Release.
icUInt32Number GetLength() const
Name: CIccTagUtf16Text::GetLength.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagUtf16Text::Validate.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagUtf16Text::Describe.
void SetText(const icUChar16 *szText)
Name: CIccTagUtf16Text::SetText.
icUChar16 * m_szText
CIccTagUtf16Text & operator=(const CIccTagUtf16Text &TextTag)
Name: CIccTagUtf16Text::operator=.
const icChar * GetText(std::string &bufStr) const
Name: CIccTagUtf16Text::GetText.
Class: CIccTagUtf8Text()
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagUtf8Text::Describe.
virtual ~CIccTagUtf8Text()
Name: CIccTagUtf8Text::~CIccTagUtf8Text.
virtual bool Write(CIccIO *pIO)
Name: CIccTagUtf8Text::Write.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagUtf8Text::Read.
CIccTagUtf8Text & operator=(const CIccTagUtf8Text &TextTag)
Name: CIccTagUtf8Text::operator=.
CIccTagUtf8Text()
Name: CIccTagUtf8Text::CIccTagUtf8Text.
const icUChar * GetText() const
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagUtf8Text::Validate.
void Release()
Name: CIccTagUtf8Text::Release.
icUChar * GetBuffer(icUInt32Number nSize)
Name: CIccTagUtf8Text::GetBuffer.
icUChar * m_szText
void SetText(const icUChar16 *szText)
Name: CIccTagUtf8Text::SetText.
Class: CIccTagViewingConditions.
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagViewingConditions::Describe.
virtual bool Write(CIccIO *pIO)
Name: CIccTagViewingConditions::Write.
virtual ~CIccTagViewingConditions()
Name: CIccTagViewingConditions::~CIccTagViewingConditions.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagViewingConditions::Read.
CIccTagViewingConditions()
Name: CIccTagViewingConditions::CIccTagViewingConditions.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagViewingConditions::Validate.
CIccTagViewingConditions & operator=(const CIccTagViewingConditions &ViewCondTag)
Name: CIccTagViewingConditions::operator=.
Class: CIccTagXYZ.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagXYZ::Validate.
virtual ~CIccTagXYZ()
Name: CIccTagXYZ::~CIccTagXYZ.
bool SetSize(icUInt32Number nSize, bool bZeroNew=true)
Name: CIccTagXYZ::SetSize.
icUInt32Number m_nSize
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagXYZ::Describe.
CIccTagXYZ(int nSize=1)
Name: CIccTagXYZ::CIccTagXYZ.
icXYZNumber * m_XYZ
virtual bool Write(CIccIO *pIO)
Name: CIccTagXYZ::Write.
CIccTagXYZ & operator=(const CIccTagXYZ &XYZTag)
Name: CIccTagXYZ::operator=.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagXYZ::Read.
Class: CIccTagZipUtf8Text()
virtual bool Write(CIccIO *pIO)
Name: CIccTagZipUtf8Text::Write.
virtual bool GetText(std::string &str) const
Name: CIccTagZipUtf8Text::GetText.
virtual bool Read(icUInt32Number size, CIccIO *pIO)
Name: CIccTagZipUtf8Text::Read.
virtual icValidateStatus Validate(std::string sigPath, std::string &sReport, const CIccProfile *pProfile=NULL) const
Name: CIccTagZipUtf8Text::Validate.
icUInt32Number BufferSize() const
CIccTagZipUtf8Text & operator=(const CIccTagZipUtf8Text &TextTag)
Name: CIccTagZipUtf8Text::operator=.
bool SetText(const icUChar16 *szText)
Name: CIccTagZipUtf8Text::SetText.
icUChar * GetBuffer() const
virtual void Describe(std::string &sDescription, int nVerboseness)
Name: CIccTagZipUtf8Text::Describe.
virtual ~CIccTagZipUtf8Text()
Name: CIccTagZipUtf8Text::~CIccTagZipUtf8Text.
icUChar * AllocBuffer(icUInt32Number nSize)
Name: CIccTagZipUtf8Text::AllocBuffer.
CIccTagZipUtf8Text()
Name: CIccTagZipUtf8Text::CIccTagZipUtf8Text.
virtual icFloatNumber get(int index) const =0
virtual icUInt8Number * getPtr(int index=0) const =0
unsigned char icUInt8Number
Number definitions.
float icFloat32Number
#define icSigUnknownType
Convenience Enum Definitions - Not defined in ICC specification.
icSparseMatrixType
@ icSparseMatrixUInt16
@ icSparseMatrixFloat32
@ icSparseMatrixFloat16
@ icSparseMatrixUInt8
unsigned short icUInt16Number
icUInt32Number icU16Fixed16Number
long icInt32Number
@ icSigFilmWriter
@ icSigCRTDisplay
@ icSigOffsetLithography
@ icSigFlexography
@ icSigSilkscreen
@ icSigPhotographicPaperPrinter
@ icSigVideoMonitor
@ icSigMotionPictureFilmScanner
@ icSigElectrostaticPrinter
@ icSigPMDisplay
@ icSigGravure
@ icSigInkJetPrinter
@ icSigReflectiveScanner
@ icSigDigitalCamera
@ icSigVideoCamera
@ icSigDyeSublimationPrinter
@ icSigThermalWaxPrinter
@ icSigFilmScanner
@ icSigDigitalMotionPictureCamera
@ icSigPhotoCD
@ icSigMotionPictureFilmRecorder
@ icSigDigitalCinemaProjector
@ icSigPhotoImageSetter
@ icSigElectrophotographicPrinter
@ icSigProjectionTelevision
@ icSigAMDisplay
@ icSigLinkClass
icIlluminant
Pre-defined illuminants, used in measurement and viewing conditions type.
@ icIlluminantF8
@ icIlluminantEquiPowerE
@ icIlluminantF2
@ icIlluminantD55
@ icIlluminantA
@ icIlluminantUnknown
@ icIlluminantD65
@ icIlluminantD93
@ icIlluminantD50
#define icIsSameColorSpaceType(sig, type)
icColorantEncoding
Colorant and Phosphor Encodings used in chromaticity type.
@ icColorantEBU
@ icColorantITU
@ icColorantSMPTE
@ icColorantP22
icUInt16Number icCountryCode
icUInt16Number icFloat16Number
IEEE float storage numbers.
double icFloat64Number
#define icSparseMatrixFloatNum
Convenience Enum Definition - Not defined in ICC specification.
#define icVersionNumberV5_1
icColorSpaceSignature
Color Space Signatures.
@ icSigLabData
@ icSigXYZData
@ icSigRgbData
@ icSigYCbCrData
#define icRange380nm
Useful spectral range numbers.
icUInt32Number icSignature
icUInt16Number icLanguageCode
#define icCompressedData
icMeasurementUnitSig
Measurement Unit Signatures used in ResponseCurveSet16Type.
@ icSigStatusI
@ icSigStatusE
@ icSigDNNP
@ icSigStatusA
@ icSigDN
@ icSigStatusT
@ icSigDNP
@ icSigDNN
@ icSigStatusM
@ icPngImageType
@ icTiffImageType
@ icSigUInt8ArrayType
@ icSigUtf8TextType
@ icSigFloat16ArrayType
@ icSigMultiLocalizedUnicodeType
@ icSigS15Fixed16ArrayType
@ icSigUtf16TextType
@ icSigTextDescriptionType
@ icSigFloat64ArrayType
@ icSigUInt64ArrayType
@ icSigTextType
@ icSigU16Fixed16ArrayType
@ icSigZipUtf8TextType
@ icSigFloat32ArrayType
@ icSigUInt32ArrayType
@ icCompressedUtfData
@ icCompressedAsciiData
@ icCompressedBinaryData
@ icUtfData
@ icBinaryData
@ icAsciiData
icUInt32Number icUInt64Number[2]
#define icSigUnknownData
@ icSigSparseMatrixReflectanceData
#define icDataTypeMask
@ icGeometry045or450
@ icGeometry0dord0
@ icGeometryUnknown
@ icSigSceneColorimetryEstimates
@ icSigReflectionPrintOutputColorimetry
@ icSigFocalPlaneColorimetryEstimates
@ icSigReflectionHardcopyOriginalColorimetry
@ icSigSceneAppearanceEstimates
#define icRange780nm
icInt32Number icS15Fixed16Number
Fixed numbers.
@ icSigPerceptualReferenceMediumGamut
@ icSigPerceptualRenderingIntentGamutTag
@ icSigColorimetricIntentImageStateTag
@ icSigMaterialDefaultValuesTag
@ icSigSpectralDataInfoTag
@ icSigSaturationRenderingIntentGamutTag
@ icSigColorantTableTag
@ icSigSpectralWhitePointTag
@ icSigCharTargetTag
@ icSigCopyrightTag
@ icSigColorantTableOutTag
@ icSigTechnologyTag
icStandardObserver
Standard Observer, used in the measurmentType tag.
@ icStdObsUnknown
@ icStdObs1964TenDegrees
@ icStdObs1931TwoDegrees
static icFloatNumber UnitClip(icFloatNumber v)
icChar rootName[32]
icFloatNumber deviceCoords[1]
icFloatNumber pcsCoords[3]
icFloatNumber lab[3]
xy Chromaticity Number
ColorantTable Entry.
The base date time number.
The Profile header.
icSpectralRange spectralRange
icSpectralColorSignature spectralPCS
icSpectralRange biSpectralRange
icIlluminant illum
icFloatNumber spd[81]
icStandardObserver obs
icFloatNumber cmf[81 *3]
response16Number
icUInt16Number deviceCode
icS15Fixed16Number measurementValue
icUInt16Number reserved
spectral range
icUInt16Number steps
icFloat16Number start
icFloat16Number end