Bug Summary

File:IccXML/IccLibXML/IccTagXml.cpp
Warning:line 1667, column 18
Value stored to 'ptr' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-apple-macosx14.0.0 -Wundef-prefix=TARGET_OS_ -Werror=undef-prefix -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name IccTagXml.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=osx -analyzer-checker=security.insecureAPI.decodeValueOfObjCType -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -ffp-contract=on -fno-rounding-math -funwind-tables=2 -target-sdk-version=14.0 -fcompatibility-qualified-id-block-type-checking -fvisibility-inlines-hidden-static-local-var -target-cpu penryn -tune-cpu generic -debugger-tuning=lldb -target-linker-version 1015.7 -fprofile-instrument=clang -fcoverage-mapping -fcoverage-compilation-dir=/Users/xss/DemoIccMAX-hoyt-master/build/IccXML -resource-dir /usr/local/Cellar/llvm/17.0.3/lib/clang/17 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk -D IccXML2_EXPORTS -I /Users/xss/DemoIccMAX-hoyt-master/build/Cmake/../../IccProfLib -I /Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk/usr/include/libxml2 -I /Developer/Headers/FlatCarbon -F/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk/System/Library/Frameworks -internal-isystem /usr/local/Cellar/llvm/17.0.3/bin/../include/c++/v1 -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk/usr/local/include -internal-isystem /usr/local/Cellar/llvm/17.0.3/lib/clang/17/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk/usr/include -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/Users/xss/DemoIccMAX-hoyt-master/build/IccXML -ferror-limit 19 -fsanitize=address -fsanitize-system-ignorelist=/usr/local/Cellar/llvm/17.0.3/lib/clang/17/share/asan_ignorelist.txt -fno-sanitize-memory-param-retval -fsanitize-address-use-after-scope -fsanitize-address-globals-dead-stripping -fno-assume-sane-operator-new -stack-protector 1 -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fmax-type-align=16 -analyzer-output=html -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /var/folders/l9/sd9kj1px4yq2wc5_lkwhlt6w0000gn/T/scan-build-2023-10-28-102616-57860-1 -x c++ /Users/xss/DemoIccMAX-hoyt-master/IccXML/IccLibXML/IccTagXml.cpp
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__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")strcmp((const char *)(pNode->name), (const char*)("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")strcmp((const char *)(pNode->name), (const char*)("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")strcmp((const char *)(pNode->name), (const char*)("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")strcmp((const char *)(pNode->name), (const char*)("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")strcmp((const char *)(pNode->name), (const char*)("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")strcmp((const char *)(pNode->name), (const char*)("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=\"%f\" end=\"%f\" 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=\"%f\" end=\"%f\" 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=\"%.8f\" a=\"%.8f\" b=\"%.8f\"", 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=\"%.8f\" Y=\"%.8f\" Z=\"%.8f\"", 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
750 icUInt32Number i;
751
752 SIccNamedColorEntry *pNamedColor = m_NamedColor;
753
754 for (i=0, pNode=pNode->children; pNode; pNode=pNode->next) {
755 const icChar *szName = NULL__null;
756 if (pNode->type == XML_ELEMENT_NODE &&
757 !icXmlStrCmp(pNode->name, "NamedColor")strcmp((const char *)(pNode->name), (const char*)("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")strcmp((const char *)(pNode->name), (const char*)("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")strcmp((const char *)(pNode->name), (const char*)("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
838 icUInt32Number j;
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
849 icUInt32Number j;
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
860 icUInt32Number j;
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=\"%.8f\" Y=\"%.8f\" Z=\"%.8f\"/>\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) {
900 icUInt32Number i;
901 SetSize(n);
902
903 for (i=0; pNode; pNode=pNode->next) {
904 if (pNode->type == XML_ELEMENT_NODE &&
905 !icXmlStrCmp(pNode->name, "XYZNumber")strcmp((const char *)(pNode->name), (const char*)("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=\"%.8f\" y=\"%.8f\"/>\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) {
958 icUInt32Number i;
959 SetSize(n);
960
961 for (i=0; pNode; pNode=pNode->next) {
962 if (pNode->type == XML_ELEMENT_NODE &&
963 !icXmlStrCmp(pNode->name, "Channel")strcmp((const char *)(pNode->name), (const char*)("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 CIccTagXmlSparseMatrixArray::ToXml(std::string &xml, std::string blanks/* = ""*/)
984{
985 char buf[256];
986 int i, j, n;
987
988 sprintf(buf, "<SparseMatrixArray outputChannels=\"%d\" matrixType=\"%d\">\n", m_nChannelsPerMatrix, m_nMatrixType);
989 xml += blanks + buf;
990
991 CIccSparseMatrix mtx;
992 icUInt32Number bytesPerMatrix = GetBytesPerMatrix();
993
994 for (i=0; i<(int)m_nSize; i++) {
995 mtx.Reset(m_RawData+i*bytesPerMatrix, bytesPerMatrix, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), true);
996 sprintf(buf, " <SparseMatrix rows=\"%d\" cols=\"%d\">\n", mtx.Rows(), mtx.Cols());
997 xml += blanks + buf;
998
999 for (j=0; j<(int)mtx.Rows(); j++) {
1000 xml += blanks + " <SparseRow>\n";
1001
1002 n=mtx.GetNumRowColumns(j);
1003
1004 xml += blanks + " <ColIndices>\n";
1005 CIccUInt16Array::DumpArray(xml, blanks+" ", mtx.GetColumnsForRow(j), n, icConvert16Bit, 8);
1006 xml += blanks + " </ColIndices>\n";
1007
1008 xml += blanks + " <ColData>\n";
1009 CIccFloatArray::DumpArray(xml, blanks+" ", (icFloatNumber*)(mtx.GetData()->getPtr(mtx.GetRowOffset(j))), n, icConvertFloat, 8);
1010 xml += blanks + " </ColData>\n";
1011
1012 xml += blanks + " </SparseRow>\n";
1013 }
1014 xml += blanks + " </SparseMatrix>\n";
1015 }
1016
1017 xml += blanks + "</SparseMatrixArray>\n";
1018
1019 return true;
1020}
1021
1022
1023bool CIccTagXmlSparseMatrixArray::ParseXml(xmlNode *pNode, std::string &parseStr)
1024{
1025 pNode = icXmlFindNode(pNode, "SparseMatrixArray");
1026
1027 if (pNode) {
1028 xmlAttr *outputChan = icXmlFindAttr(pNode, "outputChannels");
1029 xmlAttr *matrixType = icXmlFindAttr(pNode, "matrixType");
1030
1031 if (outputChan && matrixType) {
1032 icUInt32Number nChannelsPerMatrix = atoi(icXmlAttrValue(outputChan));
1033 icSparseMatrixType nMatrixType = (icSparseMatrixType)atoi(icXmlAttrValue(matrixType));
1034
1035 xmlNode *pChild;
1036
1037 int n=0;
1038 for (pChild = pNode->children; pChild; pChild=pChild->next) {
1039 if (pChild->type == XML_ELEMENT_NODE &&
1040 (!icXmlStrCmp(pChild->name, "SparseMatrix")strcmp((const char *)(pChild->name), (const char*)("SparseMatrix"
))
|| !icXmlStrCmp(pChild->name, "FullMatrix")strcmp((const char *)(pChild->name), (const char*)("FullMatrix"
))
))
1041 n++;
1042
1043 }
1044 Reset(n, (icUInt16Number)nChannelsPerMatrix);
1045 m_nMatrixType = (icSparseMatrixType)nMatrixType;
1046
1047 icUInt32Number bytesPerMatrix = GetBytesPerMatrix();
1048 CIccSparseMatrix mtx;
1049 int i=0;
1050 for (pChild = pNode->children; pChild; pChild=pChild->next) {
1051 if (pChild->type == XML_ELEMENT_NODE) {
1052 if (!icXmlStrCmp(pChild->name, "SparseMatrix")strcmp((const char *)(pChild->name), (const char*)("SparseMatrix"
))
) {
1053 mtx.Reset(m_RawData + i*bytesPerMatrix, bytesPerMatrix, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), false);
1054
1055 xmlAttr *rows = icXmlFindAttr(pChild, "rows");
1056 xmlAttr *cols = icXmlFindAttr(pChild, "cols");
1057
1058 if (rows && cols) {
1059 icUInt16Number nRows, nCols;
1060
1061 nRows = atoi(icXmlAttrValue(rows));
1062 nCols = atoi(icXmlAttrValue(cols));
1063
1064 mtx.Init(nRows, nCols, true);
1065
1066 icUInt16Number *rowstart = mtx.GetRowStart();
1067 icUInt32Number nMaxEntries = mtx.GetMaxEntries();
1068 xmlNode *pRow;
1069 int iRow=0;
1070 icUInt32Number pos = 0;
1071 for (pRow=pChild->children; pRow; pRow=pRow->next) {
1072 if (pRow->type == XML_ELEMENT_NODE && !icXmlStrCmp(pRow->name, "SparseRow")strcmp((const char *)(pRow->name), (const char*)("SparseRow"
))
) {
1073 xmlNode *pIdx = icXmlFindNode(pRow->children, "ColIndices");
1074 xmlNode *pData = icXmlFindNode(pRow->children, "ColData");
1075
1076 if (pIdx && pData) {
1077 CIccUInt16Array idx;
1078 CIccFloatArray data;
1079
1080 if (!idx.ParseTextArray(pIdx) || !data.ParseTextArray(pData)) {
1081 parseStr += "Unable to parse SparseRow index or data values\n";
1082 return false;
1083 }
1084 if (idx.GetSize() != data.GetSize()) {
1085 parseStr += "Mismatch between SparseRow index and data lengths\n";
1086 return false;
1087 }
1088 if (pos+idx.GetSize() > nMaxEntries) {
1089 parseStr += "Exceeded maximum number of sparse matrix entries\n";
1090 return false;
1091 }
1092 rowstart[iRow] = (icUInt16Number)pos;
1093 memcpy(mtx.GetColumnsForRow(iRow), idx.GetBuf(), idx.GetSize()*sizeof(icUInt16Number));
1094 memcpy(mtx.GetData()->getPtr(pos), data.GetBuf(), data.GetSize()*sizeof(icFloatNumber));
1095 pos += idx.GetSize();
1096 }
1097 iRow++;
1098 }
1099 }
1100 while(iRow<nRows) {
1101 rowstart[iRow] = (icUInt16Number)pos;
1102 iRow++;
1103 }
1104 rowstart[iRow] = (icUInt16Number)pos;
1105 }
1106 else {
1107 parseStr += "Cannot find SparseMatrix rows and cols\n";
1108 return false;
1109 }
1110
1111 i++;
1112 }
1113 else if (!icXmlStrCmp(pChild->name, "FullMatrix")strcmp((const char *)(pChild->name), (const char*)("FullMatrix"
))
) {
1114 mtx.Reset(m_RawData + i*bytesPerMatrix, bytesPerMatrix, icSparseMatrixFloatNum((icSparseMatrixType)0x0000), false);
1115
1116 xmlAttr *rows = icXmlFindAttr(pChild, "rows");
1117 xmlAttr *cols = icXmlFindAttr(pChild, "cols");
1118
1119 if (rows && cols) {
1120 icUInt16Number nRows, nCols;
1121
1122 nRows = atoi(icXmlAttrValue(rows));
1123 nCols = atoi(icXmlAttrValue(cols));
1124
1125 mtx.Init(nRows, nCols, true);
1126
1127 CIccFloatArray data;
1128 data.ParseTextArray(pChild);
1129 if (data.GetSize()==nRows*nCols) {
1130 if (!mtx.FillFromFullMatrix(data.GetBuf()))
1131 parseStr += "Exceeded maximum number of sparse matrix entries\n";
1132 }
1133 else {
1134 parseStr += "Invalid FullMatrix data dimensions\n";
1135 return false;
1136 }
1137 }
1138 else {
1139 parseStr += "Cannot find FullMatrix rows and cols\n";
1140 return false;
1141 }
1142 i++;
1143 }
1144 }
1145 }
1146 return true;
1147 }
1148 else {
1149 parseStr += "Cannot find outputChannels and matrixType members\n";
1150 }
1151 }
1152 else {
1153 parseStr += "Cannot find SparseMatrixArray node\n";
1154 }
1155
1156 return false;
1157}
1158
1159
1160template <class T, icTagTypeSignature Tsig>
1161const icChar* CIccTagXmlFixedNum<T, Tsig>::GetClassName() const
1162{
1163 if (Tsig==icSigS15Fixed16ArrayType)
1164 return "CIccTagXmlS15Fixed16";
1165 else
1166 return "CIccTagXmlU16Fixed16";
1167}
1168
1169// for multi-platform support
1170// added "this->" modifier to data members.
1171template <class T, icTagTypeSignature Tsig>
1172bool CIccTagXmlFixedNum<T, Tsig>::ToXml(std::string &xml, std::string blanks/* = ""*/)
1173{
1174 char buf[256];
1175 int i;
1176
1177 if (Tsig==icSigS15Fixed16ArrayType) {
1178 int n = 8;
1179 xml += blanks + "<Array>\n";
1180 for (i=0; i<(int)this->m_nSize; i++) {
1181 if (!(i%n)) {
1182 if (i)
1183 xml += "\n";
1184 xml += blanks + blanks;
1185 }
1186 else {
1187 xml += " ";
1188 }
1189 sprintf(buf, "%.8f", (float)icFtoD(this->m_Num[i]));
1190 xml += buf;
1191 }
1192
1193 if ((i%n)!=1) {
1194 xml += "\n";
1195 }
1196 }
1197 else {
1198 for (i=0; i<(int)this->m_nSize; i++) {
1199
1200 if (!(i%8)) {
1201 if (i)
1202 xml += "\n";
1203 xml += blanks + blanks;
1204 }
1205 else {
1206 xml += " ";
1207 }
1208 sprintf(buf, "%.8f", (float)icUFtoD(this->m_Num[i]));
1209 xml += buf;
1210 }
1211
1212 if ((i%8)!=1) {
1213 xml += "\n";
1214 }
1215 }
1216 xml += blanks + "</Array>\n";
1217 return true;
1218}
1219
1220// for multi-platform support
1221// added "this->" modifier to data members.
1222template <class T, icTagTypeSignature Tsig>
1223bool CIccTagXmlFixedNum<T, Tsig>::ParseXml(xmlNode *pNode, std::string &parseStr)
1224{
1225 pNode = icXmlFindNode(pNode, "Array");
1226 pNode = pNode->children;
1227
1228 CIccFloatArray a;
1229
1230 if (!a.ParseArray(pNode) || !a.GetSize()) {
1231 return false;
1232 }
1233
1234 icUInt32Number i, n = a.GetSize();
1235 icFloatNumber *buf = a.GetBuf();
1236
1237 this->SetSize(n);
1238
1239 for (i=0; i<n; i++) {
1240 if (Tsig==icSigS15Fixed16ArrayType) {
1241 this->m_Num[i] = icDtoF(buf[i]);
1242 }
1243 else {
1244 this->m_Num[i] = icDtoUF(buf[i]);
1245 }
1246 }
1247 return true;
1248}
1249
1250
1251//Make sure typedef classes get built
1252template class CIccTagXmlFixedNum<icS15Fixed16Number, icSigS15Fixed16ArrayType>;
1253template class CIccTagXmlFixedNum<icU16Fixed16Number, icSigU16Fixed16ArrayType>;
1254
1255
1256template <class T, class A, icTagTypeSignature Tsig>
1257const icChar *CIccTagXmlNum<T, A, Tsig>::GetClassName() const
1258{
1259 if (sizeof(T)==sizeof(icUInt8Number))
1260 return "CIccTagXmlUInt8";
1261 else if (sizeof(T)==sizeof(icUInt16Number))
1262 return "CIccTagXmlUInt16";
1263 else if (sizeof(T)==sizeof(icUInt32Number))
1264 return "CIccTagXmlUInt32";
1265 else if (sizeof(T)==sizeof(icUInt64Number))
1266 return "CIccTagXmlUInt64";
1267 else
1268 return "CIccTagXmlNum<>";
1269}
1270
1271// for multi-platform support
1272// added "this->" modifier to data members.
1273template <class T, class A, icTagTypeSignature Tsig>
1274bool CIccTagXmlNum<T, A, Tsig>::ToXml(std::string &xml, std::string blanks/* = ""*/)
1275{
1276 char buf[512];
1277 int i;
1278
1279 xml += blanks + "<Array>\n";
1280 for (i=0; i<(int)this->m_nSize; i++) {
1281 if (!(i%16)) {
1282 if (i)
1283 xml += "\n";
1284 xml += blanks + blanks;
1285 }
1286 else {
1287 xml += " ";
1288 }
1289 if (sizeof(T)==16)
1290 sprintf(buf, "%llu", (icUInt64Number)this->m_Num[i]);
1291 else
1292 sprintf(buf, "%u", (icUInt32Number)this->m_Num[i]);
1293 xml += buf;
1294 }
1295
1296 if ((i%16)!=1) {
1297 xml += "\n";
1298 }
1299
1300 xml += blanks + "</Array>\n";
1301 return true;
1302 return true;
1303}
1304
1305// for multi-platform support
1306// added "this->" modifier to data members.
1307template <class T, class A, icTagTypeSignature Tsig>
1308bool CIccTagXmlNum<T, A, Tsig>::ParseXml(xmlNode *pNode, std::string &parseStr)
1309{
1310 xmlNode *pDataNode = icXmlFindNode(pNode, "Data");
1311 if (!pDataNode) {
1312 pDataNode = icXmlFindNode(pNode, "Array");
1313 }
1314 if (!pDataNode) {
1315 return false;
1316 }
1317
1318 pNode = pDataNode->children;
1319
1320 A a;
1321
1322 if (!a.ParseArray(pNode) || !a.GetSize()) {
1323 return false;
1324 }
1325
1326 icUInt32Number i, n = a.GetSize();
1327 T *buf = a.GetBuf();
1328
1329 this->SetSize(n);
1330
1331 for (i=0; i<n; i++) {
1332 this->m_Num[i] = buf[i];
1333 }
1334
1335 return true;
1336}
1337
1338//Make sure typedef classes get built
1339template class CIccTagXmlNum<icUInt8Number, CIccUInt8Array, icSigUInt8ArrayType>;
1340template class CIccTagXmlNum<icUInt16Number, CIccUInt16Array, icSigUInt16ArrayType>;
1341template class CIccTagXmlNum<icUInt32Number, CIccUInt32Array, icSigUInt32ArrayType>;
1342template class CIccTagXmlNum<icUInt64Number, CIccUInt64Array, icSigUInt64ArrayType>;
1343
1344
1345template <class T, class A, icTagTypeSignature Tsig>
1346const icChar *CIccTagXmlFloatNum<T, A, Tsig>::GetClassName() const
1347{
1348 if (Tsig==icSigFloat16ArrayType)
1349 return "CIccTagXmlFloat32";
1350 else if (Tsig==icSigFloat32ArrayType)
1351 return "CIccTagXmlFloat32";
1352 else if (Tsig==icSigFloat64ArrayType)
1353 return "CIccTagXmlFloat64";
1354 else
1355 return "CIccTagXmlFloatNum<>";
1356}
1357
1358// for multi-platform support
1359// added "this->" modifier to data members.
1360template <class T, class A, icTagTypeSignature Tsig>
1361bool CIccTagXmlFloatNum<T, A, Tsig>::ToXml(std::string &xml, std::string blanks/* = ""*/)
1362{
1363 char buf[512];
1364
1365 if (this->m_nSize==1) {
1366#ifdef _WIN32
1367 if (sizeof(T)==sizeof(icFloat32Number))
1368 sprintf(buf, "<Data>%.8f</Data>\n", this->m_Num[0]);
1369 else if (sizeof(T)==sizeof(icFloat64Number))
1370 sprintf(buf, "<Data>%.16lf</Data>\n", this->m_Num[0]);
1371 else
1372#endif
1373 sprintf(buf, "<Data>%.8f</Data>", this->m_Num[0]);
1374 xml += blanks;
1375 xml += buf;
1376 }
1377 else {
1378 int i;
1379 int n = 8;
1380 xml += blanks + "<Data>\n";
1381 for (i=0; i<(int)this->m_nSize; i++) {
1382 if (!(i%n)) {
1383 if (i)
1384 xml += "\n";
1385 xml += blanks + blanks;
1386 }
1387 else {
1388 xml += " ";
1389 }
1390#ifdef _WIN32
1391 if (sizeof(T)==sizeof(icFloat32Number))
1392 sprintf(buf, "%.8f", this->m_Num[i]);
1393
1394 else if (sizeof(T)==sizeof(icFloat32Number))
1395 sprintf(buf, "%.16lf", this->m_Num[i]);
1396 else
1397#endif
1398 sprintf(buf, "%.8f", this->m_Num[i]);
1399 xml += buf;
1400 }
1401
1402 if ((i%n)!=1) {
1403 xml += "\n";
1404 xml += blanks + "</Data>\n";
1405 }
1406 else {
1407 xml += " </Data>\n";
1408 }
1409 }
1410 return true;
1411}
1412
1413// for multi-platform support
1414// added "this->" modifier to data members.
1415template <class T, class A, icTagTypeSignature Tsig>
1416bool CIccTagXmlFloatNum<T, A, Tsig>::ParseXml(xmlNode *pNode, std::string &parseStr)
1417{
1418 pNode = icXmlFindNode(pNode, "Data");
1419
1420 const char *filename = icXmlAttrValue(pNode, "Filename", "");
1421 if (!filename[0]) {
1422 filename = icXmlAttrValue(pNode, "File", "");
1423 }
1424
1425 A a;
1426
1427 if (filename[0]) {
1428 CIccIO *file = IccOpenFileIO(filename, "rb");
1429 if (!file){
1430 parseStr += "Error! - File '";
1431 parseStr += filename;
1432 parseStr +="' not found.\n";
1433 delete file;
1434 return false;
1435 }
1436
1437 icUInt32Number len = file->GetLength();
1438
1439 if (!stricmpstrcasecmp(icXmlAttrValue(pNode, "Format", "text"), "text")) {
1440 char *fbuf = (char*)malloc(len+1);
1441 fbuf[len]=0;
1442 if (!fbuf) {
1443 parseStr += "Memory error!\n";
1444 delete file;
1445 return false;
1446 }
1447
1448 if (file->Read8(fbuf, len)!=len) {
1449 parseStr += "Read error of (";
1450 parseStr += filename;
1451 parseStr += ")!\n";
1452 free(fbuf);
1453 delete file;
1454 return false;
1455 }
1456 delete file;
1457
1458 if (!a.ParseTextArray(fbuf) || !a.GetSize()) {
1459 parseStr += "Parse error of (";
1460 parseStr += filename;
1461 parseStr += ")!\n";
1462 free(fbuf);
1463 return false;
1464 }
1465 free(fbuf);
1466 }
1467 else if (Tsig==icSigFloat16ArrayType && sizeof(T)==sizeof(icFloat16Number)) {
1468 icUInt32Number n = len/sizeof(icFloat16Number);
1469 this->SetSize(n);
1470 if (file->Read16(&this->m_Num[0], n)!=n) {
1471 delete file;
1472 return false;
1473 }
1474 delete file;
1475 return true;
1476 }
1477 else if (Tsig==icSigFloat16ArrayType && sizeof(T)==sizeof(icFloat32Number)) {
1478 icUInt32Number n = len/sizeof(icFloat32Number);
1479 this->SetSize(n);
1480 if (file->ReadFloat16Float(&this->m_Num[0], n)!=n) {
1481 delete file;
1482 return false;
1483 }
1484 delete file;
1485 return true;
1486 }
1487 else if (Tsig==icSigFloat32ArrayType && sizeof(T)==sizeof(icFloat32Number)) {
1488 icUInt32Number n = len/sizeof(icFloat32Number);
1489 this->SetSize(n);
1490 if (file->ReadFloat32Float(&this->m_Num[0], n)!=n) {
1491 delete file;
1492 return false;
1493 }
1494 delete file;
1495 return true;
1496 }
1497 else if (Tsig==icSigFloat64ArrayType && sizeof(T)==sizeof(icFloat64Number)) {
1498 icUInt32Number n = len/sizeof(icFloat64Number);
1499 this->SetSize(n);
1500 if (file->Read64(&this->m_Num[0], n)!=n) {
1501 delete file;
1502 return false;
1503 }
1504 delete file;
1505 return true;
1506
1507 }
1508 else {
1509 delete file;
1510 parseStr += "Unsupported file parsing type!\n";
1511 return false;
1512 }
1513 }
1514 else {
1515 pNode = pNode->children;
1516
1517 if (!a.ParseArray(pNode) || !a.GetSize()) {
1518 return false;
1519 }
1520 }
1521
1522 icUInt32Number i, n = a.GetSize();
1523 T *buf = a.GetBuf();
1524
1525 this->SetSize(n);
1526
1527 for (i=0; i<n; i++) {
1528 this->m_Num[i] = buf[i];
1529 }
1530 return true;
1531}
1532
1533
1534//Make sure typedef classes get built
1535template class CIccTagXmlFloatNum<icFloat32Number, CIccFloat32Array, icSigFloat16ArrayType>;
1536template class CIccTagXmlFloatNum<icFloat32Number, CIccFloat32Array, icSigFloat32ArrayType>;
1537template class CIccTagXmlFloatNum<icFloat64Number, CIccFloat64Array, icSigFloat64ArrayType>;
1538
1539
1540bool CIccTagXmlMeasurement::ToXml(std::string &xml, std::string blanks/* = ""*/)
1541{
1542 char buf[256];
1543
1544 CIccInfo info;
1545
1546 sprintf(buf,"<StandardObserver>%s</StandardObserver>\n",icGetStandardObserverName(m_Data.stdObserver));
1547 xml += blanks + buf;
1548
1549 sprintf(buf, "<MeasurementBacking X=\"%.8f\" Y=\"%.8f\" Z=\"%.8f\"/>\n", icFtoD(m_Data.backing.X),
1550 icFtoD(m_Data.backing.Y), icFtoD(m_Data.backing.Z));
1551 xml += blanks + buf;
1552
1553 sprintf(buf,"<Geometry>%s</Geometry>\n",info.GetMeasurementGeometryName(m_Data.geometry));
1554 xml += blanks + buf;
1555
1556 sprintf(buf,"<Flare>%s</Flare>\n",info.GetMeasurementFlareName(m_Data.flare));
1557 xml += blanks + buf;
1558
1559 sprintf(buf,"<StandardIlluminant>%s</StandardIlluminant>\n",info.GetIlluminantName(m_Data.illuminant));
1560 xml += blanks + buf;
1561 return true;
1562}
1563
1564
1565bool CIccTagXmlMeasurement::ParseXml(xmlNode *pNode, std::string &parseStr)
1566{
1567 memset(&m_Data, 0, sizeof(m_Data));
1568
1569 pNode = icXmlFindNode(pNode, "StandardObserver");
1570 if (pNode) {
1571 m_Data.stdObserver = icGetNamedStandardObserverValue(pNode->children ? (icChar*)pNode->children->content: "");
1572 }
1573
1574
1575 pNode = icXmlFindNode(pNode, "MeasurementBacking");
1576 if (pNode){
1577 xmlAttr *attr;
1578
1579 attr = icXmlFindAttr(pNode, "X");
1580 if (attr) {
1581 m_Data.backing.X = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1582 }
1583
1584 attr = icXmlFindAttr(pNode, "Y");
1585 if (attr) {
1586 m_Data.backing.Y = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1587 }
1588
1589 attr = icXmlFindAttr(pNode, "Z");
1590 if (attr) {
1591 m_Data.backing.Z = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1592 }
1593 }
1594
1595 pNode = icXmlFindNode(pNode, "Geometry");
1596 if (pNode){
1597 m_Data.geometry = icGeNamedtMeasurementGeometryValue(pNode->children ? (icChar*)pNode->children->content : "");
1598 }
1599
1600 pNode = icXmlFindNode(pNode, "Flare");
1601 if (pNode){
1602 m_Data.flare = icGetNamedMeasurementFlareValue(pNode->children ? (icChar*)pNode->children->content : "");
1603 }
1604
1605 pNode = icXmlFindNode(pNode, "StandardIlluminant");
1606 if (pNode){
1607 m_Data.illuminant = icGetIlluminantValue(pNode->children ? (icChar*)pNode->children->content : "");
1608 }
1609
1610 return true;
1611}
1612
1613bool CIccTagXmlMultiLocalizedUnicode::ToXml(std::string &xml, std::string blanks/* = ""*/)
1614{
1615 std::string xmlbuf;
1616 char data[256];
1617 std::string bufstr;
1618 CIccMultiLocalizedUnicode::iterator i;
1619
1620 if (!m_Strings)
1621 return false;
1622
1623 for (i=m_Strings->begin(); i!=m_Strings->end(); i++) {
1624 xml += blanks + "<LocalizedText LanguageCountry=\"";
1625 xml += icFixXml(xmlbuf, icGetSigStr(data, (i->m_nLanguageCode<<16) + i->m_nCountryCode));
1626 xml += "\"><![CDATA[";
1627 xml += icFixXml(xmlbuf, icUtf16ToUtf8(bufstr, i->GetBuf(), i->GetLength()));
1628 xml += "]]></LocalizedText>\n";
1629 }
1630 return true;
1631}
1632
1633
1634bool CIccTagXmlMultiLocalizedUnicode::ParseXml(xmlNode *pNode, std::string &parseStr)
1635{
1636 xmlAttr *langCode;
1637 int n = 0;
1638
1639 for (pNode = icXmlFindNode(pNode, "LocalizedText"); pNode; pNode = icXmlFindNode(pNode->next, "LocalizedText")) {
1640 if ((langCode = icXmlFindAttr(pNode, "LanguageCountry"))) {
1641 xmlNode *pText;
1642
1643 for (pText = pNode->children; pText; pText = pText->next) {
1644 if (pText->type == XML_TEXT_NODE || pText->type == XML_CDATA_SECTION_NODE)
1645 break;
1646 }
1647
1648 if (pText) {
1649 icUInt32Number lc = icGetSigVal(icXmlAttrValue(langCode));
1650 CIccUTF16String str((const char*)pText->content);
1651
1652 SetText(str.c_str(), (icLanguageCode)(lc>>16), (icCountryCode)(lc & 0xffff));
1653 n++;
1654 }
1655 else {
1656 SetText("");
1657 n++;
1658 }
1659 }
1660 }
1661 return n>0; //We succeed if we parsed at least one string
1662}
1663
1664
1665bool CIccTagXmlTagData::ToXml(std::string &xml, std::string blanks/* = ""*/)
1666{
1667 icUInt8Number *ptr = m_pData;
Value stored to 'ptr' during its initialization is never read
1668 char buf[60];
1669 std::string szFlag("ASCII");
1670
1671 if (m_nDataFlag == 1)
1672 szFlag = "binary";
1673 sprintf (buf, "<Data Flag=\"%s\">\n", szFlag.c_str());
1674 xml += blanks + buf;
1675 icXmlDumpHexData(xml, blanks+" ", m_pData, m_nSize);
1676 xml += blanks + "</Data>\n";
1677
1678 return true;
1679}
1680
1681
1682bool CIccTagXmlTagData::ParseXml(xmlNode *pNode, std::string &parseStr)
1683{
1684 pNode = icXmlFindNode(pNode, "Data");
1685 if (pNode && pNode->children && pNode->children->content) {
1686 const icChar *szFlag = icXmlAttrValue(pNode, "Flag");
1687 m_nDataFlag = icAsciiData;
1688 if (!strcmp(szFlag,"binary"))
1689 m_nDataFlag = icBinaryData;
1690
1691 icUInt32Number nSize = icXmlGetHexDataSize((const char *)pNode->children->content);
1692 SetSize(nSize, false);
1693 if (nSize) {
1694 icXmlGetHexData(m_pData, (const char*)pNode->children->content, nSize);
1695 }
1696
1697 return true;
1698 }
1699 return false;
1700}
1701
1702
1703bool CIccTagXmlDateTime::ToXml(std::string &xml, std::string blanks/* = ""*/)
1704{
1705 char buf[256];
1706 sprintf(buf, "<DateTime>%d-%02d-%02dT%02d:%02d:%02d</DateTime>\n",
1707 m_DateTime.year, m_DateTime.month, m_DateTime.day, m_DateTime.hours, m_DateTime.minutes, m_DateTime.seconds);
1708 xml += blanks + buf;
1709 return true;
1710}
1711
1712
1713bool CIccTagXmlDateTime::ParseXml(xmlNode *pNode, std::string &parseStr)
1714{
1715 memset(&m_DateTime, 0, sizeof(m_DateTime));
1716
1717 pNode = icXmlFindNode(pNode, "DateTime");
1718 if (pNode) {
1719 m_DateTime = icGetDateTimeValue(pNode->children ? (const char*)pNode->children->content : "");
1720 return true;
1721 }
1722 return false;
1723}
1724
1725
1726bool CIccTagXmlColorantOrder::ToXml(std::string &xml, std::string blanks/* = ""*/)
1727{
1728 char buf[40];
1729 int i;
1730
1731 xml += blanks + "<ColorantOrder>\n"; //+ blanks + " ";
1732 for (i=0; i<(int)m_nCount; i++) {
1733 sprintf(buf, " <n>%d</n>\n", m_pData[i]);
1734 xml += blanks + buf;
1735 }
1736
1737 xml += blanks + "</ColorantOrder>\n";
1738
1739 return true;
1740}
1741
1742bool CIccTagXmlColorantOrder::ParseXml(xmlNode *pNode, std::string &parseStr)
1743{
1744 pNode = icXmlFindNode(pNode, "ColorantOrder");
1745
1746 if (pNode) {
1747 int n = icXmlNodeCount(pNode->children, "n");
1748
1749 if (n) {
1750 SetSize(n);
1751
1752 if (m_pData) {
1753 if (CIccUInt8Array::ParseArray(m_pData, n, pNode->children))
1754 return true;
1755 }
1756 }
1757 }
1758 return false;
1759}
1760
1761
1762bool CIccTagXmlColorantTable::ToXml(std::string &xml, std::string blanks/* = ""*/)
1763{
1764 char buf[256];
1765 char fix[256];
1766 int i;
1767 std::string str;
1768
1769 xml += blanks + "<ColorantTable>\n";
1770 for (i=0; i<(int)m_nCount; i++) {
1771 icFloatNumber lab[3];
1772 lab[0] = icU16toF(m_pData[i].data[0]);
1773 lab[1] = icU16toF(m_pData[i].data[1]);
1774 lab[2] = icU16toF(m_pData[i].data[2]);
1775 icLabFromPcs(lab);
1776 sprintf(buf, " <Colorant Name=\"%s\" Channel1=\"%.8f\" Channel2=\"%.8f\" Channel3=\"%f\"/>\n",
1777 icFixXml(fix, icAnsiToUtf8(str, m_pData[i].name)), lab[0], lab[1], lab[2]);
1778 xml += blanks + buf;
1779 }
1780 //xml += "\n";
1781 xml += blanks + "</ColorantTable>\n";
1782
1783 return true;
1784}
1785
1786
1787bool CIccTagXmlColorantTable::ParseXml(xmlNode *pNode, std::string &parseStr)
1788{
1789 pNode = icXmlFindNode(pNode, "ColorantTable");
1790
1791 if (pNode && pNode->children) {
1792 pNode = pNode->children;
1793
1794 icUInt16Number n = (icUInt16Number)icXmlNodeCount(pNode, "Colorant");
1795
1796 if (n) {
1797 icUInt32Number i;
1798 SetSize(n);
1799
1800 for (i=0; pNode; pNode=pNode->next) {
1801 if (pNode->type == XML_ELEMENT_NODE &&
1802 !icXmlStrCmp(pNode->name, "Colorant")strcmp((const char *)(pNode->name), (const char*)("Colorant"
))
&&
1803 i<n) {
1804 std::string str;
1805 const icChar *name = icXmlAttrValue(pNode, "Name");
1806 xmlAttr *L = icXmlFindAttr(pNode, "Channel1");
1807 xmlAttr *a = icXmlFindAttr(pNode, "Channel2");
1808 xmlAttr *b = icXmlFindAttr(pNode, "Channel3");
1809
1810 if (name && L && a && b) {
1811 strncpy(m_pData[i].name, icUtf8ToAnsi(str, name), sizeof(m_pData[i].name));
1812 m_pData[i].name[sizeof(m_pData[i].name)-1]=0;
1813
1814 icFloatNumber lab[3];
1815
1816 lab[0] = (icFloatNumber)atof(icXmlAttrValue(L));
1817 lab[1] = (icFloatNumber)atof(icXmlAttrValue(a));
1818 lab[2] = (icFloatNumber)atof(icXmlAttrValue(b));
1819
1820 icLabToPcs(lab);
1821 m_pData[i].data[0] = icFtoU16(lab[0]);
1822 m_pData[i].data[1] = icFtoU16(lab[1]);
1823 m_pData[i].data[2] = icFtoU16(lab[2]);
1824
1825 i++;
1826 }
1827 else
1828 return false;
1829 }
1830 }
1831 return i==n;
1832 }
1833 return false;
1834 }
1835 return false;
1836}
1837
1838
1839bool CIccTagXmlViewingConditions::ToXml(std::string &xml, std::string blanks/* = ""*/)
1840{
1841 char buf[256];
1842
1843 sprintf(buf, "<IlluminantXYZ X=\"%.8f\" Y=\"%.8f\" Z=\"%.8f\"/>\n",
1844 icFtoD(m_XYZIllum.X), icFtoD(m_XYZIllum.Y), icFtoD(m_XYZIllum.Z));
1845 xml += blanks + buf;
1846
1847 sprintf(buf, "<SurroundXYZ X=\"%.8f\" Y=\"%.8f\" Z=\"%.8f\"/>\n",
1848 icFtoD(m_XYZSurround.X), icFtoD(m_XYZSurround.Y), icFtoD(m_XYZSurround.Z));
1849 xml += blanks + buf;
1850
1851 CIccInfo info;
1852 sprintf(buf, "<IllumType>%s</IllumType>\n", info.GetIlluminantName(m_illumType));
1853 xml += blanks + buf;
1854
1855 return true;
1856}
1857
1858bool CIccTagXmlViewingConditions::ParseXml(xmlNode *pNode, std::string &parseStr)
1859{
1860 xmlAttr *attr;
1861 xmlNode *pChild;
1862
1863 memset(&m_XYZIllum, 0, sizeof(m_XYZIllum));
1864 memset(&m_XYZSurround, 0, sizeof(m_XYZSurround));
1865 m_illumType = (icIlluminant)0;
1866
1867 pChild = icXmlFindNode(pNode, "IlluminantXYZ");
1868 if (pChild) {
1869
1870 attr = icXmlFindAttr(pChild, "X");
1871 if (attr) {
1872 m_XYZIllum.X = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1873 }
1874
1875 attr = icXmlFindAttr(pChild, "Y");
1876 if (attr) {
1877 m_XYZIllum.Y = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1878 }
1879
1880 attr = icXmlFindAttr(pChild, "Z");
1881 if (attr) {
1882 m_XYZIllum.Z = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1883 }
1884 }
1885
1886 pChild = icXmlFindNode(pNode, "SurroundXYZ");
1887 if (pChild) {
1888 attr = icXmlFindAttr(pChild, "X");
1889 if (attr) {
1890 m_XYZSurround.X = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1891 }
1892
1893 attr = icXmlFindAttr(pChild, "Y");
1894 if (attr) {
1895 m_XYZSurround.Y = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1896 }
1897
1898 attr = icXmlFindAttr(pChild, "Z");
1899 if (attr) {
1900 m_XYZSurround.Z = icDtoF((icFloatNumber)atof(icXmlAttrValue(attr)));
1901 }
1902 }
1903
1904 pChild = icXmlFindNode(pNode, "IllumType");
1905 if (pChild && pChild->children && pChild->children->content) {
1906 m_illumType = icGetIlluminantValue((icChar*)pChild->children->content);
1907 }
1908
1909 return true;
1910}
1911
1912bool CIccTagXmlSpectralViewingConditions::ToXml(std::string &xml, std::string blanks/* = ""*/)
1913{
1914 char buf[256];
1915 int i, j;
1916 icFloatNumber *ptr;
1917 CIccInfo info;
1918
1919 sprintf(buf, "<StdObserver>%s</StdObserver>\n", info.GetStandardObserverName(m_stdObserver));
1920 xml += blanks + buf;
1921
1922 sprintf(buf, "<IlluminantXYZ X=\"%.8f\" Y=\"%.8f\" Z=\"%.8f\"/>\n",
1923 m_illuminantXYZ.X, m_illuminantXYZ.Y, m_illuminantXYZ.Z);
1924 xml += blanks + buf;
1925
1926 if (m_observer) {
1927 sprintf(buf, "<ObserverFuncs start=\"%.8f\" end=\"%.8f\" steps=\"%d\"",
1928 icF16toF(m_observerRange.start), icF16toF(m_observerRange.end), m_observerRange.steps);
1929 xml += blanks + buf;
1930
1931 if (m_reserved2) {
1932 sprintf(buf, " Reserved=\"%d\"", m_reserved2);
1933 xml += buf;
1934 }
1935 xml += ">\n";
1936
1937 ptr = &m_observer[0];
1938
1939 for (j=0; j<3; j++) {
1940 xml += blanks;
1941 for (i=0; i<m_observerRange.steps; i++) {
1942 if (i && !(i%8)) {
1943 xml += "\n";
1944 xml += blanks;
1945 }
1946 sprintf(buf, " %.8f", *ptr);
1947 ptr++;
1948 xml += buf;
1949 }
1950 xml += "\n";
1951 }
1952 xml += blanks + "</ObserverFuncs>\n";
1953 }
1954
1955 sprintf(buf, "<StdIlluminant>%s</StdIlluminant>\n", info.GetIlluminantName(m_stdIlluminant));
1956 xml += blanks + buf;
1957
1958 sprintf(buf, "<ColorTemperature>%.8f</ColorTemperature>\n", m_colorTemperature);
1959 xml += blanks + buf;
1960
1961 if (m_illuminant) {
1962 sprintf(buf, "<IlluminantSPD start=\"%.8f.\" end=\"%.8f\" steps=\"%d\"",
1963 icF16toF(m_illuminantRange.start), icF16toF(m_illuminantRange.end), m_illuminantRange.steps);
1964 xml += blanks + buf;
1965
1966 if (m_reserved3) {
1967 sprintf(buf, " Reserved=\"%d\"", m_reserved3);
1968 xml += buf;
1969 }
1970 xml += ">\n";
1971
1972 ptr = &m_illuminant[0];
1973
1974 xml += blanks;
1975 for (i=0; i<m_illuminantRange.steps; i++) {
1976 if (i && !(i%8)) {
1977 xml += "\n";
1978 xml += blanks;
1979 }
1980 sprintf(buf, " %.8f", *ptr);
1981 ptr++;
1982 xml += buf;
1983 }
1984 xml += "\n";
1985
1986 xml += blanks + "</IlluminantSPD>\n";
1987 }
1988
1989 sprintf(buf, "<SurroundXYZ X=\"%.8f\" Y=\"%.8f\" Z=\"%.8f\"/>\n",
1990 m_surroundXYZ.X, m_surroundXYZ.Y, m_surroundXYZ.Z);
1991 xml += blanks + buf;
1992
1993
1994 return true;
1995}
1996
1997bool CIccTagXmlSpectralViewingConditions::ParseXml(xmlNode *pNode, std::string &parseStr)
1998{
1999 xmlNode *pChild;
2000 xmlAttr *attr;
2001
2002 memset(&m_illuminantXYZ, 0, sizeof(m_illuminantXYZ));
2003 memset(&m_surroundXYZ, 0, sizeof(m_surroundXYZ));
2004 m_stdIlluminant = icIlluminantUnknown;
2005 m_stdObserver = icStdObsUnknown;
2006 m_colorTemperature = 0;
2007 m_reserved2 = 0;
2008 m_reserved3 = 0;
2009
2010 pChild = icXmlFindNode(pNode, "StdObserver");
2011 if (pChild && pChild->children && pChild->children->content) {
2012 m_stdObserver = icGetNamedStandardObserverValue((icChar*)pChild->children->content);
2013 }
2014
2015 pChild = icXmlFindNode(pNode, "IlluminantXYZ");
2016 if (pChild) {
2017
2018 attr = icXmlFindAttr(pChild, "X");
2019 if (attr) {
2020 m_illuminantXYZ.X = (icFloatNumber)atof(icXmlAttrValue(attr));
2021 }
2022
2023 attr = icXmlFindAttr(pChild, "Y");
2024 if (attr) {
2025 m_illuminantXYZ.Y = (icFloatNumber)atof(icXmlAttrValue(attr));
2026 }
2027
2028 attr = icXmlFindAttr(pChild, "Z");
2029 if (attr) {
2030 m_illuminantXYZ.Z = (icFloatNumber)atof(icXmlAttrValue(attr));
2031 }
2032 }
2033
2034 pChild = icXmlFindNode(pNode, "ObserverFuncs");
2035 if (pChild) {
2036 attr = icXmlFindAttr(pChild, "start");
2037 if (attr) {
2038 m_observerRange.start =icFtoF16((icFloatNumber)atof(icXmlAttrValue(attr)));
2039 }
2040 attr = icXmlFindAttr(pChild, "end");
2041 if (attr) {
2042 m_observerRange.end = icFtoF16((icFloatNumber)atoi(icXmlAttrValue(attr)));
2043 }
2044 attr = icXmlFindAttr(pChild, "steps");
2045 if (attr) {
2046 m_observerRange.steps = (icUInt16Number)atoi(icXmlAttrValue(attr));
2047 }
2048 attr = icXmlFindAttr(pChild, "reserved");
2049 if (attr) {
2050 m_reserved2 = (icUInt16Number)atoi(icXmlAttrValue(attr));
2051 }
2052
2053 if (pChild->children && pChild->children->content) {
2054 CIccFloatArray vals;
2055 vals.ParseTextArray((icChar*)pChild->children->content);
2056 if (vals.GetSize()!=m_observerRange.steps*3)
2057 return false;
2058 m_observer = (icFloatNumber*)malloc(m_observerRange.steps*3*sizeof(icFloatNumber));
2059 if (!m_observer)
2060 return false;
2061 icFloatNumber *pBuf = vals.GetBuf();
2062 memcpy(m_observer, pBuf, m_observerRange.steps*3*sizeof(icFloatNumber));
2063 }
2064 }
2065
2066 pChild = icXmlFindNode(pNode, "StdIlluminant");
2067 if (pChild && pChild->children && pChild->children->content) {
2068 m_stdIlluminant = icGetIlluminantValue((icChar*)pChild->children->content);
2069 }
2070
2071 pChild = icXmlFindNode(pNode, "ColorTemperature");
2072 if (pChild && pChild->children && pChild->children->content) {
2073 m_colorTemperature = (icFloatNumber)atof((icChar*)pChild->children->content);
2074 }
2075
2076 pChild = icXmlFindNode(pNode, "IlluminantSPD");
2077 if (pChild) {
2078 attr = icXmlFindAttr(pChild, "start");
2079 if (attr) {
2080 m_illuminantRange.start = icFtoF16((icFloatNumber)atof(icXmlAttrValue(attr)));
2081 }
2082 attr = icXmlFindAttr(pChild, "end");
2083 if (attr) {
2084 m_illuminantRange.end = icFtoF16((icFloatNumber)atof(icXmlAttrValue(attr)));
2085 }
2086 attr = icXmlFindAttr(pChild, "steps");
2087 if (attr) {
2088 m_illuminantRange.steps = (icUInt16Number)atoi(icXmlAttrValue(attr));
2089 }
2090 attr = icXmlFindAttr(pChild, "reserved");
2091 if (attr) {
2092 m_reserved3 = (icUInt16Number)atoi(icXmlAttrValue(attr));
2093 }
2094
2095 if (pChild->children && pChild->children->content && m_illuminantRange.steps) {
2096 CIccFloatArray vals;
2097 vals.ParseTextArray((icChar*)pChild->children->content);
2098 if (vals.GetSize()!=m_illuminantRange.steps)
2099 return false;
2100 m_illuminant = (icFloatNumber*)malloc(m_illuminantRange.steps * sizeof(icFloatNumber));
2101 if (!m_illuminant)
2102 return false;
2103 icFloatNumber *pBuf = vals.GetBuf();
2104 memcpy(m_illuminant, pBuf, m_illuminantRange.steps * sizeof(icFloatNumber));
2105 }
2106 else {
2107 setIlluminant(m_stdIlluminant, m_illuminantRange, NULL__null, m_colorTemperature);
2108 }
2109 }
2110
2111 pChild = icXmlFindNode(pChild, "SurroundXYZ");
2112 if (pChild) {
2113 attr = icXmlFindAttr(pChild, "X");
2114 if (attr) {
2115 m_surroundXYZ.X = (icFloatNumber)atof(icXmlAttrValue(attr));
2116 }
2117
2118 attr = icXmlFindAttr(pChild, "Y");
2119 if (attr) {
2120 m_surroundXYZ.Y = (icFloatNumber)atof(icXmlAttrValue(attr));
2121 }
2122
2123 attr = icXmlFindAttr(pChild, "Z");
2124 if (attr) {
2125 m_surroundXYZ.Z = (icFloatNumber)atof(icXmlAttrValue(attr));
2126 }
2127 }
2128
2129 return true;
2130}
2131
2132
2133
2134bool icProfDescToXml(std::string &xml, CIccProfileDescStruct &p, std::string blanks = "")
2135{
2136 char fix[256];
2137 char buf[256];
2138 char data[256];
2139
2140 sprintf(buf, "<ProfileDesc>\n");
2141 xml += blanks + buf;
2142
2143 sprintf(buf, "<DeviceManufacturerSignature>%s</DeviceManufacturerSignature>\n", icFixXml(fix, icGetSigStr(data, p.m_deviceMfg)));
2144 xml += blanks + blanks + buf;
2145
2146 sprintf(buf, "<DeviceModelSignature>%s</DeviceModelSignature>\n", icFixXml(fix, icGetSigStr(data, p.m_deviceModel)));
2147 xml += blanks + blanks + buf;
2148
2149 std::string szAttributes = icGetDeviceAttrName(p.m_attributes);
2150 //sprintf(buf, "<DeviceAttributes>\"%016lX\" technology=\"%s\">\n", p.m_attributes, icFixXml(fix, icGetSigStr(data, p.m_technology)));
2151 //xml += buf;
2152 xml += blanks + blanks + icGetDeviceAttrName(p.m_attributes);
2153
2154 sprintf(buf, "<Technology>%s</Technology>\n", icFixXml(fix, icGetSigStr(data, p.m_technology)));
2155 xml += blanks + blanks + buf;
2156
2157 CIccTag *pTag = p.m_deviceMfgDesc.GetTag();
2158 CIccTagXml *pExt;
2159
2160 if (pTag) {
2161
2162 pExt = (CIccTagXml*)(pTag->GetExtension());
2163
2164 if (!pExt || !pExt->GetExtClassName() || strcmp(pExt->GetExtClassName(), "CIccTagXml"))
2165 return false;
2166
2167 xml += blanks + blanks + "<DeviceManufacturer>\n";
2168
2169 const icChar* tagSig = icGetTagSigTypeName(pTag->GetType());
2170 sprintf(buf, "<%s>\n", tagSig);
2171 xml += blanks + blanks + blanks + buf;
2172
2173 if (!pExt->ToXml(xml, blanks + " "))
2174 return false;
2175
2176 sprintf(buf, "</%s>\n", tagSig);
2177 xml += blanks + blanks + blanks + buf;
2178
2179 xml += blanks + blanks +"</DeviceManufacturer>\n";
2180 }
2181
2182 pTag = p.m_deviceModelDesc.GetTag();
2183
2184 if (pTag) {
2185 pExt = (CIccTagXml*)(pTag->GetExtension());
2186
2187 if (!pExt || !pExt->GetExtClassName() || strcmp(pExt->GetExtClassName(), "CIccTagXml"))
2188 return false;
2189
2190 xml += blanks + blanks + "<DeviceModel>\n";
2191
2192 const icChar* tagSig = icGetTagSigTypeName(pTag->GetType());
2193 sprintf(buf, "<%s>\n", tagSig);
2194 xml += blanks + blanks + blanks + buf;
2195
2196 if (!pExt->ToXml(xml, blanks + " "))
2197 return false;
2198
2199 sprintf(buf, "</%s>\n", tagSig);
2200 xml += blanks + blanks + blanks + buf;
2201
2202 xml += blanks + " </DeviceModel>\n";
2203 }
2204
2205 xml += blanks + "</ProfileDesc>\n";
2206
2207 return true;
2208}
2209
2210bool icXmlParseProfDesc(xmlNode *pNode, CIccProfileDescStruct &p, std::string &parseStr)
2211{
2212 if (pNode->type==XML_ELEMENT_NODE && !icXmlStrCmp(pNode->name, "ProfileDesc")strcmp((const char *)(pNode->name), (const char*)("ProfileDesc"
))
) {
2213 xmlNode *pDescNode;
2214
2215 for (pDescNode = pNode->children; pDescNode; pDescNode=pDescNode->next) {
2216 if (pDescNode->type == XML_ELEMENT_NODE) {
2217 if (!icXmlStrCmp(pDescNode->name, "DeviceManufacturerSignature")strcmp((const char *)(pDescNode->name), (const char*)("DeviceManufacturerSignature"
))
){
2218 p.m_deviceMfg = icXmlStrToSig(pDescNode->children ? (const icChar*)pDescNode->children->content: "");
2219 }
2220 else if (!icXmlStrCmp(pDescNode->name, "DeviceModelSignature")strcmp((const char *)(pDescNode->name), (const char*)("DeviceModelSignature"
))
){
2221 p.m_deviceModel = icXmlStrToSig(pDescNode->children ? (const icChar*)pDescNode->children->content : "");
2222 }
2223 else if (!icXmlStrCmp(pDescNode->name, "DeviceAttributes")strcmp((const char *)(pDescNode->name), (const char*)("DeviceAttributes"
))
){
2224 p.m_attributes = icGetDeviceAttrValue(pDescNode);
2225 }
2226 else if (!icXmlStrCmp(pDescNode->name, "Technology")strcmp((const char *)(pDescNode->name), (const char*)("Technology"
))
){
2227 p.m_technology = (icTechnologySignature)icXmlStrToSig(pDescNode->children ? (const icChar*)pDescNode->children->content : "");
2228 }
2229 else if (!icXmlStrCmp(pDescNode->name, "DeviceManufacturer")strcmp((const char *)(pDescNode->name), (const char*)("DeviceManufacturer"
))
) {
2230 xmlNode *pDevManNode = icXmlFindNode(pDescNode->children, "multiLocalizedUnicodeType");
2231
2232 if (!pDevManNode){
2233 pDevManNode = icXmlFindNode(pDescNode->children, "textDescriptionType");
2234 }
2235
2236 if (pDevManNode){
2237 icTagTypeSignature tagSig = icGetTypeNameTagSig ((icChar*) pDevManNode->name);
2238
2239 if (!p.m_deviceMfgDesc.SetType(tagSig)){
2240 return false;
2241 }
2242 CIccTag *pTag = p.m_deviceMfgDesc.GetTag();
2243
2244 if (!pTag)
2245 return false;
2246
2247 CIccTagXml *pExt = (CIccTagXml*)(pTag->GetExtension());
2248
2249 if (!pExt || !pExt->GetExtClassName() || strcmp(pExt->GetExtClassName(), "CIccTagXml"))
2250 return false;
2251
2252 pExt->ParseXml(pDevManNode->children, parseStr);
2253 }
2254 }
2255 else if (!icXmlStrCmp(pDescNode->name, "DeviceModel")strcmp((const char *)(pDescNode->name), (const char*)("DeviceModel"
))
) {
2256 xmlNode *pDevModNode = icXmlFindNode(pDescNode->children, "multiLocalizedUnicodeType");
2257
2258 if (!pDevModNode){
2259 pDevModNode = icXmlFindNode(pDescNode->children, "textDescriptionType");
2260 }
2261
2262 if (pDevModNode){
2263 icTagTypeSignature tagSig = icGetTypeNameTagSig ((icChar*) pDevModNode->name);
2264
2265 if (!p.m_deviceModelDesc.SetType(tagSig)) {
2266 return false;
2267 }
2268 CIccTag *pTag = p.m_deviceModelDesc.GetTag();
2269
2270 if (!pTag)
2271 return false;
2272
2273 CIccTagXml *pExt = (CIccTagXml*)(pTag->GetExtension());
2274
2275 if (!pExt || !pExt->GetExtClassName() || strcmp(pExt->GetExtClassName(), "CIccTagXml"))
2276 return false;
2277
2278 pExt->ParseXml(pDevModNode->children, parseStr);
2279 }
2280 }
2281 }
2282 }
2283 }
2284 else
2285 return false;
2286
2287 if (!p.m_deviceMfgDesc.GetTag() || !p.m_deviceModelDesc.GetTag())
2288 return false;
2289
2290 return true;
2291}
2292
2293
2294bool CIccTagXmlProfileSeqDesc::ToXml(std::string &xml, std::string blanks/* = ""*/)
2295{
2296 CIccProfileSeqDesc::iterator i;
2297 if (!m_Descriptions)
2298 return false;
2299
2300 xml += blanks + "<ProfileSequence>\n";
2301 for (i=m_Descriptions->begin(); i!=m_Descriptions->end(); i++) {
2302 if (!icProfDescToXml(xml, *i, blanks + " "))
2303 return false;
2304 }
2305 xml += blanks + "</ProfileSequence>\n";
2306 return true;
2307}
2308
2309
2310bool CIccTagXmlProfileSeqDesc::ParseXml(xmlNode *pNode, std::string &parseStr)
2311{
2312 pNode = icXmlFindNode(pNode, "ProfileSequence");
2313
2314 if (!m_Descriptions)
2315 return false;
2316
2317 m_Descriptions->clear();
2318
2319 if (pNode) {
2320 for (pNode = pNode->children; pNode; pNode=pNode->next) {
2321 if (pNode->type==XML_ELEMENT_NODE && !icXmlStrCmp(pNode->name, "ProfileDesc")strcmp((const char *)(pNode->name), (const char*)("ProfileDesc"
))
) {
2322 CIccProfileDescStruct ProfileDescStruct;
2323
2324 if (!icXmlParseProfDesc(pNode, ProfileDescStruct, parseStr))
2325 return false;
2326
2327 m_Descriptions->push_back(ProfileDescStruct);
2328 }
2329 }
2330 }
2331 return true;
2332}
2333
2334
2335bool CIccTagXmlResponseCurveSet16::ToXml(std::string &xml, std::string blanks/* = ""*/)
2336{
2337 char line[80];
2338 int i;
2339
2340 CIccInfo info;
2341
2342 sprintf(line, "<CountOfChannels>%d</CountOfChannels>\n", m_nChannels);
2343 xml += blanks + line;
2344
2345 CIccResponseCurveStruct *pCurves=GetFirstCurves();
2346 while (pCurves) {
2347 sprintf(line, "<ResponseCurve MeasUnitSignature=\"%s\">\n", info.GetMeasurementUnit(pCurves->GetMeasurementType()));
2348 xml += blanks + line;
2349 for (i=0; i<pCurves->GetNumChannels(); i++) {
2350 CIccResponse16List *pResponseList = pCurves->GetResponseList(i);
2351 icXYZNumber *pXYZ = pCurves->GetXYZ(i);
2352 sprintf(line, " <ChannelResponses X=\"%.8f\" Y=\"%.8f\" Z=\"%.8f\" >\n", icFtoD(pXYZ->X), icFtoD(pXYZ->Y), icFtoD(pXYZ->Z));
2353 xml += blanks + line;
2354
2355 CIccResponse16List::iterator j;
2356 for (j=pResponseList->begin(); j!=pResponseList->end(); j++) {
2357 sprintf(line, " <Measurement DeviceCode=\"%d\" MeasValue=\"%.8f\"", j->deviceCode, icFtoD(j->measurementValue));
2358 xml += blanks + line;
2359
2360 if (j->reserved) {
2361 sprintf(line, " Reserved=\"%d\"", j->reserved);
2362 xml += line;
2363 }
2364 xml += "/>\n";
2365 }
2366
2367 xml += blanks + " </ChannelResponses>\n";
2368 }
2369 xml += blanks + " </ResponseCurve>\n";
2370 pCurves = GetNextCurves();
2371 }
2372
2373 return true;
2374}
2375
2376
2377bool CIccTagXmlResponseCurveSet16::ParseXml(xmlNode *pNode, std::string &parseStr)
2378{
2379 pNode = icXmlFindNode(pNode, "CountOfChannels");
2380
2381 if(!pNode)
2382 return false;
2383
2384 int nChannels = atoi((const char*)pNode->children->content);
2385 SetNumChannels(nChannels);
2386
2387 if (!m_ResponseCurves)
2388 return false;
2389
2390 if (!m_ResponseCurves->empty())
2391 m_ResponseCurves->clear();
2392
2393 for (pNode = pNode->next; pNode; pNode = pNode->next) {
2394 if (pNode->type==XML_ELEMENT_NODE && !icXmlStrCmp(pNode->name, "ResponseCurve")strcmp((const char *)(pNode->name), (const char*)("ResponseCurve"
))
) {
2395 const icChar *szMeasurmentType = icXmlAttrValue(pNode, "MeasUnitSignature");
2396
2397 if (nChannels != icXmlNodeCount(pNode->children, "ChannelResponses"))
2398 return false;
2399
2400 CIccResponseCurveStruct curves(icGetMeasurementValue(szMeasurmentType), nChannels);
2401 xmlNode *pChild, *pMeasurement;
2402 int i;
2403
2404 for (i=0, pChild = pNode->children; pChild; pChild = pChild->next) {
2405 if (pChild->type == XML_ELEMENT_NODE && !icXmlStrCmp(pChild->name, "ChannelResponses")strcmp((const char *)(pChild->name), (const char*)("ChannelResponses"
))
) {
2406 CIccResponse16List *pResponseList = curves.GetResponseList(i);
2407 icXYZNumber *pXYZ = curves.GetXYZ(i);
2408 icResponse16Number response;
2409
2410 const icChar *szX = icXmlAttrValue(pChild, "X");
2411 const icChar *szY = icXmlAttrValue(pChild, "Y");
2412 const icChar *szZ = icXmlAttrValue(pChild, "Z");
2413
2414 if (!szX || !szY || !szZ || !*szX || !*szY || !*szZ)
2415 return false;
2416
2417 pXYZ->X = icDtoF((icFloatNumber)atof(szX));
2418 pXYZ->Y = icDtoF((icFloatNumber)atof(szY));
2419 pXYZ->Z = icDtoF((icFloatNumber)atof(szZ));
2420
2421 for (pMeasurement = pChild->children; pMeasurement; pMeasurement = pMeasurement->next) {
2422 if (pMeasurement->type == XML_ELEMENT_NODE && !icXmlStrCmp(pMeasurement->name, "Measurement")strcmp((const char *)(pMeasurement->name), (const char*)("Measurement"
))
) {
2423 const icChar *szDeviceCode = icXmlAttrValue(pMeasurement, "DeviceCode");
2424 const icChar *szValue = icXmlAttrValue(pMeasurement, "MeasValue");
2425 const icChar *szReserved = icXmlAttrValue(pMeasurement, "Reserved");
2426
2427 if (!szDeviceCode || !szValue || !*szDeviceCode || !*szValue)
2428 return false;
2429
2430 response.deviceCode = (icUInt16Number)atoi(szDeviceCode);
2431 response.measurementValue = icDtoF((icFloatNumber)atof(szValue));
2432
2433 if (szReserved && *szReserved)
2434 response.reserved = atoi(szReserved);
2435
2436 pResponseList->push_back(response);
2437 }
2438 }
2439 i++;
2440 }
2441 }
2442 m_ResponseCurves->push_back(curves);
2443 }
2444 }
2445
2446 return true;
2447}
2448
2449
2450bool CIccTagXmlCurve::ToXml(std::string &xml, std::string blanks/* = ""*/)
2451{
2452 return ToXml(xml, icConvert16Bit, blanks);
2453}
2454
2455
2456bool CIccTagXmlCurve::ToXml(std::string &xml, icConvertType nType, std::string blanks/*= ""*/)
2457{
2458 char buf[40];
2459 int i;
2460
2461 if (!m_nSize) {
2462 xml += blanks + "<Curve/>\n";
2463 }
2464 else if (IsIdentity()) {
2465 xml += blanks + "<Curve IdentitySize=\"";
2466 sprintf(buf, "%d", m_nSize);
2467 xml += buf;
2468 xml += "\"/>\n";
2469 }
2470 else if (nType==icConvert8Bit) {
2471 xml += blanks + "<Curve>\n" + blanks;
2472 for (i=0; i<(int)m_nSize; i++) {
2473 if ( i && !(i%16)) {
2474 xml += "\n";
2475 xml += blanks;
2476 }
2477 sprintf(buf, " %3u", (int)(m_Curve[i] * 255.0 + 0.5));
2478 xml += buf;
2479 }
2480 xml += "\n";
2481 xml += blanks + "</Curve>\n";
2482 }
2483 else if (nType==icConvert16Bit || nType==icConvertVariable) {
2484 xml += blanks + "<Curve>\n" + blanks;
2485 for (i=0; i<(int)m_nSize; i++) {
2486 if (i && !(i%16)) {
2487 xml += "\n";
2488 xml += blanks + " ";
2489 }
2490 sprintf(buf, " %5u", (int)(m_Curve[i] * 65535.0 + 0.5));
2491 xml += buf;
2492 }
2493 xml += "\n";
2494 xml += blanks + "</Curve>\n";
2495 }
2496 else if (nType==icConvertFloat) {
2497 xml += blanks + "<Curve>\n" + blanks + " ";
2498 for (i=0; i<(int)m_nSize; i++) {
2499 if (i && !(i%16)) {
2500 xml += "\n";
2501 xml += blanks + " ";
2502 }
2503 sprintf(buf, " %13.8f", m_Curve[i]);
2504 xml += buf;
2505 }
2506 xml += "\n";
2507 xml += blanks + "</Curve>\n";
2508 }
2509 else
2510 return false;
2511
2512 return true;
2513}
2514
2515
2516bool CIccTagXmlCurve::ParseXml(xmlNode *pNode, std::string &parseStr )
2517{
2518 return ParseXml(pNode, icConvert16Bit, parseStr);
2519}
2520
2521
2522
2523bool CIccTagXmlCurve::ParseXml(xmlNode *pNode, icConvertType nType, std::string &parseStr)
2524{
2525 xmlNode *pCurveNode;
2526 pCurveNode = icXmlFindNode(pNode, "Curve");
2527
2528 if(pCurveNode){
2529 const char *filename = icXmlAttrValue(pCurveNode, "File");
2530
2531 // file exists
2532 if (filename[0]) {
2533 CIccIO *file = IccOpenFileIO(filename, "rb");
2534 if (!file){
2535 parseStr += "Error! - File '";
2536 parseStr += filename;
2537 parseStr +="' not found.\n";
2538 delete file;
2539 return false;
2540 }
2541
2542 const char *format = icXmlAttrValue(pCurveNode, "Format");
2543
2544 // format is text
2545 if (!strcmp(format, "text")) {
2546 icUInt32Number num = file->GetLength();
2547 char *buf = (char *) new char[num];
2548
2549 if (!buf) {
2550 perror("Memory Error");
2551 parseStr += "'";
2552 parseStr += filename;
2553 parseStr += "' may not be a valid text file.\n";
2554 free(buf);
2555 delete file;
2556 return false;
2557 }
2558
2559 if (file->Read8(buf, num) !=num) {
2560 perror("Read-File Error");
2561 parseStr += "'";
2562 parseStr += filename;
2563 parseStr += "' may not be a valid text file.\n";
2564 free(buf);
2565 delete file;
2566 return false;
2567 }
2568
2569 // lut8type
2570 if (nType == icConvert8Bit) {
2571 CIccUInt8Array data;
2572
2573 //if (!data.ParseTextArray(buf)) {
2574 if (!data.ParseTextArrayNum(buf, num, parseStr)){
2575 parseStr += "File '";
2576 parseStr += filename;
2577 parseStr += "' is not a valid text file.\n";
2578 SetSize(0);
2579 free(buf);
2580 delete file;
2581 return false;
2582 }
2583
2584 else {
2585 SetSize(data.GetSize());
2586 icUInt8Number *src = data.GetBuf();
2587 icFloatNumber *dst = GetData(0);
2588
2589 icUInt32Number i;
2590 for (i=0; i<data.GetSize(); i++) {
2591 *dst = (icFloatNumber)(*src) / 255.0f;
2592 dst++;
2593 src++;
2594 }
2595
2596 //if (i!=256) {
2597 //printf("Error! - Input/Output table does not have 256 entries.\n");
2598 //SetSize(0);
2599 //return false;
2600 //}
2601 delete file;
2602 return true;
2603 }
2604 }
2605
2606 //lut16type
2607 else if (nType == icConvert16Bit || nType == icConvertVariable) {
2608 CIccUInt16Array data;
2609
2610 //if (!data.ParseTextArray(buf)) {
2611 if (!data.ParseTextArrayNum(buf, num, parseStr)){
2612 parseStr += "File '";
2613 parseStr += filename;
2614 parseStr += "' is not a valid text file.\n";
2615 SetSize(0);
2616 free(buf);
2617 delete file;
2618 return false;
2619 }
2620
2621 else {
2622 SetSize(data.GetSize());
2623
2624 icUInt16Number *src = data.GetBuf();
2625 icFloatNumber *dst = GetData(0);
2626
2627 icUInt32Number i;
2628 for (i=0; i<data.GetSize(); i++) {
2629 *dst = (icFloatNumber)(*src) / 65535.0f;
2630 dst++;
2631 src++;
2632 }
2633 }
2634 delete file;
2635 return true;
2636 }
2637
2638 //float type
2639 else if (nType == icConvertFloat){
2640 CIccFloatArray data;
2641
2642 //if (!data.ParseTextArray(buf)) {
2643 if (!data.ParseTextArrayNum(buf, num, parseStr)){
2644 parseStr += "File '";
2645 parseStr += filename;
2646 parseStr += "' is not a valid text file.\n";
2647 SetSize(0);
2648 free(buf);
2649 delete file;
2650 return false;
2651 }
2652
2653 else {
2654 SetSize(data.GetSize());
2655 icFloatNumber *src = data.GetBuf();
2656 icFloatNumber *dst = GetData(0);
2657
2658 icUInt32Number i;
2659 for (i=0; i<data.GetSize(); i++) {
2660 *dst = *src;
2661 dst++;
2662 src++;
2663 }
2664 }
2665 delete file;
2666 return true;
2667 }
2668 else {
2669 delete file;
2670 return false;
2671 }
2672 }
2673 // format is binary
2674 else if (!strcmp(format, "binary")) {
2675 const char *order = icXmlAttrValue(pCurveNode, "Endian");
2676 bool little_endian = !strcmp(order, "little");
2677
2678 if (nType == icConvert8Bit){
2679 icUInt32Number num = file->GetLength();
2680 icUInt8Number value;
2681
2682 SetSize(num);
2683 icFloatNumber *dst = GetData(0);
2684 icUInt32Number i;
2685 for (i=0; i<num; i++) {
2686 if (!file->Read8(&value)) {
2687 perror("Read-File Error");
2688 parseStr += "'";
2689 parseStr += filename;
2690 parseStr += "' may not be a valid binary file.\n";
2691 delete file;
2692 return false;
2693 }
2694 *dst++ = (icFloatNumber)value / 255.0f;
2695 }
2696 delete file;
2697 return true;
2698 }
2699 else if (nType == icConvert16Bit || nType == icConvertVariable){
2700 icUInt32Number num = file->GetLength() / sizeof(icUInt16Number);
2701 icUInt16Number value;
2702 icUInt8Number *ptr = (icUInt8Number*)&value;
2703
2704 SetSize(num);
2705 icFloatNumber *dst = GetData(0);
2706 icUInt32Number i;
2707 for (i=0; i<num; i++) {
2708 if (!file->Read16(&value)) { //this assumes data is big endian
2709 perror("Read-File Error");
2710 parseStr += "'";
2711 parseStr += filename;
2712 parseStr += "' may not be a valid binary file.\n";
2713 delete file;
2714 return false;
2715 }
2716#ifdef ICC_BYTE_ORDER_LITTLE_ENDIAN
2717 if (little_endian) {
2718#else
2719 if (!little_endian) {
2720#endif
2721 icUInt8Number t = ptr[0];
2722 ptr[0] = ptr[1];
2723 ptr[1] = t;
2724 }
2725 *dst++ = (icFloatNumber)value / 65535.0f;
2726 }
2727 delete file;
2728 return true;
2729 }
2730 else if (nType == icConvertFloat) {
2731 icUInt32Number num = file->GetLength()/sizeof(icFloat32Number);
2732 icFloat32Number value;
2733 icUInt8Number *ptr = (icUInt8Number*)&value;
2734
2735 SetSize(num);
2736 icFloatNumber *dst = GetData(0);
2737
2738 icUInt32Number i;
2739 for (i=0; i<num; i++) {
2740 if (!file->ReadFloat32Float(&value)) { //assumes data is big endian
2741 perror("Read-File Error");
2742 parseStr += "'";
2743 parseStr += filename;
2744 parseStr += "' may not be a valid binary file.\n";
2745 delete file;
2746 return false;
2747 }
2748#ifdef ICC_BYTE_ORDER_LITTLE_ENDIAN
2749 if (little_endian) {
2750#else
2751 if (!little_endian) {
2752#endif
2753 icUInt8Number tmp;
2754 tmp = ptr[0]; ptr[0] = ptr[3]; ptr[3] = tmp;
2755 tmp = ptr[1]; ptr[1] = ptr[2]; ptr[2] = tmp;
2756 }
2757 *dst++ = value;
2758 }
2759 delete file;
2760 return true;
2761 }
2762 else { //not 8bit/16bit/float
2763 delete file;
2764 return false;
2765 }
2766 }
2767 else {//not text/binary
2768 delete file;
2769 return false;
2770 }
2771 }
2772 // no file
2773 else{
2774 if (nType == icConvert8Bit){
2775 CIccUInt8Array data;
2776
2777 if (!data.ParseArray(pCurveNode->children)) {
2778 const char *szSize = icXmlAttrValue(pCurveNode, "IdentitySize");
2779
2780 if (szSize && *szSize) {
2781 icUInt32Number nSize = (icUInt32Number)atol(szSize);
2782 SetSize(nSize);
2783
2784 if (m_nSize == nSize) {
2785 icUInt32Number j;
2786 icFloatNumber *dst = GetData(0);
2787 for (j=0; j<nSize; j++) {
2788 *dst = (icFloatNumber)(j) / (icFloatNumber)(nSize-1);
2789 dst++;
2790 }
2791 }
2792 else
2793 return false;
2794 }
2795 else { //Identity curve with size=0
2796 SetSize(0);
2797 }
2798 }
2799 else {
2800 SetSize(data.GetSize());
2801
2802 icUInt32Number j;
2803 icUInt8Number *src = data.GetBuf();
2804 icFloatNumber *dst = GetData(0);
2805 for (j=0; j<data.GetSize(); j++) {
2806 *dst = (icFloatNumber)(*src) / 255.0f;
2807 dst++;
2808 src++;
2809 }
2810
2811 //if (j!=256) {
2812 //printf("Error! - Input/Output table does not have 256 entries.\n");
2813 //SetSize(0);
2814 //return false;
2815 //}
2816 }
2817 return true;
2818 }
2819
2820 else if (nType == icConvert16Bit || nType == icConvertVariable){
2821 CIccUInt16Array data;
2822
2823 if (!data.ParseArray(pCurveNode->children)) {
2824 const char *szSize = icXmlAttrValue(pCurveNode, "IdentitySize");
2825
2826 if (szSize && *szSize) {
2827 icUInt32Number nSize = (icUInt32Number)atol(szSize);
2828 SetSize(nSize);
2829
2830 if (m_nSize == nSize) {
2831 icUInt32Number j;
2832 icFloatNumber *dst = GetData(0);
2833 for (j=0; j<nSize; j++) {
2834 *dst = (icFloatNumber)(j) / (icFloatNumber)(nSize-1);
2835 dst++;
2836 }
2837 }
2838 else
2839 return false;
2840 }
2841 else { //Identity curve with size=0
2842 SetSize(0);
2843 }
2844 }
2845 else {
2846 SetSize(data.GetSize());
2847
2848 icUInt32Number j;
2849 icUInt16Number *src = data.GetBuf();
2850 icFloatNumber *dst = GetData(0);
2851 for (j=0; j<data.GetSize(); j++) {
2852 *dst = (icFloatNumber)(*src) / 65535.0f;
2853 dst++;
2854 src++;
2855 }
2856 }
2857 return true;
2858 }
2859 else if (nType == icConvertFloat){
2860 CIccFloatArray data;
2861
2862 if (!data.ParseArray(pCurveNode->children)) {
2863 const char *szSize = icXmlAttrValue(pCurveNode, "IdentitySize");
2864
2865 if (szSize && *szSize) {
2866 icUInt32Number nSize = (icUInt32Number)atol(szSize);
2867
2868 SetSize(nSize);
2869
2870 if (m_nSize == nSize) {
2871 icUInt32Number j;
2872 icFloatNumber *dst = GetData(0);
2873 for (j=0; j<nSize; j++) {
2874 *dst = (icFloatNumber)(j) / (icFloatNumber)(nSize-1);
2875 dst++;
2876 }
2877 }
2878 else
2879 return false;
2880 }
2881 else { //Identity curve with size=0
2882 SetSize(0);
2883 }
2884 }
2885 else {
2886 SetSize(data.GetSize());
2887
2888 icUInt32Number j;
2889 icFloatNumber *src = data.GetBuf();
2890 icFloatNumber *dst = GetData(0);
2891 for (j=0; j<data.GetSize(); j++) {
2892 *dst = *src;
2893 dst++;
2894 src++;
2895 }
2896 }
2897 return true;
2898 }
2899 // unsupported encoding
2900 else
2901 return false;
2902 }
2903 }
2904 return false;
2905}
2906
2907
2908bool CIccTagXmlParametricCurve::ToXml(std::string &xml, std::string blanks/* = ""*/)
2909{
2910 char buf[80];
2911 int i;
2912
2913 sprintf(buf, "<ParametricCurve FunctionType=\"%d\"", m_nFunctionType);
2914 xml += blanks + buf;
2915
2916 if (m_nReserved2) {
2917 sprintf(buf, " Reserved=\"%d\"", m_nReserved2);
2918 xml += buf;
2919 }
2920 xml += ">\n";
2921 xml += blanks + " ";
2922
2923 for (i=0; i<(int)m_nNumParam; i++) {
2924 sprintf(buf, " %.8f", m_dParam[i]);
2925 xml += buf;
2926 }
2927 xml += "\n";
2928
2929 sprintf(buf, "</ParametricCurve>\n");
2930 xml += blanks + buf;
2931
2932 return true;
2933}
2934
2935bool CIccTagXmlParametricCurve::ToXml(std::string &xml, icConvertType nType, std::string blanks/* = */)
2936{
2937 return ToXml(xml, blanks);
2938}
2939
2940bool CIccTagXmlParametricCurve::ParseXml(xmlNode *pNode, icConvertType nType, std::string &parseStr)
2941{
2942 return ParseXml (pNode, parseStr);
2943}
2944
2945bool CIccTagXmlParametricCurve::ParseXml(xmlNode *pNode, std::string &parseStr)
2946{
2947 xmlNode *pCurveNode = icXmlFindNode(pNode->children, "ParametricCurve");
2948
2949 for (pCurveNode = pNode; pCurveNode; pCurveNode=pCurveNode->next) {
2950 if (pCurveNode->type==XML_ELEMENT_NODE) {
2951 if (!icXmlStrCmp(pCurveNode->name, "ParametricCurve")strcmp((const char *)(pCurveNode->name), (const char*)("ParametricCurve"
))
) {
2952
2953 const char *functionType = icXmlAttrValue(pCurveNode, "FunctionType");
2954
2955 if (!functionType)
2956 return false;
2957
2958 if (!SetFunctionType(atoi(functionType))){
2959 return false;
2960 }
2961 CIccFloatArray data;
2962
2963 if (!data.ParseArray(pCurveNode->children)){
2964 return false;
2965 }
2966
2967 if (data.GetSize()!=GetNumParam()){
2968 return false;
2969 }
2970
2971 icUInt32Number j;
2972 icFloatNumber *dParams = GetParams();
2973 icFloatNumber *dataBuf = data.GetBuf();
2974 for (j=0; j<data.GetSize(); j++) {
2975 dParams[j] = dataBuf[j];
2976 }
2977
2978 xmlAttr *reserved2 = icXmlFindAttr(pCurveNode, "Reserved");
2979
2980 if (reserved2) {
2981 m_nReserved2 = (icUInt16Number)atoi(icXmlAttrValue(reserved2));
2982 }
2983 return true;
2984 }
2985 }
2986 }
2987 return false;
2988}
2989
2990
2991bool icCurvesToXml(std::string &xml, const char *szName, CIccCurve **pCurves, int numCurve, icConvertType nType, std::string blanks)
2992{
2993 if (pCurves) {
2994 int i;
2995
2996 xml += blanks + "<" + szName + ">\n";
2997 for (i=0; i<numCurve; i++) {
2998 IIccExtensionTag *pTag = pCurves[i]->GetExtension();
2999 if (!pTag || strcmp(pTag->GetExtDerivedClassName(), "CIccCurveXml"))
3000 return false;
3001
3002 if (!((CIccCurveXml *)pTag)->ToXml(xml, nType, blanks + " "))
3003 return false;
3004 }
3005 xml += blanks + "</" + szName + ">\n";
3006 }
3007 return true;
3008}
3009
3010
3011bool CIccTagXmlSegmentedCurve::ToXml(std::string &xml, std::string blanks/* = ""*/)
3012{
3013 if (m_pCurve)
3014 return ((CIccSegmentedCurveXml*)m_pCurve)->ToXml(xml, blanks);
3015
3016 return true;
3017}
3018
3019
3020bool CIccTagXmlSegmentedCurve::ToXml(std::string &xml, icConvertType nType, std::string blanks/* = */)
3021{
3022 return ToXml(xml, blanks);
3023}
3024
3025
3026bool CIccTagXmlSegmentedCurve::ParseXml(xmlNode *pNode, std::string &parseStr )
3027{
3028 xmlNode *pCurveNode = icXmlFindNode(pNode, "SegmentedCurve");
3029 if (pCurveNode) {
3030 CIccSegmentedCurveXml *pCurve = new CIccSegmentedCurveXml();
3031
3032 if (pCurve) {
3033 if (pCurve->ParseXml(pCurveNode, parseStr)) {
3034 SetCurve(pCurve);
3035 return true;
3036 }
3037 else {
3038 delete pCurve;
3039 return false;
3040 }
3041 }
3042 parseStr += "Unable to allocate Segmented Curve\n";
3043 return false;
3044 }
3045 parseStr += "Unable to find Segmented Curve\n";
3046 return false;
3047}
3048
3049
3050bool CIccTagXmlSegmentedCurve::ParseXml(xmlNode *pNode, icConvertType nType, std::string &parseStr)
3051{
3052 return ParseXml(pNode, parseStr);
3053}
3054
3055
3056bool icMatrixToXml(std::string &xml, CIccMatrix *pMatrix, std::string blanks)
3057{
3058 char buf[128];
3059 xml += blanks + "<Matrix\n";
3060
3061 sprintf(buf, " e1=\"%.8f\" e2=\"%.8f\" e3=\"%.8f\"\n", pMatrix->m_e[0], pMatrix->m_e[1], pMatrix->m_e[2]);
3062 xml += blanks + buf;
3063
3064 sprintf(buf, " e4=\"%.8f\" e5=\"%.8f\" e6=\"%.8f\"\n", pMatrix->m_e[3], pMatrix->m_e[4], pMatrix->m_e[5]);
3065 xml += blanks + buf;
3066
3067 sprintf(buf, " e7=\"%.8f\" e8=\"%.8f\" e9=\"%.8f\"", pMatrix->m_e[6], pMatrix->m_e[7], pMatrix->m_e[8]);
3068 xml += blanks + buf;
3069
3070 if (pMatrix->m_bUseConstants) {
3071 xml += "\n";
3072 sprintf(buf, " e10=\"%.8f\" e11=\"%.8f\" e12=\"%.8f\"", pMatrix->m_e[9], pMatrix->m_e[10], pMatrix->m_e[11]);
3073 xml += blanks + buf;
3074 }
3075 xml += "/>\n";
3076 return true;
3077}
3078
3079// for luts
3080bool icMBBToXml(std::string &xml, CIccMBB *pMBB, icConvertType nType, std::string blanks="", bool bSaveGridPoints=false)
3081{
3082 //blanks += " ";
3083 char buf[256];
3084
3085 sprintf(buf, "<Channels InputChannels=\"%d\" OutputChannels=\"%d\"/>\n", pMBB->InputChannels(), pMBB->OutputChannels());
3086 xml += blanks + buf;
3087
3088 if (pMBB->IsInputMatrix()) {
3089 if (pMBB->SwapMBCurves()) {
3090 if (pMBB->GetMatrix()) {
3091 // added if-statement
3092 if (!icMatrixToXml(xml, pMBB->GetMatrix(), blanks)) {
3093 return false;
3094 }
3095 }
3096
3097 if (pMBB->GetCurvesB()) {
3098 // added if-statement
3099 if (!icCurvesToXml(xml, "BCurves", pMBB->GetCurvesM(), pMBB->InputChannels(), nType, blanks)) {
3100 return false;
3101 }
3102 }
3103 }
3104 else {
3105 if (pMBB->GetCurvesB()) {
3106 // added if-statement
3107 if (!icCurvesToXml(xml, "BCurves", pMBB->GetCurvesB(), pMBB->InputChannels(), nType, blanks)) {
3108 return false;
3109 }
3110 }
3111
3112 if (pMBB->GetMatrix()) {
3113 // added if-statement
3114 if (!icMatrixToXml(xml, pMBB->GetMatrix(), blanks)) {
3115 return false;
3116 }
3117 }
3118
3119 if (pMBB->GetCurvesM()) {
3120 // added if-statement
3121 if (!icCurvesToXml(xml, "MCurves", pMBB->GetCurvesM(), 3, nType, blanks)){
3122 return false;
3123 }
3124 }
3125 }
3126
3127 if (pMBB->GetCLUT()) {
3128 // added if-statement
3129 if (!icCLUTToXml(xml, pMBB->GetCLUT(), nType, blanks, bSaveGridPoints)){
3130 return false;
3131 }
3132 }
3133
3134 if (pMBB->GetCurvesA()) {
3135 // added if-statement
3136 if (!icCurvesToXml(xml, "ACurves", pMBB->GetCurvesA(), pMBB->OutputChannels(), nType, blanks)){
3137 return false;
3138 }
3139 }
3140 }
3141 else {
3142 if (pMBB->GetCurvesA()) {
3143 // added if-statement
3144 if (!icCurvesToXml(xml, "ACurves", pMBB->GetCurvesA(), pMBB->InputChannels(), nType, blanks)){
3145 return false;
3146 }
3147 }
3148
3149 if (pMBB->GetCLUT()) {
3150 // added if-statement
3151 if (!icCLUTToXml(xml, pMBB->GetCLUT(), nType, blanks, bSaveGridPoints)){
3152 return false;
3153 }
3154 }
3155
3156 if (pMBB->GetCurvesM()) {
3157 // added if-statement
3158 if (!icCurvesToXml(xml, "MCurves", pMBB->GetCurvesM(), 3, nType, blanks)){
3159 return false;
3160 }
3161 }
3162
3163 if (pMBB->GetMatrix()) {
3164 // added if-statement
3165 if (!icMatrixToXml(xml, pMBB->GetMatrix(), blanks)) {
3166 return false;
3167 }
3168 }
3169
3170 if (pMBB->GetCurvesB()) {
3171 // added if-statement
3172 if (!icCurvesToXml(xml, "BCurves", pMBB->GetCurvesB(), pMBB->OutputChannels(), nType, blanks)){
3173 return false;
3174 }
3175 }
3176 }
3177 return true;
3178}
3179
3180
3181bool icCurvesFromXml(LPIccCurve *pCurve, icUInt32Number nChannels, xmlNode *pNode, icConvertType nType, std::string &parseStr)
3182{
3183 icUInt32Number i;
3184 xmlNode *pCurveNode;
3185
3186 for (i=0, pCurveNode = pNode; i<nChannels && pCurveNode; pCurveNode=pCurveNode->next) {
3187 if (pCurveNode->type==XML_ELEMENT_NODE) {
3188 CIccCurve *pCurveTag = NULL__null;
3189 if (!icXmlStrCmp(pCurveNode->name, "Curve")strcmp((const char *)(pCurveNode->name), (const char*)("Curve"
))
) {
3190 pCurveTag = new CIccTagXmlCurve;
3191 }
3192 else if (!icXmlStrCmp(pCurveNode->name, "ParametricCurve")strcmp((const char *)(pCurveNode->name), (const char*)("ParametricCurve"
))
) {
3193 pCurveTag = new CIccTagXmlParametricCurve();
3194 }
3195
3196 if (pCurveTag) {
3197 IIccExtensionTag *pExt = pCurveTag->GetExtension();
3198
3199 if (pExt) {
3200 if (!strcmp(pExt->GetExtDerivedClassName(), "CIccCurveXml")) {
3201 CIccCurveXml *pCurveXml = (CIccCurveXml *)pExt;
3202
3203 if (pCurveXml->ParseXml(pCurveNode, nType, parseStr)) {
3204 pCurve[i] = pCurveTag;
3205 i++;
3206 }
3207 // added else statement
3208 else {
3209 char num[40];
3210 parseStr += "Unable to parse curve at Line";
3211 sprintf(num, "%d\n", pCurveNode->line);
3212 parseStr += num;
3213 return false;
3214 }
3215 }
3216 else if (!strcmp(pExt->GetExtClassName(), "CIccTagXml")) {
3217 CIccTagXml *pXmlTag = (CIccTagXml *)pExt;
3218
3219 if (pXmlTag->ParseXml(pCurveNode, parseStr)) {
3220 pCurve[i] = pCurveTag;
3221 i++;
3222 }
3223 // added else statement
3224 else {
3225 char num[40];
3226 parseStr += "Unable to parse curve tag at Line";
3227 sprintf(num, "%d\n", pCurveNode->line);
3228 parseStr += num;
3229 return false;
3230 }
3231 }
3232 }
3233 }
3234 }
3235 }
3236 if (!i != nChannels) {
3237 parseStr += "Channel number mismatch!\n";
3238 }
3239 return i==nChannels;
3240}
3241
3242bool icMatrixFromXml(CIccMatrix *pMatrix, xmlNode *pNode)
3243{
3244 memset(pMatrix->m_e, 0, sizeof(pMatrix->m_e));
3245 pMatrix->m_bUseConstants = false;
3246
3247 char attrName[15];
3248 int i;
3249
3250 for (i=0; i<9; i++) {
3251 sprintf(attrName, "e%d", i+1);
3252 xmlAttr *attr = icXmlFindAttr(pNode, attrName);
3253 if (attr) {
3254 pMatrix->m_e[i] = (icFloatNumber)atof(icXmlAttrValue(attr));
3255 }
3256 }
3257 for (i=9; i<12; i++) {
3258 sprintf(attrName, "e%d", i+1);
3259 xmlAttr *attr = icXmlFindAttr(pNode, attrName);
3260 if (attr) {
3261 pMatrix->m_e[i] = (icFloatNumber)atof(icXmlAttrValue(attr));
3262 pMatrix->m_bUseConstants = true;
3263 }
3264 }
3265 return true;
3266}
3267
3268CIccCLUT *icCLutFromXml(xmlNode *pNode, int nIn, int nOut, icConvertType nType, std::string &parseStr)
3269{
3270 CIccCLUT *pCLUT = NULL__null;
3271
3272 int nPrecision = 2;
3273 if (nType == icConvert8Bit)
3274 nPrecision = 1;
3275
3276 icUInt8Number nInput = (icUInt8Number)nIn;
3277 icUInt16Number nOutput = (icUInt16Number)nOut;
3278
3279 pCLUT = new CIccCLUT(nInput, nOutput, nPrecision);
3280
3281 if (!pCLUT){
3282 parseStr += "Error in creating CLUT Table. Check values of Precision, InputChannel, or OutputChannels.\n";
3283 return NULL__null;
3284 }
3285
3286 xmlNode *grid = icXmlFindNode(pNode->children, "GridPoints");
3287 if (grid) {
3288 CIccUInt8Array points;
3289
3290 if (points.ParseArray(grid->children)) {
3291 if (!pCLUT->Init(points.GetBuf())) {
3292 parseStr += "Error in setting the size of GridPoints. Check values of GridPoints, InputChannel, or OutputChannels.\n";
3293 delete pCLUT;
3294 return NULL__null;
3295 }
3296 }
3297 else {
3298 parseStr += "Error parsing GridPoints.\n";
3299 delete pCLUT;
3300 return NULL__null;
3301 }
3302 }
3303 else {
3304 icUInt8Number nGridGranularity;
3305
3306 xmlAttr *gridGranularity = icXmlFindAttr(pNode, "GridGranularity");
3307
3308 if (gridGranularity) {
3309 nGridGranularity = (icUInt8Number)atoi(icXmlAttrValue(gridGranularity));
3310 }
3311 else {
3312 delete pCLUT;
3313 return NULL__null;
3314 }
3315 if (!pCLUT->Init(nGridGranularity)) {
3316 parseStr += "Error in setting the size of GridGranularity. Check values of GridGranularity, InputChannel, or OutputChannels.\n";
3317 delete pCLUT;
3318 return NULL__null;
3319 }
3320 }
3321
3322 xmlNode *table = icXmlFindNode(pNode->children, "TableData");
3323
3324 if (table) {
3325 if (nType == icConvertVariable) {
3326 const char *precision = icXmlAttrValue(table, "Precision");
3327 if (precision && atoi(precision) == 1) {
3328 nType = icConvert8Bit;
3329 pCLUT->SetPrecision(1);
3330 }
3331 else {
3332 nType = icConvert16Bit;
3333 pCLUT->SetPrecision(2);
3334 }
3335 }
3336
3337 const char *filename = icXmlAttrValue(table, "Filename");
3338 if (!filename || !filename[0]) {
3339 filename = icXmlAttrValue(table, "File");
3340 }
3341
3342 if (filename[0]) {
3343 CIccIO *file = IccOpenFileIO(filename, "rb");
3344
3345 if (!file) {
3346 // added error message
3347 parseStr += "Error! - File '";
3348 parseStr += filename;
3349 parseStr +="' not found.\n";
3350 delete pCLUT;
3351 return NULL__null;
3352 }
3353
3354 const char *format = icXmlAttrValue(table, "Format");
3355
3356 if (!strcmp(format, "text")) {
3357 icUInt32Number num = file->GetLength();
3358 char *buf = (char *)malloc(num);
3359
3360 if (!buf) {
3361 perror("Memory Error");
3362 parseStr += "'";
3363 parseStr += filename;
3364 parseStr += "' may not be a valid text file.\n";
3365 delete file;
3366 delete pCLUT;
3367 return NULL__null;
3368 }
3369
3370 //Allow for different encoding in text file than implied by the table type
3371 const char *encoding = icXmlAttrValue(table, "FileEncoding");
3372
3373 if (!strcmp(encoding, "int8"))
3374 nType = icConvert8Bit;
3375 else if (!strcmp(encoding, "int16"))
3376 nType = icConvert16Bit;
3377 else if (!strcmp(encoding, "float"))
3378 nType = icConvertFloat;
3379 else if (encoding[0]) {
3380 parseStr+= "Unknown encoding \"";
3381 parseStr+= encoding;
3382 parseStr+= "\" - using default encoding\n";
3383 }
3384
3385 if (file->Read8(buf, num)!=num) {
3386 perror("Read-File Error");
3387 parseStr += "'";
3388 parseStr += filename;
3389 parseStr += "' may not be a valid text file.\n";
3390 free(buf);
3391 delete file;
3392 delete pCLUT;
3393 return NULL__null;
3394 }
3395
3396 if (nType == icConvert8Bit) {
3397 CIccUInt8Array data;
3398
3399 if (!data.ParseTextArrayNum(buf, num, parseStr)) {
3400 parseStr += "File '";
3401 parseStr += filename;
3402 parseStr += "' is not a valid text file.\n";
3403 free(buf);
3404 delete file;
3405 delete pCLUT;
3406 return NULL__null;
3407 }
3408
3409 if (data.GetSize()!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3410 parseStr += "Error! - Number of entries in file '";
3411 parseStr += filename;
3412 parseStr += "'is not equal to the size of the CLUT Table.\n";
3413 parseStr += " a. Check values of GridGranularity/GridPoints, InputChannel, or OutputChannels.\n";
3414 parseStr += " b. File may not be a valid text file.\n";
3415 free(buf);
3416 delete file;
3417 delete pCLUT;
3418 return NULL__null;
3419 }
3420 icUInt8Number *src = data.GetBuf();
3421 icFloatNumber *dst = pCLUT->GetData(0);
3422
3423 icUInt32Number i;
3424 for (i=0; i<data.GetSize(); i++) {
3425 *dst++ = (icFloatNumber)(*src++) / 255.0f;
3426 }
3427 }
3428 else if (nType == icConvert16Bit) {
3429 CIccUInt16Array data;
3430
3431 if (!data.ParseTextArrayNum(buf, num, parseStr)) {
3432 parseStr += "File '";
3433 parseStr += filename;
3434 parseStr += "' is not a valid text file.\n";
3435 free(buf);
3436 delete file;
3437 delete pCLUT;
3438 return NULL__null;
3439 }
3440
3441 if (data.GetSize()!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3442 parseStr += "Error! - Number of entries in file '";
3443 parseStr += filename;
3444 parseStr += "'is not equal to the size of the CLUT Table.\n";
3445 parseStr += " a. Check values of GridGranularity/GridPoints, InputChannel, or OutputChannels.\n";
3446 parseStr += " b. File may not be a valid text file.\n";
3447 free(buf);
3448 delete file;
3449 delete pCLUT;
3450 return NULL__null;
3451 }
3452 icUInt16Number *src = data.GetBuf();
3453 icFloatNumber *dst = pCLUT->GetData(0);
3454
3455 icUInt32Number i;
3456 for (i=0; i<data.GetSize(); i++) {
3457 *dst++ = (icFloatNumber)(*src++) / 65535.0f;
3458 }
3459 }
3460 else if (nType == icConvertFloat) {
3461 CIccFloatArray data;
3462
3463 if (!data.ParseTextArrayNum(buf, num, parseStr)) {
3464 parseStr += "File '";
3465 parseStr += filename;
3466 parseStr += "' is not a valid text file.\n";
3467 free(buf);
3468 delete file;
3469 delete pCLUT;
3470 return NULL__null;
3471 }
3472
3473 if (data.GetSize()!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3474 parseStr += "Error! - Number of entries in file '";
3475 parseStr += filename;
3476 parseStr += "'is not equal to the size of the CLUT Table.\n";
3477 parseStr += " a. Check values of GridGranularity/GridPoints, InputChannel, or OutputChannels.\n";
3478 parseStr += " b. File may not be a valid text file.\n";
3479 free(buf);
3480 delete file;
3481 delete pCLUT;
3482 return NULL__null;
3483 }
3484 icFloatNumber *src = data.GetBuf();
3485 icFloatNumber *dst = pCLUT->GetData(0);
3486
3487 icUInt32Number i;
3488 for (i=0; i<data.GetSize(); i++) {
3489 *dst++ = *src++;
3490 }
3491 }
3492 else {
3493 parseStr += "Error! Unknown text data type.\n";
3494 free(buf);
3495 delete file;
3496 delete pCLUT;
3497 return NULL__null;
3498 }
3499 free(buf);
3500 }
3501 else if (!strcmp(format, "binary")) {
3502 const char *order = icXmlAttrValue(table, "Endian");
3503 bool little_endian = !strcmp(order, "little");
3504
3505 if (nType==icConvertVariable) {
3506 //Allow encoding to be defined
3507 const char *encoding = icXmlAttrValue(table, "FileEncoding");
3508
3509 if (!strcmp(encoding, "int8"))
3510 nType = icConvert8Bit;
3511 else if (!strcmp(encoding, "int16"))
3512 nType = icConvert16Bit;
3513 else if (!strcmp(encoding, "float"))
3514 nType = icConvertFloat;
3515 else if (encoding[0]) {
3516 parseStr+= "Unknown encoding \"";
3517 parseStr+= encoding;
3518 parseStr+= "\" - using int16.\n";
3519 nType = icConvert16Bit;
3520 }
3521 else {
3522 parseStr+= "CLUT TableData Encoding type not specified.\n";
3523 }
3524 }
3525
3526 if (nType == icConvert8Bit){
3527 icUInt32Number num = file->GetLength();
3528 icUInt8Number value;
3529 // if number of entries in file is not equal to size of CLUT table, flag as error
3530 if (num!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3531 parseStr += "Error! - Number of entries in file '";
3532 parseStr += filename;
3533 parseStr += "'is not equal to the size of the CLUT Table.\n";
3534 parseStr += " a. Check values of GridGranularity/GridPoints, InputChannel, or OutputChannels.\n";
3535 parseStr += " b. File may not be a valid binary file.\n";
3536 delete file;
3537 delete pCLUT;
3538 return NULL__null;
3539 }
3540 icFloatNumber *dst = pCLUT->GetData(0);
3541 icUInt32Number i;
3542 for (i=0; i<num; i++) {
3543 if (!file->Read8(&value)) {
3544 perror("Read-File Error");
3545 parseStr += "'";
3546 parseStr += filename;
3547 parseStr += "' may not be a valid binary file.\n";
3548 delete file;
3549 delete pCLUT;
3550 return NULL__null;
3551 }
3552 *dst++ = (icFloatNumber)value / 255.0f;
3553 }
3554 }
3555 else if (nType == icConvert16Bit){
3556 icUInt32Number num = file->GetLength() / sizeof(icUInt16Number);
3557 icUInt16Number value;
3558 icUInt8Number *ptr = (icUInt8Number*)&value;
3559
3560 if (num<pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3561 parseStr += "Error! - Number of entries in file '";
3562 parseStr += filename;
3563 parseStr += "'is not equal to the size of the CLUT Table.\n";
3564 parseStr += " a. Check values of GridGranularity/GridPoints, InputChannel, or OutputChannels.\n";
3565 parseStr += " b. File may not be a valid binary file.\n";
3566 delete file;
3567 delete pCLUT;
3568 return NULL__null;
3569 }
3570 icFloatNumber *dst = pCLUT->GetData(0);
3571
3572 icUInt32Number i;
3573 for (i=0; i<num; i++) {
3574 if (!file->Read16(&value)) { //this assumes data is big endian
3575 perror("Read-File Error");
3576 parseStr += "'";
3577 parseStr += filename;
3578 parseStr += "' may not be a valid binary file.\n";
3579 delete file;
3580 delete pCLUT;
3581 return NULL__null;
3582 }
3583#ifdef ICC_BYTE_ORDER_LITTLE_ENDIAN
3584 if (little_endian) {
3585#else
3586 if (!little_endian) {
3587#endif
3588 icUInt8Number t = ptr[0];
3589 ptr[0] = ptr[1];
3590 ptr[1] = t;
3591 }
3592 *dst++ = (icFloatNumber)value / 65535.0f;
3593 }
3594 }
3595 else if (nType == icConvertFloat){
3596 icUInt32Number num = file->GetLength()/sizeof(icFloat32Number);
3597 icFloat32Number value;
3598 icUInt8Number *ptr = (icUInt8Number*)&value;
3599
3600 if (num<pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3601 parseStr += "Error! - Number of entries in file '";
3602 parseStr += filename;
3603 parseStr += "'is not equal to the size of the CLUT Table.\n";
3604 parseStr += " a. Check values of GridGranularity/GridPoints, InputChannel, or OutputChannels.\n";
3605 parseStr += " b. File may not be a valid binary file.\n";
3606 delete file;
3607 delete pCLUT;
3608 return NULL__null;
3609 }
3610 icFloatNumber *dst = pCLUT->GetData(0);
3611
3612 icUInt32Number i;
3613 for (i=0; i<num; i++) {
3614 if (!file->ReadFloat32Float(&value)) { //this assumes data is big endian
3615 perror("Read-File Error");
3616 parseStr += "'";
3617 parseStr += filename;
3618 parseStr += "' may not be a valid binary file.\n";
3619 delete file;
3620 delete pCLUT;
3621 return NULL__null;
3622 }
3623#ifdef ICC_BYTE_ORDER_LITTLE_ENDIAN
3624 if (little_endian) {
3625#else
3626 if (!little_endian) {
3627#endif
3628 icUInt8Number tmp;
3629 tmp = ptr[0]; ptr[0] = ptr[3]; ptr[3] = tmp;
3630 tmp = ptr[1]; ptr[1] = ptr[2]; ptr[2] = tmp;
3631 }
3632 *dst++ = value;
3633 }
3634 }
3635 else {
3636 parseStr += "Error! Unknown binary data type.\n";
3637 delete file;
3638 delete pCLUT;
3639 return NULL__null;
3640 }
3641
3642 }
3643 else {
3644 parseStr += "Error! Unknown Format type.\n";
3645 delete pCLUT;
3646 return NULL__null;
3647 }
3648
3649 delete file;
3650 }
3651 else { // no file
3652 if (nType == icConvert8Bit) {
3653 CIccUInt8Array data;
3654
3655 if (!data.ParseArray(table->children)) {
3656 parseStr += "Error! - unable to parse data in CLUT.\n";
3657 delete pCLUT;
3658 return NULL__null;
3659 }
3660
3661 if (data.GetSize()!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3662 parseStr += "Error! - Number of entries is not equal to the size of the CLUT Table.\n";
3663 delete pCLUT;
3664 return NULL__null;
3665 }
3666 icUInt8Number *src = data.GetBuf();
3667 icFloatNumber *dst = pCLUT->GetData(0);
3668
3669 icUInt32Number i;
3670 for (i=0; i<data.GetSize(); i++) {
3671 *dst++ = (icFloatNumber)(*src++) / 255.0f;
3672 }
3673 }
3674 else if (nType == icConvert16Bit || nType==icConvertVariable) {
3675 CIccUInt16Array data;
3676
3677 if (!data.ParseArray(table->children)) {
3678 parseStr += "Error! - unable to parse data in CLUT.\n";
3679 delete pCLUT;
3680 return NULL__null;
3681 }
3682
3683 if (data.GetSize()!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3684 parseStr += "Error! - Number of entries is not equal to the size of the CLUT Table.\n";
3685 delete pCLUT;
3686 return NULL__null;
3687 }
3688 icUInt16Number *src = data.GetBuf();
3689 icFloatNumber *dst = pCLUT->GetData(0);
3690
3691 icUInt32Number i;
3692 for (i=0; i<data.GetSize(); i++) {
3693 *dst++ = (icFloatNumber)(*src++) / 65535.0f;
3694 }
3695 }
3696 else if (nType == icConvertFloat){
3697 CIccFloatArray data;
3698
3699 if (!data.ParseArray(table->children)) {
3700 parseStr += "Error! - unable to parse data in CLUT.\n";
3701 delete pCLUT;
3702 return NULL__null;
3703 }
3704
3705 if (data.GetSize()!=pCLUT->NumPoints()*pCLUT->GetOutputChannels()) {
3706 parseStr += "Error! - Number of entries is not equal to the size of the CLUT Table.\n";
3707 delete pCLUT;
3708 return NULL__null;
3709 }
3710 icFloatNumber *src = data.GetBuf();
3711 icFloatNumber *dst = pCLUT->GetData(0);
3712
3713 icUInt32Number i;
3714 for (i=0; i<data.GetSize(); i++) {
3715 *dst++ = *src++;
3716 }
3717 }
3718 else {
3719 parseStr += "Error! Unknown table data type.";
3720 delete pCLUT;
3721 return NULL__null;
3722 }
3723 }
3724 }
3725 else {
3726 parseStr += "Error! Cannot find table data.";
3727 delete pCLUT;
3728 return NULL__null;
3729 }
3730
3731 return pCLUT;
3732}
3733
3734bool icMBBFromXml(CIccMBB *pMBB, xmlNode *pNode, icConvertType nType, std::string &parseStr)
3735{
3736 xmlNode *pChannels = icXmlFindNode(pNode, "Channels");
3737
3738 if (!pChannels)
3739 return false;
3740
3741 xmlAttr *in = icXmlFindAttr(pChannels, "InputChannels");
3742 xmlAttr *out = icXmlFindAttr(pChannels, "OutputChannels");
3743
3744 if (!in || !out)
3745 return false;
3746
3747 int nIn = atoi(icXmlAttrValue(in));
3748 int nOut = atoi(icXmlAttrValue(out));
3749
3750 pMBB->Init(nIn, nOut);
3751
3752 for (; pNode; pNode = pNode->next) {
3753 if (pNode->type == XML_ELEMENT_NODE) {
3754 if (!icXmlStrCmp(pNode->name, "ACurves")strcmp((const char *)(pNode->name), (const char*)("ACurves"
))
&& !pMBB->GetCurvesA()) {
3755 LPIccCurve *pCurves = pMBB->NewCurvesA();
3756 if (!icCurvesFromXml(pCurves, !pMBB->IsInputB() ? nIn : nOut, pNode->children, nType, parseStr)) {
3757 parseStr += "Error! - Failed to parse ACurves.\n";
3758 return false;
3759 }
3760 }
3761 else if (!icXmlStrCmp(pNode->name, "BCurves")strcmp((const char *)(pNode->name), (const char*)("BCurves"
))
&& !pMBB->GetCurvesB()) {
3762 LPIccCurve *pCurves = pMBB->NewCurvesB();
3763 if (!icCurvesFromXml(pCurves, pMBB->IsInputB() ? nIn : nOut, pNode->children, nType, parseStr)) {
3764 parseStr += "Error! - Failed to parse BCurves.\n";
3765 return false;
3766 }
3767 }
3768 else if (!icXmlStrCmp(pNode->name, "MCurves")strcmp((const char *)(pNode->name), (const char*)("MCurves"
))
&& !pMBB->GetCurvesM()) {
3769 LPIccCurve *pCurves = pMBB->NewCurvesM();
3770 if (!icCurvesFromXml(pCurves, !pMBB->IsInputMatrix() ? nIn : nOut, pNode->children, nType, parseStr)) {
3771 parseStr += "Error! - Failed to parse MCurves.\n";
3772 return false;
3773 }
3774 }
3775 else if (!icXmlStrCmp(pNode->name, "Matrix")strcmp((const char *)(pNode->name), (const char*)("Matrix"
))
&& !pMBB->GetMatrix()) {
3776 CIccMatrix *pMatrix = pMBB->NewMatrix();
3777 if (!icMatrixFromXml(pMatrix, pNode)) {
3778 parseStr += "Error! - Failed to parse Matrix.\n";
3779 return false;
3780 }
3781 }
3782 else if (!icXmlStrCmp(pNode->name, "CLUT")strcmp((const char *)(pNode->name), (const char*)("CLUT")) && !pMBB->GetCLUT()) {
3783 CIccCLUT *pCLUT = icCLutFromXml(pNode, nIn, nOut, nType, parseStr);
3784 if (pCLUT) {
3785 if (!pMBB->SetCLUT(pCLUT)) {
3786 parseStr += "Error! - Failed to set CLUT to LUT.\n";
3787 return false;
3788 }
3789 }
3790 else {
3791 parseStr += "Error! - Failed to parse CLUT.\n";
3792 return false;
3793 }
3794 }
3795 }
3796 }
3797
3798 return true;
3799}
3800
3801bool CIccTagXmlLutAtoB::ToXml(std::string &xml, std::string blanks/* = ""*/)
3802{
3803 std::string info;
3804
3805 bool rv = icMBBToXml(xml, this, icConvertVariable, blanks, true);
3806
3807 return rv;
3808}
3809
3810
3811bool CIccTagXmlLutAtoB::ParseXml(xmlNode *pNode, std::string &parseStr)
3812{
3813
3814 if (pNode) {
3815 return icMBBFromXml(this, pNode, icConvertVariable, parseStr);
3816 }
3817
3818 return false;
3819}
3820
3821
3822bool CIccTagXmlLutBtoA::ToXml(std::string &xml, std::string blanks/* = ""*/)
3823{
3824 std::string info;
3825
3826 bool rv = icMBBToXml(xml, this, icConvertVariable, blanks, true);
3827
3828 return rv;
3829}
3830
3831
3832bool CIccTagXmlLutBtoA::ParseXml(xmlNode *pNode, std::string &parseStr)
3833{
3834 if (pNode) {
3835 return icMBBFromXml(this, pNode, icConvertVariable, parseStr);
3836 }
3837
3838 return false;
3839}
3840
3841
3842bool CIccTagXmlLut8::ToXml(std::string &xml, std::string blanks/* = ""*/)
3843{
3844 std::string info;
3845
3846 bool rv = icMBBToXml(xml, this, icConvert8Bit, blanks, false);
3847
3848 return rv;
3849}
3850
3851
3852bool CIccTagXmlLut8::ParseXml(xmlNode *pNode, std::string &parseStr)
3853{
3854
3855 if (pNode) {
3856 return icMBBFromXml(this, pNode, icConvert8Bit, parseStr);
3857 }
3858 return false;
3859}
3860
3861
3862bool CIccTagXmlLut16::ToXml(std::string &xml, std::string blanks/* = ""*/)
3863{
3864 std::string info;
3865
3866 bool rv = icMBBToXml(xml, this, icConvert16Bit, blanks, false);
3867
3868 return rv;
3869}
3870
3871
3872bool CIccTagXmlLut16::ParseXml(xmlNode *pNode, std::string &parseStr)
3873{
3874 if (pNode) {
3875 return icMBBFromXml(this, pNode, icConvert16Bit, parseStr);
3876 }
3877 return false;
3878}
3879
3880
3881bool CIccTagXmlMultiProcessElement::ToXml(std::string &xml, std::string blanks/* = ""*/)
3882{
3883 std::string info;
3884 char line[256];
3885
3886 CIccMultiProcessElementList::iterator i;
3887
3888 sprintf(line, "<MultiProcessElements InputChannels=\"%d\" OutputChannels=\"%d\">\n", NumInputChannels(), NumOutputChannels());
3889 xml += blanks + line;
3890
3891 for (i=m_list->begin(); i!=m_list->end(); i++) {
3892 if (i->ptr) {
3893 CIccMultiProcessElement *pMpe = i->ptr;
3894
3895 IIccExtensionMpe *pMpeExt = pMpe->GetExtension();
3896
3897 if (pMpeExt) {
3898 if (!strcmp(pMpeExt->GetExtClassName(), "CIccMpeXml")) {
3899 CIccMpeXml *pMpeXml = (CIccMpeXml*)pMpeExt;
3900
3901 pMpeXml->ToXml(xml, blanks + " ");
3902 }
3903 else {
3904 return false;
3905 }
3906 }
3907 else {
3908 return false;
3909 }
3910 }
3911 }
3912 xml += blanks + "</MultiProcessElements>\n";
3913 return true;
3914}
3915
3916
3917CIccMultiProcessElement *CIccTagXmlMultiProcessElement::CreateElement(const icChar *szElementNodeName)
3918{
3919 if (!strcmp(szElementNodeName, "UnknownElement")) {
3920 return new CIccMpeXmlUnknown;
3921 }
3922 if (!strcmp(szElementNodeName, "CurveSetElement")) {
3923 return new CIccMpeXmlCurveSet;
3924 }
3925 if (!strcmp(szElementNodeName, "MatrixElement")) {
3926 return new CIccMpeXmlMatrix;
3927 }
3928 if (!strcmp(szElementNodeName, "CLutElement")) {
3929 return new CIccMpeXmlCLUT;
3930 }
3931 if (!strcmp(szElementNodeName, "ExtCLutElement")) {
3932 return new CIccMpeXmlExtCLUT;
3933 }
3934 if (!strcmp(szElementNodeName, "BAcsElement")) {
3935 return new CIccMpeXmlBAcs;
3936 }
3937 if (!strcmp(szElementNodeName, "EAcsElement")) {
3938 return new CIccMpeXmlEAcs;
3939 }
3940 if (!strcmp(szElementNodeName, "CalculatorElement")) {
3941 return new CIccMpeXmlCalculator;
3942 }
3943 if (!strcmp(szElementNodeName, "JabToXYZElement")) {
3944 return new CIccMpeXmlJabToXYZ;
3945 }
3946 if (!strcmp(szElementNodeName, "XYZToJabElement")) {
3947 return new CIccMpeXmlXYZToJab;
3948 }
3949 if (!strcmp(szElementNodeName, "TintArrayElement")) {
3950 return new CIccMpeXmlTintArray;
3951 }
3952 if (!strcmp(szElementNodeName, "EmissionMatrixElement")) {
3953 return new CIccMpeXmlEmissionMatrix;
3954 }
3955 if (!strcmp(szElementNodeName, "InvEmissionMatrixElement")) {
3956 return new CIccMpeXmlInvEmissionMatrix;
3957 }
3958 if (!strcmp(szElementNodeName, "EmissionCLutElement")) {
3959 return new CIccMpeXmlEmissionCLUT;
3960 }
3961 if (!strcmp(szElementNodeName, "ReflectanceCLutElement")) {
3962 return new CIccMpeXmlReflectanceCLUT;
3963 }
3964 if (!strcmp(szElementNodeName, "EmissionObserverElement")) {
3965 return new CIccMpeXmlEmissionObserver;
3966 }
3967 if (!strcmp(szElementNodeName, "ReflectanceObserverElement")) {
3968 return new CIccMpeXmlReflectanceObserver;
3969 }
3970 return NULL__null;
3971}
3972
3973
3974bool CIccTagXmlMultiProcessElement::ParseElement(xmlNode *pNode, std::string &parseStr)
3975{
3976 xmlAttr *attr;
3977
3978 if (pNode->type != XML_ELEMENT_NODE) {
3979 return false;
3980 }
3981
3982 CIccMultiProcessElement *pMpe = CreateElement((const icChar*)pNode->name);
3983
3984 if (!pMpe) {
3985 parseStr += std::string("Unknown Element Type (") + (const icChar*)pNode->name + ")\n";
3986 return false;
3987 }
3988
3989 CIccMultiProcessElementPtr ptr;
3990
3991 IIccExtensionMpe *pExt = pMpe->GetExtension();
3992
3993 if (pExt) {
3994 if (!strcmp(pExt->GetExtClassName(), "CIccMpeXml")) {
3995 CIccMpeXml* pXmlMpe = (CIccMpeXml*)pExt;
3996
3997 if (pXmlMpe->ParseXml(pNode, parseStr)) {
3998 if ((attr=icXmlFindAttr(pNode, "Reserved"))) {
3999 sscanf(icXmlAttrValue(attr), "%u", &pMpe->m_nReserved);
4000 }
4001
4002 ptr.ptr = pMpe;
4003 m_list->push_back(ptr);
4004 }
4005 else {
4006 parseStr += std::string("Unable to parse element of type ") + pMpe->GetClassName() + "\n";
4007 delete pMpe;
4008 return false;
4009 }
4010 }
4011 else {
4012 parseStr += std::string("Element ") + pMpe->GetClassName() + "isn't of type CIccMpeXml\n";
4013 delete pMpe;
4014 return false;
4015 }
4016 }
4017 else {
4018 parseStr += std::string("Element ") + pMpe->GetClassName() + "isn't of type CIccMpeXml\n";
4019 delete pMpe;
4020 return false;
4021 }
4022
4023 return true;
4024}
4025
4026
4027bool CIccTagXmlMultiProcessElement::ParseXml(xmlNode *pNode, std::string &parseStr)
4028{
4029 pNode = icXmlFindNode(pNode, "MultiProcessElements");
4030
4031 if (!pNode) {
4032 parseStr += "Cannot Find MultiProcessElements\r\n";
4033 return false;
4034 }
4035
4036 xmlAttr *pInputChannels = icXmlFindAttr(pNode, "InputChannels");
4037 xmlAttr *pOutputChannels = icXmlFindAttr(pNode, "OutputChannels");
4038
4039 if (!pInputChannels || !pOutputChannels) {
4040 parseStr += "Invalid channels in MultiProcessElements\r\n";
4041 return false;
4042 }
4043
4044 m_nInputChannels = atoi(icXmlAttrValue(pInputChannels));
4045 m_nOutputChannels = atoi(icXmlAttrValue(pOutputChannels));
4046
4047 if (!m_list) {
4048 m_list = new CIccMultiProcessElementList();
4049 }
4050 else {
4051 m_list->clear();
4052 }
4053
4054 xmlNode *elemNode;
4055 for (elemNode = pNode->children; elemNode; elemNode = elemNode->next) {
4056 if (elemNode->type == XML_ELEMENT_NODE) {
4057 if (!ParseElement(elemNode, parseStr)) {
4058 char str[100];
4059 parseStr += "Unable to parse element (";
4060 parseStr += (char*)elemNode->name;
4061 sprintf(str, ") starting on line %d\r\n", elemNode->line);
4062 parseStr += str;
4063 return false;
4064 }
4065 }
4066 }
4067
4068 return true;
4069}
4070
4071
4072bool CIccTagXmlProfileSequenceId::ToXml(std::string &xml, std::string blanks/* = ""*/)
4073{
4074 std::string info;
4075
4076 xml += blanks + "<ProfileSequenceId>\n";
4077
4078 CIccProfileIdDescList::iterator pid;
4079
4080 for (pid=m_list->begin(); pid!=m_list->end(); pid++) {
4081 char buf[256];
4082 char data[256];
4083 char fix[256];
4084 std::string bufstr;
4085 int n;
4086
4087 for (n=0; n<16; n++) {
4088 sprintf(buf + n*2, "%02X", pid->m_profileID.ID8[n]);
4089 }
4090 buf[n*2]='\0';
4091 xml += blanks + " <ProfileIdDesc id=\"";
4092 xml += buf;
4093 xml += "\">\n";
4094
4095 if (pid->m_desc.m_Strings) {
4096 CIccMultiLocalizedUnicode::iterator i;
4097
4098 for (i=pid->m_desc.m_Strings->begin(); i!=pid->m_desc.m_Strings->end(); i++) {
4099 sprintf(buf, "<LocalizedText LanguangeCountry=\"%s\"", icFixXml(fix, icGetSigStr(data, (i->m_nLanguageCode<<16) + i->m_nCountryCode)));
4100 xml += blanks + buf;
4101
4102 sprintf(buf, ">%s</LocalizedText>\n", icFixXml(fix, icUtf16ToUtf8(bufstr, i->GetBuf(), i->GetLength())));
4103 xml += buf;
4104 }
4105 }
4106 xml += blanks + " </ProfileIdDesc>\n";
4107 }
4108
4109 xml += blanks + "</ProfileSequenceId>\n";
4110 return true;
4111}
4112
4113
4114bool CIccTagXmlProfileSequenceId::ParseXml(xmlNode *pNode, std::string &parseStr)
4115{
4116 pNode = icXmlFindNode(pNode, "ProfileSequenceId");
4117
4118 if (!pNode)
4119 return false;
4120
4121 m_list->clear();
4122
4123 for (pNode = icXmlFindNode(pNode->children, "ProfileIdDesc"); pNode; pNode = icXmlFindNode(pNode->next, "ProfileIdDesc")) {
4124 CIccProfileIdDesc desc;
4125 const icChar *szDesc = icXmlAttrValue(pNode, "id");
4126
4127 if (szDesc && *szDesc)
4128 icXmlGetHexData(&desc.m_profileID, szDesc, sizeof(desc.m_profileID));
4129
4130 xmlAttr *langCode;
4131
4132 for (pNode = icXmlFindNode(pNode, "LocalizedText"); pNode; pNode = icXmlFindNode(pNode->next, "LocalizedText")) {
4133 if ((langCode = icXmlFindAttr(pNode, "languageCountry")) &&
4134 pNode->children) {
4135 xmlNode *pText;
4136
4137 for (pText = pNode->children; pText && pText->type != XML_TEXT_NODE; pText = pText->next);
4138
4139 if (pText) {
4140 icUInt32Number lc = icGetSigVal(icXmlAttrValue(langCode));
4141 CIccUTF16String str((const char*)pText->content);
4142 desc.m_desc.SetText(str.c_str(), (icLanguageCode)(lc>>16), (icCountryCode)(lc & 0xffff));
4143 }
4144 else {
4145 desc.m_desc.SetText("");
4146 }
4147 }
4148 }
4149 m_list->push_back(desc);
4150 }
4151
4152 return false;
4153}
4154
4155
4156bool CIccTagXmlDict::ToXml(std::string &xml, std::string blanks/* = ""*/)
4157{
4158 std::string info;
4159
4160 CIccNameValueDict::iterator nvp;
4161
4162 for (nvp=m_Dict->begin(); nvp!=m_Dict->end(); nvp++) {
4163 CIccDictEntry *nv = nvp->ptr;
4164 if (!nv)
4165 continue;
4166
4167 char buf[256];
4168 char data[256];
4169 char fix[256];
4170 std::string bufstr;
4171
4172 xml += blanks + " <DictEntry Name=\"";
4173 xml += icFixXml(fix, icUtf16ToUtf8(bufstr, (icUInt16Number*)nv->GetName().c_str(), (int)nv->GetName().size()));
4174 xml += "\"";
4175
4176 if (nv->IsValueSet()) {
4177 xml += " Value=\"";
4178 xml += icFixXml(fix, icUtf16ToUtf8(bufstr, (icUInt16Number*)nv->GetValue().c_str(), (int)nv->GetValue().size()));
4179 xml += "\"";
4180 }
4181
4182 if (!nv->GetNameLocalized() && !nv->GetValueLocalized()) {
4183 xml += "/>\n";
4184 }
4185 else {
4186 xml += "\n";
4187
4188 if (nv->GetNameLocalized()) {
4189 CIccMultiLocalizedUnicode::iterator i;
4190
4191 for (i=nv->GetNameLocalized()->m_Strings->begin(); i!=nv->GetNameLocalized()->m_Strings->end(); i++) {
4192 sprintf(buf, " <LocalizedName LanguageCountry=\"%s\"", icFixXml(fix, icGetSigStr(data, (i->m_nLanguageCode<<16) + i->m_nCountryCode)));
4193 xml += blanks + buf;
4194
4195 sprintf(buf, "><![CDATA[%s]]></LocalizedName>\n", icFixXml(fix, icUtf16ToUtf8(bufstr, i->GetBuf(), i->GetLength())));
4196 xml += buf;
4197 }
4198 }
4199 if (nv->GetValueLocalized()) {
4200 CIccMultiLocalizedUnicode::iterator i;
4201
4202 for (i=nv->GetValueLocalized()->m_Strings->begin(); i!=nv->GetValueLocalized()->m_Strings->end(); i++) {
4203 sprintf(buf, " <LocalizedValue LanguageCountry=\"%s\"", icFixXml(fix, icGetSigStr(data, (i->m_nLanguageCode<<16) + i->m_nCountryCode)));
4204 xml += blanks + buf;
4205
4206 sprintf(buf, "><![CDATA[%s]]></LocalizedValue>\n", icFixXml(fix, icUtf16ToUtf8(bufstr, i->GetBuf(), i->GetLength())));
4207 xml += buf;
4208 }
4209 }
4210 xml += blanks + " </DictEntry>\n";
4211 }
4212 }
4213 return true;
4214}
4215
4216
4217bool CIccTagXmlDict::ParseXml(xmlNode *pNode, std::string &parseStr)
4218{
4219 m_Dict->clear();
4220
4221 for (pNode = icXmlFindNode(pNode, "DictEntry"); pNode; pNode = icXmlFindNode(pNode->next, "DictEntry")) {
4222 CIccDictEntryPtr ptr;
4223 CIccDictEntry *pDesc = new CIccDictEntry();
4224 xmlAttr *pAttr;
4225 CIccUTF16String str;
4226
4227 if (!pDesc)
4228 return false;
4229 ptr.ptr = pDesc;
4230
4231 str = icXmlAttrValue(pNode, "Name", "");
4232 str.ToWString(pDesc->GetName());
4233
4234 pAttr = icXmlFindAttr(pNode, "Value");
4235 if (pAttr) {
4236 std::wstring wstr;
4237 str = icXmlAttrValue(pAttr, "");
4238 str.ToWString(wstr);
4239
4240 pDesc->SetValue(wstr);
4241 }
4242
4243 xmlNode *pChild;
4244
4245 for (pChild = pNode->children; pChild; pChild = pChild->next) {
4246 if (pChild->type == XML_ELEMENT_NODE && !icXmlStrCmp(pChild->name, "LocalizedName")strcmp((const char *)(pChild->name), (const char*)("LocalizedName"
))
) {
4247 CIccTagMultiLocalizedUnicode *pTag = pDesc->GetNameLocalized();
4248 if (!pTag) {
4249 pTag = new CIccTagMultiLocalizedUnicode();
4250 pDesc->SetNameLocalized(pTag);
4251 }
4252
4253 if ((pAttr = icXmlFindAttr(pChild, "LanguageCountry")) && pChild->children) {
4254 xmlNode *pText;
4255 icUInt32Number lc = icGetSigVal(icXmlAttrValue(pAttr));
4256
4257 for (pText = pChild->children; pText && pText->type != XML_TEXT_NODE && pText->type != XML_CDATA_SECTION_NODE; pText = pText->next);
4258
4259 if (pText) {
4260 CIccUTF16String str((const char*)pText->content);
4261
4262 pTag->SetText(str.c_str(), (icLanguageCode)(lc>>16), (icCountryCode)(lc & 0xffff));
4263 }
4264 else {
4265 pTag->SetText("");
4266 }
4267 }
4268 }
4269 else if (pChild->type == XML_ELEMENT_NODE && !icXmlStrCmp(pChild->name, "LocalizedValue")strcmp((const char *)(pChild->name), (const char*)("LocalizedValue"
))
) {
4270 CIccTagMultiLocalizedUnicode *pTag = pDesc->GetValueLocalized();
4271 if (!pTag) {
4272 pTag = new CIccTagMultiLocalizedUnicode();
4273 pDesc->SetValueLocalized(pTag);
4274 }
4275
4276 if ((pAttr = icXmlFindAttr(pChild, "LanguageCountry")) && pChild->children) {
4277 xmlNode *pText;
4278 icUInt32Number lc = icGetSigVal(icXmlAttrValue(pAttr));
4279
4280 for (pText = pChild->children; pText && pText->type != XML_TEXT_NODE && pText->type != XML_CDATA_SECTION_NODE; pText = pText->next);
4281
4282 if (pText) {
4283 CIccUTF16String str((const char*)pText->content);
4284 pTag->SetText(str.c_str(), (icLanguageCode)(lc>>16), (icCountryCode)(lc & 0xffff));
4285 }
4286 else {
4287 pTag->SetText("");
4288 }
4289 }
4290 }
4291 }
4292
4293 m_Dict->push_back(ptr);
4294 }
4295
4296 return true;
4297}
4298
4299
4300bool CIccTagXmlStruct::ToXml(std::string &xml, std::string blanks/* = ""*/)
4301{
4302 std::string info;
4303 char buf[256], fix[256], line[256];
4304 IIccStruct *pStruct = GetStructHandler();
4305
4306 const icChar *structName = ((pStruct != NULL__null) ? pStruct->GetDisplayName() : NULL__null);
4307 blanks += " ";
4308
4309 if (structName && strcmp(structName, "privateStruct")) {
4310 sprintf(line, "<%s> <MemberTags>\n", structName);
4311 }
4312 else {
4313 // print out the struct signature
4314 sprintf(line, "<privateStruct StructSignature=\"%s\"/> <MemberTags>\n", icFixXml(fix, icGetSigStr(buf, m_sigStructType)));
4315 structName = "privateStruct";
4316 }
4317
4318 xml += blanks + line;
4319 TagEntryList::iterator i, j;
4320 std::set<icTagSignature> sigSet;
4321 CIccInfo Fmt;
4322 IccOffsetTagSigMap offsetTags;
4323
4324 for (i=m_ElemEntries->begin(); i!=m_ElemEntries->end(); i++) {
4325 if (sigSet.find(i->TagInfo.sig)==sigSet.end()) {
4326 CIccTag *pTag = FindElem(i->TagInfo.sig);
4327
4328 if (pTag) {
4329 CIccTagXml *pTagXml = (CIccTagXml*)(pTag->GetExtension());
4330 if (pTagXml) {
4331 IccOffsetTagSigMap::iterator prevTag = offsetTags.find(i->TagInfo.offset);
4332 std::string tagName = ((pStruct!=NULL__null) ? pStruct->GetElemName((icSignature)i->TagInfo.sig) : "");
4333 if (prevTag == offsetTags.end()) {
4334 const icChar* tagSig = icGetTagSigTypeName(pTag->GetType());
4335
4336 if (tagName.size() && strncmp(tagName.c_str(), "PrivateSubTag", 13)) {
4337 sprintf(line, " <%s>", icFixXml(fix, tagName.c_str()));
4338 }
4339 else {
4340 sprintf(line, " <PrivateSubTag TagSignature=\"%s\">", icFixXml(fix, icGetSigStr(buf, i->TagInfo.sig)));
4341 tagName = "PrivateSubTag";
4342 }
4343 xml += blanks + line;
4344
4345 // PrivateType - a type that does not belong to the list in the icc specs - custom for vendor.
4346 if (!strcmp("PrivateType", tagSig))
4347 sprintf(line, " <PrivateType type=\"%s\">\n", icFixXml(fix, icGetSigStr(buf, pTag->GetType())));
4348 else
4349 sprintf(line, " <%s>\n", tagSig); //parent node is the tag type
4350
4351 xml += line;
4352 j = i;
4353#if 0
4354 // print out the tag signature (there is at least one)
4355 sprintf(line, " <TagSignature>%s</TagSignature>\n", icFixXml(fix, icGetSigStr(buf, i->TagInfo.sig)));
4356 xml += blanks + line;
4357
4358 sigSet.insert(i->TagInfo.sig);
4359
4360 // print out the rest of the tag signatures
4361 for (j++; j != m_ElemEntries->end(); j++) {
4362 if (j->pTag == i->pTag || j->TagInfo.offset == i->TagInfo.offset) {
4363 sprintf(line, " <TagSignature>%s</TagSignature>\n", icFixXml(fix, icGetSigStr(buf, j->TagInfo.sig)));
4364 xml += blanks + line;
4365 sigSet.insert(j->TagInfo.sig);
4366 }
4367 }
4368 // if (pTag->m_nReserved) {
4369 // sprintf(line, " Reserved=\"%08x\"", pTag->m_nReserved);
4370 // xml += line;
4371 // }
4372 // xml += ">\n";
4373#endif
4374 //convert the rest of the tag to xml
4375 if (!pTagXml->ToXml(xml, blanks + " ")) {
4376 printf("Unable to output sub-tag with type %s\n", icGetSigStr(buf, i->TagInfo.sig));
4377 return false;
4378 }
4379 sprintf(line, " </%s> </%s>\n", tagSig, tagName.c_str());
4380 xml += blanks + line;
4381 offsetTags[i->TagInfo.offset] = i->TagInfo.sig;
4382 }
4383 else {
4384 std::string prevTagName = ((pStruct != NULL__null) ? pStruct->GetElemName(prevTag->second) : "");
4385 char fix2[200];
4386
4387 if (tagName.size() && strncmp(tagName.c_str(), "PrivateSubTag", 13))
4388 sprintf(line, " <%s SameAs=\"%s\"", icFixXml(fix, tagName.c_str()), icFixXml(fix2, prevTagName.c_str())); //parent node is the tag type
4389 else
4390 sprintf(line, " <PrivateSubTag TagSignature=\"%s\" SameAs=\"%s\"", icFixXml(fix2, icGetSigStr(buf, i->TagInfo.sig)), icFixXml(fix, prevTagName.c_str()));
4391
4392 xml += line;
4393 if (prevTagName.size() || !strncmp(prevTagName.c_str(), "PrivateSubTag", 13)) {
4394 sprintf(line, " SameAsSignature=\"%s\"", icFixXml(fix2, icGetSigStr(buf, prevTag->second)));
4395 xml += line;
4396 }
4397
4398 xml += "/>\n";
4399 }
4400 }
4401 else {
4402 printf("Non XML tag in list with type %s!\n", icGetSigStr(buf, i->TagInfo.sig));
4403 return false;
4404 }
4405 }
4406 else {
4407 printf("Unable to find tag with type %s!\n", icGetSigStr(buf, i->TagInfo.sig));
4408 return false;
4409 }
4410 }
4411 }
4412
4413 xml += blanks + "</MemberTags> </" + structName + ">\n";
4414 return true;
4415}
4416
4417/**
4418******************************************************************************
4419* Name: CIccTagXmlStruct::ParseTag
4420*
4421* Purpose: This will load from the indicated IO object and associate a tag
4422* object to a tag directory entry. Nothing happens if tag directory entry
4423* is associated with a tag object.
4424*
4425* Args:
4426* pNode - pointer to xmlNode object to parse from
4427*
4428* Return:
4429* true - tag from node successfully parsed,
4430* false - failure
4431*******************************************************************************
4432*/
4433bool CIccTagXmlStruct::ParseTag(xmlNode *pNode, std::string &parseStr)
4434{
4435 xmlAttr *attr;
4436
4437 if (pNode->type != XML_ELEMENT_NODE) {// || icXmlStrCmp(pNode->name, "Tag")) {
4438 parseStr += "Invalid Tag Node: ";
4439 parseStr += (const char *)pNode->name;
4440 parseStr += "\n";
4441 return false;
4442 }
4443
4444 CIccTag *pTag = NULL__null;
4445
4446 std::string nodeName = (icChar*)pNode->name;
4447 icSignature sigTag;
4448 if (m_pStruct)
4449 sigTag = m_pStruct->GetElemSig(nodeName.c_str());
4450 else
4451 sigTag = 0;
4452
4453 if (sigTag != 0 || nodeName == "PrivateSubTag") { //Parsing of XML tags by name
4454 if (nodeName == "PrivateSubTag") {
4455 const char *tagSig = icXmlAttrValue(pNode, "TagSignature", "");
4456 if (tagSig[0]) {
4457 sigTag = (icTagSignature)icGetSigVal(tagSig);
4458 }
4459 else {
4460 parseStr += "Invalid TagSignature for PrivateSubTag\n";
4461 return false;
4462 }
4463 }
4464
4465 const char *sameAs = icXmlAttrValue(pNode, "SameAs", "");
4466
4467 if (sameAs[0]) {
4468 icTagSignature sigParentTag = icGetTagNameSig(sameAs);
4469 if (!strcmp(sameAs, "PrivateSubTag") || sigParentTag == icSigUnknownTag((icTagSignature) 0x3f3f3f3f)) {
4470 const char *sameAsSig = icXmlAttrValue(pNode, "SameAsSignature", "");
4471 if (sameAsSig[0]) {
4472 sigParentTag = (icTagSignature)icGetSigVal(sameAsSig);
4473 }
4474 else {
4475 parseStr += "Invalid SameAsSignature for PrivateSubTag\n";
4476 return false;
4477 }
4478 }
4479 pTag = this->FindElem(sigParentTag);
4480 if (pTag) {
4481 AttachElem(sigTag, pTag);
4482 }
4483 else {
4484 parseStr += "SameAs tag ";
4485 parseStr += sameAs;
4486 parseStr += " for ";
4487 parseStr += nodeName + " does not exist\n";
4488 return false;
4489 }
4490
4491 return true;
4492 }
4493 else { //Parse the type node as the first child
4494 xmlNode *pTypeNode;
4495 for (pTypeNode = pNode->children; pTypeNode; pTypeNode = pTypeNode->next) {
4496 if (pTypeNode->type == XML_ELEMENT_NODE) {
4497 break;
4498 }
4499 }
4500
4501 if (!pTypeNode) {
4502 parseStr += "No tag type node defined for ";
4503 parseStr += nodeName;
4504 parseStr += "\n";
4505 return false;
4506 }
4507
4508 // get the tag type signature
4509 icTagTypeSignature sigType = icGetTypeNameTagSig((const icChar*)pTypeNode->name);
4510
4511 if (sigType == icSigUnknownType((icTagTypeSignature) 0x3f3f3f3f)) {
4512 xmlAttr *attr = icXmlFindAttr(pTypeNode, "type");
4513 sigType = (icTagTypeSignature)icGetSigVal((icChar*)icXmlAttrValue(attr));
4514 }
4515
4516 CIccInfo info;
4517
4518 // create a tag based on the signature
4519 pTag = CIccTag::Create(sigType);
4520
4521 IIccExtensionTag *pExt;
4522
4523 if (pTag && (pExt = pTag->GetExtension()) && !strcmp(pExt->GetExtClassName(), "CIccTagXml")) {
4524 CIccTagXml* pXmlTag = (CIccTagXml*)pExt;
4525
4526 if (pXmlTag->ParseXml(pTypeNode->children, parseStr)) {
4527 if ((attr = icXmlFindAttr(pTypeNode, "reserved"))) {
4528 sscanf(icXmlAttrValue(attr), "%u", &pTag->m_nReserved);
4529 }
4530 AttachElem(sigTag, pTag);
4531 }
4532 else {
4533 parseStr += "Unable to Parse \"";
4534 parseStr += (const char*)pTypeNode->name;
4535 parseStr += "\" (";
4536 parseStr += nodeName;
4537 parseStr += ") Tag\n";
4538 return false;
4539 }
4540 }
4541 else {
4542 parseStr += "Invalid tag extension for \"";
4543 parseStr += (const char*)pTypeNode->name;
4544 parseStr += "\" (";
4545 parseStr += nodeName;
4546 parseStr += ") Tag\n";
4547 return false;
4548 }
4549 }
4550 }
4551 else { //Legacy parsing of XML tags by type
4552 sigTag = (icTagSignature)0;
4553 // get the tag type signature
4554 icTagTypeSignature sigType = icGetTypeNameTagSig(nodeName.c_str());
4555
4556 if (sigType == icSigUnknownType((icTagTypeSignature) 0x3f3f3f3f)) {
4557 xmlAttr *attr = icXmlFindAttr(pNode, "type");
4558 sigType = (icTagTypeSignature)icGetSigVal((icChar*)icXmlAttrValue(attr));
4559 }
4560
4561 CIccInfo info;
4562
4563 // create a tag based on the signature
4564 pTag = CIccTag::Create(sigType);
4565
4566 IIccExtensionTag *pExt;
4567
4568 if (pTag && (pExt = pTag->GetExtension()) && !strcmp(pExt->GetExtClassName(), "CIccTagXml")) {
4569 CIccTagXml* pXmlTag = (CIccTagXml*)pExt;
4570
4571 if (pXmlTag->ParseXml(pNode->children, parseStr)) {
4572 if ((attr = icXmlFindAttr(pNode, "reserved"))) {
4573 sscanf(icXmlAttrValue(attr), "%u", &pTag->m_nReserved);
4574 }
4575
4576 for (xmlNode *tagSigNode = pNode->children; tagSigNode; tagSigNode = tagSigNode->next) {
4577 if (tagSigNode->type == XML_ELEMENT_NODE && !icXmlStrCmp(tagSigNode->name, "TagSignature")strcmp((const char *)(tagSigNode->name), (const char*)("TagSignature"
))
) {
4578 sigTag = (icTagSignature)icGetSigVal((const icChar*)tagSigNode->children->content);
4579 AttachElem(sigTag, pTag);
4580 }
4581 }
4582 }
4583 else {
4584 parseStr += "Unable to Parse \"";
4585 parseStr += info.GetTagTypeSigName(sigType);
4586 parseStr += "\" (";
4587 parseStr += nodeName;
4588 parseStr += ") Tag\n";
4589 return false;
4590 }
4591 }
4592 else {
4593 parseStr += "Invalid tag extension for \"";
4594 parseStr += info.GetTagTypeSigName(sigType);
4595 parseStr += "\" (";
4596 parseStr += nodeName;
4597 parseStr += ") Tag\n";
4598 return false;
4599 }
4600 }
4601
4602 return true;
4603}
4604
4605
4606bool CIccTagXmlStruct::ParseXml(xmlNode *pNode, std::string &parseStr)
4607{
4608 // parse each tag
4609 xmlNode *tagNode, *firstNode=pNode;
4610
4611 for (; pNode; pNode = pNode->next) {
4612 if (pNode->type == XML_ELEMENT_NODE)
4613 break;
4614 }
4615 if (!pNode) {
4616 parseStr += "Invalid Tag Structure: ";
4617 parseStr += (const char *)firstNode->name;
4618 parseStr += "\n";
4619 return false;
4620 }
4621
4622 std::string nodeName = (icChar*)pNode->name;
4623 icStructSignature sigStruct = CIccStructCreator::GetStructSig(nodeName.c_str());
4624
4625 if (sigStruct) {
4626 m_sigStructType = sigStruct;
4627 m_pStruct = CIccStructCreator::CreateStruct(m_sigStructType, this);
4628 pNode = pNode->children;
4629 }
4630 else {
4631 tagNode = icXmlFindNode(firstNode, "StructureSignature");
4632 if (!tagNode) {
4633 parseStr += "Unable to find StructureSignature\r\n";
4634 return false;
4635 }
4636
4637 if (tagNode->type == XML_ELEMENT_NODE && tagNode->children && tagNode->children->content) {
4638 m_sigStructType = (icStructSignature)icGetSigVal(tagNode->children ? (const icChar*)tagNode->children->content : "");
4639 m_pStruct = CIccStructCreator::CreateStruct(m_sigStructType, this);
4640 }
4641 else {
4642 parseStr += "Invalid XNode type for StructureSignature\r\n";
4643 return false;
4644 }
4645 }
4646
4647 tagNode = icXmlFindNode(pNode, "MemberTags");
4648 if (!tagNode) {
4649 parseStr += "Unable to find structure MemberTags\r\n";
4650 return false;
4651 }
4652
4653 for (tagNode = tagNode->children; tagNode; tagNode = tagNode->next) {
4654 if (tagNode->type == XML_ELEMENT_NODE) {
4655 if (!ParseTag(tagNode, parseStr)) {
4656 parseStr += "Failed to parse tag member (";
4657 parseStr += (char*)tagNode->name;
4658 parseStr += ")\r\n";
4659 return false;
4660 }
4661 }
4662 }
4663
4664 return true;
4665}
4666
4667bool CIccTagXmlArray::ToXml(std::string &xml, std::string blanks/* = ""*/)
4668{
4669 std::string info;
4670 char buf[256], fix[256], line[256];
4671
4672 std::string arrayName;
4673 std::string arrayBlanks = "";
4674 bool found = CIccArrayCreator::GetArraySigName(arrayName, m_sigArrayType, false);
4675
4676 if (found) {
4677 sprintf(line, "<%s> ", arrayName.c_str());
4678 arrayBlanks = " ";
4679 }
4680 else {
4681 // print out the struct signature
4682 sprintf(line, "<privateArray StructSignature=\"%s\"/> ", icFixXml(fix, icGetSigStr(buf, m_sigArrayType)));
4683 arrayName = "privateArray";
4684 }
4685
4686 xml += blanks + line + "<ArrayTags>\n";
4687 int i;
4688
4689 for (i=0; i<(int)m_nSize; i++) {
4690 CIccTag* pTag = m_TagVals[i].ptr;
4691 if (pTag) {
4692 CIccTagXml *pTagXml = (CIccTagXml*)(pTag->GetExtension());
4693 if (pTagXml) {
4694 const icChar* tagSig = icGetTagSigTypeName(pTag->GetType());
4695
4696 // PrivateType - a type that does not belong to the list in the icc specs - custom for vendor.
4697 if ( !strcmp("PrivateType", tagSig) )
4698 sprintf(line, " <PrivateType type=\"%s\">\n", icFixXml(fix, icGetSigStr(buf, pTag->GetType())));
4699 else
4700 sprintf(line, " <%s>\n", tagSig); //parent node is the tag type
4701
4702 xml += blanks + arrayBlanks + line;
4703
4704 //convert the rest of the tag to xml
4705 if (!pTagXml->ToXml(xml, blanks + arrayBlanks + " ")) {
4706 printf("Unable to output tag with type %s\n", icGetSigStr(buf, pTag->GetType()));
4707 return false;
4708 }
4709 sprintf(line, " </%s>\n\n", tagSig);
4710 xml += blanks + arrayBlanks + line;
4711 }
4712 else {
4713 printf("Non XML tag in list with type %s!\n", icGetSigStr(buf, pTag->GetType()));
4714 return false;
4715 }
4716 }
4717 }
4718 xml += blanks + "</ArrayTags> </" + arrayName + ">\n";
4719
4720 return true;
4721}
4722
4723
4724bool CIccTagXmlArray::ParseXml(xmlNode *pNode, std::string &parseStr)
4725{
4726 // parse each tag
4727 xmlNode *tagNode, *indexNode, *firstNode = pNode;;
4728 xmlAttr *attr;
4729
4730 for (; pNode; pNode = pNode->next) {
4731 if (pNode->type == XML_ELEMENT_NODE)
4732 break;
4733 }
4734 if (!pNode) {
4735 parseStr += "Invalid Tag Array: ";
4736 parseStr += (const char *)firstNode->name;
4737 parseStr += "\n";
4738 return false;
4739 }
4740
4741 std::string nodeName = (icChar*)pNode->name;
4742 icArraySignature sigArray = CIccArrayCreator::GetArraySig(nodeName.c_str());
4743
4744 if (sigArray) {
4745 m_sigArrayType = sigArray;
4746 m_pArray = CIccArrayCreator::CreateArray(m_sigArrayType, this);
4747 pNode = pNode->children;
4748 }
4749 else {
4750 tagNode = icXmlFindNode(firstNode, "ArraySignature");
4751 if (!tagNode) {
4752 parseStr += "Unable to find ArraySignature\r\n";
4753 return false;
4754 }
4755
4756 if (tagNode->type == XML_ELEMENT_NODE && tagNode->children && tagNode->children->content) {
4757 m_sigArrayType = (icArraySignature)icGetSigVal(tagNode->children ? (const icChar*)tagNode->children->content : "");
4758 m_pArray = CIccArrayCreator::CreateArray(m_sigArrayType, this);
4759 }
4760 else {
4761 parseStr += "Invalid XNode type for ArraySignature\r\n";
4762 return false;
4763 }
4764 }
4765
4766 indexNode = icXmlFindNode(pNode, "ArrayTags");
4767 if (!indexNode)
4768 return false;
4769
4770 int nMaxIndex = 0, n=0;
4771 for (tagNode = indexNode->children; tagNode; tagNode = tagNode->next) {
4772 if (tagNode->type == XML_ELEMENT_NODE) {
4773 nMaxIndex++;
4774 }
4775 }
4776 if (!SetSize(nMaxIndex))
4777 return false;
4778
4779 n=0;
4780 for (tagNode = indexNode->children; tagNode; tagNode = tagNode->next) {
4781 if (tagNode->type == XML_ELEMENT_NODE) {
4782 CIccTag *pTag = NULL__null;
4783 icSignature sigTag = (icSignature)0;
4784
4785 // get the tag signature
4786 icTagTypeSignature sigType = icGetTypeNameTagSig ((icChar*) tagNode->name);
4787
4788 if (sigType==icSigUnknownType((icTagTypeSignature) 0x3f3f3f3f)){
4789 xmlAttr *attr = icXmlFindAttr(pNode, "type");
4790 sigType = (icTagTypeSignature)icGetSigVal((icChar*) icXmlAttrValue(attr));
4791 }
4792
4793 CIccInfo info;
4794
4795 // create a tag based on the signature
4796 pTag = CIccTag::Create(sigType);
4797
4798 IIccExtensionTag *pExt;
4799
4800 if (pTag && (pExt = pTag->GetExtension()) && !strcmp(pExt->GetExtClassName(), "CIccTagXml")) {
4801 CIccTagXml* pXmlTag = (CIccTagXml*)pExt;
4802
4803 if (pXmlTag->ParseXml(tagNode->children, parseStr)) {
4804 if ((attr=icXmlFindAttr(pNode, "reserved"))) {
4805 sscanf(icXmlAttrValue(attr), "%u", &pTag->m_nReserved);
4806 }
4807
4808 if (!m_TagVals[n].ptr)
4809 m_TagVals[n].ptr = pTag;
4810 else {
4811 parseStr += "Tag Array Index ";
4812 parseStr += n;
4813 parseStr += " already filled!\r\n";
4814 return false;
4815 }
4816 }
4817 else {
4818 parseStr += "Unable to Parse xml node named \"";
4819 parseStr += (icChar*)tagNode->name;
4820 parseStr += "\"\n\r";
4821 return false;
4822 }
4823 }
4824 n++;
4825 }
4826 }
4827
4828 for (n=0; n<(int)m_nSize; n++) {
4829 if (!m_TagVals[n].ptr) {
4830 parseStr += "Undefined Array Tag at index ";
4831 parseStr += n;
4832 parseStr += "\n";
4833 return false;
4834 }
4835 }
4836
4837 return true;
4838}
4839
4840bool CIccTagXmlGamutBoundaryDesc::ToXml(std::string &xml, std::string blanks/* = ""*/)
4841{
4842 std::string info;
4843 char line[256];
4844 int i;
4845
4846 if (m_NumberOfVertices && (m_PCSValues || m_DeviceValues)) {
4847 xml += blanks + "<Vertices>\n";
4848
4849 if (m_PCSValues) {
4850 sprintf(line, " <PCSValues channels=\"%d\">\n", m_nPCSChannels);
4851 xml += blanks + line;
4852 CIccFloatArray::DumpArray(xml, blanks+" ", m_PCSValues, m_NumberOfVertices*m_nPCSChannels, icConvertFloat, 9);
4853 xml += blanks + " </PCSValues>\n";
4854 }
4855 if (m_DeviceValues) {
4856 sprintf(line, " <DeviceValues channels=\"%d\">\n", m_nDeviceChannels);
4857 xml += blanks + line;
4858 CIccFloatArray::DumpArray(xml, blanks+" ", m_DeviceValues, m_NumberOfVertices*m_nDeviceChannels, icConvertFloat, 8);
4859 xml += blanks + " </DeviceValues>\n";
4860 }
4861 xml += blanks + "</Vertices>\n";
4862 }
4863
4864 if (m_Triangles && m_NumberOfTriangles) {
4865 xml += blanks + "<Triangles>\n";
4866
4867 for (i=0; i<m_NumberOfTriangles; i++) {
4868 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]);
4869 xml += blanks + line;
4870 }
4871
4872 xml += blanks + "</Triangles>\n";
4873 }
4874
4875 return true;
4876}
4877
4878
4879bool CIccTagXmlGamutBoundaryDesc::ParseXml(xmlNode *pNode, std::string &parseStr)
4880{
4881 // parse each tag
4882 xmlNode *childNode, *subNode;
4883
4884 childNode = icXmlFindNode(pNode, "Vertices");
4885 if (!childNode) {
4886 parseStr += "Cannot find Vertices\n";
4887 return false;
4888 }
4889
4890 subNode = icXmlFindNode(childNode->children, "PCSValues");
4891
4892 if (subNode) {
4893 m_nPCSChannels = atoi(icXmlAttrValue(subNode, "channels", "0"));
4894
4895 if (!m_nPCSChannels) {
4896 parseStr += "Bad PCSValues channels\n";
4897 return false;
4898 }
4899
4900 CIccFloatArray vals;
4901 if (!vals.ParseArray(subNode->children)) {
4902 parseStr += "Unable to parse GamutBoundaryDesc PCSValues\n";
4903 return false;
4904 }
4905
4906 m_NumberOfVertices = vals.GetSize() / m_nPCSChannels;
4907
4908 if (m_NumberOfVertices<4) {
4909 parseStr += "Must have at least 4 PCSValues vertices\n";
4910 return false;
4911 }
4912
4913 m_PCSValues = new icFloatNumber[m_NumberOfVertices * m_nPCSChannels];
4914
4915 if (!m_PCSValues)
4916 return false;
4917
4918 memcpy(m_PCSValues, vals.GetBuf(), m_NumberOfVertices * m_nPCSChannels*sizeof(icFloatNumber));
4919 }
4920 else {
4921 parseStr += "Cannot find PCSValues\n";
4922 return false;
4923 }
4924
4925 subNode = icXmlFindNode(childNode->children, "DeviceValues");
4926
4927 if (subNode) {
4928 m_nDeviceChannels = atoi(icXmlAttrValue(subNode, "channels", "0"));
4929
4930 if (!m_nDeviceChannels) {
4931 parseStr += "Bad DeviceValues channels\n";
4932 return false;
4933 }
4934
4935 CIccFloatArray vals;
4936 if (!vals.ParseArray(subNode->children)) {
4937 parseStr += "Unable to parse GamutBoundaryDesc DeviceValues\n";
4938 return false;
4939 }
4940
4941 int nVertices = vals.GetSize() / m_nDeviceChannels;
4942
4943 if (m_NumberOfVertices != nVertices) {
4944 parseStr += "Number of Device vertices doesn't match PCS verticies\n";
4945 return false;
4946 }
4947
4948 m_DeviceValues = new icFloatNumber[m_NumberOfVertices * m_nDeviceChannels];
4949
4950 if (!m_DeviceValues)
4951 return false;
4952
4953 memcpy(m_DeviceValues, vals.GetBuf(), m_NumberOfVertices * m_nDeviceChannels * sizeof(icFloatNumber));
4954 }
4955 else if (!m_PCSValues)
4956 m_NumberOfVertices = 0;
4957
4958 childNode = icXmlFindNode(pNode, "Triangles");
4959 if (!childNode) {
4960 parseStr += "Cannot find Triangles\n";
4961 return false;
4962 }
4963
4964 int nMaxIndex = 0, n=0;
4965 for (subNode = childNode->children; subNode; subNode = subNode->next) {
4966 if (subNode->type == XML_ELEMENT_NODE && !strcmp((icChar*)subNode->name, "T")) {
4967 nMaxIndex++;
4968 }
4969 }
4970 m_NumberOfTriangles = nMaxIndex;
4971 m_Triangles = new icGamutBoundaryTriangle[m_NumberOfTriangles];
4972
4973 n=0;
4974 for (subNode = childNode->children; subNode && n<nMaxIndex; subNode = subNode->next) {
4975 if (subNode->type == XML_ELEMENT_NODE && !strcmp((icChar*)subNode->name, "T")) {
4976 CIccUInt32Array ids;
4977
4978 if (!ids.ParseArray(subNode->children) || ids.GetSize()!=3) {
4979 parseStr += "Invalid Triangle entry\n";
4980 return false;
4981 }
4982 icUInt32Number *v = ids.GetBuf();
4983
4984 m_Triangles[n].m_VertexNumbers[0] = v[0];
4985 m_Triangles[n].m_VertexNumbers[1] = v[1];
4986 m_Triangles[n].m_VertexNumbers[2] = v[2];
4987
4988 n++;
4989 }
4990 }
4991
4992 return true;
4993}
4994
4995bool CIccTagXmlEmbeddedProfile::ParseXml(xmlNode *pNode, std::string &parseStr)
4996{
4997 // parse each tag
4998 xmlNode *tagNode;
4999
5000 tagNode = icXmlFindNode(pNode, "IccProfile");
5001 if (!tagNode)
5002 return false;
5003
5004 if (m_pProfile) {
5005 delete m_pProfile;
5006 }
5007
5008 CIccProfileXml *pProfile = new CIccProfileXml();
5009 m_pProfile = pProfile;
5010
5011 if (!pProfile->ParseXml(tagNode, parseStr)) {
5012 delete m_pProfile;
5013 m_pProfile = NULL__null;
5014 return false;
5015 }
5016 return true;
5017}
5018
5019bool CIccTagXmlEmbeddedProfile::ToXml(std::string &xml, std::string blanks/* = ""*/)
5020{
5021 if (!m_pProfile || strcmp(m_pProfile->GetClassName(), "CIccProfileXml")) {
5022 return false;
5023 }
5024
5025 CIccProfileXml *pProfile = (CIccProfileXml*)m_pProfile;
5026
5027 return pProfile->ToXmlWithBlanks(xml, blanks);
5028}
5029
5030bool CIccTagXmlEmbeddedHeightImage::ParseXml(xmlNode *pNode, std::string &parseStr)
5031{
5032 // parse tag
5033 xmlNode *tagNode;
5034
5035 tagNode = icXmlFindNode(pNode, "HeightImage");
5036 if (!tagNode)
5037 return false;
5038
5039 m_nSeamlesIndicator = atoi(icXmlAttrValue(tagNode, "SeamlessIndicator", "0"));
5040 m_nEncodingFormat = (icImageEncodingType)atoi(icXmlAttrValue(tagNode, "EncodingFormat", "0"));
5041 m_fMetersMinPixelValue = (icFloatNumber)atof(icXmlAttrValue(tagNode, "MetersMinPixelValue", "0.0"));
5042 m_fMetersMaxPixelValue = (icFloatNumber)atof(icXmlAttrValue(tagNode, "MetersMaxPixelValue", "0.0"));
5043
5044 xmlNode *pImageNode;
5045 pImageNode = icXmlFindNode(tagNode->children, "Image");
5046
5047 if (pImageNode) {
5048 const char *filename = icXmlAttrValue(pImageNode, "File");
5049 if (!filename || !filename[0]) {
5050 filename = icXmlAttrValue(pImageNode, "Filename");
5051 }
5052
5053 // file exists
5054 if (filename[0]) {
5055 CIccIO *file = IccOpenFileIO(filename, "rb");
5056 if (!file) {
5057 parseStr += "Error! - File '";
5058 parseStr += filename;
5059 parseStr += "' not found.\n";
5060 delete file;
5061 return false;
5062 }
5063
5064 icUInt32Number num = file->GetLength();
5065
5066 SetSize(num);
5067 icUInt8Number *dst = GetData(0);
5068 if (file->Read8(dst, num)!=num) {
5069 perror("Read-File Error");
5070 parseStr += "'";
5071 parseStr += filename;
5072 parseStr += "' may not be a valid binary file.\n";
5073 delete file;
5074 return false;
5075 }
5076 delete file;
5077 return true;
5078 }
5079 // no file
5080 else if (pImageNode->children && pImageNode->children->content){
5081 unsigned long nSize = icXmlGetHexDataSize((const icChar*)pImageNode->children->content);
5082
5083 SetSize(nSize);
5084 if (m_pData) {
5085 if (icXmlGetHexData(m_pData, (const icChar*)pImageNode->children->content, m_nSize) != m_nSize)
5086 return false;
5087 }
5088
5089 return true;
5090 }
5091 }
5092 return false;
5093}
5094
5095bool CIccTagXmlEmbeddedHeightImage::ToXml(std::string &xml, std::string blanks/*= ""*/)
5096{
5097 char buf[200];
5098
5099 xml += blanks + "<HeightImage";
5100 sprintf(buf, " SeamlessIndicator=\"%d\"", m_nSeamlesIndicator);
5101 xml += buf;
5102
5103 sprintf(buf, " EncodingFormat=\"%d\"", m_nEncodingFormat);
5104 xml += buf;
5105
5106 sprintf(buf, " MetersMinPixelValue=\"%.12f\"", m_fMetersMinPixelValue);
5107 xml += buf;
5108
5109 sprintf(buf, " MetersMaxPixelValue=\"%.12f\"", m_fMetersMaxPixelValue);
5110 xml += buf;
5111
5112 if (!m_nSize) {
5113 xml += blanks + "/>\n";
5114 }
5115 else {
5116 xml += ">\n";
5117 xml += blanks + " <Image>\n";
5118 icXmlDumpHexData(xml, blanks + " ", m_pData, m_nSize);
5119 xml += blanks + " </Image>\n";
5120 xml += blanks + "</HeightImage>\n";
5121 }
5122
5123 return true;
5124}
5125
5126bool CIccTagXmlEmbeddedNormalImage::ParseXml(xmlNode *pNode, std::string &parseStr)
5127{
5128 // parse tag
5129 xmlNode *tagNode;
5130
5131 tagNode = icXmlFindNode(pNode, "NormalImage");
5132 if (!tagNode)
5133 return false;
5134
5135 m_nSeamlesIndicator = atoi(icXmlAttrValue(tagNode, "SeamlessIndicator", "0"));
5136 m_nEncodingFormat = (icImageEncodingType)atoi(icXmlAttrValue(tagNode, "EncodingFormat", "0"));
5137
5138 xmlNode *pImageNode;
5139 pImageNode = icXmlFindNode(tagNode->children, "Image");
5140
5141 if (pImageNode) {
5142 const char *filename = icXmlAttrValue(pImageNode, "File");
5143 if (!filename || !filename[0]) {
5144 filename = icXmlAttrValue(pImageNode, "Filename");
5145 }
5146
5147 // file exists
5148 if (filename[0]) {
5149 CIccIO *file = IccOpenFileIO(filename, "rb");
5150 if (!file) {
5151 parseStr += "Error! - File '";
5152 parseStr += filename;
5153 parseStr += "' not found.\n";
5154 delete file;
5155 return false;
5156 }
5157
5158 icUInt32Number num = file->GetLength();
5159
5160 SetSize(num);
5161 icUInt8Number *dst = GetData(0);
5162 if (file->Read8(dst, num) != num) {
5163 perror("Read-File Error");
5164 parseStr += "'";
5165 parseStr += filename;
5166 parseStr += "' may not be a valid binary file'.\n";
5167 delete file;
5168 return false;
5169 }
5170 delete file;
5171 return true;
5172 }
5173 // no file
5174 else if (pImageNode->children && pImageNode->children->content) {
5175 unsigned long nSize = icXmlGetHexDataSize((const icChar*)pImageNode->children->content);
5176
5177 SetSize(nSize);
5178 if (m_pData) {
5179 if (icXmlGetHexData(m_pData, (const icChar*)pImageNode->children->content, m_nSize) != m_nSize)
5180 return false;
5181 }
5182 return true;
5183 }
5184 }
5185 return false;
5186}
5187
5188bool CIccTagXmlEmbeddedNormalImage::ToXml(std::string &xml, std::string blanks/*= ""*/)
5189{
5190 char buf[200];
5191
5192 xml += blanks + "<NormalImage";
5193 sprintf(buf, " SeamlessIndicator=\"%d\"", m_nSeamlesIndicator);
5194 xml += buf;
5195
5196 sprintf(buf, " EncodingFormat=\"%d\"", m_nEncodingFormat);
5197 xml += buf;
5198
5199 if (!m_nSize) {
5200 xml += blanks + "/>\n";
5201 }
5202 else {
5203 xml += ">\n";
5204 xml += blanks + " <Image>\n";
5205 icXmlDumpHexData(xml, blanks + " ", m_pData, m_nSize);
5206 xml += blanks + " </Image>\n";
5207 xml += blanks + "</NormalImage>\n";
5208 }
5209
5210 return true;
5211}
5212
5213
5214#ifdef USEREFICCMAXNAMESPACE
5215}
5216#endif