Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
IccTagXml.cpp
Go to the documentation of this file.
1/** @file
2 File: IccTagXML.cpp
3
4 Contains: Implementation ICC tag XML format conversions
5
6 Version: V1
7
8 Copyright: (c) see ICC Software License
9*/
10
11/*
12 * The ICC Software License, Version 0.2
13 *
14 *
15 * Copyright (c) 2003-2012 The International Color Consortium. All rights
16 * reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 *
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 *
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in
27 * the documentation and/or other materials provided with the
28 * distribution.
29 *
30 * 3. In the absence of prior written permission, the names "ICC" and "The
31 * International Color Consortium" must not be used to imply that the
32 * ICC organization endorses or promotes products derived from this
33 * software.
34 *
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE INTERNATIONAL COLOR CONSORTIUM OR
40 * ITS CONTRIBUTING MEMBERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the The International Color Consortium.
52 *
53 *
54 * Membership in the ICC is encouraged when this software is used for
55 * commercial purposes.
56 *
57 *
58 * For more information on The International Color Consortium, please
59 * see <http://www.color.org/>.
60 *
61 *
62 */
63
64#include "IccTagXml.h"
65#include "IccMpeXml.h"
66#include "IccUtil.h"
67#include "IccUtilXml.h"
68#include "IccIoXml.h"
69#include "IccSparseMatrix.h"
70#include "IccProfileXml.h"
71#include "IccStructFactory.h"
72#include "IccArrayFactory.h"
73#include <cstring> /* C strings strcpy, memcpy ... */
74#include <set>
75#include <map>
76#include <sstream> // Make sure to include this header
77#include <iomanip> // Include this header for setw and setfill
78
79typedef std::map<icUInt32Number, icTagSignature> IccOffsetTagSigMap;
80
81#ifdef USEREFICCMAXNAMESPACE
82namespace refIccMAX {
83#endif
84
85
86bool CIccTagXmlUnknown::ToXml(std::string &xml, std::string blanks/* = ""*/)
87{
88 xml += blanks + "<UnknownData>\n";
89 icXmlDumpHexData(xml, blanks+" ", m_pData, m_nSize);
90 xml += blanks + "</UnknownData>\n";
91
92 return true;
93}
94
95
96bool CIccTagXmlUnknown::ParseXml(xmlNode *pNode, std::string &parseStr)
97{
98 const char *tagType = icXmlAttrValue(pNode->parent, "type");
99 if (tagType) {
100 m_nType = (icTagTypeSignature)icGetSigVal(tagType);
101 }
102
103 pNode = icXmlFindNode(pNode, "UnknownData");
104
105 if (pNode && pNode->children && pNode->children->content) {
106 m_nSize = icXmlGetHexDataSize((const icChar*)pNode->children->content);
107
108 if (m_pData) {
109 delete [] m_pData;
110 m_pData = NULL;
111 }
112 if (m_nSize) {
113 m_pData = new icUInt8Number[m_nSize];
114
115 if (icXmlGetHexData(m_pData, (const icChar*)pNode->children->content, m_nSize)!=m_nSize)
116 return false;
117 }
118 return true;
119 }
120 return false;
121}
122
123
124static bool icXmlDumpTextData(std::string &xml, std::string blanks, const char *szText, bool bConvert=true)
125{
126 if (strstr(szText, "]]>")) {
127 xml += blanks + "<HexTextData>";
128 icXmlDumpHexData(xml, blanks+" ", (void*)szText, (icUInt32Number)strlen(szText));
129 xml += blanks + "</HexTextData>\n";
130 }
131 else {
132 std::string buf;
133
134 xml += blanks + "<TextData>";
135 xml += "<![CDATA[";
136 if (bConvert)
137 xml += icAnsiToUtf8(buf, szText);
138 else
139 xml += szText;
140 xml += "]]></TextData>\n";
141 }
142
143 return true;
144}
145
146bool CIccTagXmlText::ToXml(std::string &xml, std::string blanks/* = ""*/)
147{
148 return icXmlDumpTextData(xml, blanks, m_szText);
149}
150
151bool CIccTagXmlUtf8Text::ToXml(std::string &xml, std::string blanks/* = ""*/)
152{
153 return icXmlDumpTextData(xml, blanks, (icChar*)m_szText, false);
154}
155
156bool CIccTagXmlZipUtf8Text::ToXml(std::string &xml, std::string blanks/* = ""*/)
157{
158 xml += blanks + "<HexCompressedData>\n";
159 icXmlDumpHexData(xml, blanks+" ", m_pZipBuf, m_nBufSize);
160 xml += blanks + "</HexCompressedData>\n";
161
162 return true;
163}
164
165bool CIccTagXmlZipXml::ToXml(std::string &xml, std::string blanks/* = ""*/)
166{
167 xml += blanks + "<HexCompressedData>\n";
168 icXmlDumpHexData(xml, blanks+" ", m_pZipBuf, m_nBufSize);
169 xml += blanks + "</HexCompressedData>\n";
170
171 return true;
172}
173
174bool CIccTagXmlUtf16Text::ToXml(std::string &xml, std::string blanks/* = ""*/)
175{
176 std::string buf;
177 return icXmlDumpTextData(xml, blanks, GetText(buf), false);
178}
179
180static std::string icXmlParseTextString(xmlNode *pNode, std::string &parseStr, bool bConvert = true)
181{
182 std::string str;
183
184 while (pNode) {
185 if (pNode->type==XML_ELEMENT_NODE) {
186 if (!icXmlStrCmp(pNode->name, "HexTextData") && pNode->children && pNode->children->content) {
187 CIccUInt8Array buf;
188 if (!buf.SetSize(icXmlGetHexDataSize((const icChar*)pNode->children->content) ||
189 icXmlGetHexData(buf.GetBuf(), (const icChar*)pNode->children->content, buf.GetSize())!=buf.GetSize()))
190 return str;
191
192 str += (char*)buf.GetBuf();
193 }
194 else if (!icXmlStrCmp(pNode->name, "TextData") ) {
195 std::string buf;
196 const icChar *filename = icXmlAttrValue(pNode, "File");
197
198 // file exists
199 if (filename[0]) {
200 CIccIO *file = IccOpenFileIO(filename, "rb");
201 if (!file){
202 parseStr += "Error! - File '";
203 parseStr += filename;
204 parseStr +="' not found.\n";
205 delete file;
206 return str;
207 }
208
209 icUInt32Number fileLength = file->GetLength();
210 char *ansiStr = (char *)malloc(fileLength+1);
211
212 if (!ansiStr) {
213 perror("Memory Error");
214 parseStr += "'";
215 parseStr += filename;
216 parseStr += "' may not be a valid text file.\n";
217 delete file;
218 return str;
219 }
220 // read the contents of the file
221 if (file->ReadLine(ansiStr, fileLength)!=fileLength) {
222 parseStr += "Error while reading file '";
223 parseStr += filename;
224 parseStr += "'. Size read is not equal to file length. File may not be a valid text file.\n";
225 free(ansiStr);
226 delete file;
227 return str;
228 }
229 // convert utf8 (xml format) to ansi (icc format)
230 if (bConvert)
231 icUtf8ToAnsi(buf, ansiStr);
232 else
233 buf = ansiStr;
234 free(ansiStr);
235 delete file;
236 }
237 // file does not exist
238 else if (pNode->children && pNode->children->content){
239 if (bConvert)
240 icUtf8ToAnsi(buf, (const icChar*)pNode->children->content);
241 else
242 buf = (const icChar*)pNode->children->content;
243 }
244 str += buf;
245 }
246 }
247 pNode = pNode->next;
248 }
249
250 return str;
251}
252
253bool CIccTagXmlText::ParseXml(xmlNode *pNode, std::string &parseStr)
254{
255 std::string str = icXmlParseTextString(pNode, parseStr);
256
257 if (!str.empty()){
258 SetText(str.c_str());
259 return true;
260 }
261 return false;
262}
263
264bool CIccTagXmlUtf8Text::ParseXml(xmlNode *pNode, std::string &parseStr)
265{
266 std::string str = icXmlParseTextString(pNode, parseStr, false);
267
268 if (!str.empty()){
269 SetText(str.c_str());
270 return true;
271 }
272 return false;
273}
274
275bool CIccTagXmlZipUtf8Text::ParseXml(xmlNode *pNode, std::string &parseStr)
276{
277 while (pNode) {
278 if (pNode->type==XML_ELEMENT_NODE) {
279 if (!icXmlStrCmp(pNode->name, "HexCompressedData") && pNode->children && pNode->children->content) {
280 CIccUInt8Array buf;
281 if (!buf.SetSize(icXmlGetHexDataSize((const icChar*)pNode->children->content) ||
282 icXmlGetHexData(buf.GetBuf(), (const icChar*)pNode->children->content, buf.GetSize())!=buf.GetSize()))
283 return false;
284
285 AllocBuffer(buf.GetSize());
286 if (m_nBufSize && m_pZipBuf) {
287 memcpy(m_pZipBuf, buf.GetBuf(), m_nBufSize);
288 }
289 return true;
290 }
291 }
292 pNode = pNode->next;
293 }
294
295 std::string str = icXmlParseTextString(pNode, parseStr, false);
296
297 return SetText(str.c_str());
298}
299
300bool CIccTagXmlZipXml::ParseXml(xmlNode *pNode, std::string &parseStr)
301{
302 while (pNode) {
303 if (pNode->type==XML_ELEMENT_NODE) {
304 if (!icXmlStrCmp(pNode->name, "HexCompressedData") && pNode->children && pNode->children->content) {
305 CIccUInt8Array buf;
306 if (!buf.SetSize(icXmlGetHexDataSize((const icChar*)pNode->children->content) ||
307 icXmlGetHexData(buf.GetBuf(), (const icChar*)pNode->children->content, buf.GetSize())!=buf.GetSize()))
308 return false;
309
310 AllocBuffer(buf.GetSize());
311 if (m_nBufSize && m_pZipBuf) {
312 memcpy(m_pZipBuf, buf.GetBuf(), m_nBufSize);
313 }
314 return true;
315 }
316 }
317 pNode = pNode->next;
318 }
319
320 std::string str = icXmlParseTextString(pNode, parseStr, false);
321
322 return SetText(str.c_str());
323}
324
325bool CIccTagXmlUtf16Text::ParseXml(xmlNode *pNode, std::string &parseStr)
326{
327 std::string str = icXmlParseTextString(pNode, parseStr, false);
328
329 if (!str.empty()){
330 SetText(str.c_str());
331 return true;
332 }
333 return false;
334}
335
336bool CIccTagXmlTextDescription::ToXml(std::string &xml, std::string blanks/* = ""*/)
337{
338 std::string fix;
339 std::string buf;
340 char data[256]; // Adjust the size as needed
341 std::string datastr;
342
343 icXmlDumpTextData(xml, blanks, m_szText);
344
345 // Added support for <![CData[Insert Text here]]> for Unicode
346 if (m_uzUnicodeText[0]) {
347 if (m_nUnicodeLanguageCode == 0)
348 buf = "<Unicode>";
349 else {
350 icGetSigStr(data, m_nUnicodeLanguageCode);
351 icFixXml(fix, data);
352 buf = "<Unicode LanguageCode=\"" + fix + "\">";
353 }
354 xml += blanks + buf;
355
356 icUtf16ToUtf8(datastr, m_uzUnicodeText);
357 icFixXml(fix, datastr.c_str());
358 buf = "<![CDATA[" + fix + "]]></Unicode>\n";
359 xml += buf;
360 }
361
362 if (m_nScriptSize) {
363 buf = "<MacScript ScriptCode=\"" + std::to_string(m_nScriptCode) + "\">";
364 xml += blanks + buf;
365
366 std::stringstream ss;
367 for (int i = 0; i < m_nScriptSize; i++) {
368 ss << std::hex << std::uppercase << std::setw(2) << std::setfill('0')
369 << static_cast<int>(static_cast<unsigned char>(m_szScriptText[i]));
370 }
371 buf = ss.str();
372
373 xml += buf;
374 xml += "</MacScript>\n";
375 }
376
377 return true;
378}
379
380
381bool CIccTagXmlTextDescription::ParseXml(xmlNode *pNode, std::string &parseStr)
382{
383 pNode = icXmlFindNode(pNode, "TextData");
384
385 // support for reading desc, dmmd, and dmnd tags from file.
386 // if (!pNode || !pNode->children)
387 if (!pNode)
388 return false;
389
390 // search for "file" attribute in <TextDescription/> tag
391 const icChar *filename = icXmlAttrValue(pNode, "File");
392
393 // file exists
394 if (filename[0]) {
395 CIccIO *file = IccOpenFileIO(filename, "rb");
396
397 if (!file){
398 parseStr += "Error! - File '";
399 parseStr += filename;
400 parseStr +="' not found.\n";
401 delete file;
402 return false;
403 }
404
405 icUInt32Number fileLength = file->GetLength();
406 char *buf = (char *)malloc(fileLength);
407
408 if (!buf) {
409 perror("Memory Error");
410 parseStr += "'";
411 parseStr += filename;
412 parseStr += "' may not be a valid text file.\n";
413 delete file;
414 return false;
415 }
416
417 if (file->ReadLine(buf, fileLength)!=fileLength) {
418 parseStr += "Error while reading file '";
419 parseStr += filename;
420 parseStr += "'. Size read is not equal to file length. File may not be a valid text file.\n";
421 free(buf);
422 delete file;
423 return false;
424 }
425
426 // set ANSII string
427 std::string ansiStr;
428 icUtf8ToAnsi(ansiStr, buf);
429
430 icUInt32Number nStrSize = (icUInt32Number)ansiStr.size();
431 GetBuffer(nStrSize);
432 if (nStrSize) {
433 memcpy(m_szText, ansiStr.c_str(), nStrSize);
434 m_nASCIISize = nStrSize + 1;
435 }
436 else
437 m_szText[0] = '\0';
438
439 // set Unicode String
440 CIccUTF16String wstr(buf);
441
442 nStrSize = (icUInt32Number)wstr.Size();
443 m_uzUnicodeText = GetUnicodeBuffer(nStrSize);
444
445 if (nStrSize) {
446 // assign each entry in wstr to m_uzUnicodeText
447 for (int i=0; i < (int) nStrSize; i++) {
448 m_uzUnicodeText[i] = wstr[i];
449 }
450
451 // include the null termintor in the string size.
452 m_nUnicodeSize = nStrSize + 1;
453 }
454 else
455 m_uzUnicodeText[0] = 0;
456
457 // Set ScriptCode
458 m_nScriptCode=0;
459 m_nScriptSize = (icUInt8Number) fileLength + 1;
460 memcpy(m_szScriptText, buf, 67);
461
462 delete file;
463 }
464
465 // file does not exist
466 else {
467 std::string str = icXmlParseTextString(pNode, parseStr);
468 icUInt32Number nSize = (icUInt32Number)str.size();
469 icChar *pBuf = GetBuffer(nSize);
470
471 if (nSize) {
472 memcpy(m_szText, str.c_str(), nSize);
473
474 // include the null termintor in the string size.
475 m_nASCIISize = nSize + 1;
476 }
477 else
478 m_szText[0] = '\0';
479
480 Release();
481
482 // support for automatically generating unicode and scriptcode tags if these do not
483 // exist in the XML file.
484 bool unicodeExists = false;
485 bool scriptcodeExists = false;
486 for (;pNode; pNode = pNode->next) {
487 if (pNode->type==XML_ELEMENT_NODE) {
488 if (!icXmlStrCmp(pNode->name, "Unicode")) {
489 const icChar *pRegion = icXmlAttrValue(pNode, "LanguageCode");
490
491 // *pRegion may not have value.
492 if (pRegion && /* *pRegion && */pNode->children && pNode->children->content) {
493 CIccUTF16String wstr((const char*)pNode->children->content);
494
495 nSize = (icUInt32Number)wstr.Size();
496
497 // set size of m_uzUnicodeText
498 m_uzUnicodeText = GetUnicodeBuffer(nSize);
499 if (nSize) {
500
501 // assign each entry in wstr to m_uzUnicodeText
502 for (int i=0; i < (int) nSize; i++) {
503 m_uzUnicodeText[i] = wstr[i];
504 }
505
506 // include the null termintor in the string size.
507 m_nUnicodeSize = nSize + 1;
508
509 unicodeExists = true;
510 }
511 else
512 m_uzUnicodeText[0] = 0;
513 }
514 }
515 else if (!icXmlStrCmp(pNode->name, "MacScript")) {
516 const icChar *pScript = icXmlAttrValue(pNode, "ScriptCode");
517
518 if (pScript && *pScript) {
519 icUInt32Number nCode=0;
520
521 sscanf(pScript, "%x", &nCode);
522 m_nScriptCode = (icUInt16Number)nCode;
523 if (pNode->children && pNode->children->content) {
524 // set m_nScriptSize as receiver the return value of icXmlGetHexData
525 // no need to add 1 since the return value is already exact.
526 m_nScriptSize = (icUInt8Number) icXmlGetHexData(m_szScriptText, (const char*)pNode->children->content, sizeof(m_szScriptText));
527 scriptcodeExists = true;
528 }
529 else
530 m_szScriptText[0] = 0;
531 }
532 }
533 }
534 }
535#if 0
536 // automatically generate unicode tag in the profile if it does not exist
537 if (!unicodeExists){
538
539 m_uzUnicodeText = GetUnicodeBuffer(nSize);
540
541 if (nSize) {
542 // assign each entry in wstr to m_uzUnicodeText
543 for (int i=0; i < (int) nSize; i++) {
544 m_uzUnicodeText[i] = str[i];
545 }
546
547 // include the null termintor in the string size.
548 m_nUnicodeSize = nSize + 1;
549 }
550 else
551 m_uzUnicodeText[0] = 0;
552 }
553
554 // automatically generate scriptcode tag in the profile if it does not exist
555 if (!scriptcodeExists){
556 m_nScriptCode=0;
557 m_nScriptSize = (icUInt8Number)m_nASCIISize;
558 memcpy(m_szScriptText, m_szText, 67);
559
560 }
561#endif
562 }
563
564 return true;
565}
566
567
568bool CIccTagXmlSignature::ToXml(std::string &xml, std::string blanks/* = ""*/)
569{
570 char fix[40];
571 char line[256];
572 char buf[40];
573
574 sprintf(line, "<Signature>%s</Signature>\n", icFixXml(fix, icGetSigStr(buf, m_nSig)));
575
576 xml += blanks + line;
577 return true;
578}
579
580
581bool CIccTagXmlSignature::ParseXml(xmlNode *pNode, std::string &parseStr)
582{
583 if ((pNode = icXmlFindNode(pNode, "Signature"))) {
584 this->SetValue(icGetSigVal(pNode->children ? (const icChar*)pNode->children->content : ""));
585
586 return true;
587 }
588 return false;
589}
590
591
592bool CIccTagXmlSpectralDataInfo::ToXml(std::string &xml, std::string blanks/* = ""*/)
593{
594 char fix[40];
595 char line[256];
596 char buf[40];
597
598 sprintf(line, "<SpectralSpace>%s</SpectralSpace>\n", icFixXml(fix, icGetColorSigStr(buf, m_nSig)));
599 xml += blanks + line;
600
601 xml += blanks + "<SpectralRange>\n";
602 sprintf(line, " <Wavelengths start=\"" icXmlHalfFmt "\" end=\"" icXmlHalfFmt "\" steps=\"%d\"/>\n", icF16toF(m_spectralRange.start), icF16toF(m_spectralRange.end), m_spectralRange.steps);
603 xml += blanks + line;
604 xml += blanks + "</SpectralRange>\n";
605
606 if (m_biSpectralRange.steps) {
607 xml +=blanks + "<BiSpectralRange>\n";
608 sprintf(line, " <Wavelengths start=\"" icXmlHalfFmt "\" end=\"" icXmlHalfFmt "\" steps=\"%d\"/>\n", icF16toF(m_biSpectralRange.start), icF16toF(m_biSpectralRange.end), m_biSpectralRange.steps);
609 xml += blanks + line;
610 xml += blanks + "</BiSpectralRange>\n";
611 }
612
613 return true;
614}
615
616
617bool CIccTagXmlSpectralDataInfo::ParseXml(xmlNode *pNode, std::string &parseStr)
618{
619 xmlNode *pChild;
620
621 if (!(pChild = icXmlFindNode(pNode, "SpectralSpace"))) {
622 parseStr += "No SpectralSpace section found\n";
623 return false;
624 }
625 m_nSig = icGetSigVal(pChild->children ? (const icChar*)pChild->children->content : "");
626
627 if (!(pChild = icXmlFindNode(pNode, "SpectralRange"))) {
628 parseStr += "No SpectralRange section found\n";
629 return false;
630 }
631
632 if (!(pChild = icXmlFindNode(pChild->children, "Wavelengths"))) {
633 parseStr += "SpectralRange missing Wavelengths\n";
634 return false;
635 }
636
637 m_spectralRange.start = icFtoF16((icUInt16Number)atof(icXmlAttrValue(pChild, "start")));
638 m_spectralRange.end = icFtoF16((icUInt16Number)atof(icXmlAttrValue(pChild, "end")));
639 m_spectralRange.steps = (icUInt16Number)atoi(icXmlAttrValue(pChild, "steps"));
640
641 pChild = icXmlFindNode(pNode, "BiSpectralRange");
642
643 if (pChild) {
644 if ((pChild = icXmlFindNode(pChild->children, "Wavelengths"))) {
645 m_biSpectralRange.start = icFtoF16((icUInt16Number)atof(icXmlAttrValue(pChild, "start")));
646 m_biSpectralRange.end = icFtoF16((icUInt16Number)atof(icXmlAttrValue(pChild, "end")));
647 m_biSpectralRange.steps = (icUInt16Number)atoi(icXmlAttrValue(pChild, "steps"));
648 }
649 }
650
651 return true;
652}
653
654
655bool CIccTagXmlNamedColor2::ToXml(std::string &xml, std::string blanks/* = ""*/)
656{
657 char fix[256];
658 char line[256];
659 char buf[256];
660 int i, j;
661 std::string str;
662
663 sprintf(line, "<NamedColors VendorFlag=\"%08x\" CountOfDeviceCoords=\"%d\" DeviceEncoding=\"int16\"", m_nVendorFlags, m_nDeviceCoords);
664 xml += blanks + line;
665
666 sprintf(line, " Prefix=\"%s\"", icFixXml(fix, icAnsiToUtf8(str, m_szPrefix)));
667 xml += line;
668
669 sprintf(line, " Suffix=\"%s\">\n", icFixXml(fix, icAnsiToUtf8(str, m_szSufix)));
670 xml += line;
671
672 for (i=0; i<(int)m_nSize; i++) {
673 SIccNamedColorEntry *pEntry= GetEntry(i);
674
675 const char *szNodeName = "";
676
677 if (pEntry) {
678 if (m_csPCS==icSigLabData) {
679 icFloatNumber lab[3];
680
681 Lab2ToLab4(lab, pEntry->pcsCoords);
682 icLabFromPcs(lab);
683 szNodeName = "LabNamedColor";
684 sprintf(line, " <%s Name=\"%s\" L=\"" icXmlFloatFmt "\" a=\"" icXmlFloatFmt "\" b=\"" icXmlFloatFmt "\"", szNodeName,
685 icFixXml(fix, icAnsiToUtf8(str, pEntry->rootName)), lab[0], lab[1], lab[2]);
686 xml += blanks + line;
687 }
688 else {
689 icFloatNumber xyz[3];
690
691 memcpy(xyz, pEntry->pcsCoords, 3*sizeof(icFloatNumber));
692 icXyzFromPcs(xyz);
693 szNodeName = "XYZNamedColor";
694 sprintf(line, " <%s Name=\"%s\" X=\"" icXmlFloatFmt "\" Y=\"" icXmlFloatFmt "\" Z=\"" icXmlFloatFmt "\"", szNodeName,
695 icFixXml(fix, icAnsiToUtf8(str, pEntry->rootName)), xyz[0], xyz[1], xyz[2]);
696 xml += blanks + line;
697 }
698
699 if (!m_nDeviceCoords) {
700 xml += "/>\n";
701 }
702 else {
703 xml += ">";
704 for (j=0; j<(int)m_nDeviceCoords; j++) {
705 if (j)
706 xml+=" ";
707 sprintf(buf, "%d", (int)(pEntry->deviceCoords[j] * 65535.0 + 0.5));
708 xml += buf;
709 }
710 xml += "\n";
711
712 xml += blanks + " </" + szNodeName + ">\n";
713 }
714 }
715 }
716 xml += blanks + " </NamedColors>\n";
717 return true;
718}
719
720
721bool CIccTagXmlNamedColor2::ParseXml(xmlNode *pNode, std::string &parseStr)
722{
723 pNode = icXmlFindNode(pNode, "NamedColors");
724
725 if (pNode) {
726 const icChar *szVendorFlags = icXmlAttrValue(pNode, "VendorFlag");
727 const icChar *szDeviceCoords = icXmlAttrValue(pNode, "CountOfDeviceCoords");
728 const icChar *szDeviceEncoding = icXmlAttrValue(pNode, "DeviceEncoding");
729 const icChar *szPrefix = icXmlAttrValue(pNode, "Prefix");
730 const icChar *szSufix = icXmlAttrValue(pNode, "Suffix");
731
732 if (szVendorFlags && *szVendorFlags &&
733 szDeviceCoords && *szDeviceCoords &&
734 szDeviceEncoding && *szDeviceEncoding &&
735 szPrefix && szSufix) {
736 std::string str;
737
738 sscanf(szVendorFlags, "%x", &m_nVendorFlags);
739
740 strncpy(m_szPrefix, icUtf8ToAnsi(str, szPrefix), sizeof(m_szPrefix));
741 m_szPrefix[sizeof(m_szPrefix)-1] = '\0';
742
743 strncpy(m_szSufix, icUtf8ToAnsi(str, szSufix), sizeof(m_szSufix));
744 m_szSufix[sizeof(m_szSufix)-1] = '\0';
745
746 m_nDeviceCoords = atoi(szDeviceCoords);
747 icUInt32Number n = icXmlNodeCount3(pNode->children, "NamedColor", "LabNamedColor", "XYZNamedColor");
748 SetSize(n, m_nDeviceCoords);
749
751
752 SIccNamedColorEntry *pNamedColor = m_NamedColor;
753
754 for (i=0, pNode=pNode->children; pNode; pNode=pNode->next) {
755 const icChar *szName = NULL;
756 if (pNode->type == XML_ELEMENT_NODE &&
757 !icXmlStrCmp(pNode->name, "NamedColor") &&
758 i<n) {
759 szName = icXmlAttrValue(pNode, "Name");
760 xmlAttr *L = icXmlFindAttr(pNode, "L");
761 xmlAttr *a = icXmlFindAttr(pNode, "a");
762 xmlAttr *b = icXmlFindAttr(pNode, "b");
763
764 if (L && a && b) {
765 pNamedColor->pcsCoords[0] = (icFloatNumber)atof(icXmlAttrValue(L));
766 pNamedColor->pcsCoords[1] = (icFloatNumber)atof(icXmlAttrValue(a));
767 pNamedColor->pcsCoords[2] = (icFloatNumber)atof(icXmlAttrValue(b));
768
769 icLabToPcs(pNamedColor->pcsCoords);
770 Lab4ToLab2(pNamedColor->pcsCoords, pNamedColor->pcsCoords);
771 }
772 else {
773 xmlAttr *x = icXmlFindAttr(pNode, "X");
774 xmlAttr *y = icXmlFindAttr(pNode, "Y");
775 xmlAttr *z = icXmlFindAttr(pNode, "Z");
776
777 if (x && y && z) {
778 pNamedColor->pcsCoords[0] = (icFloatNumber)atof(icXmlAttrValue(x));
779 pNamedColor->pcsCoords[1] = (icFloatNumber)atof(icXmlAttrValue(y));
780 pNamedColor->pcsCoords[2] = (icFloatNumber)atof(icXmlAttrValue(z));
781
782 icXyzToPcs(pNamedColor->pcsCoords);
783 }
784 else
785 return false;
786 }
787 }
788 else if (pNode->type == XML_ELEMENT_NODE &&
789 !icXmlStrCmp(pNode->name, "LabNamedColor") &&
790 i < n) {
791 szName = icXmlAttrValue(pNode, "Name");
792 xmlAttr *L = icXmlFindAttr(pNode, "L");
793 xmlAttr *a = icXmlFindAttr(pNode, "a");
794 xmlAttr *b = icXmlFindAttr(pNode, "b");
795
796 if (L && a && b) {
797 pNamedColor->pcsCoords[0] = (icFloatNumber)atof(icXmlAttrValue(L));
798 pNamedColor->pcsCoords[1] = (icFloatNumber)atof(icXmlAttrValue(a));
799 pNamedColor->pcsCoords[2] = (icFloatNumber)atof(icXmlAttrValue(b));
800
801 icLabToPcs(pNamedColor->pcsCoords);
802 Lab4ToLab2(pNamedColor->pcsCoords, pNamedColor->pcsCoords);
803 }
804 else {
805 return false;
806 }
807 }
808 else if (pNode->type == XML_ELEMENT_NODE &&
809 !icXmlStrCmp(pNode->name, "XYZNamedColor") &&
810 i < n) {
811 szName = icXmlAttrValue(pNode, "Name");
812 xmlAttr *x = icXmlFindAttr(pNode, "X");
813 xmlAttr *y = icXmlFindAttr(pNode, "Y");
814 xmlAttr *z = icXmlFindAttr(pNode, "Z");
815
816 if (x && y && z) {
817 pNamedColor->pcsCoords[0] = (icFloatNumber)atof(icXmlAttrValue(x));
818 pNamedColor->pcsCoords[1] = (icFloatNumber)atof(icXmlAttrValue(y));
819 pNamedColor->pcsCoords[2] = (icFloatNumber)atof(icXmlAttrValue(z));
820
821 icXyzToPcs(pNamedColor->pcsCoords);
822 }
823 else
824 return false;
825 }
826
827 if (szName) {
828 strncpy(pNamedColor->rootName, icUtf8ToAnsi(str, szName), sizeof(pNamedColor->rootName));
829 pNamedColor->rootName[sizeof(pNamedColor->rootName) - 1] = 0;
830
831 if (m_nDeviceCoords && pNode->children) {
832 if (!strcmp(szDeviceEncoding, "int8")) {
833 CIccUInt8Array coords;
834
835 coords.ParseArray(pNode->children);
836 icUInt8Number *pBuf = coords.GetBuf();
837
839 for (j = 0; j < m_nDeviceCoords && j < coords.GetSize(); j++) {
840 pNamedColor->deviceCoords[j] = (icFloatNumber)pBuf[i] / 255.0f;
841 }
842 }
843 else if (!strcmp(szDeviceEncoding, "int16")) {
844 CIccUInt16Array coords;
845
846 coords.ParseArray(pNode->children);
847 icUInt16Number *pBuf = coords.GetBuf();
848
850 for (j = 0; j < m_nDeviceCoords && j < coords.GetSize(); j++) {
851 pNamedColor->deviceCoords[j] = (icFloatNumber)pBuf[i] / 65535.0f;
852 }
853 }
854 else if (!strcmp(szDeviceEncoding, "float")) {
855 CIccFloatArray coords;
856
857 coords.ParseArray(pNode->children);
858 icFloatNumber *pBuf = coords.GetBuf();
859
861 for (j = 0; j < m_nDeviceCoords && j < coords.GetSize(); j++) {
862 pNamedColor->deviceCoords[j] = (icFloatNumber)pBuf[i];
863 }
864 }
865 else
866 return false;
867 }
868
869 i++;
870 pNamedColor = (SIccNamedColorEntry*)((icChar*)pNamedColor + m_nColorEntrySize);
871 }
872 }
873 return i==n;
874 }
875 }
876 return false;
877}
878
879
880bool CIccTagXmlXYZ::ToXml(std::string &xml, std::string blanks/* = ""*/)
881{
882 char buf[256];
883 int i;
884
885 for (i=0; i<(int)m_nSize; i++) {
886 sprintf(buf, "<XYZNumber X=\"" icXmlFloatFmt "\" Y=\"" icXmlFloatFmt "\" Z=\"" icXmlFloatFmt "\"/>\n", (float)icFtoD(m_XYZ[i].X),
887 (float)icFtoD(m_XYZ[i].Y),
888 (float)icFtoD(m_XYZ[i].Z));
889 xml += blanks + buf;
890 }
891 return true;
892}
893
894
895bool CIccTagXmlXYZ::ParseXml(xmlNode *pNode, std::string &parseStr)
896{
897 icUInt32Number n = icXmlNodeCount(pNode, "XYZNumber");
898
899 if (n) {
901 SetSize(n);
902
903 for (i=0; pNode; pNode=pNode->next) {
904 if (pNode->type == XML_ELEMENT_NODE &&
905 !icXmlStrCmp(pNode->name, "XYZNumber") &&
906 i<n) {
907 xmlAttr *x = icXmlFindAttr(pNode, "X");
908 xmlAttr *y = icXmlFindAttr(pNode, "Y");
909 xmlAttr *z = icXmlFindAttr(pNode, "Z");
910
911 if (x && y && z) {
912 m_XYZ[i].X = icDtoF((icFloatNumber)atof(icXmlAttrValue(x)));
913 m_XYZ[i].Y = icDtoF((icFloatNumber)atof(icXmlAttrValue(y)));
914 m_XYZ[i].Z = icDtoF((icFloatNumber)atof(icXmlAttrValue(z)));
915 i++;
916 }
917 else
918 return false;
919 }
920 }
921 return i==n;
922 }
923 return false;
924}
925
926
927bool CIccTagXmlChromaticity::ToXml(std::string &xml, std::string blanks/* = ""*/)
928{
929 char buf[256];
930 int i;
931
932 CIccInfo info;
933 sprintf(buf, "<Colorant>%s</Colorant>\n",info.GetColorantEncoding((icColorantEncoding)m_nColorantType));
934 xml += blanks + buf;
935
936 for (i=0; i<(int)m_nChannels; i++) {
937 sprintf(buf, " <Channel x=\"" icXmlFloatFmt "f\" y=\"" icXmlFloatFmt "\"/>\n", (float)icUFtoD(m_xy[i].x),
938 (float)icUFtoD(m_xy[i].y));
939 xml += blanks + buf;
940 }
941
942 return true;
943}
944
945
946bool CIccTagXmlChromaticity::ParseXml(xmlNode *pNode, std::string &parseStr)
947{
948
949 pNode = icXmlFindNode(pNode, "Colorant");
950
951 if (pNode)
952 m_nColorantType = icGetColorantValue(pNode->children ? (const icChar*)pNode->children->content : "");
953
954
955 icUInt16Number n = (icUInt16Number)icXmlNodeCount(pNode, "Channel");
956
957 if (n) {
959 SetSize(n);
960
961 for (i=0; pNode; pNode=pNode->next) {
962 if (pNode->type == XML_ELEMENT_NODE &&
963 !icXmlStrCmp(pNode->name, "Channel") &&
964 i<n) {
965 xmlAttr *x = icXmlFindAttr(pNode, "x");
966 xmlAttr *y = icXmlFindAttr(pNode, "y");
967
968 if (x && y) {
969 m_xy[i].x = icDtoUF((icFloatNumber)atof(icXmlAttrValue(x)));
970 m_xy[i].y = icDtoUF((icFloatNumber)atof(icXmlAttrValue(y)));
971 i++;
972 }
973 else
974 return false;
975 }
976 }
977 return i==n;
978 }
979 return false;
980}
981
982
983bool CIccTagXmlCicp::ToXml(std::string& xml, std::string blanks/* = ""*/)
984{
985 char buf[256];
986
987 CIccInfo info;
988 sprintf(buf, "<cicpFields ColorPrimaries=\"%d\" TransferCharacteristics=\"%d\" MatrixCoefficients=\"%d\" VideoFullRangeFlag=\"%d\"/>\n",
989 m_nColorPrimaries, m_nTransferCharacteristics, m_nMatrixCoefficients, m_nVideoFullRangeFlag);
990 xml += blanks + buf;
991
992 return true;
993}
994
995
996bool CIccTagXmlCicp::ParseXml(xmlNode* pNode, std::string& parseStr)
997{
998
999 pNode = icXmlFindNode(pNode, "cicpFields");
1000
1001 if (pNode) {
1002 xmlAttr* attr;
1003 if ((attr = icXmlFindAttr(pNode, "ColorPrimaries")))
1004 m_nColorPrimaries = atoi(icXmlAttrValue(attr));
1005 else
1006 m_nColorPrimaries = 0;
1007
1008 if ((attr = icXmlFindAttr(pNode, "TransferCharacteristics")))
1009 m_nTransferCharacteristics = atoi(icXmlAttrValue(attr));
1010 else
1011 m_nTransferCharacteristics = 0;
1012
1013 if ((attr = icXmlFindAttr(pNode, "MatrixCoefficients")))
1014 m_nMatrixCoefficients = atoi(icXmlAttrValue(attr));
1015 else
1016 m_nMatrixCoefficients = 0;
1017
1018 if ((attr = icXmlFindAttr(pNode, "VideoFullRangeFlag")))
1019 m_nVideoFullRangeFlag = atoi(icXmlAttrValue(attr));
1020 else
1021 m_nVideoFullRangeFlag = 0;
1022 }
1023 else
1024 return false;
1025
1026 return true;
1027}
1028
1029
1030bool CIccTagXmlSparseMatrixArray::ToXml(std::string &xml, std::string blanks/* = ""*/)
1031{
1032 char buf[256];
1033 int i, j, n;
1034
1035 sprintf(buf, "<SparseMatrixArray outputChannels=\"%d\" matrixType=\"%d\">\n", m_nChannelsPerMatrix, m_nMatrixType);
1036 xml += blanks + buf;
1037
1038 CIccSparseMatrix mtx;
1039 icUInt32Number bytesPerMatrix = GetBytesPerMatrix();
1040
1041 for (i=0; i<(int)m_nSize; i++) {
1042 mtx.Reset(m_RawData+i*bytesPerMatrix, bytesPerMatrix, icSparseMatrixFloatNum, true);
1043 sprintf(buf, " <SparseMatrix rows=\"%d\" cols=\"%d\">\n", mtx.Rows(), mtx.Cols());
1044 xml += blanks + buf;
1045
1046 for (j=0; j<(int)mtx.Rows(); j++) {
1047 xml += blanks + " <SparseRow>\n";
1048
1049 n=mtx.GetNumRowColumns(j);
1050
1051 xml += blanks + " <ColIndices>\n";
1052 CIccUInt16Array::DumpArray(xml, blanks+" ", mtx.GetColumnsForRow(j), n, icConvert16Bit, 8);
1053 xml += blanks + " </ColIndices>\n";
1054
1055 xml += blanks + " <ColData>\n";
1056 CIccFloatArray::DumpArray(xml, blanks+" ", (icFloatNumber*)(mtx.GetData()->getPtr(mtx.GetRowOffset(j))), n, icConvertFloat, 8);
1057 xml += blanks + " </ColData>\n";
1058
1059 xml += blanks + " </SparseRow>\n";
1060 }
1061 xml += blanks + " </SparseMatrix>\n";
1062 }
1063
1064 xml += blanks + "</SparseMatrixArray>\n";
1065
1066 return true;
1067}
1068
1069
1070bool CIccTagXmlSparseMatrixArray::ParseXml(xmlNode *pNode, std::string &parseStr)
1071{
1072 pNode = icXmlFindNode(pNode, "SparseMatrixArray");
1073
1074 if (pNode) {
1075 xmlAttr *outputChan = icXmlFindAttr(pNode, "outputChannels");
1076 xmlAttr *matrixType = icXmlFindAttr(pNode, "matrixType");
1077
1078 if (outputChan && matrixType) {
1079 icUInt32Number nChannelsPerMatrix = atoi(icXmlAttrValue(outputChan));
1080 icSparseMatrixType nMatrixType = (icSparseMatrixType)atoi(icXmlAttrValue(matrixType));
1081
1082 xmlNode *pChild;
1083
1084 int n=0;
1085 for (pChild = pNode->children; pChild; pChild=pChild->next) {
1086 if (pChild->type == XML_ELEMENT_NODE &&
1087 (!icXmlStrCmp(pChild->name, "SparseMatrix") || !icXmlStrCmp(pChild->name, "FullMatrix")))
1088 n++;
1089
1090 }
1091 Reset(n, (icUInt16Number)nChannelsPerMatrix);
1092 m_nMatrixType = (icSparseMatrixType)nMatrixType;
1093
1094 icUInt32Number bytesPerMatrix = GetBytesPerMatrix();
1095 CIccSparseMatrix mtx;
1096 int i=0;
1097 for (pChild = pNode->children; pChild; pChild=pChild->next) {
1098 if (pChild->type == XML_ELEMENT_NODE) {
1099 if (!icXmlStrCmp(pChild->name, "SparseMatrix")) {
1100 mtx.Reset(m_RawData + i*bytesPerMatrix, bytesPerMatrix, icSparseMatrixFloatNum, false);
1101
1102 xmlAttr *rows = icXmlFindAttr(pChild, "rows");
1103 xmlAttr *cols = icXmlFindAttr(pChild, "cols");
1104
1105 if (rows && cols) {
1106 icUInt16Number nRows, nCols;
1107
1108 nRows = atoi(icXmlAttrValue(rows));
1109 nCols = atoi(icXmlAttrValue(cols));
1110
1111 mtx.Init(nRows, nCols, true);
1112
1113 icUInt16Number *rowstart = mtx.GetRowStart();
1114 icUInt32Number nMaxEntries = mtx.GetMaxEntries();
1115 xmlNode *pRow;
1116 int iRow=0;
1117 icUInt32Number pos = 0;
1118 for (pRow=pChild->children; pRow; pRow=pRow->next) {
1119 if (pRow->type == XML_ELEMENT_NODE && !icXmlStrCmp(pRow->name, "SparseRow")) {
1120 xmlNode *pIdx = icXmlFindNode(pRow->children, "ColIndices");
1121 xmlNode *pData = icXmlFindNode(pRow->children, "ColData");
1122
1123 if (pIdx && pData) {
1124 CIccUInt16Array idx;
1125 CIccFloatArray data;
1126
1127 if (!idx.ParseTextArray(pIdx) || !data.ParseTextArray(pData)) {
1128 parseStr += "Unable to parse SparseRow index or data values\n";
1129 return false;
1130 }
1131 if (idx.GetSize() != data.GetSize()) {
1132 parseStr += "Mismatch between SparseRow index and data lengths\n";
1133 return false;
1134 }
1135 if (pos+idx.GetSize() > nMaxEntries) {
1136 parseStr += "Exceeded maximum number of sparse matrix entries\n";
1137 return false;
1138 }
1139 rowstart[iRow] = (icUInt16Number)pos;
1140 memcpy(mtx.GetColumnsForRow(iRow), idx.GetBuf(), idx.GetSize()*sizeof(icUInt16Number));
1141 memcpy(mtx.GetData()->getPtr(pos), data.GetBuf(), data.GetSize()*sizeof(icFloatNumber));
1142 pos += idx.GetSize();
1143 }
1144 iRow++;
1145 }
1146 }
1147 while(iRow<nRows) {
1148 rowstart[iRow] = (icUInt16Number)pos;
1149 iRow++;
1150 }
1151 rowstart[iRow] = (icUInt16Number)pos;
1152 }
1153 else {
1154 parseStr += "Cannot find SparseMatrix rows and cols\n";
1155 return false;
1156 }
1157
1158 i++;
1159 }
1160 else if (!icXmlStrCmp(pChild->name, "FullMatrix")) {
1161 mtx.Reset(m_RawData + i*bytesPerMatrix, bytesPerMatrix, icSparseMatrixFloatNum, false);
1162
1163 xmlAttr *rows = icXmlFindAttr(pChild, "rows");
1164 xmlAttr *cols = icXmlFindAttr(pChild, "cols");
1165
1166 if (rows && cols) {
1167 icUInt16Number nRows, nCols;
1168
1169 nRows = atoi(icXmlAttrValue(rows));
1170 nCols = atoi(icXmlAttrValue(cols));
1171
1172 mtx.Init(nRows, nCols, true);
1173
1174 CIccFloatArray data;
1175 data.ParseTextArray(pChild);
1176 if (data.GetSize()==nRows*nCols) {
1177 if (!mtx.FillFromFullMatrix(data.GetBuf()))
1178 parseStr += "Exceeded maximum number of sparse matrix entries\n";
1179 }
1180 else {
1181 parseStr += "Invalid FullMatrix data dimensions\n";
1182 return false;
1183 }
1184 }
1185 else {
1186 parseStr += "Cannot find FullMatrix rows and cols\n";
1187 return false;
1188 }
1189 i++;
1190 }
1191 }
1192 }
1193 return true;
1194 }
1195 else {
1196 parseStr += "Cannot find outputChannels and matrixType members\n";
1197 }
1198 }
1199 else {
1200 parseStr += "Cannot find SparseMatrixArray node\n";
1201 }
1202
1203 return false;
1204}
1205
1206
1207template <class T, icTagTypeSignature Tsig>
1209{
1210 if (Tsig==icSigS15Fixed16ArrayType)
1211 return "CIccTagXmlS15Fixed16";
1212 else
1213 return "CIccTagXmlU16Fixed16";
1214}
1215
1216// for multi-platform support
1217// added "this->" modifier to data members.
1218template <class T, icTagTypeSignature Tsig>
1219bool CIccTagXmlFixedNum<T, Tsig>::ToXml(std::string &xml, std::string blanks/* = ""*/)
1220{
1221 char buf[256];
1222 int i;
1223
1224 if (Tsig==icSigS15Fixed16ArrayType) {
1225 int n = 8;
1226 xml += blanks + "<Array>\n";
1227 for (i=0; i<(int)this->m_nSize; i++) {
1228 if (!(i%n)) {
1229 if (i)
1230 xml += "\n";
1231 xml += blanks + blanks;
1232 }
1233 else {
1234 xml += " ";
1235 }
1236 sprintf(buf, icXmlFloatFmt, (float)icFtoD(this->m_Num[i]));
1237 xml += buf;
1238 }
1239
1240 if ((i%n)!=1) {
1241 xml += "\n";
1242 }
1243 }
1244 else {
1245 for (i=0; i<(int)this->m_nSize; i++) {
1246
1247 if (!(i%8)) {
1248 if (i)
1249 xml += "\n";
1250 xml += blanks + blanks;
1251 }
1252 else {
1253 xml += " ";
1254 }
1255 sprintf(buf, icXmlFloatFmt, (float)icUFtoD(this->m_Num[i]));
1256 xml += buf;
1257 }
1258
1259 if ((i%8)!=1) {
1260 xml += "\n";
1261 }
1262 }
1263 xml += blanks + "</Array>\n";
1264 return true;
1265}
1266
1267// for multi-platform support
1268// added "this->" modifier to data members.
1269template <class T, icTagTypeSignature Tsig>
1270bool CIccTagXmlFixedNum<T, Tsig>::ParseXml(xmlNode *pNode, std::string &parseStr)
1271{
1272 pNode = icXmlFindNode(pNode, "Array");
1273 pNode = pNode->children;
1274
1276
1277 if (!a.ParseArray(pNode) || !a.GetSize()) {
1278 return false;
1279 }
1280
1281 icUInt32Number i, n = a.GetSize();
1282 icFloatNumber *buf = a.GetBuf();
1283
1284 this->SetSize(n);
1285
1286 for (i=0; i<n; i++) {
1287 if (Tsig==icSigS15Fixed16ArrayType) {
1288 this->m_Num[i] = icDtoF(buf[i]);
1289 }
1290 else {
1291 this->m_Num[i] = icDtoUF(buf[i]);
1292 }
1293 }
1294 return true;
1295}
1296
1297
1298//Make sure typedef classes get built
1301
1302
1303template <class T, class A, icTagTypeSignature Tsig>
1305{
1306 if (sizeof(T)==sizeof(icUInt8Number))
1307 return "CIccTagXmlUInt8";
1308 else if (sizeof(T)==sizeof(icUInt16Number))
1309 return "CIccTagXmlUInt16";
1310 else if (sizeof(T)==sizeof(icUInt32Number))
1311 return "CIccTagXmlUInt32";
1312 else if (sizeof(T)==sizeof(icUInt64Number))
1313 return "CIccTagXmlUInt64";
1314 else
1315 return "CIccTagXmlNum<>";
1316}
1317
1318// for multi-platform support
1319// added "this->" modifier to data members.
1320template <class T, class A, icTagTypeSignature Tsig>
1321bool CIccTagXmlNum<T, A, Tsig>::ToXml(std::string &xml, std::string blanks/* = ""*/)
1322{
1323 char buf[512];
1324 int i;
1325
1326 xml += blanks + "<Array>\n";
1327 for (i=0; i<(int)this->m_nSize; i++) {
1328 if (!(i%16)) {
1329 if (i)
1330 xml += "\n";
1331 xml += blanks + blanks;
1332 }
1333 else {
1334 xml += " ";
1335 }
1336 if (sizeof(T)==16)
1337 sprintf(buf, "%llu", (icUInt64Number)this->m_Num[i]);
1338 else
1339 sprintf(buf, "%u", (icUInt32Number)this->m_Num[i]);
1340 xml += buf;
1341 }
1342
1343 if ((i%16)!=1) {
1344 xml += "\n";
1345 }
1346
1347 xml += blanks + "</Array>\n";
1348 return true;
1349 return true;
1350}
1351
1352// for multi-platform support
1353// added "this->" modifier to data members.
1354template <class T, class A, icTagTypeSignature Tsig>
1355bool CIccTagXmlNum<T, A, Tsig>::ParseXml(xmlNode *pNode, std::string &parseStr)
1356{
1357 xmlNode *pDataNode = icXmlFindNode(pNode, "Data");
1358 if (!pDataNode) {
1359 pDataNode = icXmlFindNode(pNode, "Array");
1360 }
1361 if (!pDataNode) {
1362 return false;
1363 }
1364
1365 pNode = pDataNode->children;
1366
1367 A a;
1368
1369 if (!a.ParseArray(pNode) || !a.GetSize()) {
1370 return false;
1371 }
1372
1373 icUInt32Number i, n = a.GetSize();
1374 T *buf = a.GetBuf();
1375
1376 this->SetSize(n);
1377
1378 for (i=0; i<n; i++) {
1379 this->m_Num[i] = buf[i];
1380 }
1381
1382 return true;
1383}
1384
1385//Make sure typedef classes get built
1390
1391
1392template <class T, class A, icTagTypeSignature Tsig>
1394{
1395 if (Tsig==icSigFloat16ArrayType)
1396 return "CIccTagXmlFloat32";
1397 else if (Tsig==icSigFloat32ArrayType)
1398 return "CIccTagXmlFloat32";
1399 else if (Tsig==icSigFloat64ArrayType)
1400 return "CIccTagXmlFloat64";
1401 else
1402 return "CIccTagXmlFloatNum<>";
1403}
1404
1405// for multi-platform support
1406// added "this->" modifier to data members.
1407template <class T, class A, icTagTypeSignature Tsig>
1408bool CIccTagXmlFloatNum<T, A, Tsig>::ToXml(std::string &xml, std::string blanks/* = ""*/)
1409{
1410 char buf[512];
1411
1412 if (this->m_nSize==1) {
1413#ifdef _WIN32
1414 if (sizeof(T)==sizeof(icFloat32Number))
1415 sprintf(buf, "<Data>" icXmlFloatFmt "</Data>\n", this->m_Num[0]);
1416 else if (sizeof(T)==sizeof(icFloat64Number))
1417 sprintf(buf, "<Data>" icXmlDoubleFmt "</Data>\n", this->m_Num[0]);
1418 else
1419#endif
1420 sprintf(buf, "<Data>" icXmlFloatFmt "</Data>", this->m_Num[0]);
1421 xml += blanks;
1422 xml += buf;
1423 }
1424 else {
1425 int i;
1426 int n = 8;
1427 xml += blanks + "<Data>\n";
1428 for (i=0; i<(int)this->m_nSize; i++) {
1429 if (!(i%n)) {
1430 if (i)
1431 xml += "\n";
1432 xml += blanks + blanks;
1433 }
1434 else {
1435 xml += " ";
1436 }
1437#ifdef _WIN32
1438 if (sizeof(T)==sizeof(icFloat32Number))
1439 sprintf(buf, icXmlFloatFmt, this->m_Num[i]);
1440
1441 else if (sizeof(T)==sizeof(icFloat32Number))
1442 sprintf(buf, icXmlDoubleFmt, this->m_Num[i]);
1443 else
1444#endif
1445 sprintf(buf, icXmlFloatFmt, this->m_Num[i]);
1446 xml += buf;
1447 }
1448
1449 if ((i%n)!=1) {
1450 xml += "\n";
1451 xml += blanks + "</Data>\n";
1452 }
1453 else {
1454 xml += " </Data>\n";
1455 }
1456 }
1457 return true;
1458}
1459
1460// for multi-platform support
1461// added "this->" modifier to data members.
1462template <class T, class A, icTagTypeSignature Tsig>
1463bool CIccTagXmlFloatNum<T, A, Tsig>::ParseXml(xmlNode *pNode, std::string &parseStr)
1464{
1465 pNode = icXmlFindNode(pNode, "Data");
1466
1467 const char *filename = icXmlAttrValue(pNode, "Filename", "");
1468 if (!filename[0]) {
1469 filename = icXmlAttrValue(pNode, "File", "");
1470 }
1471
1472 A a;
1473
1474 if (filename[0]) {
1475 CIccIO *file = IccOpenFileIO(filename, "rb");
1476 if (!file){
1477 parseStr += "Error! - File '";
1478 parseStr += filename;
1479 parseStr +="' not found.\n";
1480 delete file;
1481 return false;
1482 }
1483
1484 icUInt32Number len = file->GetLength();
1485
1486 if (!stricmp(icXmlAttrValue(pNode, "Format", "text"), "text")) {
1487 char *fbuf = (char*)malloc(len+1);
1488 fbuf[len]=0;
1489 if (!fbuf) {
1490 parseStr += "Memory error!\n";
1491 delete file;
1492 return false;
1493 }
1494
1495 if (file->Read8(fbuf, len)!=len) {
1496 parseStr += "Read error of (";
1497 parseStr += filename;
1498 parseStr += ")!\n";
1499 free(fbuf);
1500 delete file;
1501 return false;
1502 }
1503 delete file;
1504
1505 if (!a.ParseTextArray(fbuf) || !a.GetSize()) {
1506 parseStr += "Parse error of (";
1507 parseStr += filename;
1508 parseStr += ")!\n";
1509 free(fbuf);
1510 return false;
1511 }
1512 free(fbuf);
1513 }
1514 else if (Tsig==icSigFloat16ArrayType && sizeof(T)==sizeof(icFloat16Number)) {
1515 icUInt32Number n = len/sizeof(icFloat16Number);
1516 this->SetSize(n);
1517 if (file->Read16(&this->m_Num[0], n)!=n) {
1518 delete file;
1519 return false;
1520 }
1521 delete file;
1522 return true;
1523 }
1524 else if (Tsig==icSigFloat16ArrayType && sizeof(T)==sizeof(icFloat32Number)) {
1525 icUInt32Number n = len/sizeof(icFloat32Number);
1526 this->SetSize(n);
1527 if (file->ReadFloat16Float(&this->m_Num[0], n)!=n) {
1528 delete file;
1529 return false;
1530 }
1531 delete file;
1532 return true;
1533 }
1534 else if (Tsig==icSigFloat32ArrayType && sizeof(T)==sizeof(icFloat32Number)) {
1535 icUInt32Number n = len/sizeof(icFloat32Number);
1536 this->SetSize(n);
1537 if (file->ReadFloat32Float(&this->m_Num[0], n)!=n) {
1538 delete file;
1539 return false;
1540 }
1541 delete file;
1542 return true;
1543 }
1544 else if (Tsig==icSigFloat64ArrayType && sizeof(T)==sizeof(icFloat64Number)) {
1545 icUInt32Number n = len/sizeof(icFloat64Number);
1546 this->SetSize(n);
1547 if (file->Read64(&this->m_Num[0], n)!=n) {
1548 delete file;
1549 return false;
1550 }
1551 delete file;
1552 return true;
1553
1554 }
1555 else {
1556 delete file;
1557 parseStr += "Unsupported file parsing type!\n";
1558 return false;
1559 }
1560 }
1561 else {
1562 pNode = pNode->children;
1563
1564 if (!a.ParseArray(pNode) || !a.GetSize()) {
1565 return false;
1566 }
1567 }
1568
1569 icUInt32Number i, n = a.GetSize();
1570 T *buf = a.GetBuf();
1571
1572 this->SetSize(n);
1573
1574 for (i=0; i<n; i++) {
1575 this->m_Num[i] = buf[i];
1576 }
1577 return true;
1578}
1579
1580
1581//Make sure typedef classes get built
1585
1586
1587bool CIccTagXmlMeasurement::ToXml(std::string &xml, std::string blanks/* = ""*/)
1588{
1589 char buf[256];
1590
1591 CIccInfo info;
1592
1593 sprintf(buf,"<StandardObserver>%s</StandardObserver>\n",icGetStandardObserverName(m_Data.stdObserver));
1594 xml += blanks + buf;
1595
1596 sprintf(buf, "<MeasurementBacking X=\"" icXmlFloatFmt "\" Y=\"" icXmlFloatFmt "\" Z=\"" icXmlFloatFmt "\"/>\n", icFtoD(m_Data.backing.X),
1597 icFtoD(m_Data.backing.Y), icFtoD(m_Data.backing.Z));
1598 xml += blanks + buf;
1599
1600 sprintf(buf,"<Geometry>%s</Geometry>\n",info.GetMeasurementGeometryName(m_Data.geometry));
1601 xml += blanks + buf;
1602
1603 sprintf(buf,"<Flare>%s</Flare>\n",info.GetMeasurementFlareName(m_Data.flare));
1604 xml += blanks + buf;
1605
1606 sprintf(buf,"<StandardIlluminant>%s</StandardIlluminant>\n",info.GetIlluminantName(m_Data.illuminant));
1607 xml += blanks + buf;
1608 return true;
1609}
1610
1611
1612bool CIccTagXmlMeasurement::ParseXml(xmlNode *pNode, std::string &parseStr)
1613{
1614 memset(&m_Data, 0, sizeof(m_Data));
1615
1616 pNode = icXmlFindNode(pNode, "StandardObserver");
1617 if (pNode) {
1618 m_Data.stdObserver = icGetNamedStandardObserverValue(pNode->children ? (icChar*)pNode->children->content: "");
1619 }
1620
1621
1622 pNode = icXmlFindNode(pNode, "MeasurementBacking");
1623 if (pNode){
1624 xmlAttr *attr;
1625
1626 attr = icXmlFindAttr(pNode, "X");
1627 if (attr) {
1628 m_Data.backing.X = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1629 }
1630
1631 attr = icXmlFindAttr(pNode, "Y");
1632 if (attr) {
1633 m_Data.backing.Y = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1634 }
1635
1636 attr = icXmlFindAttr(pNode, "Z");
1637 if (attr) {
1638 m_Data.backing.Z = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1639 }
1640 }
1641
1642 pNode = icXmlFindNode(pNode, "Geometry");
1643 if (pNode){
1644 m_Data.geometry = icGeNamedtMeasurementGeometryValue(pNode->children ? (icChar*)pNode->children->content : "");
1645 }
1646
1647 pNode = icXmlFindNode(pNode, "Flare");
1648 if (pNode){
1649 m_Data.flare = icGetNamedMeasurementFlareValue(pNode->children ? (icChar*)pNode->children->content : "");
1650 }
1651
1652 pNode = icXmlFindNode(pNode, "StandardIlluminant");
1653 if (pNode){
1654 m_Data.illuminant = icGetIlluminantValue(pNode->children ? (icChar*)pNode->children->content : "");
1655 }
1656
1657 return true;
1658}
1659
1660bool CIccTagXmlMultiLocalizedUnicode::ToXml(std::string &xml, std::string blanks/* = ""*/)
1661{
1662 std::string xmlbuf;
1663 char data[256];
1664 std::string bufstr;
1665 CIccMultiLocalizedUnicode::iterator i;
1666
1667 if (!m_Strings)
1668 return false;
1669
1670 for (i=m_Strings->begin(); i!=m_Strings->end(); i++) {
1671 xml += blanks + "<LocalizedText LanguageCountry=\"";
1672 xml += icFixXml(xmlbuf, icGetSigStr(data, (i->m_nLanguageCode<<16) + i->m_nCountryCode));
1673 xml += "\"><![CDATA[";
1674 xml += icFixXml(xmlbuf, icUtf16ToUtf8(bufstr, i->GetBuf(), i->GetLength()));
1675 xml += "]]></LocalizedText>\n";
1676 }
1677 return true;
1678}
1679
1680
1681bool CIccTagXmlMultiLocalizedUnicode::ParseXml(xmlNode *pNode, std::string &parseStr)
1682{
1683 xmlAttr *langCode;
1684 int n = 0;
1685
1686 for (pNode = icXmlFindNode(pNode, "LocalizedText"); pNode; pNode = icXmlFindNode(pNode->next, "LocalizedText")) {
1687 if ((langCode = icXmlFindAttr(pNode, "LanguageCountry"))) {
1688 xmlNode *pText;
1689
1690 for (pText = pNode->children; pText; pText = pText->next) {
1691 if (pText->type == XML_TEXT_NODE || pText->type == XML_CDATA_SECTION_NODE)
1692 break;
1693 }
1694
1695 if (pText) {
1697 CIccUTF16String str((const char*)pText->content);
1698
1699 SetText(str.c_str(), (icLanguageCode)(lc>>16), (icCountryCode)(lc & 0xffff));
1700 n++;
1701 }
1702 else {
1703 SetText("");
1704 n++;
1705 }
1706 }
1707 }
1708 return n>0; //We succeed if we parsed at least one string
1709}
1710
1711
1712bool CIccTagXmlTagData::ToXml(std::string &xml, std::string blanks/* = ""*/)
1713{
1714 icUInt8Number *ptr = m_pData;
1715 char buf[60];
1716 std::string szFlag("ASCII");
1717
1718 if (m_nDataFlag == 1)
1719 szFlag = "binary";
1720 sprintf (buf, "<Data Flag=\"%s\">\n", szFlag.c_str());
1721 xml += blanks + buf;
1722 icXmlDumpHexData(xml, blanks+" ", m_pData, m_nSize);
1723 xml += blanks + "</Data>\n";
1724
1725 return true;
1726}
1727
1728
1729bool CIccTagXmlTagData::ParseXml(xmlNode *pNode, std::string &parseStr)
1730{
1731 pNode = icXmlFindNode(pNode, "Data");
1732 if (pNode && pNode->children && pNode->children->content) {
1733 const icChar *szFlag = icXmlAttrValue(pNode, "Flag");
1734 m_nDataFlag = icAsciiData;
1735 if (!strcmp(szFlag,"binary"))
1736 m_nDataFlag = icBinaryData;
1737
1738 icUInt32Number nSize = icXmlGetHexDataSize((const char *)pNode->children->content);
1739 SetSize(nSize, false);
1740 if (nSize) {
1741 icXmlGetHexData(m_pData, (const char*)pNode->children->content, nSize);
1742 }
1743
1744 return true;
1745 }
1746 return false;
1747}
1748
1749
1750bool CIccTagXmlDateTime::ToXml(std::string &xml, std::string blanks/* = ""*/)
1751{
1752 char buf[256];
1753 sprintf(buf, "<DateTime>%d-%02d-%02dT%02d:%02d:%02d</DateTime>\n",
1754 m_DateTime.year, m_DateTime.month, m_DateTime.day, m_DateTime.hours, m_DateTime.minutes, m_DateTime.seconds);
1755 xml += blanks + buf;
1756 return true;
1757}
1758
1759
1760bool CIccTagXmlDateTime::ParseXml(xmlNode *pNode, std::string &parseStr)
1761{
1762 memset(&m_DateTime, 0, sizeof(m_DateTime));
1763
1764 pNode = icXmlFindNode(pNode, "DateTime");
1765 if (pNode) {
1766 m_DateTime = icGetDateTimeValue(pNode->children ? (const char*)pNode->children->content : "");
1767 return true;
1768 }
1769 return false;
1770}
1771
1772
1773bool CIccTagXmlColorantOrder::ToXml(std::string &xml, std::string blanks/* = ""*/)
1774{
1775 char buf[40];
1776 int i;
1777
1778 xml += blanks + "<ColorantOrder>\n"; //+ blanks + " ";
1779 for (i=0; i<(int)m_nCount; i++) {
1780 sprintf(buf, " <n>%d</n>\n", m_pData[i]);
1781 xml += blanks + buf;
1782 }
1783
1784 xml += blanks + "</ColorantOrder>\n";
1785
1786 return true;
1787}
1788
1789bool CIccTagXmlColorantOrder::ParseXml(xmlNode *pNode, std::string &parseStr)
1790{
1791 pNode = icXmlFindNode(pNode, "ColorantOrder");
1792
1793 if (pNode) {
1794 int n = icXmlNodeCount(pNode->children, "n");
1795
1796 if (n) {
1797 SetSize(n);
1798
1799 if (m_pData) {
1800 if (CIccUInt8Array::ParseArray(m_pData, n, pNode->children))
1801 return true;
1802 }
1803 }
1804 }
1805 return false;
1806}
1807
1808
1809bool CIccTagXmlColorantTable::ToXml(std::string &xml, std::string blanks/* = ""*/)
1810{
1811 char buf[256];
1812 char fix[256];
1813 int i;
1814 std::string str;
1815
1816 xml += blanks + "<ColorantTable>\n";
1817 for (i=0; i<(int)m_nCount; i++) {
1818 icFloatNumber lab[3];
1819 lab[0] = icU16toF(m_pData[i].data[0]);
1820 lab[1] = icU16toF(m_pData[i].data[1]);
1821 lab[2] = icU16toF(m_pData[i].data[2]);
1822 icLabFromPcs(lab);
1823 sprintf(buf, " <Colorant Name=\"%s\" Channel1=\"" icXmlFloatFmt "\" Channel2=\"" icXmlFloatFmt "\" Channel3=\"" icXmlFloatFmt "\"/>\n",
1824 icFixXml(fix, icAnsiToUtf8(str, m_pData[i].name)), lab[0], lab[1], lab[2]);
1825 xml += blanks + buf;
1826 }
1827 //xml += "\n";
1828 xml += blanks + "</ColorantTable>\n";
1829
1830 return true;
1831}
1832
1833
1834bool CIccTagXmlColorantTable::ParseXml(xmlNode *pNode, std::string &parseStr)
1835{
1836 pNode = icXmlFindNode(pNode, "ColorantTable");
1837
1838 if (pNode && pNode->children) {
1839 pNode = pNode->children;
1840
1841 icUInt16Number n = (icUInt16Number)icXmlNodeCount(pNode, "Colorant");
1842
1843 if (n) {
1845 SetSize(n);
1846
1847 for (i=0; pNode; pNode=pNode->next) {
1848 if (pNode->type == XML_ELEMENT_NODE &&
1849 !icXmlStrCmp(pNode->name, "Colorant") &&
1850 i<n) {
1851 std::string str;
1852 const icChar *name = icXmlAttrValue(pNode, "Name");
1853 xmlAttr *L = icXmlFindAttr(pNode, "Channel1");
1854 xmlAttr *a = icXmlFindAttr(pNode, "Channel2");
1855 xmlAttr *b = icXmlFindAttr(pNode, "Channel3");
1856
1857 if (name && L && a && b) {
1858 strncpy(m_pData[i].name, icUtf8ToAnsi(str, name), sizeof(m_pData[i].name));
1859 m_pData[i].name[sizeof(m_pData[i].name)-1]=0;
1860
1861 icFloatNumber lab[3];
1862
1863 lab[0] = (icFloatNumber)atof(icXmlAttrValue(L));
1864 lab[1] = (icFloatNumber)atof(icXmlAttrValue(a));
1865 lab[2] = (icFloatNumber)atof(icXmlAttrValue(b));
1866
1867 icLabToPcs(lab);
1868 m_pData[i].data[0] = icFtoU16(lab[0]);
1869 m_pData[i].data[1] = icFtoU16(lab[1]);
1870 m_pData[i].data[2] = icFtoU16(lab[2]);
1871
1872 i++;
1873 }
1874 else
1875 return false;
1876 }
1877 }
1878 return i==n;
1879 }
1880 return false;
1881 }
1882 return false;
1883}
1884
1885
1886bool CIccTagXmlViewingConditions::ToXml(std::string &xml, std::string blanks/* = ""*/)
1887{
1888 char buf[256];
1889
1890 sprintf(buf, "<IlluminantXYZ X=\"" icXmlFloatFmt "\" Y=\"" icXmlFloatFmt "\" Z=\"" icXmlFloatFmt "\"/>\n",
1891 icFtoD(m_XYZIllum.X), icFtoD(m_XYZIllum.Y), icFtoD(m_XYZIllum.Z));
1892 xml += blanks + buf;
1893
1894 sprintf(buf, "<SurroundXYZ X=\"" icXmlFloatFmt "\" Y=\"" icXmlFloatFmt "\" Z=\"" icXmlFloatFmt "\"/>\n",
1895 icFtoD(m_XYZSurround.X), icFtoD(m_XYZSurround.Y), icFtoD(m_XYZSurround.Z));
1896 xml += blanks + buf;
1897
1898 CIccInfo info;
1899 sprintf(buf, "<IllumType>%s</IllumType>\n", info.GetIlluminantName(m_illumType));
1900 xml += blanks + buf;
1901
1902 return true;
1903}
1904
1905bool CIccTagXmlViewingConditions::ParseXml(xmlNode *pNode, std::string &parseStr)
1906{
1907 xmlAttr *attr;
1908 xmlNode *pChild;
1909
1910 memset(&m_XYZIllum, 0, sizeof(m_XYZIllum));
1911 memset(&m_XYZSurround, 0, sizeof(m_XYZSurround));
1912 m_illumType = (icIlluminant)0;
1913
1914 pChild = icXmlFindNode(pNode, "IlluminantXYZ");
1915 if (pChild) {
1916
1917 attr = icXmlFindAttr(pChild, "X");
1918 if (attr) {
1919 m_XYZIllum.X = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1920 }
1921
1922 attr = icXmlFindAttr(pChild, "Y");
1923 if (attr) {
1924 m_XYZIllum.Y = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1925 }
1926
1927 attr = icXmlFindAttr(pChild, "Z");
1928 if (attr) {
1929 m_XYZIllum.Z = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1930 }
1931 }
1932
1933 pChild = icXmlFindNode(pNode, "SurroundXYZ");
1934 if (pChild) {
1935 attr = icXmlFindAttr(pChild, "X");
1936 if (attr) {
1937 m_XYZSurround.X = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1938 }
1939
1940 attr = icXmlFindAttr(pChild, "Y");
1941 if (attr) {
1942 m_XYZSurround.Y = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1943 }
1944
1945 attr = icXmlFindAttr(pChild, "Z");
1946 if (attr) {
1947 m_XYZSurround.Z = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1948 }
1949 }
1950
1951 pChild = icXmlFindNode(pNode, "IllumType");
1952 if (pChild && pChild->children && pChild->children->content) {
1953 m_illumType = icGetIlluminantValue((icChar*)pChild->children->content);
1954 }
1955
1956 return true;
1957}
1958
1959bool CIccTagXmlSpectralViewingConditions::ToXml(std::string &xml, std::string blanks/* = ""*/)
1960{
1961 char buf[256];
1962 int i, j;
1963 icFloatNumber *ptr;
1964 CIccInfo info;
1965
1966 sprintf(buf, "<StdObserver>%s</StdObserver>\n", info.GetStandardObserverName(m_stdObserver));
1967 xml += blanks + buf;
1968
1969 sprintf(buf, "<IlluminantXYZ X=\"" icXmlFloatFmt "\" Y=\"" icXmlFloatFmt "\" Z=\"" icXmlFloatFmt "\"/>\n",
1970 m_illuminantXYZ.X, m_illuminantXYZ.Y, m_illuminantXYZ.Z);
1971 xml += blanks + buf;
1972
1973 if (m_observer) {
1974 sprintf(buf, "<ObserverFuncs start=\"" icXmlHalfFmt "\" end=\"" icXmlHalfFmt "\" steps=\"%d\"",
1975 icF16toF(m_observerRange.start), icF16toF(m_observerRange.end), m_observerRange.steps);
1976 xml += blanks + buf;
1977
1978 if (m_reserved2) {
1979 sprintf(buf, " Reserved=\"%d\"", m_reserved2);
1980 xml += buf;
1981 }
1982 xml += ">\n";
1983
1984 ptr = &m_observer[0];
1985
1986 for (j=0; j<3; j++) {
1987 xml += blanks;
1988 for (i=0; i<m_observerRange.steps; i++) {
1989 if (i && !(i%8)) {
1990 xml += "\n";
1991 xml += blanks;
1992 }
1993 sprintf(buf, " " icXmlFloatFmt, *ptr);
1994 ptr++;
1995 xml += buf;
1996 }
1997 xml += "\n";
1998 }
1999 xml += blanks + "</ObserverFuncs>\n";
2000 }
2001
2002 sprintf(buf, "<StdIlluminant>%s</StdIlluminant>\n", info.GetIlluminantName(m_stdIlluminant));
2003 xml += blanks + buf;
2004
2005 sprintf(buf, "<ColorTemperature>" icXmlFloatFmt "</ColorTemperature>\n", m_colorTemperature);
2006 xml += blanks + buf;
2007
2008 if (m_illuminant) {
2009 sprintf(buf, "<IlluminantSPD start=\"" icXmlHalfFmt "\" end=\"" icXmlHalfFmt "\" steps=\"%d\"",
2010 icF16toF(m_illuminantRange.start), icF16toF(m_illuminantRange.end), m_illuminantRange.steps);
2011 xml += blanks + buf;
2012
2013 if (m_reserved3) {
2014 sprintf(buf, " Reserved=\"%d\"", m_reserved3);
2015 xml += buf;
2016 }
2017 xml += ">\n";
2018
2019 ptr = &m_illuminant[0];
2020
2021 xml += blanks;
2022 for (i=0; i<m_illuminantRange.steps; i++) {
2023 if (i && !(i%8)) {
2024 xml += "\n";
2025 xml += blanks;
2026 }
2027 sprintf(buf, " " icXmlFloatFmt, *ptr);
2028 ptr++;
2029 xml += buf;
2030 }
2031 xml += "\n";
2032
2033 xml += blanks + "</IlluminantSPD>\n";
2034 }
2035
2036 sprintf(buf, "<SurroundXYZ X=\"" icXmlFloatFmt "\" Y=\"" icXmlFloatFmt "\" Z=\"" icXmlFloatFmt "\"/>\n",
2037 m_surroundXYZ.X, m_surroundXYZ.Y, m_surroundXYZ.Z);
2038 xml += blanks + buf;
2039
2040
2041 return true;
2042}
2043
2044bool CIccTagXmlSpectralViewingConditions::ParseXml(xmlNode *pNode, std::string &parseStr)
2045{
2046 xmlNode *pChild;
2047 xmlAttr *attr;
2048
2049 memset(&m_illuminantXYZ, 0, sizeof(m_illuminantXYZ));
2050 memset(&m_surroundXYZ, 0, sizeof(m_surroundXYZ));
2051 m_stdIlluminant = icIlluminantUnknown;
2052 m_stdObserver = icStdObsUnknown;
2053 m_colorTemperature = 0;
2054 m_reserved2 = 0;
2055 m_reserved3 = 0;
2056
2057 pChild = icXmlFindNode(pNode, "StdObserver");
2058 if (pChild && pChild->children && pChild->children->content) {
2059 m_stdObserver = icGetNamedStandardObserverValue((icChar*)pChild->children->content);
2060 }
2061
2062 pChild = icXmlFindNode(pNode, "IlluminantXYZ");
2063 if (pChild) {
2064
2065 attr = icXmlFindAttr(pChild, "X");
2066 if (attr) {
2067 m_illuminantXYZ.X = (icFloatNumber)atof(icXmlAttrValue(attr));
2068 }
2069
2070 attr = icXmlFindAttr(pChild, "Y");
2071 if (attr) {
2072 m_illuminantXYZ.Y = (icFloatNumber)atof(icXmlAttrValue(attr));
2073 }
2074
2075 attr = icXmlFindAttr(pChild, "Z");
2076 if (attr) {
2077 m_illuminantXYZ.Z = (icFloatNumber)atof(icXmlAttrValue(attr));
2078 }
2079 }
2080
2081 pChild = icXmlFindNode(pNode, "ObserverFuncs");
2082 if (pChild) {
2083 attr = icXmlFindAttr(pChild, "start");
2084 if (attr) {
2085 m_observerRange.start =icFtoF16((icFloatNumber)atof(icXmlAttrValue(attr)));
2086 }
2087 attr = icXmlFindAttr(pChild, "end");
2088 if (attr) {
2089 m_observerRange.end = icFtoF16((icFloatNumber)atoi(icXmlAttrValue(attr)));
2090 }
2091 attr = icXmlFindAttr(pChild, "steps");
2092 if (attr) {
2093 m_observerRange.steps = (icUInt16Number)atoi(icXmlAttrValue(attr));
2094 }
2095 attr = icXmlFindAttr(pChild, "reserved");
2096 if (attr) {
2097 m_reserved2 = (icUInt16Number)atoi(icXmlAttrValue(attr));
2098 }
2099
2100 if (pChild->children && pChild->children->content) {
2101 CIccFloatArray vals;
2102 vals.ParseTextArray((icChar*)pChild->children->content);
2103 if (vals.GetSize()!=m_observerRange.steps*3)
2104 return false;
2105 m_observer = (icFloatNumber*)malloc(m_observerRange.steps*3*sizeof(icFloatNumber));
2106 if (!m_observer)
2107 return false;
2108 icFloatNumber *pBuf = vals.GetBuf();
2109 memcpy(m_observer, pBuf, m_observerRange.steps*3*sizeof(icFloatNumber));
2110 }
2111 }
2112
2113 pChild = icXmlFindNode(pNode, "StdIlluminant");
2114 if (pChild && pChild->children && pChild->children->content) {
2115 m_stdIlluminant = icGetIlluminantValue((icChar*)pChild->children->content);
2116 }
2117
2118 pChild = icXmlFindNode(pNode, "ColorTemperature");
2119 if (pChild && pChild->children && pChild->children->content) {
2120 m_colorTemperature = (icFloatNumber)atof((icChar*)pChild->children->content);
2121 }
2122
2123 pChild = icXmlFindNode(pNode, "IlluminantSPD");
2124 if (pChild) {
2125 attr = icXmlFindAttr(pChild, "start");
2126 if (attr) {
2127 m_illuminantRange.start = icFtoF16((icFloatNumber)atof(icXmlAttrValue(attr)));
2128 }
2129 attr = icXmlFindAttr(pChild, "end");
2130 if (attr) {
2131 m_illuminantRange.end = icFtoF16((icFloatNumber)atof(icXmlAttrValue(attr)));
2132 }
2133 attr = icXmlFindAttr(pChild, "steps");
2134 if (attr) {
2135 m_illuminantRange.steps = (icUInt16Number)atoi(icXmlAttrValue(attr));
2136 }
2137 attr = icXmlFindAttr(pChild, "reserved");
2138 if (attr) {
2139 m_reserved3 = (icUInt16Number)atoi(icXmlAttrValue(attr));
2140 }
2141
2142 if (pChild->children && pChild->children->content && m_illuminantRange.steps) {
2143 CIccFloatArray vals;
2144 vals.ParseTextArray((icChar*)pChild->children->content);
2145 if (vals.GetSize()!=m_illuminantRange.steps)
2146 return false;
2147 m_illuminant = (icFloatNumber*)malloc(m_illuminantRange.steps * sizeof(icFloatNumber));
2148 if (!m_illuminant)
2149 return false;
2150 icFloatNumber *pBuf = vals.GetBuf();
2151 memcpy(m_illuminant, pBuf, m_illuminantRange.steps * sizeof(icFloatNumber));
2152 }
2153 else {
2154 setIlluminant(m_stdIlluminant, m_illuminantRange, NULL, m_colorTemperature);
2155 }
2156 }
2157
2158 pChild = icXmlFindNode(pNode, "SurroundXYZ");
2159 if (pChild) {
2160 attr = icXmlFindAttr(pChild, "X");
2161 if (attr) {
2162 m_surroundXYZ.X = (icFloatNumber)atof(icXmlAttrValue(attr));
2163 }
2164
2165 attr = icXmlFindAttr(pChild, "Y");
2166 if (attr) {
2167 m_surroundXYZ.Y = (icFloatNumber)atof(icXmlAttrValue(attr));
2168 }
2169
2170 attr = icXmlFindAttr(pChild, "Z");
2171 if (attr) {
2172 m_surroundXYZ.Z = (icFloatNumber)atof(icXmlAttrValue(attr));
2173 }
2174 }
2175
2176 return true;
2177}
2178
2179
2180
2181bool icProfDescToXml(std::string &xml, CIccProfileDescStruct &p, std::string blanks = "")
2182{
2183 char fix[256];
2184 char buf[256];
2185 char data[256];
2186
2187 sprintf(buf, "<ProfileDesc>\n");
2188 xml += blanks + buf;
2189
2190 sprintf(buf, "<DeviceManufacturerSignature>%s</DeviceManufacturerSignature>\n", icFixXml(fix, icGetSigStr(data, p.m_deviceMfg)));
2191 xml += blanks + blanks + buf;
2192
2193 sprintf(buf, "<DeviceModelSignature>%s</DeviceModelSignature>\n", icFixXml(fix, icGetSigStr(data, p.m_deviceModel)));
2194 xml += blanks + blanks + buf;
2195
2196 std::string szAttributes = icGetDeviceAttrName(p.m_attributes);
2197 //sprintf(buf, "<DeviceAttributes>\"%016lX\" technology=\"%s\">\n", p.m_attributes, icFixXml(fix, icGetSigStr(data, p.m_technology)));
2198 //xml += buf;
2199 xml += blanks + blanks + icGetDeviceAttrName(p.m_attributes);
2200
2201 sprintf(buf, "<Technology>%s</Technology>\n", icFixXml(fix, icGetSigStr(data, p.m_technology)));
2202 xml += blanks + blanks + buf;
2203
2204 CIccTag *pTag = p.m_deviceMfgDesc.GetTag();
2205 CIccTagXml *pExt;
2206
2207 if (pTag) {
2208
2209 pExt = (CIccTagXml*)(pTag->GetExtension());
2210
2211 if (!pExt || !pExt->GetExtClassName() || strcmp(pExt->GetExtClassName(), "CIccTagXml"))
2212 return false;
2213
2214 xml += blanks + blanks + "<DeviceManufacturer>\n";
2215
2216 const icChar* tagSig = icGetTagSigTypeName(pTag->GetType());
2217 sprintf(buf, "<%s>\n", tagSig);
2218 xml += blanks + blanks + blanks + buf;
2219
2220 if (!pExt->ToXml(xml, blanks + " "))
2221 return false;
2222
2223 sprintf(buf, "</%s>\n", tagSig);
2224 xml += blanks + blanks + blanks + buf;
2225
2226 xml += blanks + blanks +"</DeviceManufacturer>\n";
2227 }
2228
2229 pTag = p.m_deviceModelDesc.GetTag();
2230
2231 if (pTag) {
2232 pExt = (CIccTagXml*)(pTag->GetExtension());
2233
2234 if (!pExt || !pExt->GetExtClassName() || strcmp(pExt->GetExtClassName(), "CIccTagXml"))
2235 return false;
2236
2237 xml += blanks + blanks + "<DeviceModel>\n";
2238
2239 const icChar* tagSig = icGetTagSigTypeName(pTag->GetType());
2240 sprintf(buf, "<%s>\n", tagSig);
2241 xml += blanks + blanks + blanks + buf;
2242
2243 if (!pExt->ToXml(xml, blanks + " "))
2244 return false;
2245
2246 sprintf(buf, "</%s>\n", tagSig);
2247 xml += blanks + blanks + blanks + buf;
2248
2249 xml += blanks + " </DeviceModel>\n";
2250 }
2251
2252 xml += blanks + "</ProfileDesc>\n";
2253
2254 return true;
2255}
2256
2257bool icXmlParseProfDesc(xmlNode *pNode, CIccProfileDescStruct &p, std::string &parseStr)
2258{
2259 if (pNode->type==XML_ELEMENT_NODE && !icXmlStrCmp(pNode->name, "ProfileDesc")) {
2260 xmlNode *pDescNode;
2261
2262 for (pDescNode = pNode->children; pDescNode; pDescNode=pDescNode->next) {
2263 if (pDescNode->type == XML_ELEMENT_NODE) {
2264 if (!icXmlStrCmp(pDescNode->name, "DeviceManufacturerSignature")){
2265 p.m_deviceMfg = icXmlStrToSig(pDescNode->children ? (const icChar*)pDescNode->children->content: "");
2266 }
2267 else if (!icXmlStrCmp(pDescNode->name, "DeviceModelSignature")){
2268 p.m_deviceModel = icXmlStrToSig(pDescNode->children ? (const icChar*)pDescNode->children->content : "");
2269 }
2270 else if (!icXmlStrCmp(pDescNode->name, "DeviceAttributes")){
2271 p.m_attributes = icGetDeviceAttrValue(pDescNode);
2272 }
2273 else if (!icXmlStrCmp(pDescNode->name, "Technology")){
2274 p.m_technology = (icTechnologySignature)icXmlStrToSig(pDescNode->children ? (const icChar*)pDescNode->children->content : "");
2275 }
2276 else if (!icXmlStrCmp(pDescNode->name, "DeviceManufacturer")) {
2277 xmlNode *pDevManNode = icXmlFindNode(pDescNode->children, "multiLocalizedUnicodeType");
2278
2279 if (!pDevManNode){
2280 pDevManNode = icXmlFindNode(pDescNode->children, "textDescriptionType");
2281 }
2282
2283 if (pDevManNode){
2284 icTagTypeSignature tagSig = icGetTypeNameTagSig ((icChar*) pDevManNode->name);
2285
2286 if (!p.m_deviceMfgDesc.SetType(tagSig)){
2287 return false;
2288 }
2289 CIccTag *pTag = p.m_deviceMfgDesc.GetTag();
2290
2291 if (!pTag)
2292 return false;
2293
2294 CIccTagXml *pExt = (CIccTagXml*)(pTag->GetExtension());
2295
2296 if (!pExt || !pExt->GetExtClassName() || strcmp(pExt->GetExtClassName(), "CIccTagXml"))
2297 return false;
2298
2299 pExt->ParseXml(pDevManNode->children, parseStr);
2300 }
2301 }
2302 else if (!icXmlStrCmp(pDescNode->name, "DeviceModel")) {
2303 xmlNode *pDevModNode = icXmlFindNode(pDescNode->children, "multiLocalizedUnicodeType");
2304
2305 if (!pDevModNode){
2306 pDevModNode = icXmlFindNode(pDescNode->children, "textDescriptionType");
2307 }
2308
2309 if (pDevModNode){
2310 icTagTypeSignature tagSig = icGetTypeNameTagSig ((icChar*) pDevModNode->name);
2311
2312 if (!p.m_deviceModelDesc.SetType(tagSig)) {
2313 return false;
2314 }
2315 CIccTag *pTag = p.m_deviceModelDesc.GetTag();
2316
2317 if (!pTag)
2318 return false;
2319
2320 CIccTagXml *pExt = (CIccTagXml*)(pTag->GetExtension());
2321
2322 if (!pExt || !pExt->GetExtClassName() || strcmp(pExt->GetExtClassName(), "CIccTagXml"))
2323 return false;
2324
2325 pExt->ParseXml(pDevModNode->children, parseStr);
2326 }
2327 }
2328 }
2329 }
2330 }
2331 else
2332 return false;
2333
2335 return false;
2336
2337 return true;
2338}
2339
2340
2341bool CIccTagXmlProfileSeqDesc::ToXml(std::string &xml, std::string blanks/* = ""*/)
2342{
2343 CIccProfileSeqDesc::iterator i;
2344 if (!m_Descriptions)
2345 return false;
2346
2347 xml += blanks + "<ProfileSequence>\n";
2348 for (i=m_Descriptions->begin(); i!=m_Descriptions->end(); i++) {
2349 if (!icProfDescToXml(xml, *i, blanks + " "))
2350 return false;
2351 }
2352 xml += blanks + "</ProfileSequence>\n";
2353 return true;
2354}
2355
2356
2357bool CIccTagXmlProfileSeqDesc::ParseXml(xmlNode *pNode, std::string &parseStr)
2358{
2359 pNode = icXmlFindNode(pNode, "ProfileSequence");
2360
2361 if (!m_Descriptions)
2362 return false;
2363
2364 m_Descriptions->clear();
2365
2366 if (pNode) {
2367 for (pNode = pNode->children; pNode; pNode=pNode->next) {
2368 if (pNode->type==XML_ELEMENT_NODE && !icXmlStrCmp(pNode->name, "ProfileDesc")) {
2369 CIccProfileDescStruct ProfileDescStruct;
2370
2371 if (!icXmlParseProfDesc(pNode, ProfileDescStruct, parseStr))
2372 return false;
2373
2374 m_Descriptions->push_back(ProfileDescStruct);
2375 }
2376 }
2377 }
2378 return true;
2379}
2380
2381
2382bool CIccTagXmlResponseCurveSet16::ToXml(std::string &xml, std::string blanks/* = ""*/)
2383{
2384 char line[80];
2385 int i;
2386
2387 CIccInfo info;
2388
2389 sprintf(line, "<CountOfChannels>%d</CountOfChannels>\n", m_nChannels);
2390 xml += blanks + line;
2391
2392 CIccResponseCurveStruct *pCurves=GetFirstCurves();
2393 while (pCurves) {
2394 sprintf(line, "<ResponseCurve MeasUnitSignature=\"%s\">\n", info.GetMeasurementUnit(pCurves->GetMeasurementType()));
2395 xml += blanks + line;
2396 for (i=0; i<pCurves->GetNumChannels(); i++) {
2397 CIccResponse16List *pResponseList = pCurves->GetResponseList(i);
2398 icXYZNumber *pXYZ = pCurves->GetXYZ(i);
2399 sprintf(line, " <ChannelResponses X=\"" icXmlFloatFmt "\" Y=\"" icXmlFloatFmt "\" Z=\"" icXmlFloatFmt "\" >\n", icFtoD(pXYZ->X), icFtoD(pXYZ->Y), icFtoD(pXYZ->Z));
2400 xml += blanks + line;
2401
2402 CIccResponse16List::iterator j;
2403 for (j=pResponseList->begin(); j!=pResponseList->end(); j++) {
2404 sprintf(line, " <Measurement DeviceCode=\"%d\" MeasValue=\"" icXmlFloatFmt "\"", j->deviceCode, icFtoD(j->measurementValue));
2405 xml += blanks + line;
2406
2407 if (j->reserved) {
2408 sprintf(line, " Reserved=\"%d\"", j->reserved);
2409 xml += line;
2410 }
2411 xml += "/>\n";
2412 }
2413
2414 xml += blanks + " </ChannelResponses>\n";
2415 }
2416 xml += blanks + " </ResponseCurve>\n";
2417 pCurves = GetNextCurves();
2418 }
2419
2420 return true;
2421}
2422
2423
2424bool CIccTagXmlResponseCurveSet16::ParseXml(xmlNode *pNode, std::string &parseStr)
2425{
2426 pNode = icXmlFindNode(pNode, "CountOfChannels");
2427
2428 if(!pNode)
2429 return false;
2430
2431 int nChannels = atoi((const char*)pNode->children->content);
2432 SetNumChannels(nChannels);
2433
2434 if (!m_ResponseCurves)
2435 return false;
2436
2437 if (!m_ResponseCurves->empty())
2438 m_ResponseCurves->clear();
2439
2440 for (pNode = pNode->next; pNode; pNode = pNode->next) {
2441 if (pNode->type==XML_ELEMENT_NODE && !icXmlStrCmp(pNode->name, "ResponseCurve")) {
2442 const icChar *szMeasurmentType = icXmlAttrValue(pNode, "MeasUnitSignature");
2443
2444 if (nChannels != icXmlNodeCount(pNode->children, "ChannelResponses"))
2445 return false;
2446
2447 CIccResponseCurveStruct curves(icGetMeasurementValue(szMeasurmentType), nChannels);
2448 xmlNode *pChild, *pMeasurement;
2449 int i;
2450
2451 for (i=0, pChild = pNode->children; pChild; pChild = pChild->next) {
2452 if (pChild->type == XML_ELEMENT_NODE && !icXmlStrCmp(pChild->name, "ChannelResponses")) {
2453 CIccResponse16List *pResponseList = curves.GetResponseList(i);
2454 icXYZNumber *pXYZ = curves.GetXYZ(i);
2455 icResponse16Number response;
2456
2457 const icChar *szX = icXmlAttrValue(pChild, "X");
2458 const icChar *szY = icXmlAttrValue(pChild, "Y");
2459 const icChar *szZ = icXmlAttrValue(pChild, "Z");
2460
2461 if (!szX || !szY || !szZ || !*szX || !*szY || !*szZ)
2462 return false;
2463
2464 pXYZ->X = icDtoF((icFloatNumber)atof(szX));
2465 pXYZ->Y = icDtoF((icFloatNumber)atof(szY));
2466 pXYZ->Z = icDtoF((icFloatNumber)atof(szZ));
2467
2468 for (pMeasurement = pChild->children; pMeasurement; pMeasurement = pMeasurement->next) {
2469 if (pMeasurement->type == XML_ELEMENT_NODE && !icXmlStrCmp(pMeasurement->name, "Measurement")) {
2470 const icChar *szDeviceCode = icXmlAttrValue(pMeasurement, "DeviceCode");
2471 const icChar *szValue = icXmlAttrValue(pMeasurement, "MeasValue");
2472 const icChar *szReserved = icXmlAttrValue(pMeasurement, "Reserved");
2473
2474 if (!szDeviceCode || !szValue || !*szDeviceCode || !*szValue)
2475 return false;
2476
2477 response.deviceCode = (icUInt16Number)atoi(szDeviceCode);
2478 response.measurementValue = icDtoF((icFloatNumber)atof(szValue));
2479
2480 if (szReserved && *szReserved)
2481 response.reserved = atoi(szReserved);
2482
2483 pResponseList->push_back(response);
2484 }
2485 }
2486 i++;
2487 }
2488 }
2489 m_ResponseCurves->push_back(curves);
2490 }
2491 }
2492
2493 return true;
2494}
2495
2496
2497bool CIccTagXmlCurve::ToXml(std::string &xml, std::string blanks/* = ""*/)
2498{
2499 return ToXml(xml, icConvert16Bit, blanks);
2500}
2501
2502
2503bool CIccTagXmlCurve::ToXml(std::string &xml, icConvertType nType, std::string blanks/*= ""*/)
2504{
2505 char buf[40];
2506 int i;
2507
2508 if (!m_nSize) {
2509 xml += blanks + "<Curve/>\n";
2510 }
2511 else if (IsIdentity()) {
2512 xml += blanks + "<Curve IdentitySize=\"";
2513 sprintf(buf, "%d", m_nSize);
2514 xml += buf;
2515 xml += "\"/>\n";
2516 }
2517 else if (nType==icConvert8Bit) {
2518 xml += blanks + "<Curve>\n" + blanks;
2519 for (i=0; i<(int)m_nSize; i++) {
2520 if ( i && !(i%16)) {
2521 xml += "\n";
2522 xml += blanks;
2523 }
2524 sprintf(buf, " %3u", (int)(m_Curve[i] * 255.0 + 0.5));
2525 xml += buf;
2526 }
2527 xml += "\n";
2528 xml += blanks + "</Curve>\n";
2529 }
2530 else if (nType==icConvert16Bit || nType==icConvertVariable) {
2531 xml += blanks + "<Curve>\n" + blanks;
2532 for (i=0; i<(int)m_nSize; i++) {
2533 if (i && !(i%16)) {
2534 xml += "\n";
2535 xml += blanks + " ";
2536 }
2537 sprintf(buf, " %5u", (int)(m_Curve[i] * 65535.0 + 0.5));
2538 xml += buf;
2539 }
2540 xml += "\n";
2541 xml += blanks + "</Curve>\n";
2542 }
2543 else if (nType==icConvertFloat) {
2544 xml += blanks + "<Curve>\n" + blanks + " ";
2545 for (i=0; i<(int)m_nSize; i++) {
2546 if (i && !(i%16)) {
2547 xml += "\n";
2548 xml += blanks + " ";
2549 }
2550 sprintf(buf, " %13.8f", m_Curve[i]);
2551 xml += buf;
2552 }
2553 xml += "\n";
2554 xml += blanks + "</Curve>\n";
2555 }
2556 else
2557 return false;
2558
2559 return true;
2560}
2561
2562
2563bool CIccTagXmlCurve::ParseXml(xmlNode *pNode, std::string &parseStr )
2564{
2565 return ParseXml(pNode, icConvert16Bit, parseStr);
2566}
2567
2568
2569
2570bool CIccTagXmlCurve::ParseXml(xmlNode *pNode, icConvertType nType, std::string &parseStr)
2571{
2572 xmlNode *pCurveNode;
2573 pCurveNode = icXmlFindNode(pNode, "Curve");
2574
2575 if(pCurveNode){
2576 const char *filename = icXmlAttrValue(pCurveNode, "File");
2577
2578 // file exists
2579 if (filename[0]) {
2580 CIccIO *file = IccOpenFileIO(filename, "rb");
2581 if (!file){
2582 parseStr += "Error! - File '";
2583 parseStr += filename;
2584 parseStr +="' not found.\n";
2585 delete file;
2586 return false;
2587 }
2588
2589 const char *format = icXmlAttrValue(pCurveNode, "Format");
2590
2591 // format is text
2592 if (!strcmp(format, "text")) {
2593 icUInt32Number num = file->GetLength();
2594 char *buf = (char *) new char[num];
2595
2596 if (!buf) {
2597 perror("Memory Error");
2598 parseStr += "'";
2599 parseStr += filename;
2600 parseStr += "' may not be a valid text file.\n";
2601 free(buf);
2602 delete file;
2603 return false;
2604 }
2605
2606 if (file->Read8(buf, num) !=num) {
2607 perror("Read-File Error");
2608 parseStr += "'";
2609 parseStr += filename;
2610 parseStr += "' may not be a valid text file.\n";
2611 free(buf);
2612 delete file;
2613 return false;
2614 }
2615
2616 // lut8type
2617 if (nType == icConvert8Bit) {
2618 CIccUInt8Array data;
2619
2620 //if (!data.ParseTextArray(buf)) {
2621 if (!data.ParseTextArrayNum(buf, num, parseStr)){
2622 parseStr += "File '";
2623 parseStr += filename;
2624 parseStr += "' is not a valid text file.\n";
2625 SetSize(0);
2626 free(buf);
2627 delete file;
2628 return false;
2629 }
2630
2631 else {
2632 SetSize(data.GetSize());
2633 icUInt8Number *src = data.GetBuf();
2634 icFloatNumber *dst = GetData(0);
2635
2637 for (i=0; i<data.GetSize(); i++) {
2638 *dst = (icFloatNumber)(*src) / 255.0f;
2639 dst++;
2640 src++;
2641 }
2642
2643 //if (i!=256) {
2644 //printf("Error! - Input/Output table does not have 256 entries.\n");
2645 //SetSize(0);
2646 //return false;
2647 //}
2648 delete file;
2649 return true;
2650 }
2651 }
2652
2653 //lut16type
2654 else if (nType == icConvert16Bit || nType == icConvertVariable) {
2655 CIccUInt16Array data;
2656
2657 //if (!data.ParseTextArray(buf)) {
2658 if (!data.ParseTextArrayNum(buf, num, parseStr)){
2659 parseStr += "File '";
2660 parseStr += filename;
2661 parseStr += "' is not a valid text file.\n";
2662 SetSize(0);
2663 free(buf);
2664 delete file;
2665 return false;
2666 }
2667
2668 else {
2669 SetSize(data.GetSize());
2670
2671 icUInt16Number *src = data.GetBuf();
2672 icFloatNumber *dst = GetData(0);
2673
2675 for (i=0; i<data.GetSize(); i++) {
2676 *dst = (icFloatNumber)(*src) / 65535.0f;
2677 dst++;
2678 src++;
2679 }
2680 }
2681 delete file;
2682 return true;
2683 }
2684
2685 //float type
2686 else if (nType == icConvertFloat){
2687 CIccFloatArray data;
2688
2689 //if (!data.ParseTextArray(buf)) {
2690 if (!data.ParseTextArrayNum(buf, num, parseStr)){
2691 parseStr += "File '";
2692 parseStr += filename;
2693 parseStr += "' is not a valid text file.\n";
2694 SetSize(0);
2695 free(buf);
2696 delete file;
2697 return false;
2698 }
2699
2700 else {
2701 SetSize(data.GetSize());
2702 icFloatNumber *src = data.GetBuf();
2703 icFloatNumber *dst = GetData(0);
2704
2706 for (i=0; i<data.GetSize(); i++) {
2707 *dst = *src;
2708 dst++;
2709 src++;
2710 }
2711 }
2712 delete file;
2713 return true;
2714 }
2715 else {
2716 delete file;
2717 return false;
2718 }
2719 }
2720 // format is binary
2721 else if (!strcmp(format, "binary")) {
2722 const char *order = icXmlAttrValue(pCurveNode, "Endian");
2723 bool little_endian = !strcmp(order, "little");
2724
2725 if (nType == icConvert8Bit){
2726 icUInt32Number num = file->GetLength();
2727 icUInt8Number value;
2728
2729 SetSize(num);
2730 icFloatNumber *dst = GetData(0);
2732 for (i=0; i<num; i++) {
2733 if (!file->Read8(&value)) {
2734 perror("Read-File Error");
2735 parseStr += "'";
2736 parseStr += filename;
2737 parseStr += "' may not be a valid binary file.\n";
2738 delete file;
2739 return false;
2740 }
2741 *dst++ = (icFloatNumber)value / 255.0f;
2742 }
2743 delete file;
2744 return true;
2745 }
2746 else if (nType == icConvert16Bit || nType == icConvertVariable){
2747 icUInt32Number num = file->GetLength() / sizeof(icUInt16Number);
2748 icUInt16Number value;
2749 icUInt8Number *ptr = (icUInt8Number*)&value;
2750
2751 SetSize(num);
2752 icFloatNumber *dst = GetData(0);
2754 for (i=0; i<num; i++) {
2755 if (!file->Read16(&value)) { //this assumes data is big endian
2756 perror("Read-File Error");
2757 parseStr += "'";
2758 parseStr += filename;
2759 parseStr += "' may not be a valid binary file.\n";
2760 delete file;
2761 return false;
2762 }
2763#ifdef ICC_BYTE_ORDER_LITTLE_ENDIAN
2764 if (little_endian) {
2765#else
2766 if (!little_endian) {
2767#endif
2768 icUInt8Number t = ptr[0];
2769 ptr[0] = ptr[1];
2770 ptr[1] = t;
2771 }
2772 *dst++ = (icFloatNumber)value / 65535.0f;
2773 }
2774 delete file;
2775 return true;
2776 }
2777 else if (nType == icConvertFloat) {
2778 icUInt32Number num = file->GetLength()/sizeof(icFloat32Number);
2779 icFloat32Number value;
2780 icUInt8Number *ptr = (icUInt8Number*)&value;
2781
2782 SetSize(num);
2783 icFloatNumber *dst = GetData(0);
2784
2786 for (i=0; i<num; i++) {
2787 if (!file->ReadFloat32Float(&value)) { //assumes data is big endian
2788 perror("Read-File Error");
2789 parseStr += "'";
2790 parseStr += filename;
2791 parseStr += "' may not be a valid binary file.\n";
2792 delete file;
2793 return false;
2794 }
2795#ifdef ICC_BYTE_ORDER_LITTLE_ENDIAN
2796 if (little_endian) {
2797#else
2798 if (!little_endian) {
2799#endif
2800 icUInt8Number tmp;
2801 tmp = ptr[0]; ptr[0] = ptr[3]; ptr[3] = tmp;
2802 tmp = ptr[1]; ptr[1] = ptr[2]; ptr[2] = tmp;
2803 }
2804 *dst++ = value;
2805 }
2806 delete file;
2807 return true;
2808 }
2809 else { //not 8bit/16bit/float
2810 delete file;
2811 return false;
2812 }
2813 }
2814 else {//not text/binary
2815 delete file;
2816 return false;
2817 }
2818 }
2819 // no file
2820 else{
2821 if (nType == icConvert8Bit){
2822 CIccUInt8Array data;
2823
2824 if (!data.ParseArray(pCurveNode->children)) {
2825 const char *szSize = icXmlAttrValue(pCurveNode, "IdentitySize");
2826
2827 if (szSize && *szSize) {
2828 icUInt32Number nSize = (icUInt32Number)atol(szSize);
2829 SetSize(nSize);
2830
2831 if (m_nSize == nSize) {
2833 icFloatNumber *dst = GetData(0);
2834 for (j=0; j<nSize; j++) {
2835 *dst = (icFloatNumber)(j) / (icFloatNumber)(nSize-1);
2836 dst++;
2837 }
2838 }
2839 else
2840 return false;
2841 }
2842 else { //Identity curve with size=0
2843 SetSize(0);
2844 }
2845 }
2846 else {
2847 SetSize(data.GetSize());
2848
2850 icUInt8Number *src = data.GetBuf();
2851 icFloatNumber *dst = GetData(0);
2852 for (j=0; j<data.GetSize(); j++) {
2853 *dst = (icFloatNumber)(*src) / 255.0f;
2854 dst++;
2855 src++;
2856 }
2857
2858 //if (j!=256) {
2859 //printf("Error! - Input/Output table does not have 256 entries.\n");
2860 //SetSize(0);
2861 //return false;
2862 //}
2863 }
2864 return true;
2865 }
2866
2867 else if (nType == icConvert16Bit || nType == icConvertVariable){
2868 CIccUInt16Array data;
2869
2870 if (!data.ParseArray(pCurveNode->children)) {
2871 const char *szSize = icXmlAttrValue(pCurveNode, "IdentitySize");
2872
2873 if (szSize && *szSize) {
2874 icUInt32Number nSize = (icUInt32Number)atol(szSize);
2875 SetSize(nSize);
2876
2877 if (m_nSize == nSize) {
2879 icFloatNumber *dst = GetData(0);
2880 for (j=0; j<nSize; j++) {
2881 *dst = (icFloatNumber)(j) / (icFloatNumber)(nSize-1);
2882 dst++;
2883 }
2884 }
2885 else
2886 return false;
2887 }
2888 else { //Identity curve with size=0
2889 SetSize(0);
2890 }
2891 }
2892 else {
2893 SetSize(data.GetSize());
2894
2896 icUInt16Number *src = data.GetBuf();
2897 icFloatNumber *dst = GetData(0);
2898 for (j=0; j<data.GetSize(); j++) {
2899 *dst = (icFloatNumber)(*src) / 65535.0f;
2900 dst++;
2901 src++;
2902 }
2903 }
2904 return true;
2905 }
2906 else if (nType == icConvertFloat){
2907 CIccFloatArray data;
2908
2909 if (!data.ParseArray(pCurveNode->children)) {
2910 const char *szSize = icXmlAttrValue(pCurveNode, "IdentitySize");
2911
2912 if (szSize && *szSize) {
2913 icUInt32Number nSize = (icUInt32Number)atol(szSize);
2914
2915 SetSize(nSize);
2916
2917 if (m_nSize == nSize) {
2919 icFloatNumber *dst = GetData(0);
2920 for (j=0; j<nSize; j++) {
2921 *dst = (icFloatNumber)(j) / (icFloatNumber)(nSize-1);
2922 dst++;
2923 }
2924 }
2925 else
2926 return false;
2927 }
2928 else { //Identity curve with size=0
2929 SetSize(0);
2930 }
2931 }
2932 else {
2933 SetSize(data.GetSize());
2934
2936 icFloatNumber *src = data.GetBuf();
2937 icFloatNumber *dst = GetData(0);
2938 for (j=0; j<data.GetSize(); j++) {
2939 *dst = *src;
2940 dst++;
2941 src++;
2942 }
2943 }
2944 return true;
2945 }
2946 // unsupported encoding
2947 else
2948 return false;
2949 }
2950 }
2951 return false;
2952}
2953
2954
2955bool CIccTagXmlParametricCurve::ToXml(std::string &xml, std::string blanks/* = ""*/)
2956{
2957 char buf[80];
2958 int i;
2959
2960 sprintf(buf, "<ParametricCurve FunctionType=\"%d\"", m_nFunctionType);
2961 xml += blanks + buf;
2962
2963 if (m_nReserved2) {
2964 sprintf(buf, " Reserved=\"%d\"", m_nReserved2);
2965 xml += buf;
2966 }
2967 xml += ">\n";
2968 xml += blanks + " ";
2969
2970 for (i=0; i<(int)m_nNumParam; i++) {
2971 sprintf(buf, " " icXmlFloatFmt, m_dParam[i]);
2972 xml += buf;
2973 }
2974 xml += "\n";
2975
2976 sprintf(buf, "</ParametricCurve>\n");
2977 xml += blanks + buf;
2978
2979 return true;
2980}
2981
2982bool CIccTagXmlParametricCurve::ToXml(std::string &xml, icConvertType nType, std::string blanks/* = */)
2983{
2984 return ToXml(xml, blanks);
2985}
2986
2987bool CIccTagXmlParametricCurve::ParseXml(xmlNode *pNode, icConvertType nType, std::string &parseStr)
2988{
2989 return ParseXml (pNode, parseStr);
2990}
2991
2992bool CIccTagXmlParametricCurve::ParseXml(xmlNode *pNode, std::string &parseStr)
2993{
2994 xmlNode *pCurveNode = icXmlFindNode(pNode->children, "ParametricCurve");
2995
2996 for (pCurveNode = pNode; pCurveNode; pCurveNode=pCurveNode->next) {
2997 if (pCurveNode->type==XML_ELEMENT_NODE) {
2998 if (!icXmlStrCmp(pCurveNode->name, "ParametricCurve")) {
2999
3000 const char *functionType = icXmlAttrValue(pCurveNode, "FunctionType");
3001
3002 if (!functionType)
3003 return false;
3004
3005 if (!SetFunctionType(atoi(functionType))){
3006 return false;
3007 }
3008 CIccFloatArray data;
3009
3010 if (!data.ParseArray(pCurveNode->children)){
3011 return false;
3012 }
3013
3014 if (data.GetSize()!=GetNumParam()){
3015 return false;
3016 }
3017
3019 icFloatNumber *dParams = GetParams();
3020 icFloatNumber *dataBuf = data.GetBuf();
3021 for (j=0; j<data.GetSize(); j++) {
3022 dParams[j] = dataBuf[j];
3023 }
3024
3025 xmlAttr *reserved2 = icXmlFindAttr(pCurveNode, "Reserved");
3026
3027 if (reserved2) {
3028 m_nReserved2 = (icUInt16Number)atoi(icXmlAttrValue(reserved2));
3029 }
3030 return true;
3031 }
3032 }
3033 }
3034 return false;
3035}
3036
3037
3038bool icCurvesToXml(std::string &xml, const char *szName, CIccCurve **pCurves, int numCurve, icConvertType nType, std::string blanks)
3039{
3040 if (pCurves) {
3041 int i;
3042
3043 xml += blanks + "<" + szName + ">\n";
3044 for (i=0; i<numCurve; i++) {
3045 IIccExtensionTag *pTag = pCurves[i]->GetExtension();
3046 if (!pTag || strcmp(pTag->GetExtDerivedClassName(), "CIccCurveXml"))
3047 return false;
3048
3049 if (!((CIccCurveXml *)pTag)->ToXml(xml, nType, blanks + " "))
3050 return false;
3051 }
3052 xml += blanks + "</" + szName + ">\n";
3053 }
3054 return true;
3055}
3056
3057
3058bool CIccTagXmlSegmentedCurve::ToXml(std::string &xml, std::string blanks/* = ""*/)
3059{
3060 if (m_pCurve)
3061 return ((CIccSegmentedCurveXml*)m_pCurve)->ToXml(xml, blanks);
3062
3063 return true;
3064}
3065
3066
3067bool CIccTagXmlSegmentedCurve::ToXml(std::string &xml, icConvertType nType, std::string blanks/* = */)
3068{
3069 return ToXml(xml, blanks);
3070}
3071
3072
3073bool CIccTagXmlSegmentedCurve::ParseXml(xmlNode *pNode, std::string &parseStr )
3074{
3075 xmlNode *pCurveNode = icXmlFindNode(pNode, "SegmentedCurve");
3076 if (pCurveNode) {
3078
3079 if (pCurve) {
3080 if (pCurve->ParseXml(pCurveNode, parseStr)) {
3081 SetCurve(pCurve);
3082 return true;
3083 }
3084 else {
3085 delete pCurve;
3086 return false;
3087 }
3088 }
3089 parseStr += "Unable to allocate Segmented Curve\n";
3090 return false;
3091 }
3092 parseStr += "Unable to find Segmented Curve\n";
3093 return false;
3094}
3095
3096
3097bool CIccTagXmlSegmentedCurve::ParseXml(xmlNode *pNode, icConvertType nType, std::string &parseStr)
3098{
3099 return ParseXml(pNode, parseStr);
3100}
3101
3102
3103bool icMatrixToXml(std::string &xml, CIccMatrix *pMatrix, std::string blanks)
3104{
3105 char buf[128];
3106 xml += blanks + "<Matrix\n";
3107
3108 sprintf(buf, " e1=\"" icXmlFloatFmt "\" e2=\"" icXmlFloatFmt "\" e3=\"" icXmlFloatFmt "\"\n", pMatrix->m_e[0], pMatrix->m_e[1], pMatrix->m_e[2]);
3109 xml += blanks + buf;
3110
3111 sprintf(buf, " e4=\"" icXmlFloatFmt "\" e5=\"" icXmlFloatFmt "\" e6=\"" icXmlFloatFmt "\"\n", pMatrix->m_e[3], pMatrix->m_e[4], pMatrix->m_e[5]);
3112 xml += blanks + buf;
3113
3114 sprintf(buf, " e7=\"" icXmlFloatFmt "\" e8=\"" icXmlFloatFmt "\" e9=\"" icXmlFloatFmt "\"", pMatrix->m_e[6], pMatrix->m_e[7], pMatrix->m_e[8]);
3115 xml += blanks + buf;
3116
3117 if (pMatrix->m_bUseConstants) {
3118 xml += "\n";
3119 sprintf(buf, " e10=\"" icXmlFloatFmt "\" e11=\"" icXmlFloatFmt "\" e12=\"" icXmlFloatFmt "\"", pMatrix->m_e[9], pMatrix->m_e[10], pMatrix->m_e[11]);
3120 xml += blanks + buf;
3121 }
3122 xml += "/>\n";
3123 return true;
3124}
3125
3126// for luts
3127bool icMBBToXml(std::string &xml, CIccMBB *pMBB, icConvertType nType, std::string blanks="", bool bSaveGridPoints=false)
3128{
3129 //blanks += " ";
3130 char buf[256];
3131
3132 sprintf(buf, "<Channels InputChannels=\"%d\" OutputChannels=\"%d\"/>\n", pMBB->InputChannels(), pMBB->OutputChannels());
3133 xml += blanks + buf;
3134
3135 if (pMBB->IsInputMatrix()) {
3136 if (pMBB->SwapMBCurves()) {
3137 if (pMBB->GetMatrix()) {
3138 // added if-statement
3139 if (!icMatrixToXml(xml, pMBB->GetMatrix(), blanks)) {
3140 return false;
3141 }
3142 }
3143
3144 if (pMBB->GetCurvesB()) {
3145 // added if-statement
3146 if (!icCurvesToXml(xml, "BCurves", pMBB->GetCurvesM(), pMBB->InputChannels(), nType, blanks)) {
3147 return false;
3148 }
3149 }
3150 }
3151 else {
3152 if (pMBB->GetCurvesB()) {
3153 // added if-statement
3154 if (!icCurvesToXml(xml, "BCurves", pMBB->GetCurvesB(), pMBB->InputChannels(), nType, blanks)) {
3155 return false;
3156 }
3157 }
3158
3159 if (pMBB->GetMatrix()) {
3160 // added if-statement
3161 if (!icMatrixToXml(xml, pMBB->GetMatrix(), blanks)) {
3162 return false;
3163 }
3164 }
3165
3166 if (pMBB->GetCurvesM()) {
3167 // added if-statement
3168 if (!icCurvesToXml(xml, "MCurves", pMBB->GetCurvesM(), 3, nType, blanks)){
3169 return false;
3170 }
3171 }
3172 }
3173
3174 if (pMBB->GetCLUT()) {
3175 // added if-statement
3176 if (!icCLUTToXml(xml, pMBB->GetCLUT(), nType, blanks, bSaveGridPoints)){
3177 return false;
3178 }
3179 }
3180
3181 if (pMBB->GetCurvesA()) {
3182 // added if-statement
3183 if (!icCurvesToXml(xml, "ACurves", pMBB->GetCurvesA(), pMBB->OutputChannels(), nType, blanks)){
3184 return false;
3185 }
3186 }
3187 }
3188 else {
3189 if (pMBB->GetCurvesA()) {
3190 // added if-statement
3191 if (!icCurvesToXml(xml, "ACurves", pMBB->GetCurvesA(), pMBB->InputChannels(), nType, blanks)){
3192 return false;
3193 }
3194 }
3195
3196 if (pMBB->GetCLUT()) {
3197 // added if-statement
3198 if (!icCLUTToXml(xml, pMBB->GetCLUT(), nType, blanks, bSaveGridPoints)){
3199 return false;
3200 }
3201 }
3202
3203 if (pMBB->GetCurvesM()) {
3204 // added if-statement
3205 if (!icCurvesToXml(xml, "MCurves", pMBB->GetCurvesM(), 3, nType, blanks)){
3206 return false;
3207 }
3208 }
3209
3210 if (pMBB->GetMatrix()) {
3211 // added if-statement
3212 if (!icMatrixToXml(xml, pMBB->GetMatrix(), blanks)) {
3213 return false;
3214 }
3215 }
3216
3217 if (pMBB->GetCurvesB()) {
3218 // added if-statement
3219 if (!icCurvesToXml(xml, "BCurves", pMBB->GetCurvesB(), pMBB->OutputChannels(), nType, blanks)){
3220 return false;
3221 }
3222 }
3223 }
3224 return true;
3225}
3226
3227
3228bool icCurvesFromXml(LPIccCurve *pCurve, icUInt32Number nChannels, xmlNode *pNode, icConvertType nType, std::string &parseStr)
3229{
3231 xmlNode *pCurveNode;
3232
3233 for (i=0, pCurveNode = pNode; i<nChannels && pCurveNode; pCurveNode=pCurveNode->next) {
3234 if (pCurveNode->type==XML_ELEMENT_NODE) {
3235 CIccCurve *pCurveTag = NULL;
3236 if (!icXmlStrCmp(pCurveNode->name, "Curve")) {
3237 pCurveTag = new CIccTagXmlCurve;
3238 }
3239 else if (!icXmlStrCmp(pCurveNode->name, "ParametricCurve")) {
3240 pCurveTag = new CIccTagXmlParametricCurve();
3241 }
3242
3243 if (pCurveTag) {
3244 IIccExtensionTag *pExt = pCurveTag->GetExtension();
3245
3246 if (pExt) {
3247 if (!strcmp(pExt->GetExtDerivedClassName(), "CIccCurveXml")) {
3248 CIccCurveXml *pCurveXml = (CIccCurveXml *)pExt;
3249
3250 if (pCurveXml->ParseXml(pCurveNode, nType, parseStr)) {
3251 pCurve[i] = pCurveTag;
3252 i++;
3253 }
3254 // added else statement
3255 else {
3256 char num[40];
3257 parseStr += "Unable to parse curve at Line";
3258 sprintf(num, "%d\n", pCurveNode->line);
3259 parseStr += num;
3260 return false;
3261 }
3262 }
3263 else if (!strcmp(pExt->GetExtClassName(), "CIccTagXml")) {
3264 CIccTagXml *pXmlTag = (CIccTagXml *)pExt;
3265
3266 if (pXmlTag->ParseXml(pCurveNode, parseStr)) {
3267 pCurve[i] = pCurveTag;
3268 i++;
3269 }
3270 // added else statement
3271 else {
3272 char num[40];
3273 parseStr += "Unable to parse curve tag at Line";
3274 sprintf(num, "%d\n", pCurveNode->line);
3275 parseStr += num;
3276 return false;
3277 }
3278 }
3279 }
3280 }
3281 }
3282 }
3283 if (!i != nChannels) {
3284 parseStr += "Channel number mismatch!\n";
3285 }
3286 return i==nChannels;
3287}
3288
3289bool icMatrixFromXml(CIccMatrix *pMatrix, xmlNode *pNode)
3290{
3291 memset(pMatrix->m_e, 0, sizeof(pMatrix->m_e));
3292 pMatrix->m_bUseConstants = false;
3293
3294 char attrName[15];
3295 int i;
3296
3297 for (i=0; i<9; i++) {
3298 sprintf(attrName, "e%d", i+1);
3299 xmlAttr *attr = icXmlFindAttr(pNode, attrName);
3300 if (attr) {
3301 pMatrix->m_e[i] = (icFloatNumber)atof(icXmlAttrValue(attr));
3302 }
3303 }
3304 for (i=9; i<12; i++) {
3305 sprintf(attrName, "e%d", i+1);
3306 xmlAttr *attr = icXmlFindAttr(pNode, attrName);
3307 if (attr) {
3308 pMatrix->m_e[i] = (icFloatNumber)atof(icXmlAttrValue(attr));
3309 pMatrix->m_bUseConstants = true;
3310 }
3311 }
3312 return true;
3313}
3314
3315CIccCLUT *icCLutFromXml(xmlNode *pNode, int nIn, int nOut, icConvertType nType, std::string &parseStr)
3316{
3317 CIccCLUT *pCLUT = NULL;
3318
3319 int nPrecision = 2;
3320 if (nType == icConvert8Bit)
3321 nPrecision = 1;
3322
3323 icUInt8Number nInput = (icUInt8Number)nIn;
3324 icUInt16Number nOutput = (icUInt16Number)nOut;
3325
3326 pCLUT = new CIccCLUT(nInput, nOutput, nPrecision);
3327
3328 if (!pCLUT){
3329 parseStr += "Error in creating CLUT Table. Check values of Precision, InputChannel, or OutputChannels.\n";
3330 return NULL;
3331 }
3332
3333 xmlNode *grid = icXmlFindNode(pNode->children, "GridPoints");
3334 if (grid) {
3335 CIccUInt8Array points;
3336
3337 if (points.ParseArray(grid->children)) {
3338 if (!pCLUT->Init(points.GetBuf())) {
3339 parseStr += "Error in setting the size of GridPoints. Check values of GridPoints, InputChannel, or OutputChannels.\n";
3340 delete pCLUT;
3341 return NULL;
3342 }
3343 }
3344 else {
3345 parseStr += "Error parsing GridPoints.\n";
3346 delete pCLUT;
3347 return NULL;
3348 }
3349 }
3350 else {
3351 icUInt8Number nGridGranularity;
3352
3353 xmlAttr *gridGranularity = icXmlFindAttr(pNode, "GridGranularity");
3354
3355 if (gridGranularity) {
3356 nGridGranularity = (icUInt8Number)atoi(icXmlAttrValue(gridGranularity));
3357 }
3358 else {
3359 delete pCLUT;
3360 return NULL;
3361 }
3362 if (!pCLUT->Init(nGridGranularity)) {
3363 parseStr += "Error in setting the size of GridGranularity. Check values of GridGranularity, InputChannel, or OutputChannels.\n";
3364 delete pCLUT;
3365 return NULL;
3366 }
3367 }
3368
3369 xmlNode *table = icXmlFindNode(pNode->children, "TableData");
3370
3371 if (table) {
3372 if (nType == icConvertVariable) {
3373 const char *precision = icXmlAttrValue(table, "Precision");
3374 if (precision && atoi(precision) == 1) {
3375 nType = icConvert8Bit;
3376 pCLUT->SetPrecision(1);
3377 }
3378 else {
3379 nType = icConvert16Bit;
3380 pCLUT->SetPrecision(2);
3381 }
3382 }
3383
3384 const char *filename = icXmlAttrValue(table, "Filename");
3385 if (!filename || !filename[0]) {
3386 filename = icXmlAttrValue(table, "File");
3387 }
3388
3389 if (filename[0]) {
3390 CIccIO *file = IccOpenFileIO(filename, "rb");
3391
3392 if (!file) {
3393 // added error message
3394 parseStr += "Error! - File '";
3395 parseStr += filename;
3396 parseStr +="' not found.\n";
3397 delete pCLUT;
3398 return NULL;
3399 }
3400
3401 const char *format = icXmlAttrValue(table, "Format");
3402
3403 if (!strcmp(format, "text")) {
3404 icUInt32Number num = file->GetLength();
3405 char *buf = (char *)malloc(num);
3406
3407 if (!buf) {
3408 perror("Memory Error");
3409 parseStr += "'";
3410 parseStr += filename;
3411 parseStr += "' may not be a valid text file.\n";
3412 delete file;
3413 delete pCLUT;
3414 return NULL;
3415 }
3416
3417 //Allow for different encoding in text file than implied by the table type
3418 const char *encoding = icXmlAttrValue(table, "FileEncoding");
3419
3420 if (!strcmp(encoding, "int8"))
3421 nType = icConvert8Bit;
3422 else if (!strcmp(encoding, "int16"))
3423 nType = icConvert16Bit;
3424 else if (!strcmp(encoding, "float"))
3425 nType = icConvertFloat;
3426 else if (encoding[0]) {
3427 parseStr+= "Unknown encoding \"";
3428 parseStr+= encoding;
3429 parseStr+= "\" - using default encoding\n";
3430 }
3431
3432 if (file->Read8(buf, num)!=num) {
3433 perror("Read-File Error");
3434 parseStr += "'";
3435 parseStr += filename;
3436 parseStr += "' may not be a valid text file.\n";
3437 free(buf);
3438 delete file;
3439 delete pCLUT;
3440 return NULL;
3441 }
3442
3443 if (nType == icConvert8Bit) {
3444 CIccUInt8Array data;
3445
3446 if (!data.ParseTextArrayNum(buf, num, parseStr)) {
3447 parseStr += "File '";
3448 parseStr += filename;
3449 parseStr += "' is not a valid text file.\n";
3450 free(buf);
3451 delete file;
3452 delete pCLUT;
3453 return NULL;
3454 }
3455
3456 if (data.GetSize()!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3457 parseStr += "Error! - Number of entries in file '";
3458 parseStr += filename;
3459 parseStr += "'is not equal to the size of the CLUT Table.\n";
3460 parseStr += " a. Check values of GridGranularity/GridPoints, InputChannel, or OutputChannels.\n";
3461 parseStr += " b. File may not be a valid text file.\n";
3462 free(buf);
3463 delete file;
3464 delete pCLUT;
3465 return NULL;
3466 }
3467 icUInt8Number *src = data.GetBuf();
3468 icFloatNumber *dst = pCLUT->GetData(0);
3469
3471 for (i=0; i<data.GetSize(); i++) {
3472 *dst++ = (icFloatNumber)(*src++) / 255.0f;
3473 }
3474 }
3475 else if (nType == icConvert16Bit) {
3476 CIccUInt16Array data;
3477
3478 if (!data.ParseTextArrayNum(buf, num, parseStr)) {
3479 parseStr += "File '";
3480 parseStr += filename;
3481 parseStr += "' is not a valid text file.\n";
3482 free(buf);
3483 delete file;
3484 delete pCLUT;
3485 return NULL;
3486 }
3487
3488 if (data.GetSize()!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3489 parseStr += "Error! - Number of entries in file '";
3490 parseStr += filename;
3491 parseStr += "'is not equal to the size of the CLUT Table.\n";
3492 parseStr += " a. Check values of GridGranularity/GridPoints, InputChannel, or OutputChannels.\n";
3493 parseStr += " b. File may not be a valid text file.\n";
3494 free(buf);
3495 delete file;
3496 delete pCLUT;
3497 return NULL;
3498 }
3499 icUInt16Number *src = data.GetBuf();
3500 icFloatNumber *dst = pCLUT->GetData(0);
3501
3503 for (i=0; i<data.GetSize(); i++) {
3504 *dst++ = (icFloatNumber)(*src++) / 65535.0f;
3505 }
3506 }
3507 else if (nType == icConvertFloat) {
3508 CIccFloatArray data;
3509
3510 if (!data.ParseTextArrayNum(buf, num, parseStr)) {
3511 parseStr += "File '";
3512 parseStr += filename;
3513 parseStr += "' is not a valid text file.\n";
3514 free(buf);
3515 delete file;
3516 delete pCLUT;
3517 return NULL;
3518 }
3519
3520 if (data.GetSize()!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3521 parseStr += "Error! - Number of entries in file '";
3522 parseStr += filename;
3523 parseStr += "'is not equal to the size of the CLUT Table.\n";
3524 parseStr += " a. Check values of GridGranularity/GridPoints, InputChannel, or OutputChannels.\n";
3525 parseStr += " b. File may not be a valid text file.\n";
3526 free(buf);
3527 delete file;
3528 delete pCLUT;
3529 return NULL;
3530 }
3531 icFloatNumber *src = data.GetBuf();
3532 icFloatNumber *dst = pCLUT->GetData(0);
3533
3535 for (i=0; i<data.GetSize(); i++) {
3536 *dst++ = *src++;
3537 }
3538 }
3539 else {
3540 parseStr += "Error! Unknown text data type.\n";
3541 free(buf);
3542 delete file;
3543 delete pCLUT;
3544 return NULL;
3545 }
3546 free(buf);
3547 }
3548 else if (!strcmp(format, "binary")) {
3549 const char *order = icXmlAttrValue(table, "Endian");
3550 bool little_endian = !strcmp(order, "little");
3551
3552 if (nType==icConvertVariable) {
3553 //Allow encoding to be defined
3554 const char *encoding = icXmlAttrValue(table, "FileEncoding");
3555
3556 if (!strcmp(encoding, "int8"))
3557 nType = icConvert8Bit;
3558 else if (!strcmp(encoding, "int16"))
3559 nType = icConvert16Bit;
3560 else if (!strcmp(encoding, "float"))
3561 nType = icConvertFloat;
3562 else if (encoding[0]) {
3563 parseStr+= "Unknown encoding \"";
3564 parseStr+= encoding;
3565 parseStr+= "\" - using int16.\n";
3566 nType = icConvert16Bit;
3567 }
3568 else {
3569 parseStr+= "CLUT TableData Encoding type not specified.\n";
3570 }
3571 }
3572
3573 if (nType == icConvert8Bit){
3574 icUInt32Number num = file->GetLength();
3575 icUInt8Number value;
3576 // if number of entries in file is not equal to size of CLUT table, flag as error
3577 if (num!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3578 parseStr += "Error! - Number of entries in file '";
3579 parseStr += filename;
3580 parseStr += "'is not equal to the size of the CLUT Table.\n";
3581 parseStr += " a. Check values of GridGranularity/GridPoints, InputChannel, or OutputChannels.\n";
3582 parseStr += " b. File may not be a valid binary file.\n";
3583 delete file;
3584 delete pCLUT;
3585 return NULL;
3586 }
3587 icFloatNumber *dst = pCLUT->GetData(0);
3589 for (i=0; i<num; i++) {
3590 if (!file->Read8(&value)) {
3591 perror("Read-File Error");
3592 parseStr += "'";
3593 parseStr += filename;
3594 parseStr += "' may not be a valid binary file.\n";
3595 delete file;
3596 delete pCLUT;
3597 return NULL;
3598 }
3599 *dst++ = (icFloatNumber)value / 255.0f;
3600 }
3601 }
3602 else if (nType == icConvert16Bit){
3603 icUInt32Number num = file->GetLength() / sizeof(icUInt16Number);
3604 icUInt16Number value;
3605 icUInt8Number *ptr = (icUInt8Number*)&value;
3606
3607 if (num<pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3608 parseStr += "Error! - Number of entries in file '";
3609 parseStr += filename;
3610 parseStr += "'is not equal to the size of the CLUT Table.\n";
3611 parseStr += " a. Check values of GridGranularity/GridPoints, InputChannel, or OutputChannels.\n";
3612 parseStr += " b. File may not be a valid binary file.\n";
3613 delete file;
3614 delete pCLUT;
3615 return NULL;
3616 }
3617 icFloatNumber *dst = pCLUT->GetData(0);
3618
3620 for (i=0; i<num; i++) {
3621 if (!file->Read16(&value)) { //this assumes data is big endian
3622 perror("Read-File Error");
3623 parseStr += "'";
3624 parseStr += filename;
3625 parseStr += "' may not be a valid binary file.\n";
3626 delete file;
3627 delete pCLUT;
3628 return NULL;
3629 }
3630#ifdef ICC_BYTE_ORDER_LITTLE_ENDIAN
3631 if (little_endian) {
3632#else
3633 if (!little_endian) {
3634#endif
3635 icUInt8Number t = ptr[0];
3636 ptr[0] = ptr[1];
3637 ptr[1] = t;
3638 }
3639 *dst++ = (icFloatNumber)value / 65535.0f;
3640 }
3641 }
3642 else if (nType == icConvertFloat){
3643 icUInt32Number num = file->GetLength()/sizeof(icFloat32Number);
3644 icFloat32Number value;
3645 icUInt8Number *ptr = (icUInt8Number*)&value;
3646
3647 if (num<pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3648 parseStr += "Error! - Number of entries in file '";
3649 parseStr += filename;
3650 parseStr += "'is not equal to the size of the CLUT Table.\n";
3651 parseStr += " a. Check values of GridGranularity/GridPoints, InputChannel, or OutputChannels.\n";
3652 parseStr += " b. File may not be a valid binary file.\n";
3653 delete file;
3654 delete pCLUT;
3655 return NULL;
3656 }
3657 icFloatNumber *dst = pCLUT->GetData(0);
3658
3660 for (i=0; i<num; i++) {
3661 if (!file->ReadFloat32Float(&value)) { //this assumes data is big endian
3662 perror("Read-File Error");
3663 parseStr += "'";
3664 parseStr += filename;
3665 parseStr += "' may not be a valid binary file.\n";
3666 delete file;
3667 delete pCLUT;
3668 return NULL;
3669 }
3670#ifdef ICC_BYTE_ORDER_LITTLE_ENDIAN
3671 if (little_endian) {
3672#else
3673 if (!little_endian) {
3674#endif
3675 icUInt8Number tmp;
3676 tmp = ptr[0]; ptr[0] = ptr[3]; ptr[3] = tmp;
3677 tmp = ptr[1]; ptr[1] = ptr[2]; ptr[2] = tmp;
3678 }
3679 *dst++ = value;
3680 }
3681 }
3682 else {
3683 parseStr += "Error! Unknown binary data type.\n";
3684 delete file;
3685 delete pCLUT;
3686 return NULL;
3687 }
3688
3689 }
3690 else {
3691 parseStr += "Error! Unknown Format type.\n";
3692 delete pCLUT;
3693 return NULL;
3694 }
3695
3696 delete file;
3697 }
3698 else { // no file
3699 if (nType == icConvert8Bit) {
3700 CIccUInt8Array data;
3701
3702 if (!data.ParseArray(table->children)) {
3703 parseStr += "Error! - unable to parse data in CLUT.\n";
3704 delete pCLUT;
3705 return NULL;
3706 }
3707
3708 if (data.GetSize()!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3709 parseStr += "Error! - Number of entries is not equal to the size of the CLUT Table.\n";
3710 delete pCLUT;
3711 return NULL;
3712 }
3713 icUInt8Number *src = data.GetBuf();
3714 icFloatNumber *dst = pCLUT->GetData(0);
3715
3717 for (i=0; i<data.GetSize(); i++) {
3718 *dst++ = (icFloatNumber)(*src++) / 255.0f;
3719 }
3720 }
3721 else if (nType == icConvert16Bit || nType==icConvertVariable) {
3722 CIccUInt16Array data;
3723
3724 if (!data.ParseArray(table->children)) {
3725 parseStr += "Error! - unable to parse data in CLUT.\n";
3726 delete pCLUT;
3727 return NULL;
3728 }
3729
3730 if (data.GetSize()!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3731 parseStr += "Error! - Number of entries is not equal to the size of the CLUT Table.\n";
3732 delete pCLUT;
3733 return NULL;
3734 }
3735 icUInt16Number *src = data.GetBuf();
3736 icFloatNumber *dst = pCLUT->GetData(0);
3737
3739 for (i=0; i<data.GetSize(); i++) {
3740 *dst++ = (icFloatNumber)(*src++) / 65535.0f;
3741 }
3742 }
3743 else if (nType == icConvertFloat){
3744 CIccFloatArray data;
3745
3746 if (!data.ParseArray(table->children)) {
3747 parseStr += "Error! - unable to parse data in CLUT.\n";
3748 delete pCLUT;
3749 return NULL;
3750 }
3751
3752 if (data.GetSize()!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3753 parseStr += "Error! - Number of entries is not equal to the size of the CLUT Table.\n";
3754 delete pCLUT;
3755 return NULL;
3756 }
3757 icFloatNumber *src = data.GetBuf();
3758 icFloatNumber *dst = pCLUT->GetData(0);
3759
3761 for (i=0; i<data.GetSize(); i++) {
3762 *dst++ = *src++;
3763 }
3764 }
3765 else {
3766 parseStr += "Error! Unknown table data type.";
3767 delete pCLUT;
3768 return NULL;
3769 }
3770 }
3771 }
3772 else {
3773 parseStr += "Error! Cannot find table data.";
3774 delete pCLUT;
3775 return NULL;
3776 }
3777
3778 return pCLUT;
3779}
3780
3781bool icMBBFromXml(CIccMBB *pMBB, xmlNode *pNode, icConvertType nType, std::string &parseStr)
3782{
3783 xmlNode *pChannels = icXmlFindNode(pNode, "Channels");
3784
3785 if (!pChannels)
3786 return false;
3787
3788 xmlAttr *in = icXmlFindAttr(pChannels, "InputChannels");
3789 xmlAttr *out = icXmlFindAttr(pChannels, "OutputChannels");
3790
3791 if (!in || !out)
3792 return false;
3793
3794 int nIn = atoi(icXmlAttrValue(in));
3795 int nOut = atoi(icXmlAttrValue(out));
3796
3797 pMBB->Init(nIn, nOut);
3798
3799 for (; pNode; pNode = pNode->next) {
3800 if (pNode->type == XML_ELEMENT_NODE) {
3801 if (!icXmlStrCmp(pNode->name, "ACurves") && !pMBB->GetCurvesA()) {
3802 LPIccCurve *pCurves = pMBB->NewCurvesA();
3803 if (!icCurvesFromXml(pCurves, !pMBB->IsInputB() ? nIn : nOut, pNode->children, nType, parseStr)) {
3804 parseStr += "Error! - Failed to parse ACurves.\n";
3805 return false;
3806 }
3807 }
3808 else if (!icXmlStrCmp(pNode->name, "BCurves") && !pMBB->GetCurvesB()) {
3809 LPIccCurve *pCurves = pMBB->NewCurvesB();
3810 if (!icCurvesFromXml(pCurves, pMBB->IsInputB() ? nIn : nOut, pNode->children, nType, parseStr)) {
3811 parseStr += "Error! - Failed to parse BCurves.\n";
3812 return false;
3813 }
3814 }
3815 else if (!icXmlStrCmp(pNode->name, "MCurves") && !pMBB->GetCurvesM()) {
3816 LPIccCurve *pCurves = pMBB->NewCurvesM();
3817 if (!icCurvesFromXml(pCurves, !pMBB->IsInputMatrix() ? nIn : nOut, pNode->children, nType, parseStr)) {
3818 parseStr += "Error! - Failed to parse MCurves.\n";
3819 return false;
3820 }
3821 }
3822 else if (!icXmlStrCmp(pNode->name, "Matrix") && !pMBB->GetMatrix()) {
3823 CIccMatrix *pMatrix = pMBB->NewMatrix();
3824 if (!icMatrixFromXml(pMatrix, pNode)) {
3825 parseStr += "Error! - Failed to parse Matrix.\n";
3826 return false;
3827 }
3828 }
3829 else if (!icXmlStrCmp(pNode->name, "CLUT") && !pMBB->GetCLUT()) {
3830 CIccCLUT *pCLUT = icCLutFromXml(pNode, nIn, nOut, nType, parseStr);
3831 if (pCLUT) {
3832 if (!pMBB->SetCLUT(pCLUT)) {
3833 parseStr += "Error! - Failed to set CLUT to LUT.\n";
3834 return false;
3835 }
3836 }
3837 else {
3838 parseStr += "Error! - Failed to parse CLUT.\n";
3839 return false;
3840 }
3841 }
3842 }
3843 }
3844
3845 return true;
3846}
3847
3848bool CIccTagXmlLutAtoB::ToXml(std::string &xml, std::string blanks/* = ""*/)
3849{
3850 std::string info;
3851
3852 bool rv = icMBBToXml(xml, this, icConvertVariable, blanks, true);
3853
3854 return rv;
3855}
3856
3857
3858bool CIccTagXmlLutAtoB::ParseXml(xmlNode *pNode, std::string &parseStr)
3859{
3860
3861 if (pNode) {
3862 return icMBBFromXml(this, pNode, icConvertVariable, parseStr);
3863 }
3864
3865 return false;
3866}
3867
3868
3869bool CIccTagXmlLutBtoA::ToXml(std::string &xml, std::string blanks/* = ""*/)
3870{
3871 std::string info;
3872
3873 bool rv = icMBBToXml(xml, this, icConvertVariable, blanks, true);
3874
3875 return rv;
3876}
3877
3878
3879bool CIccTagXmlLutBtoA::ParseXml(xmlNode *pNode, std::string &parseStr)
3880{
3881 if (pNode) {
3882 return icMBBFromXml(this, pNode, icConvertVariable, parseStr);
3883 }
3884
3885 return false;
3886}
3887
3888
3889bool CIccTagXmlLut8::ToXml(std::string &xml, std::string blanks/* = ""*/)
3890{
3891 std::string info;
3892
3893 bool rv = icMBBToXml(xml, this, icConvert8Bit, blanks, false);
3894
3895 return rv;
3896}
3897
3898
3899bool CIccTagXmlLut8::ParseXml(xmlNode *pNode, std::string &parseStr)
3900{
3901
3902 if (pNode) {
3903 return icMBBFromXml(this, pNode, icConvert8Bit, parseStr);
3904 }
3905 return false;
3906}
3907
3908
3909bool CIccTagXmlLut16::ToXml(std::string &xml, std::string blanks/* = ""*/)
3910{
3911 std::string info;
3912
3913 bool rv = icMBBToXml(xml, this, icConvert16Bit, blanks, false);
3914
3915 return rv;
3916}
3917
3918
3919bool CIccTagXmlLut16::ParseXml(xmlNode *pNode, std::string &parseStr)
3920{
3921 if (pNode) {
3922 return icMBBFromXml(this, pNode, icConvert16Bit, parseStr);
3923 }
3924 return false;
3925}
3926
3927
3928bool CIccTagXmlMultiProcessElement::ToXml(std::string &xml, std::string blanks/* = ""*/)
3929{
3930 std::string info;
3931 char line[256];
3932
3933 CIccMultiProcessElementList::iterator i;
3934
3935 sprintf(line, "<MultiProcessElements InputChannels=\"%d\" OutputChannels=\"%d\">\n", NumInputChannels(), NumOutputChannels());
3936 xml += blanks + line;
3937
3938 for (i=m_list->begin(); i!=m_list->end(); i++) {
3939 if (i->ptr) {
3940 CIccMultiProcessElement *pMpe = i->ptr;
3941
3942 IIccExtensionMpe *pMpeExt = pMpe->GetExtension();
3943
3944 if (pMpeExt) {
3945 if (!strcmp(pMpeExt->GetExtClassName(), "CIccMpeXml")) {
3946 CIccMpeXml *pMpeXml = (CIccMpeXml*)pMpeExt;
3947
3948 pMpeXml->ToXml(xml, blanks + " ");
3949 }
3950 else {
3951 return false;
3952 }
3953 }
3954 else {
3955 return false;
3956 }
3957 }
3958 }
3959 xml += blanks + "</MultiProcessElements>\n";
3960 return true;
3961}
3962
3963
3965{
3966 if (!strcmp(szElementNodeName, "CurveSetElement")) {
3967 return new CIccMpeXmlCurveSet;
3968 }
3969 if (!strcmp(szElementNodeName, "MatrixElement")) {
3970 return new CIccMpeXmlMatrix;
3971 }
3972 if (!strcmp(szElementNodeName, "CLutElement")) {
3973 return new CIccMpeXmlCLUT;
3974 }
3975 if (!strcmp(szElementNodeName, "ExtCLutElement")) {
3976 return new CIccMpeXmlExtCLUT;
3977 }
3978 if (!strcmp(szElementNodeName, "CalculatorElement")) {
3979 return new CIccMpeXmlCalculator;
3980 }
3981 if (!strcmp(szElementNodeName, "TintArrayElement")) {
3982 return new CIccMpeXmlTintArray;
3983 }
3984 if (!strcmp(szElementNodeName, "ToneMapElement")) {
3985 return new CIccMpeXmlToneMap;
3986 }
3987 if (!strcmp(szElementNodeName, "JabToXYZElement")) {
3988 return new CIccMpeXmlJabToXYZ;
3989 }
3990 if (!strcmp(szElementNodeName, "UnknownElement")) {
3991 return new CIccMpeXmlUnknown;
3992 }
3993 if (!strcmp(szElementNodeName, "XYZToJabElement")) {
3994 return new CIccMpeXmlXYZToJab;
3995 }
3996 if (!strcmp(szElementNodeName, "EmissionMatrixElement")) {
3997 return new CIccMpeXmlEmissionMatrix;
3998 }
3999 if (!strcmp(szElementNodeName, "InvEmissionMatrixElement")) {
4000 return new CIccMpeXmlInvEmissionMatrix;
4001 }
4002 if (!strcmp(szElementNodeName, "EmissionCLutElement")) {
4003 return new CIccMpeXmlEmissionCLUT;
4004 }
4005 if (!strcmp(szElementNodeName, "ReflectanceCLutElement")) {
4006 return new CIccMpeXmlReflectanceCLUT;
4007 }
4008 if (!strcmp(szElementNodeName, "EmissionObserverElement")) {
4009 return new CIccMpeXmlEmissionObserver;
4010 }
4011 if (!strcmp(szElementNodeName, "ReflectanceObserverElement")) {
4013 }
4014 if (!strcmp(szElementNodeName, "BAcsElement")) {
4015 return new CIccMpeXmlBAcs;
4016 }
4017 if (!strcmp(szElementNodeName, "EAcsElement")) {
4018 return new CIccMpeXmlEAcs;
4019 }
4020 return NULL;
4021}
4022
4023
4024bool CIccTagXmlMultiProcessElement::ParseElement(xmlNode *pNode, std::string &parseStr)
4025{
4026 xmlAttr *attr;
4027
4028 if (pNode->type != XML_ELEMENT_NODE) {
4029 return false;
4030 }
4031
4032 CIccMultiProcessElement *pMpe = CreateElement((const icChar*)pNode->name);
4033
4034 if (!pMpe) {
4035 parseStr += std::string("Unknown Element Type (") + (const icChar*)pNode->name + ")\n";
4036 return false;
4037 }
4038
4040
4041 IIccExtensionMpe *pExt = pMpe->GetExtension();
4042
4043 if (pExt) {
4044 if (!strcmp(pExt->GetExtClassName(), "CIccMpeXml")) {
4045 CIccMpeXml* pXmlMpe = (CIccMpeXml*)pExt;
4046
4047 if (pXmlMpe->ParseXml(pNode, parseStr)) {
4048 if ((attr=icXmlFindAttr(pNode, "Reserved"))) {
4049 sscanf(icXmlAttrValue(attr), "%u", &pMpe->m_nReserved);
4050 }
4051
4052 ptr.ptr = pMpe;
4053 m_list->push_back(ptr);
4054 }
4055 else {
4056 parseStr += std::string("Unable to parse element of type ") + pMpe->GetClassName() + "\n";
4057 delete pMpe;
4058 return false;
4059 }
4060 }
4061 else {
4062 parseStr += std::string("Element ") + pMpe->GetClassName() + "isn't of type CIccMpeXml\n";
4063 delete pMpe;
4064 return false;
4065 }
4066 }
4067 else {
4068 parseStr += std::string("Element ") + pMpe->GetClassName() + "isn't of type CIccMpeXml\n";
4069 delete pMpe;
4070 return false;
4071 }
4072
4073 return true;
4074}
4075
4076
4077bool CIccTagXmlMultiProcessElement::ParseXml(xmlNode *pNode, std::string &parseStr)
4078{
4079 pNode = icXmlFindNode(pNode, "MultiProcessElements");
4080
4081 if (!pNode) {
4082 parseStr += "Cannot Find MultiProcessElements\n";
4083 return false;
4084 }
4085
4086 xmlAttr *pInputChannels = icXmlFindAttr(pNode, "InputChannels");
4087 xmlAttr *pOutputChannels = icXmlFindAttr(pNode, "OutputChannels");
4088
4089 if (!pInputChannels || !pOutputChannels) {
4090 parseStr += "Invalid channels in MultiProcessElements\n";
4091 return false;
4092 }
4093
4094 m_nInputChannels = atoi(icXmlAttrValue(pInputChannels));
4095 m_nOutputChannels = atoi(icXmlAttrValue(pOutputChannels));
4096
4097 if (!m_list) {
4098 m_list = new CIccMultiProcessElementList();
4099 }
4100 else {
4101 m_list->clear();
4102 }
4103
4104 xmlNode *elemNode;
4105 for (elemNode = pNode->children; elemNode; elemNode = elemNode->next) {
4106 if (elemNode->type == XML_ELEMENT_NODE) {
4107 if (!ParseElement(elemNode, parseStr)) {
4108 char str[100];
4109 parseStr += "Unable to parse element (";
4110 parseStr += (char*)elemNode->name;
4111 sprintf(str, ") starting on line %d\n", elemNode->line);
4112 parseStr += str;
4113 return false;
4114 }
4115 }
4116 }
4117
4118 return true;
4119}
4120
4121
4122bool CIccTagXmlProfileSequenceId::ToXml(std::string &xml, std::string blanks/* = ""*/)
4123{
4124 std::string info;
4125
4126 xml += blanks + "<ProfileSequenceId>\n";
4127
4128 CIccProfileIdDescList::iterator pid;
4129
4130 for (pid=m_list->begin(); pid!=m_list->end(); pid++) {
4131 char buf[256];
4132 char data[256];
4133 char fix[256];
4134 std::string bufstr;
4135 int n;
4136
4137 for (n=0; n<16; n++) {
4138 sprintf(buf + n*2, "%02X", pid->m_profileID.ID8[n]);
4139 }
4140 buf[n*2]='\0';
4141 xml += blanks + " <ProfileIdDesc id=\"";
4142 xml += buf;
4143 xml += "\">\n";
4144
4145 if (pid->m_desc.m_Strings) {
4146 CIccMultiLocalizedUnicode::iterator i;
4147
4148 for (i=pid->m_desc.m_Strings->begin(); i!=pid->m_desc.m_Strings->end(); i++) {
4149 sprintf(buf, "<LocalizedText LanguangeCountry=\"%s\"", icFixXml(fix, icGetSigStr(data, (i->m_nLanguageCode<<16) + i->m_nCountryCode)));
4150 xml += blanks + buf;
4151
4152 sprintf(buf, ">%s</LocalizedText>\n", icFixXml(fix, icUtf16ToUtf8(bufstr, i->GetBuf(), i->GetLength())));
4153 xml += buf;
4154 }
4155 }
4156 xml += blanks + " </ProfileIdDesc>\n";
4157 }
4158
4159 xml += blanks + "</ProfileSequenceId>\n";
4160 return true;
4161}
4162
4163
4164bool CIccTagXmlProfileSequenceId::ParseXml(xmlNode *pNode, std::string &parseStr)
4165{
4166 pNode = icXmlFindNode(pNode, "ProfileSequenceId");
4167
4168 if (!pNode)
4169 return false;
4170
4171 m_list->clear();
4172
4173 for (pNode = icXmlFindNode(pNode->children, "ProfileIdDesc"); pNode; pNode = icXmlFindNode(pNode->next, "ProfileIdDesc")) {
4174 CIccProfileIdDesc desc;
4175 const icChar *szDesc = icXmlAttrValue(pNode, "id");
4176
4177 if (szDesc && *szDesc)
4178 icXmlGetHexData(&desc.m_profileID, szDesc, sizeof(desc.m_profileID));
4179
4180 xmlAttr *langCode;
4181
4182 for (pNode = icXmlFindNode(pNode, "LocalizedText"); pNode; pNode = icXmlFindNode(pNode->next, "LocalizedText")) {
4183 if ((langCode = icXmlFindAttr(pNode, "languageCountry")) &&
4184 pNode->children) {
4185 xmlNode *pText;
4186
4187 for (pText = pNode->children; pText && pText->type != XML_TEXT_NODE; pText = pText->next);
4188
4189 if (pText) {
4191 CIccUTF16String str((const char*)pText->content);
4192 desc.m_desc.SetText(str.c_str(), (icLanguageCode)(lc>>16), (icCountryCode)(lc & 0xffff));
4193 }
4194 else {
4195 desc.m_desc.SetText("");
4196 }
4197 }
4198 }
4199 m_list->push_back(desc);
4200 }
4201
4202 return true;
4203}
4204
4205
4206bool CIccTagXmlDict::ToXml(std::string &xml, std::string blanks/* = ""*/)
4207{
4208 std::string info;
4209
4210 CIccNameValueDict::iterator nvp;
4211
4212 for (nvp=m_Dict->begin(); nvp!=m_Dict->end(); nvp++) {
4213 CIccDictEntry *nv = nvp->ptr;
4214 if (!nv)
4215 continue;
4216
4217 char buf[256];
4218 char data[256];
4219 char fix[256];
4220 std::string bufstr;
4221
4222 xml += blanks + " <DictEntry Name=\"";
4223 xml += icFixXml(fix, icUtf16ToUtf8(bufstr, (icUInt16Number*)nv->GetName().c_str(), (int)nv->GetName().size()));
4224 xml += "\"";
4225
4226 if (nv->IsValueSet()) {
4227 xml += " Value=\"";
4228 xml += icFixXml(fix, icUtf16ToUtf8(bufstr, (icUInt16Number*)nv->GetValue().c_str(), (int)nv->GetValue().size()));
4229 xml += "\"";
4230 }
4231
4232 if (!nv->GetNameLocalized() && !nv->GetValueLocalized()) {
4233 xml += "/>\n";
4234 }
4235 else {
4236 xml += ">\n";
4237
4238 if (nv->GetNameLocalized()) {
4239 CIccMultiLocalizedUnicode::iterator i;
4240
4241 for (i=nv->GetNameLocalized()->m_Strings->begin(); i!=nv->GetNameLocalized()->m_Strings->end(); i++) {
4242 sprintf(buf, " <LocalizedName LanguageCountry=\"%s\"", icFixXml(fix, icGetSigStr(data, (i->m_nLanguageCode<<16) + i->m_nCountryCode)));
4243 xml += blanks + buf;
4244
4245 sprintf(buf, "><![CDATA[%s]]></LocalizedName>\n", icFixXml(fix, icUtf16ToUtf8(bufstr, i->GetBuf(), i->GetLength())));
4246 xml += buf;
4247 }
4248 }
4249 if (nv->GetValueLocalized()) {
4250 CIccMultiLocalizedUnicode::iterator i;
4251
4252 for (i=nv->GetValueLocalized()->m_Strings->begin(); i!=nv->GetValueLocalized()->m_Strings->end(); i++) {
4253 sprintf(buf, " <LocalizedValue LanguageCountry=\"%s\"", icFixXml(fix, icGetSigStr(data, (i->m_nLanguageCode<<16) + i->m_nCountryCode)));
4254 xml += blanks + buf;
4255
4256 sprintf(buf, "><![CDATA[%s]]></LocalizedValue>\n", icFixXml(fix, icUtf16ToUtf8(bufstr, i->GetBuf(), i->GetLength())));
4257 xml += buf;
4258 }
4259 }
4260 xml += blanks + " </DictEntry>\n";
4261 }
4262 }
4263 return true;
4264}
4265
4266
4267bool CIccTagXmlDict::ParseXml(xmlNode *pNode, std::string &parseStr)
4268{
4269 m_Dict->clear();
4270
4271 for (pNode = icXmlFindNode(pNode, "DictEntry"); pNode; pNode = icXmlFindNode(pNode->next, "DictEntry")) {
4272 CIccDictEntryPtr ptr;
4273 CIccDictEntry *pDesc = new CIccDictEntry();
4274 xmlAttr *pAttr;
4275 CIccUTF16String str;
4276
4277 if (!pDesc)
4278 return false;
4279 ptr.ptr = pDesc;
4280
4281 str = icXmlAttrValue(pNode, "Name", "");
4282 str.ToWString(pDesc->GetName());
4283
4284 pAttr = icXmlFindAttr(pNode, "Value");
4285 if (pAttr) {
4286 std::wstring wstr;
4287 str = icXmlAttrValue(pAttr, "");
4288 str.ToWString(wstr);
4289
4290 pDesc->SetValue(wstr);
4291 }
4292
4293 xmlNode *pChild;
4294
4295 for (pChild = pNode->children; pChild; pChild = pChild->next) {
4296 if (pChild->type == XML_ELEMENT_NODE && !icXmlStrCmp(pChild->name, "LocalizedName")) {
4298 if (!pTag) {
4299 pTag = new CIccTagMultiLocalizedUnicode();
4300 pDesc->SetNameLocalized(pTag);
4301 }
4302
4303 if ((pAttr = icXmlFindAttr(pChild, "LanguageCountry")) && pChild->children) {
4304 xmlNode *pText;
4306
4307 for (pText = pChild->children; pText && pText->type != XML_TEXT_NODE && pText->type != XML_CDATA_SECTION_NODE; pText = pText->next);
4308
4309 if (pText) {
4310 CIccUTF16String str((const char*)pText->content);
4311
4312 pTag->SetText(str.c_str(), (icLanguageCode)(lc>>16), (icCountryCode)(lc & 0xffff));
4313 }
4314 else {
4315 pTag->SetText("");
4316 }
4317 }
4318 }
4319 else if (pChild->type == XML_ELEMENT_NODE && !icXmlStrCmp(pChild->name, "LocalizedValue")) {
4321 if (!pTag) {
4322 pTag = new CIccTagMultiLocalizedUnicode();
4323 pDesc->SetValueLocalized(pTag);
4324 }
4325
4326 if ((pAttr = icXmlFindAttr(pChild, "LanguageCountry")) && pChild->children) {
4327 xmlNode *pText;
4329
4330 for (pText = pChild->children; pText && pText->type != XML_TEXT_NODE && pText->type != XML_CDATA_SECTION_NODE; pText = pText->next);
4331
4332 if (pText) {
4333 CIccUTF16String str((const char*)pText->content);
4334 pTag->SetText(str.c_str(), (icLanguageCode)(lc>>16), (icCountryCode)(lc & 0xffff));
4335 }
4336 else {
4337 pTag->SetText("");
4338 }
4339 }
4340 }
4341 }
4342
4343 m_Dict->push_back(ptr);
4344 }
4345
4346 return true;
4347}
4348
4349
4350bool CIccTagXmlStruct::ToXml(std::string &xml, std::string blanks/* = ""*/)
4351{
4352 std::string info;
4353 char buf[256], fix[256], line[256];
4354 IIccStruct *pStruct = GetStructHandler();
4355
4356 const icChar *structName = ((pStruct != NULL) ? pStruct->GetDisplayName() : NULL);
4357 blanks += " ";
4358
4359 if (structName && strcmp(structName, "privateStruct")) {
4360 sprintf(line, "<%s> <MemberTags>\n", structName);
4361 }
4362 else {
4363 // print out the struct signature
4364 sprintf(line, "<privateStruct StructSignature=\"%s\"/> <MemberTags>\n", icFixXml(fix, icGetSigStr(buf, m_sigStructType)));
4365 structName = "privateStruct";
4366 }
4367
4368 xml += blanks + line;
4369 TagEntryList::iterator i, j;
4370 std::set<icTagSignature> sigSet;
4371 CIccInfo Fmt;
4372 IccOffsetTagSigMap offsetTags;
4373
4374 for (i=m_ElemEntries->begin(); i!=m_ElemEntries->end(); i++) {
4375 if (sigSet.find(i->TagInfo.sig)==sigSet.end()) {
4376 CIccTag *pTag = FindElem(i->TagInfo.sig);
4377
4378 if (pTag) {
4379 CIccTagXml *pTagXml = (CIccTagXml*)(pTag->GetExtension());
4380 if (pTagXml) {
4381 IccOffsetTagSigMap::iterator prevTag = offsetTags.find(i->TagInfo.offset);
4382 std::string tagName = ((pStruct!=NULL) ? pStruct->GetElemName((icSignature)i->TagInfo.sig) : "");
4383 if (prevTag == offsetTags.end()) {
4384 const icChar* tagSig = icGetTagSigTypeName(pTag->GetType());
4385
4386 if (tagName.size() && strncmp(tagName.c_str(), "PrivateSubTag", 13)) {
4387 sprintf(line, " <%s>", icFixXml(fix, tagName.c_str()));
4388 }
4389 else {
4390 sprintf(line, " <PrivateSubTag TagSignature=\"%s\">", icFixXml(fix, icGetSigStr(buf, i->TagInfo.sig)));
4391 tagName = "PrivateSubTag";
4392 }
4393 xml += blanks + line;
4394
4395 // PrivateType - a type that does not belong to the list in the icc specs - custom for vendor.
4396 if (!strcmp("PrivateType", tagSig))
4397 sprintf(line, " <PrivateType type=\"%s\">\n", icFixXml(fix, icGetSigStr(buf, pTag->GetType())));
4398 else
4399 sprintf(line, " <%s>\n", tagSig); //parent node is the tag type
4400
4401 xml += line;
4402 j = i;
4403#if 0
4404 // print out the tag signature (there is at least one)
4405 sprintf(line, " <TagSignature>%s</TagSignature>\n", icFixXml(fix, icGetSigStr(buf, i->TagInfo.sig)));
4406 xml += blanks + line;
4407
4408 sigSet.insert(i->TagInfo.sig);
4409
4410 // print out the rest of the tag signatures
4411 for (j++; j != m_ElemEntries->end(); j++) {
4412 if (j->pTag == i->pTag || j->TagInfo.offset == i->TagInfo.offset) {
4413 sprintf(line, " <TagSignature>%s</TagSignature>\n", icFixXml(fix, icGetSigStr(buf, j->TagInfo.sig)));
4414 xml += blanks + line;
4415 sigSet.insert(j->TagInfo.sig);
4416 }
4417 }
4418 // if (pTag->m_nReserved) {
4419 // sprintf(line, " Reserved=\"%08x\"", pTag->m_nReserved);
4420 // xml += line;
4421 // }
4422 // xml += ">\n";
4423#endif
4424 //convert the rest of the tag to xml
4425 if (!pTagXml->ToXml(xml, blanks + " ")) {
4426 printf("Unable to output sub-tag with type %s\n", icGetSigStr(buf, i->TagInfo.sig));
4427 return false;
4428 }
4429 sprintf(line, " </%s> </%s>\n", tagSig, tagName.c_str());
4430 xml += blanks + line;
4431 offsetTags[i->TagInfo.offset] = i->TagInfo.sig;
4432 }
4433 else {
4434 std::string prevTagName = ((pStruct != NULL) ? pStruct->GetElemName(prevTag->second) : "");
4435 char fix2[200];
4436
4437 if (tagName.size() && strncmp(tagName.c_str(), "PrivateSubTag", 13))
4438 sprintf(line, " <%s SameAs=\"%s\"", icFixXml(fix, tagName.c_str()), icFixXml(fix2, prevTagName.c_str())); //parent node is the tag type
4439 else
4440 sprintf(line, " <PrivateSubTag TagSignature=\"%s\" SameAs=\"%s\"", icFixXml(fix2, icGetSigStr(buf, i->TagInfo.sig)), icFixXml(fix, prevTagName.c_str()));
4441
4442 xml += line;
4443 if (prevTagName.size() || !strncmp(prevTagName.c_str(), "PrivateSubTag", 13)) {
4444 sprintf(line, " SameAsSignature=\"%s\"", icFixXml(fix2, icGetSigStr(buf, prevTag->second)));
4445 xml += line;
4446 }
4447
4448 xml += "/>\n";
4449 }
4450 }
4451 else {
4452 printf("Non XML tag in list with type %s!\n", icGetSigStr(buf, i->TagInfo.sig));
4453 return false;
4454 }
4455 }
4456 else {
4457 printf("Unable to find tag with type %s!\n", icGetSigStr(buf, i->TagInfo.sig));
4458 return false;
4459 }
4460 }
4461 }
4462
4463 xml += blanks + "</MemberTags> </" + structName + ">\n";
4464 return true;
4465}
4466
4467/**
4468******************************************************************************
4469* Name: CIccTagXmlStruct::ParseTag
4470*
4471* Purpose: This will load from the indicated IO object and associate a tag
4472* object to a tag directory entry. Nothing happens if tag directory entry
4473* is associated with a tag object.
4474*
4475* Args:
4476* pNode - pointer to xmlNode object to parse from
4477*
4478* Return:
4479* true - tag from node successfully parsed,
4480* false - failure
4481*******************************************************************************
4482*/
4483bool CIccTagXmlStruct::ParseTag(xmlNode *pNode, std::string &parseStr)
4484{
4485 xmlAttr *attr;
4486
4487 if (pNode->type != XML_ELEMENT_NODE) {// || icXmlStrCmp(pNode->name, "Tag")) {
4488 parseStr += "Invalid Tag Node: ";
4489 parseStr += (const char *)pNode->name;
4490 parseStr += "\n";
4491 return false;
4492 }
4493
4494 CIccTag *pTag = NULL;
4495
4496 std::string nodeName = (icChar*)pNode->name;
4497 icSignature sigTag;
4498 if (m_pStruct)
4499 sigTag = m_pStruct->GetElemSig(nodeName.c_str());
4500 else
4501 sigTag = 0;
4502
4503 if (sigTag != 0 || nodeName == "PrivateSubTag") { //Parsing of XML tags by name
4504 if (nodeName == "PrivateSubTag") {
4505 const char *tagSig = icXmlAttrValue(pNode, "TagSignature", "");
4506 if (tagSig[0]) {
4507 sigTag = (icTagSignature)icGetSigVal(tagSig);
4508 }
4509 else {
4510 parseStr += "Invalid TagSignature for PrivateSubTag\n";
4511 return false;
4512 }
4513 }
4514
4515 const char *sameAs = icXmlAttrValue(pNode, "SameAs", "");
4516
4517 if (sameAs[0]) {
4518 icTagSignature sigParentTag = icGetTagNameSig(sameAs);
4519 if (!strcmp(sameAs, "PrivateSubTag") || sigParentTag == icSigUnknownTag) {
4520 const char *sameAsSig = icXmlAttrValue(pNode, "SameAsSignature", "");
4521 if (sameAsSig[0]) {
4522 sigParentTag = (icTagSignature)icGetSigVal(sameAsSig);
4523 }
4524 else {
4525 parseStr += "Invalid SameAsSignature for PrivateSubTag\n";
4526 return false;
4527 }
4528 }
4529 pTag = this->FindElem(sigParentTag);
4530 if (pTag) {
4531 AttachElem(sigTag, pTag);
4532 }
4533 else {
4534 parseStr += "SameAs tag ";
4535 parseStr += sameAs;
4536 parseStr += " for ";
4537 parseStr += nodeName + " does not exist\n";
4538 return false;
4539 }
4540
4541 return true;
4542 }
4543 else { //Parse the type node as the first child
4544 xmlNode *pTypeNode;
4545 for (pTypeNode = pNode->children; pTypeNode; pTypeNode = pTypeNode->next) {
4546 if (pTypeNode->type == XML_ELEMENT_NODE) {
4547 break;
4548 }
4549 }
4550
4551 if (!pTypeNode) {
4552 parseStr += "No tag type node defined for ";
4553 parseStr += nodeName;
4554 parseStr += "\n";
4555 return false;
4556 }
4557
4558 // get the tag type signature
4559 icTagTypeSignature sigType = icGetTypeNameTagSig((const icChar*)pTypeNode->name);
4560
4561 if (sigType == icSigUnknownType) {
4562 xmlAttr *attr = icXmlFindAttr(pTypeNode, "type");
4564 }
4565
4566 CIccInfo info;
4567
4568 // create a tag based on the signature
4569 pTag = CIccTag::Create(sigType);
4570
4571 IIccExtensionTag *pExt;
4572
4573 if (pTag && (pExt = pTag->GetExtension()) && !strcmp(pExt->GetExtClassName(), "CIccTagXml")) {
4574 CIccTagXml* pXmlTag = (CIccTagXml*)pExt;
4575
4576 if (pXmlTag->ParseXml(pTypeNode->children, parseStr)) {
4577 if ((attr = icXmlFindAttr(pTypeNode, "reserved"))) {
4578 sscanf(icXmlAttrValue(attr), "%u", &pTag->m_nReserved);
4579 }
4580 AttachElem(sigTag, pTag);
4581 }
4582 else {
4583 parseStr += "Unable to Parse \"";
4584 parseStr += (const char*)pTypeNode->name;
4585 parseStr += "\" (";
4586 parseStr += nodeName;
4587 parseStr += ") Tag\n";
4588 return false;
4589 }
4590 }
4591 else {
4592 parseStr += "Invalid tag extension for \"";
4593 parseStr += (const char*)pTypeNode->name;
4594 parseStr += "\" (";
4595 parseStr += nodeName;
4596 parseStr += ") Tag\n";
4597 return false;
4598 }
4599 }
4600 }
4601 else { //Legacy parsing of XML tags by type
4602 sigTag = (icTagSignature)0;
4603 // get the tag type signature
4604 icTagTypeSignature sigType = icGetTypeNameTagSig(nodeName.c_str());
4605
4606 if (sigType == icSigUnknownType) {
4607 xmlAttr *attr = icXmlFindAttr(pNode, "type");
4609 }
4610
4611 CIccInfo info;
4612
4613 // create a tag based on the signature
4614 pTag = CIccTag::Create(sigType);
4615
4616 IIccExtensionTag *pExt;
4617
4618 if (pTag && (pExt = pTag->GetExtension()) && !strcmp(pExt->GetExtClassName(), "CIccTagXml")) {
4619 CIccTagXml* pXmlTag = (CIccTagXml*)pExt;
4620
4621 if (pXmlTag->ParseXml(pNode->children, parseStr)) {
4622 if ((attr = icXmlFindAttr(pNode, "reserved"))) {
4623 sscanf(icXmlAttrValue(attr), "%u", &pTag->m_nReserved);
4624 }
4625
4626 for (xmlNode *tagSigNode = pNode->children; tagSigNode; tagSigNode = tagSigNode->next) {
4627 if (tagSigNode->type == XML_ELEMENT_NODE && !icXmlStrCmp(tagSigNode->name, "TagSignature")) {
4628 sigTag = (icTagSignature)icGetSigVal((const icChar*)tagSigNode->children->content);
4629 AttachElem(sigTag, pTag);
4630 }
4631 }
4632 }
4633 else {
4634 parseStr += "Unable to Parse \"";
4635 parseStr += info.GetTagTypeSigName(sigType);
4636 parseStr += "\" (";
4637 parseStr += nodeName;
4638 parseStr += ") Tag\n";
4639 return false;
4640 }
4641 }
4642 else {
4643 parseStr += "Invalid tag extension for \"";
4644 parseStr += info.GetTagTypeSigName(sigType);
4645 parseStr += "\" (";
4646 parseStr += nodeName;
4647 parseStr += ") Tag\n";
4648 return false;
4649 }
4650 }
4651
4652 return true;
4653}
4654
4655
4656bool CIccTagXmlStruct::ParseXml(xmlNode *pNode, std::string &parseStr)
4657{
4658 // parse each tag
4659 xmlNode *tagNode, *firstNode=pNode;
4660
4661 for (; pNode; pNode = pNode->next) {
4662 if (pNode->type == XML_ELEMENT_NODE)
4663 break;
4664 }
4665 if (!pNode) {
4666 parseStr += "Invalid Tag Structure: ";
4667 parseStr += (const char *)firstNode->name;
4668 parseStr += "\n";
4669 return false;
4670 }
4671
4672 std::string nodeName = (icChar*)pNode->name;
4673
4674 icStructSignature sigStruct = CIccStructCreator::GetStructSig(nodeName.c_str());
4675
4676 if (sigStruct) {
4677 SetTagStructType(sigStruct);
4678 pNode = pNode->children;
4679 }
4680 else {
4681 tagNode = icXmlFindNode(firstNode, "StructureSignature");
4682 if (!tagNode) {
4683 parseStr += "Unable to find StructureSignature\n";
4684 return false;
4685 }
4686
4687 if (tagNode->type == XML_ELEMENT_NODE && tagNode->children && tagNode->children->content) {
4688
4689 sigStruct = (icStructSignature)icGetSigVal(tagNode->children ? (const icChar*)tagNode->children->content : "");
4690 SetTagStructType(sigStruct);
4691 }
4692 else {
4693 parseStr += "Invalid XNode type for StructureSignature\n";
4694 return false;
4695 }
4696 }
4697
4698 tagNode = icXmlFindNode(pNode, "MemberTags");
4699 if (!tagNode) {
4700 parseStr += "Unable to find structure MemberTags\n";
4701 return false;
4702 }
4703
4704 for (tagNode = tagNode->children; tagNode; tagNode = tagNode->next) {
4705 if (tagNode->type == XML_ELEMENT_NODE) {
4706 if (!ParseTag(tagNode, parseStr)) {
4707 parseStr += "Failed to parse tag member (";
4708 parseStr += (char*)tagNode->name;
4709 parseStr += ")\n";
4710 return false;
4711 }
4712 }
4713 }
4714
4715 return true;
4716}
4717
4718bool CIccTagXmlArray::ToXml(std::string &xml, std::string blanks/* = ""*/)
4719{
4720 std::string info;
4721 char buf[256], fix[256], line[256];
4722
4723 std::string arrayName;
4724 std::string arrayBlanks = "";
4725 bool found = CIccArrayCreator::GetArraySigName(arrayName, m_sigArrayType, false);
4726
4727 if (found) {
4728 sprintf(line, "<%s> ", arrayName.c_str());
4729 arrayBlanks = " ";
4730 }
4731 else {
4732 // print out the struct signature
4733 sprintf(line, "<privateArray StructSignature=\"%s\"/> ", icFixXml(fix, icGetSigStr(buf, m_sigArrayType)));
4734 arrayName = "privateArray";
4735 }
4736
4737 xml += blanks + line + "<ArrayTags>\n";
4738 int i;
4739
4740 for (i=0; i<(int)m_nSize; i++) {
4741 CIccTag* pTag = m_TagVals[i].ptr;
4742 if (pTag) {
4743 CIccTagXml *pTagXml = (CIccTagXml*)(pTag->GetExtension());
4744 if (pTagXml) {
4745 const icChar* tagSig = icGetTagSigTypeName(pTag->GetType());
4746
4747 // PrivateType - a type that does not belong to the list in the icc specs - custom for vendor.
4748 if ( !strcmp("PrivateType", tagSig) )
4749 sprintf(line, " <PrivateType type=\"%s\">\n", icFixXml(fix, icGetSigStr(buf, pTag->GetType())));
4750 else
4751 sprintf(line, " <%s>\n", tagSig); //parent node is the tag type
4752
4753 xml += blanks + arrayBlanks + line;
4754
4755 //convert the rest of the tag to xml
4756 if (!pTagXml->ToXml(xml, blanks + arrayBlanks + " ")) {
4757 printf("Unable to output tag with type %s\n", icGetSigStr(buf, pTag->GetType()));
4758 return false;
4759 }
4760 sprintf(line, " </%s>\n\n", tagSig);
4761 xml += blanks + arrayBlanks + line;
4762 }
4763 else {
4764 printf("Non XML tag in list with type %s!\n", icGetSigStr(buf, pTag->GetType()));
4765 return false;
4766 }
4767 }
4768 }
4769 xml += blanks + "</ArrayTags> </" + arrayName + ">\n";
4770
4771 return true;
4772}
4773
4774
4775bool CIccTagXmlArray::ParseXml(xmlNode *pNode, std::string &parseStr)
4776{
4777 // parse each tag
4778 xmlNode *tagNode, *indexNode, *firstNode = pNode;;
4779 xmlAttr *attr;
4780
4781 for (; pNode; pNode = pNode->next) {
4782 if (pNode->type == XML_ELEMENT_NODE)
4783 break;
4784 }
4785 if (!pNode) {
4786 parseStr += "Invalid Tag Array: ";
4787 parseStr += (const char *)firstNode->name;
4788 parseStr += "\n";
4789 return false;
4790 }
4791
4792 std::string nodeName = (icChar*)pNode->name;
4793 icArraySignature sigArray = CIccArrayCreator::GetArraySig(nodeName.c_str());
4794
4795 if (sigArray) {
4796 SetTagArrayType(sigArray);
4797 pNode = pNode->children;
4798 }
4799 else {
4800 tagNode = icXmlFindNode(firstNode, "ArraySignature");
4801 if (!tagNode) {
4802 parseStr += "Unable to find ArraySignature\n";
4803 return false;
4804 }
4805
4806 if (tagNode->type == XML_ELEMENT_NODE && tagNode->children && tagNode->children->content) {
4807 sigArray = (icArraySignature)icGetSigVal(tagNode->children ? (const icChar*)tagNode->children->content : "");
4808 SetTagArrayType(sigArray);
4809 }
4810 else {
4811 parseStr += "Invalid XNode type for ArraySignature\n";
4812 return false;
4813 }
4814 }
4815
4816 indexNode = icXmlFindNode(pNode, "ArrayTags");
4817 if (!indexNode)
4818 return false;
4819
4820 int nMaxIndex = 0, n=0;
4821 for (tagNode = indexNode->children; tagNode; tagNode = tagNode->next) {
4822 if (tagNode->type == XML_ELEMENT_NODE) {
4823 nMaxIndex++;
4824 }
4825 }
4826 if (!SetSize(nMaxIndex))
4827 return false;
4828
4829 n=0;
4830 for (tagNode = indexNode->children; tagNode; tagNode = tagNode->next) {
4831 if (tagNode->type == XML_ELEMENT_NODE) {
4832 CIccTag *pTag = NULL;
4833 icSignature sigTag = (icSignature)0;
4834
4835 // get the tag signature
4836 icTagTypeSignature sigType = icGetTypeNameTagSig ((icChar*) tagNode->name);
4837
4838 if (sigType==icSigUnknownType){
4839 xmlAttr *attr = icXmlFindAttr(pNode, "type");
4841 }
4842
4843 CIccInfo info;
4844
4845 // create a tag based on the signature
4846 pTag = CIccTag::Create(sigType);
4847
4848 IIccExtensionTag *pExt;
4849
4850 if (pTag && (pExt = pTag->GetExtension()) && !strcmp(pExt->GetExtClassName(), "CIccTagXml")) {
4851 CIccTagXml* pXmlTag = (CIccTagXml*)pExt;
4852
4853 if (pXmlTag->ParseXml(tagNode->children, parseStr)) {
4854 if ((attr=icXmlFindAttr(pNode, "reserved"))) {
4855 sscanf(icXmlAttrValue(attr), "%u", &pTag->m_nReserved);
4856 }
4857
4858 if (!m_TagVals[n].ptr)
4859 m_TagVals[n].ptr = pTag;
4860 else {
4861 parseStr += "Tag Array Index ";
4862 parseStr += n;
4863 parseStr += " already filled!\n";
4864 return false;
4865 }
4866 }
4867 else {
4868 parseStr += "Unable to Parse xml node named \"";
4869 parseStr += (icChar*)tagNode->name;
4870 parseStr += "\"\n";
4871 return false;
4872 }
4873 }
4874 n++;
4875 }
4876 }
4877
4878 for (n=0; n<(int)m_nSize; n++) {
4879 if (!m_TagVals[n].ptr) {
4880 parseStr += "Undefined Array Tag at index ";
4881 parseStr += n;
4882 parseStr += "\n";
4883 return false;
4884 }
4885 }
4886
4887 return true;
4888}
4889
4890bool CIccTagXmlGamutBoundaryDesc::ToXml(std::string &xml, std::string blanks/* = ""*/)
4891{
4892 std::string info;
4893 char line[256];
4894 int i;
4895
4896 if (m_NumberOfVertices && (m_PCSValues || m_DeviceValues)) {
4897 xml += blanks + "<Vertices>\n";
4898
4899 if (m_PCSValues) {
4900 sprintf(line, " <PCSValues channels=\"%d\">\n", m_nPCSChannels);
4901 xml += blanks + line;
4902 CIccFloatArray::DumpArray(xml, blanks+" ", m_PCSValues, m_NumberOfVertices*m_nPCSChannels, icConvertFloat, 9);
4903 xml += blanks + " </PCSValues>\n";
4904 }
4905 if (m_DeviceValues) {
4906 sprintf(line, " <DeviceValues channels=\"%d\">\n", m_nDeviceChannels);
4907 xml += blanks + line;
4908 CIccFloatArray::DumpArray(xml, blanks+" ", m_DeviceValues, m_NumberOfVertices*m_nDeviceChannels, icConvertFloat, 8);
4909 xml += blanks + " </DeviceValues>\n";
4910 }
4911 xml += blanks + "</Vertices>\n";
4912 }
4913
4914 if (m_Triangles && m_NumberOfTriangles) {
4915 xml += blanks + "<Triangles>\n";
4916
4917 for (i=0; i<m_NumberOfTriangles; i++) {
4918 sprintf(line, " <T>%u %u %u</T>\n", m_Triangles[i].m_VertexNumbers[0], m_Triangles[i].m_VertexNumbers[1], m_Triangles[i].m_VertexNumbers[2]);
4919 xml += blanks + line;
4920 }
4921
4922 xml += blanks + "</Triangles>\n";
4923 }
4924
4925 return true;
4926}
4927
4928
4929bool CIccTagXmlGamutBoundaryDesc::ParseXml(xmlNode *pNode, std::string &parseStr)
4930{
4931 // parse each tag
4932 xmlNode *childNode, *subNode;
4933
4934 childNode = icXmlFindNode(pNode, "Vertices");
4935 if (!childNode) {
4936 parseStr += "Cannot find Vertices\n";
4937 return false;
4938 }
4939
4940 subNode = icXmlFindNode(childNode->children, "PCSValues");
4941
4942 if (subNode) {
4943 m_nPCSChannels = atoi(icXmlAttrValue(subNode, "channels", "0"));
4944
4945 if (!m_nPCSChannels) {
4946 parseStr += "Bad PCSValues channels\n";
4947 return false;
4948 }
4949
4950 CIccFloatArray vals;
4951 if (!vals.ParseArray(subNode->children)) {
4952 parseStr += "Unable to parse GamutBoundaryDesc PCSValues\n";
4953 return false;
4954 }
4955
4956 m_NumberOfVertices = vals.GetSize() / m_nPCSChannels;
4957
4958 if (m_NumberOfVertices<4) {
4959 parseStr += "Must have at least 4 PCSValues vertices\n";
4960 return false;
4961 }
4962
4963 m_PCSValues = new icFloatNumber[m_NumberOfVertices * m_nPCSChannels];
4964
4965 if (!m_PCSValues)
4966 return false;
4967
4968 memcpy(m_PCSValues, vals.GetBuf(), m_NumberOfVertices * m_nPCSChannels*sizeof(icFloatNumber));
4969 }
4970 else {
4971 parseStr += "Cannot find PCSValues\n";
4972 return false;
4973 }
4974
4975 subNode = icXmlFindNode(childNode->children, "DeviceValues");
4976
4977 if (subNode) {
4978 m_nDeviceChannels = atoi(icXmlAttrValue(subNode, "channels", "0"));
4979
4980 if (!m_nDeviceChannels) {
4981 parseStr += "Bad DeviceValues channels\n";
4982 return false;
4983 }
4984
4985 CIccFloatArray vals;
4986 if (!vals.ParseArray(subNode->children)) {
4987 parseStr += "Unable to parse GamutBoundaryDesc DeviceValues\n";
4988 return false;
4989 }
4990
4991 int nVertices = vals.GetSize() / m_nDeviceChannels;
4992
4993 if (m_NumberOfVertices != nVertices) {
4994 parseStr += "Number of Device vertices doesn't match PCS verticies\n";
4995 return false;
4996 }
4997
4998 m_DeviceValues = new icFloatNumber[m_NumberOfVertices * m_nDeviceChannels];
4999
5000 if (!m_DeviceValues)
5001 return false;
5002
5003 memcpy(m_DeviceValues, vals.GetBuf(), m_NumberOfVertices * m_nDeviceChannels * sizeof(icFloatNumber));
5004 }
5005 else if (!m_PCSValues)
5006 m_NumberOfVertices = 0;
5007
5008 childNode = icXmlFindNode(pNode, "Triangles");
5009 if (!childNode) {
5010 parseStr += "Cannot find Triangles\n";
5011 return false;
5012 }
5013
5014 int nMaxIndex = 0, n=0;
5015 for (subNode = childNode->children; subNode; subNode = subNode->next) {
5016 if (subNode->type == XML_ELEMENT_NODE && !strcmp((icChar*)subNode->name, "T")) {
5017 nMaxIndex++;
5018 }
5019 }
5020 m_NumberOfTriangles = nMaxIndex;
5021 m_Triangles = new icGamutBoundaryTriangle[m_NumberOfTriangles];
5022
5023 n=0;
5024 for (subNode = childNode->children; subNode && n<nMaxIndex; subNode = subNode->next) {
5025 if (subNode->type == XML_ELEMENT_NODE && !strcmp((icChar*)subNode->name, "T")) {
5026 CIccUInt32Array ids;
5027
5028 if (!ids.ParseArray(subNode->children) || ids.GetSize()!=3) {
5029 parseStr += "Invalid Triangle entry\n";
5030 return false;
5031 }
5032 icUInt32Number *v = ids.GetBuf();
5033
5034 m_Triangles[n].m_VertexNumbers[0] = v[0];
5035 m_Triangles[n].m_VertexNumbers[1] = v[1];
5036 m_Triangles[n].m_VertexNumbers[2] = v[2];
5037
5038 n++;
5039 }
5040 }
5041
5042 return true;
5043}
5044
5045bool CIccTagXmlEmbeddedProfile::ParseXml(xmlNode *pNode, std::string &parseStr)
5046{
5047 // parse each tag
5048 xmlNode *tagNode;
5049
5050 tagNode = icXmlFindNode(pNode, "IccProfile");
5051 if (!tagNode)
5052 return false;
5053
5054 if (m_pProfile) {
5055 delete m_pProfile;
5056 }
5057
5058 CIccProfileXml *pProfile = new CIccProfileXml();
5059 m_pProfile = pProfile;
5060
5061 if (!pProfile->ParseXml(tagNode, parseStr)) {
5062 delete m_pProfile;
5063 m_pProfile = NULL;
5064 return false;
5065 }
5066 return true;
5067}
5068
5069bool CIccTagXmlEmbeddedProfile::ToXml(std::string &xml, std::string blanks/* = ""*/)
5070{
5071 if (!m_pProfile || strcmp(m_pProfile->GetClassName(), "CIccProfileXml")) {
5072 return false;
5073 }
5074
5075 CIccProfileXml *pProfile = (CIccProfileXml*)m_pProfile;
5076
5077 return pProfile->ToXmlWithBlanks(xml, blanks);
5078}
5079
5080bool CIccTagXmlEmbeddedHeightImage::ParseXml(xmlNode *pNode, std::string &parseStr)
5081{
5082 // parse tag
5083 xmlNode *tagNode;
5084
5085 tagNode = icXmlFindNode(pNode, "HeightImage");
5086 if (!tagNode)
5087 return false;
5088
5089 m_nSeamlesIndicator = atoi(icXmlAttrValue(tagNode, "SeamlessIndicator", "0"));
5090 m_nEncodingFormat = (icImageEncodingType)atoi(icXmlAttrValue(tagNode, "EncodingFormat", "0"));
5091 m_fMetersMinPixelValue = (icFloatNumber)atof(icXmlAttrValue(tagNode, "MetersMinPixelValue", "0.0"));
5092 m_fMetersMaxPixelValue = (icFloatNumber)atof(icXmlAttrValue(tagNode, "MetersMaxPixelValue", "0.0"));
5093
5094 xmlNode *pImageNode;
5095 pImageNode = icXmlFindNode(tagNode->children, "Image");
5096
5097 if (pImageNode) {
5098 const char *filename = icXmlAttrValue(pImageNode, "File");
5099 if (!filename || !filename[0]) {
5100 filename = icXmlAttrValue(pImageNode, "Filename");
5101 }
5102
5103 // file exists
5104 if (filename[0]) {
5105 CIccIO *file = IccOpenFileIO(filename, "rb");
5106 if (!file) {
5107 parseStr += "Error! - File '";
5108 parseStr += filename;
5109 parseStr += "' not found.\n";
5110 delete file;
5111 return false;
5112 }
5113
5114 icUInt32Number num = file->GetLength();
5115
5116 SetSize(num);
5117 icUInt8Number *dst = GetData(0);
5118 if (file->Read8(dst, num)!=num) {
5119 perror("Read-File Error");
5120 parseStr += "'";
5121 parseStr += filename;
5122 parseStr += "' may not be a valid binary file.\n";
5123 delete file;
5124 return false;
5125 }
5126 delete file;
5127 return true;
5128 }
5129 // no file
5130 else if (pImageNode->children && pImageNode->children->content){
5131 unsigned long nSize = icXmlGetHexDataSize((const icChar*)pImageNode->children->content);
5132
5133 SetSize(nSize);
5134 if (m_pData) {
5135 if (icXmlGetHexData(m_pData, (const icChar*)pImageNode->children->content, m_nSize) != m_nSize)
5136 return false;
5137 }
5138
5139 return true;
5140 }
5141 }
5142 return false;
5143}
5144
5145bool CIccTagXmlEmbeddedHeightImage::ToXml(std::string &xml, std::string blanks/*= ""*/)
5146{
5147 char buf[200];
5148
5149 xml += blanks + "<HeightImage";
5150 sprintf(buf, " SeamlessIndicator=\"%d\"", m_nSeamlesIndicator);
5151 xml += buf;
5152
5153 sprintf(buf, " EncodingFormat=\"%d\"", m_nEncodingFormat);
5154 xml += buf;
5155
5156 sprintf(buf, " MetersMinPixelValue=\"%.12f\"", m_fMetersMinPixelValue);
5157 xml += buf;
5158
5159 sprintf(buf, " MetersMaxPixelValue=\"%.12f\"", m_fMetersMaxPixelValue);
5160 xml += buf;
5161
5162 if (!m_nSize) {
5163 xml += blanks + "/>\n";
5164 }
5165 else {
5166 xml += ">\n";
5167 xml += blanks + " <Image>\n";
5168 icXmlDumpHexData(xml, blanks + " ", m_pData, m_nSize);
5169 xml += blanks + " </Image>\n";
5170 xml += blanks + "</HeightImage>\n";
5171 }
5172
5173 return true;
5174}
5175
5176bool CIccTagXmlEmbeddedNormalImage::ParseXml(xmlNode *pNode, std::string &parseStr)
5177{
5178 // parse tag
5179 xmlNode *tagNode;
5180
5181 tagNode = icXmlFindNode(pNode, "NormalImage");
5182 if (!tagNode)
5183 return false;
5184
5185 m_nSeamlesIndicator = atoi(icXmlAttrValue(tagNode, "SeamlessIndicator", "0"));
5186 m_nEncodingFormat = (icImageEncodingType)atoi(icXmlAttrValue(tagNode, "EncodingFormat", "0"));
5187
5188 xmlNode *pImageNode;
5189 pImageNode = icXmlFindNode(tagNode->children, "Image");
5190
5191 if (pImageNode) {
5192 const char *filename = icXmlAttrValue(pImageNode, "File");
5193 if (!filename || !filename[0]) {
5194 filename = icXmlAttrValue(pImageNode, "Filename");
5195 }
5196
5197 // file exists
5198 if (filename[0]) {
5199 CIccIO *file = IccOpenFileIO(filename, "rb");
5200 if (!file) {
5201 parseStr += "Error! - File '";
5202 parseStr += filename;
5203 parseStr += "' not found.\n";
5204 delete file;
5205 return false;
5206 }
5207
5208 icUInt32Number num = file->GetLength();
5209
5210 SetSize(num);
5211 icUInt8Number *dst = GetData(0);
5212 if (file->Read8(dst, num) != num) {
5213 perror("Read-File Error");
5214 parseStr += "'";
5215 parseStr += filename;
5216 parseStr += "' may not be a valid binary file'.\n";
5217 delete file;
5218 return false;
5219 }
5220 delete file;
5221 return true;
5222 }
5223 // no file
5224 else if (pImageNode->children && pImageNode->children->content) {
5225 unsigned long nSize = icXmlGetHexDataSize((const icChar*)pImageNode->children->content);
5226
5227 SetSize(nSize);
5228 if (m_pData) {
5229 if (icXmlGetHexData(m_pData, (const icChar*)pImageNode->children->content, m_nSize) != m_nSize)
5230 return false;
5231 }
5232 return true;
5233 }
5234 }
5235 return false;
5236}
5237
5238bool CIccTagXmlEmbeddedNormalImage::ToXml(std::string &xml, std::string blanks/*= ""*/)
5239{
5240 char buf[200];
5241
5242 xml += blanks + "<NormalImage";
5243 sprintf(buf, " SeamlessIndicator=\"%d\"", m_nSeamlesIndicator);
5244 xml += buf;
5245
5246 sprintf(buf, " EncodingFormat=\"%d\"", m_nEncodingFormat);
5247 xml += buf;
5248
5249 if (!m_nSize) {
5250 xml += blanks + "/>\n";
5251 }
5252 else {
5253 xml += ">\n";
5254 xml += blanks + " <Image>\n";
5255 icXmlDumpHexData(xml, blanks + " ", m_pData, m_nSize);
5256 xml += blanks + " </Image>\n";
5257 xml += blanks + "</NormalImage>\n";
5258 }
5259
5260 return true;
5261}
5262
5263
5264#ifdef USEREFICCMAXNAMESPACE
5265}
5266#endif
File: IccArrayFactory.h.
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
Definition IccDefs.h:100
char icChar
Definition IccDefs.h:109
CIccIO * IccOpenFileIO(const icChar *szFilename, const char *szAttr)
Definition IccIoXml.cpp:100
File: IccIoXml.h.
CIccCLUT * icCLutFromXml(xmlNode *pNode, int nIn, int nOut, icConvertType nType, std::string &parseStr)
File: IccMpeXml.h.
#define stricmp
std::map< icUInt32Number, icTagSignature > IccOffsetTagSigMap
File: IccProfileXml.h.
File: IccSparseMatrix.h.
File: IccStructFactory.h.
std::list< icResponse16Number > CIccResponse16List
List Class: CIccResponse16List.
const icChar * szName
std::list< CIccMultiProcessElementPtr > CIccMultiProcessElementList
Definition IccTagMPE.h:120
bool icCurvesToXml(std::string &xml, const char *szName, CIccCurve **pCurves, int numCurve, icConvertType nType, std::string blanks)
bool icXmlParseProfDesc(xmlNode *pNode, CIccProfileDescStruct &p, std::string &parseStr)
bool icMBBToXml(std::string &xml, CIccMBB *pMBB, icConvertType nType, std::string blanks="", bool bSaveGridPoints=false)
static std::string icXmlParseTextString(xmlNode *pNode, std::string &parseStr, bool bConvert=true)
bool icProfDescToXml(std::string &xml, CIccProfileDescStruct &p, std::string blanks="")
std::map< icUInt32Number, icTagSignature > IccOffsetTagSigMap
Definition IccTagXml.cpp:79
static bool icXmlDumpTextData(std::string &xml, std::string blanks, const char *szText, bool bConvert=true)
bool icMatrixToXml(std::string &xml, CIccMatrix *pMatrix, std::string blanks)
bool icCurvesFromXml(LPIccCurve *pCurve, icUInt32Number nChannels, xmlNode *pNode, icConvertType nType, std::string &parseStr)
bool icMBBFromXml(CIccMBB *pMBB, xmlNode *pNode, icConvertType nType, std::string &parseStr)
bool icMatrixFromXml(CIccMatrix *pMatrix, xmlNode *pNode)
File: IccTagXml.h.
icFloatNumber icU16toF(icUInt16Number num)
Definition IccUtil.cpp:759
void icXyzToPcs(icFloatNumber *XYZ)
Definition IccUtil.cpp:941
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
icFloatNumber icFtoD(icS15Fixed16Number num)
Definition IccUtil.cpp:559
const icChar * icGetColorSigStr(icChar *pBuf, icUInt32Number nSig)
Definition IccUtil.cpp:1139
void icLabFromPcs(icFloatNumber *Lab)
Floating point encoding of Lab in PCS is in range 0.0 to 1.0.
Definition IccUtil.cpp:919
void icLabToPcs(icFloatNumber *Lab)
Definition IccUtil.cpp:927
icFloat16Number icFtoF16(icFloat32Number num)
Definition IccUtil.cpp:673
icS15Fixed16Number icDtoF(icFloatNumber num)
Definition IccUtil.cpp:545
icUInt16Number icFtoU16(icFloatNumber num)
Definition IccUtil.cpp:745
icUInt32Number icGetSigVal(const icChar *pBuf)
Definition IccUtil.cpp:1258
icFloatNumber icF16toF(icFloat16Number num)
Definition IccUtil.cpp:629
const icChar * icGetSigStr(icChar *pBuf, icUInt32Number nSig)
Definition IccUtil.cpp:1056
File: IccUtil.h.
icMeasurementGeometry icGeNamedtMeasurementGeometryValue(const icChar *str)
const char * icUtf8ToAnsi(std::string &buf, const char *szSrc)
const std::string icGetDeviceAttrName(icUInt64Number devAttr)
icUInt32Number icXmlNodeCount3(xmlNode *pNode, const char *szNodeName1, const char *szNodeName2, const char *szNodeName3)
icColorantEncoding icGetColorantValue(const icChar *str)
icUInt32Number icXmlNodeCount(xmlNode *pNode, const char *szNodeName)
icUInt32Number icXmlGetHexDataSize(const char *szText)
icDateTimeNumber icGetDateTimeValue(const icChar *str)
const char * icUtf16ToUtf8(std::string &buf, const icUInt16Number *szSrc, int sizeSrc)
xmlAttr * icXmlFindAttr(xmlNode *pNode, const char *szAttrName)
xmlNode * icXmlFindNode(xmlNode *pNode, const char *szNodeName)
icUInt32Number icXmlGetHexData(void *pBuf, const char *szText, icUInt32Number nBufSize)
icTagTypeSignature icGetTypeNameTagSig(const icChar *szTagType)
icMeasurementFlare icGetNamedMeasurementFlareValue(const icChar *str)
const icChar * icGetStandardObserverName(icStandardObserver str)
const icChar * icGetTagSigTypeName(icTagTypeSignature tagTypeSig)
icUInt32Number icXmlDumpHexData(std::string &xml, std::string blanks, void *pBuf, icUInt32Number nBufSize)
icTagSignature icGetTagNameSig(const icChar *szName)
icUInt64Number icGetDeviceAttrValue(xmlNode *pNode)
const char * icFixXml(std::string &buf, const char *szStr)
icIlluminant icGetIlluminantValue(const icChar *str)
icMeasurementUnitSig icGetMeasurementValue(const icChar *str)
icStandardObserver icGetNamedStandardObserverValue(const icChar *str)
const char * icXmlAttrValue(xmlAttr *attr, const char *szDefault)
icSignature icXmlStrToSig(const char *szStr)
bool icCLUTToXml(std::string &xml, CIccCLUT *pCLUT, icConvertType nType, std::string blanks, bool bSaveGridPoints, const char *szExtraAttrs, const char *szName)
const char * icAnsiToUtf8(std::string &buf, const char *szSrc)
File: IccUtilXml.cpp.
#define icXmlStrCmp(x, y)
Definition IccUtilXml.h:134
#define icXmlDoubleFmt
icConvertType
@ icConvert8Bit
@ icConvertFloat
@ icConvert16Bit
@ icConvertVariable
#define icXmlHalfFmt
#define icXmlFloatFmt
icTagTypeSignature
unsigned int icUInt32Number
static bool GetArraySigName(std::string &arrayName, icArraySignature arrayTypeSig, bool bFillUnknown=true)
Function: GetArraySigName(structTypeSig) Get display name of structTypeSig.
static icArraySignature GetArraySig(const icChar *arrayName)
Function: GetArraySig(arrayName) Get signature associate with display name arrayName handler.
Class: CIccCLUT.
Definition IccTagLut.h:326
icUInt16Number GetOutputChannels() const
Definition IccTagLut.h:357
icUInt32Number NumPoints() const
Definition IccTagLut.h:348
void SetPrecision(icUInt8Number nPrecision)
Definition IccTagLut.h:382
icFloatNumber * GetData(int index)
Definition IccTagLut.h:347
bool Init(icUInt8Number nGridPoints, icUInt32Number nMaxSize=0, icUInt8Number nBytesPerPoint=4)
Name: CIccCLUT::Init.
Class: CIccCurve.
Definition IccTagLut.h:91
virtual bool ParseXml(xmlNode *pNode, icConvertType nType, std::string &parseStr)=0
Data Class: CIccDictEntry.
Definition IccTagDict.h:97
bool SetValueLocalized(CIccTagMultiLocalizedUnicode *pValueLocalized)
Name: CIccDictEntry::SetValueLocalized.
bool SetNameLocalized(CIccTagMultiLocalizedUnicode *pNameLocalized)
Name: CIccDictEntry::SetNameLocalized.
CIccTagMultiLocalizedUnicode * GetValueLocalized()
Definition IccTagDict.h:119
CIccTagMultiLocalizedUnicode * GetNameLocalized()
Definition IccTagDict.h:118
std::wstring & GetName()
Definition IccTagDict.h:109
bool SetValue(std::wstring sValue)
bool IsValueSet()
Definition IccTagDict.h:115
std::wstring GetValue()
Definition IccTagDict.h:114
Definition IccTagDict.h:139
CIccDictEntry * ptr
Definition IccTagDict.h:141
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 GetLength()
Definition IccIO.h:130
virtual icInt32Number Read8(void *pBuf8, icInt32Number nNum=1)
Definition IccIO.h:104
icInt32Number Read16(void *pBuf16, icInt32Number nNum=1)
Definition IccIO.cpp:114
icInt32Number ReadLine(void *pBuf8, icInt32Number nNum=256)
Definition IccIO.cpp:93
icInt32Number Read64(void *pBuf64, icInt32Number nNum=1)
Definition IccIO.cpp:173
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 * GetTagTypeSigName(icTagTypeSignature sig)
Definition IccUtil.cpp:1594
const icChar * GetStandardObserverName(icStandardObserver val)
Definition IccUtil.cpp:2151
Class: CIccMBB.
Definition IccTagLut.h:428
bool IsInputB()
Definition IccTagLut.h:445
LPIccCurve * GetCurvesM() const
Definition IccTagLut.h:472
LPIccCurve * NewCurvesB()
Name: CIccMBB::NewCurvesB.
CIccMatrix * NewMatrix()
Name: CIccMBB::NewMatrix.
virtual bool IsInputMatrix()
Definition IccTagLut.h:442
icUInt8Number InputChannels() const
Definition IccTagLut.h:451
icUInt8Number OutputChannels() const
Definition IccTagLut.h:452
CIccCLUT * SetCLUT(CIccCLUT *clut)
Name: CIccMBB::SetCLUT.
LPIccCurve * GetCurvesB() const
Definition IccTagLut.h:471
bool SwapMBCurves()
Definition IccTagLut.h:446
LPIccCurve * NewCurvesM()
Name: CIccMBB::NewCurvesM.
LPIccCurve * NewCurvesA()
Name: CIccMBB::NewCurvesA.
CIccCLUT * GetCLUT() const
Definition IccTagLut.h:469
CIccMatrix * GetMatrix() const
Definition IccTagLut.h:468
LPIccCurve * GetCurvesA() const
Definition IccTagLut.h:470
void Init(icUInt8Number nInputChannels, icUInt8Number nOutputChannels)
Name: CIccMBB::Init.
Class: CIccMatrix.
Definition IccTagLut.h:260
icFloatNumber m_e[12]
Definition IccTagLut.h:269
bool m_bUseConstants
Definition IccTagLut.h:270
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)=0
virtual bool ToXml(std::string &xml, std::string blanks="")=0
Class: CIccMultiProcessElement.
Definition IccTagMPE.h:146
virtual IIccExtensionMpe * GetExtension()
Definition IccTagMPE.h:182
virtual const icChar * GetClassName() const =0
icUInt32Number m_nReserved
Definition IccTagMPE.h:188
Class: CIccProcessElementPtr.
Definition IccTagMPE.h:115
CIccMultiProcessElement * ptr
Definition IccTagMPE.h:117
Data Class: CIccProfileDescStruct.
CIccProfileDescText m_deviceMfgDesc
icSignature m_deviceModel
icTechnologySignature m_technology
CIccProfileDescText m_deviceModelDesc
icUInt64Number m_attributes
bool SetType(icTagTypeSignature nType)
Name: CIccProfileDescText::SetType.
CIccTag * GetTag() const
CIccTagMultiLocalizedUnicode m_desc
icProfileID m_profileID
bool ToXmlWithBlanks(std::string &xmlString, std::string blanks)
bool ParseXml(xmlNode *pNode, std::string &parseStr)
Data Class: CIccResponseCurveStruct.
icMeasurementUnitSig GetMeasurementType() const
CIccResponse16List * GetResponseList(icUInt16Number nChannel)
icUInt16Number GetNumChannels() const
icXYZNumber * GetXYZ(icUInt32Number index)
bool ParseXml(xmlNode *pNode, std::string &parseStr)
bool FillFromFullMatrix(icFloatNumber *pData)
icUInt16Number GetNumRowColumns(icUInt16Number nRow) const
icUInt16Number GetRowOffset(icUInt16Number nRow=0)
icUInt16Number * GetColumnsForRow(icUInt16Number nRow=0) const
IIccSparseMatrixEntry * GetData() const
icUInt16Number Cols() const
icUInt32Number GetMaxEntries()
icUInt16Number Rows() const
void Reset(void *pMatrix, icUInt32Number nSize, icSparseMatrixType nType, bool bInitFromData=true)
icUInt16Number * GetRowStart() const
bool Init(icUInt16Number nRows, icUInt16Number nCols, bool bSetData=false)
static icStructSignature GetStructSig(const icChar *structName)
Function: GetStructSig(structName) Get signature of structure from display name.
Class: CIccTag.
virtual icTagTypeSignature GetType() const
Function: GetType()
icUInt32Number m_nReserved
static CIccTag * Create(icTagTypeSignature sig)
Name: CIccTag::Create.
virtual IIccExtensionTag * GetExtension()
Class: CIccTagMultiLocalizedUnicode.
void SetText(const icChar *szText, icLanguageCode nLanguageCode=icLanguageCodeEnglish, icCountryCode nRegionCode=icCountryCodeUSA)
Name: refIccMAX::CIccTagMultiLocalizedUnicode::SetText.
CIccMultiLocalizedUnicode * m_Strings
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual const char * GetClassName() const
Name: CIccTagFixedNum::GetClassName.
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual const char * GetClassName() const
Name: CIccTagFloatNum::GetClassName.
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual const char * GetExtClassName() const
Definition IccTagXml.h:79
virtual bool ToXml(std::string &xml, std::string blanks="")=0
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)=0
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
bool ParseElement(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
static CIccMultiProcessElement * CreateElement(const icChar *szElementNodeName)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual const char * GetClassName() const
Name: CIccTagNum::GetClassName.
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
bool ParseTag(xmlNode *pNode, std::string &parseStr)
Name: CIccTagXmlStruct::ParseTag.
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
Definition IccTagXml.cpp:86
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
Definition IccTagXml.cpp:96
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual bool ToXml(std::string &xml, std::string blanks="")
const icUInt16Number * c_str()
Definition IccUtilXml.h:93
size_t Size()
Definition IccUtilXml.h:84
const wchar_t * ToWString(std::wstring &buf)
bool ParseTextArray(const char *szText)
bool SetSize(icUInt32Number nSize)
static bool ParseArray(T *buf, icUInt32Number nBufSize, xmlNode *pNode)
bool ParseTextArrayNum(const char *szText, icUInt32Number num, std::string &parseStr)
static bool DumpArray(std::string &xml, std::string blanks, T *buf, icUInt32Number nBufSize, icConvertType nType, icUInt8Number nColumns)
icUInt32Number GetSize()
Definition IccUtilXml.h:166
virtual const char * GetExtClassName()=0
virtual const char * GetExtDerivedClassName() const =0
virtual const char * GetExtClassName() const =0
virtual icUInt8Number * getPtr(int index=0) const =0
Class: IIccStruct.
virtual std::string GetElemName(icSignature sigElem) const =0
virtual const icChar * GetDisplayName() const =0
unsigned char icUInt8Number
Number definitions.
float icFloat32Number
#define icSigUnknownType
Convenience Enum Definitions - Not defined in ICC specification.
icSparseMatrixType
unsigned short icUInt16Number
icTechnologySignature
technology signature descriptions
icIlluminant
Pre-defined illuminants, used in measurement and viewing conditions type.
@ icIlluminantUnknown
icColorantEncoding
Colorant and Phosphor Encodings used in chromaticity type.
icUInt16Number icCountryCode
icUInt16Number icFloat16Number
IEEE float storage numbers.
double icFloat64Number
#define icSparseMatrixFloatNum
Convenience Enum Definition - Not defined in ICC specification.
@ icSigLabData
icUInt32Number icSignature
icUInt16Number icLanguageCode
icImageEncodingType
@ icSigFloat16ArrayType
@ icSigS15Fixed16ArrayType
@ icSigFloat64ArrayType
@ icSigFloat32ArrayType
icStructSignature
Tag Structure type signatures.
@ icBinaryData
@ icAsciiData
icUInt32Number icUInt64Number[2]
#define icSigUnknownTag
Convenience Enum Definitions - Not defined in ICC specification.
icArraySignature
Tag Array type signatures.
icTagSignature
public tags and sizes
@ icStdObsUnknown
icChar rootName[32]
icFloatNumber deviceCoords[1]
icFloatNumber pcsCoords[3]
response16Number
icUInt16Number deviceCode
icS15Fixed16Number measurementValue
icUInt16Number reserved
icS15Fixed16Number Y
icS15Fixed16Number Z
icS15Fixed16Number X