78 xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
91 xml += blanks +
"<IccProfile>\n";
92 xml += blanks +
" <Header>\n";
95 sprintf(line,
" <ProfileVersion>%s</ProfileVersion>\n", info.
GetVersionName(m_Header.version));
97 if (m_Header.version & 0x0000ffff) {
98 sprintf(line,
" <ProfileSubClassVersion>%s</ProfileSubClassVersion>\n", info.
GetSubClassVersionName(m_Header.version));
101 sprintf(line,
" <ProfileDeviceClass>%s</ProfileDeviceClass>\n",
icFixXml(fix,
icGetSigStr(buf, m_Header.deviceClass)));
102 xml += blanks + line;
104 if (m_Header.deviceSubClass) {
105 sprintf(line,
" <ProfileDeviceSubClass>%s</ProfileDeviceSubClass>\n",
icFixXml(fix,
icGetSigStr(buf, m_Header.deviceSubClass)));
106 xml += blanks + line;
109 sprintf(line,
" <DataColourSpace>%s</DataColourSpace>\n",
icFixXml(fix,
icGetColorSigStr(buf, m_Header.colorSpace)));
110 xml += blanks + line;
112 xml += blanks + line;
114 sprintf(line,
" <CreationDateTime>%d-%02d-%02dT%02d:%02d:%02d</CreationDateTime>\n",
119 m_Header.date.minutes,
120 m_Header.date.seconds);
121 xml += blanks + line;
129 sprintf(line,
" <PrimaryPlatform>%s</PrimaryPlatform>\n",
icFixXml(fix,
icGetSigStr(buf, m_Header.platform)));
130 xml += blanks + line;
136 if (m_Header.manufacturer != 0){
137 sprintf(line,
" <DeviceManufacturer>%s</DeviceManufacturer>\n",
icFixXml(fix,
icGetSigStr(buf, m_Header.manufacturer)));
138 xml += blanks + line;
141 if (m_Header.model != 0){
142 sprintf(line,
" <DeviceModel>%s</DeviceModel>\n",
icFixXml(fix,
icGetSigStr(buf, m_Header.model)));
143 xml += blanks + line;
150 xml += blanks + line;
152 (
float)
icFtoD(m_Header.illuminant.X),
153 (
float)
icFtoD(m_Header.illuminant.Y),
154 (
float)
icFtoD(m_Header.illuminant.Z),
157 xml += blanks + line;
159 sprintf(line,
" <ProfileCreator>%s</ProfileCreator>\n",
icFixXml(fix,
icGetSigStr(buf, m_Header.creator)));
160 xml += blanks + line;
162 if (m_Header.profileID.ID32[0] || m_Header.profileID.ID32[1] ||
163 m_Header.profileID.ID32[2] || m_Header.profileID.ID32[3]) {
165 for (n=0; n<16; n++) {
166 sprintf(buf + n*2,
"%02X", m_Header.profileID.ID8[n]);
169 xml +=
" <ProfileID>";
171 xml +=
"</ProfileID>\n";
175 if (m_Header.spectralPCS) {
177 xml += blanks + line;
179 if (m_Header.spectralRange.steps) {
180 xml += blanks +
" <SpectralRange>\n";
182 icF16toF(m_Header.spectralRange.start),
icF16toF(m_Header.spectralRange.end), m_Header.spectralRange.steps);
183 xml += blanks + line;
184 xml += blanks +
" </SpectralRange>\n";
186 if (m_Header.biSpectralRange.steps) {
187 xml += blanks +
" <BiSpectralRange>\n";
189 icF16toF(m_Header.biSpectralRange.start),
icF16toF(m_Header.biSpectralRange.end), m_Header.biSpectralRange.steps);
190 xml += blanks + line;
191 xml += blanks +
" </BiSpectralRange>\n";
197 xml += blanks + line;
200 for (n=0; n<
sizeof(m_Header.reserved); n++) {
201 if (m_Header.reserved[n])
203 sprintf(buf + n*2,
"%02X", m_Header.reserved[n]);
207 xml += blanks +
" <Reserved>";
209 xml +=
"</Reserved>\n";
211 xml += blanks +
" </Header>\n";
213 xml += blanks +
" <Tags>\n";
214 TagEntryList::iterator i, j;
215 std::set<icTagSignature> sigSet;
219 for (i=m_Tags->begin(); i!=m_Tags->end(); i++) {
220 if (sigSet.find(i->TagInfo.sig)==sigSet.end()) {
221 CIccTag *pTag = FindTag(i->TagInfo.sig);
226 IccOffsetTagSigMap::iterator prevTag = offsetTags.find(i->TagInfo.offset);
228 if (prevTag == offsetTags.end()) {
231 if (tagName && strncmp(tagName,
"Unknown ", 8)) {
232 sprintf(line,
" <%s> ",
icFixXml(fix, tagName));
235 sprintf(line,
" <PrivateTag TagSignature=\"%s\"> ",
icFixXml(fix,
icGetSigStr(buf, i->TagInfo.sig)));
236 tagName =
"PrivateTag";
238 xml += blanks + line;
240 if (!strcmp(
"PrivateType", tagSig))
243 sprintf(line,
"<%s>\n", tagSig);
249 sprintf(line,
" <TagSignature>%s</TagSignature>\n",
icFixXml(fix,
icGetSigStr(buf, i->TagInfo.sig)));
252 sigSet.insert(i->TagInfo.sig);
255 for (j++; j != m_Tags->end(); j++) {
256 if (j->pTag == i->pTag || j->TagInfo.offset == i->TagInfo.offset) {
257 sprintf(line,
" <TagSignature>%s</TagSignature>\n",
icFixXml(fix,
icGetSigStr(buf, j->TagInfo.sig)));
259 sigSet.insert(j->TagInfo.sig);
264 if (!pTagXml->
ToXml(xml, blanks +
" ")) {
265 printf(
"Unable to output tag with type %s\n",
icGetSigStr(buf, i->TagInfo.sig));
268 sprintf(line,
" </%s> </%s>\n\n", tagSig, tagName);
269 xml += blanks + line;
270 offsetTags[i->TagInfo.offset] = i->TagInfo.sig;
274 char nameBuf[200], fix2[200];
275 if (!prevTagName || !strncmp(prevTagName,
"Unknown ", 8)) {
276 strcpy(nameBuf,
"PrivateTag");
277 prevTagName = nameBuf;
280 if (tagName && strncmp(tagName,
"Unknown ", 8))
281 sprintf(line,
" <%s SameAs=\"%s\"",
icFixXml(fix, tagName),
icFixXml(fix2, prevTagName));
283 sprintf(line,
" <PrivateTag TagSignature=\"%s\" SameAs=\"%s\"",
icFixXml(fix2,
icGetSigStr(buf, i->TagInfo.sig)),
icFixXml(fix, prevTagName));
285 xml += blanks + line;
286 if (prevTagName == nameBuf) {
287 sprintf(line,
" SameAsSignature=\"%s\"",
icFixXml(fix2,
icGetSigStr(buf, prevTag->second)));
288 xml += blanks + line;
295 printf(
"Non XML tag in list with tag %s!\n",
icGetSigStr(buf, i->TagInfo.sig));
300 printf(
"Unable to find tag with tag %s!\n",
icGetSigStr(buf, i->TagInfo.sig));
305 xml += blanks +
" </Tags>\n";
306 xml += blanks +
"</IccProfile>\n";
314 int val = atoi(szVer);
315 rv = ((val / 10) % 10) * 16 + (val % 10);
336 memset(&m_Header, 0,
sizeof(m_Header));
338 for (pNode=pNode->children; pNode; pNode=pNode->next) {
339 if (pNode->type==XML_ELEMENT_NODE) {
340 if (!
icXmlStrCmp((
const char*)pNode->name,
"ProfileVersion")) {
341 const char *szVer = (
const char*)pNode->children->content;
343 unsigned long verMajor=0, verMinor=0, verClassMajor=0, verClassMinor=0;
345 for (; *szVer && *szVer !=
'.' && *szVer !=
','; szVer++) {
354 for (; *szVer && *szVer !=
'.' && *szVer !=
','; szVer++) {
363 for (; *szVer && *szVer !=
'.' && *szVer !=
','; szVer++) {
372 for (; *szVer && *szVer !=
'.' && *szVer !=
','; szVer++) {
381 m_Header.version = (verMajor << 24) | (verMinor << 16) | (verClassMajor << 8) | verClassMinor;
383 else if (!
icXmlStrCmp((
const char*)pNode->name,
"ProfileSubClassVersion")) {
384 const char *szVer = (
const char*)pNode->children->content;
386 unsigned long verClassMajor = 0, verClassMinor = 0;
388 for (; *szVer && *szVer !=
'.' && *szVer !=
','; szVer++) {
391 verClassMajor = (
unsigned char)atoi(ver.c_str());
395 for (; *szVer && *szVer !=
'.' && *szVer !=
','; szVer++) {
398 verClassMinor = (
unsigned char)atoi(ver.c_str());
401 m_Header.version = (m_Header.version & 0xffff0000) | (((verClassMajor << 8) | verClassMinor) & 0x0000ffff);
403 else if (!
icXmlStrCmp(pNode->name,
"PreferredCMMType")) {
406 else if (!
icXmlStrCmp(pNode->name,
"ProfileDeviceClass")) {
409 else if (!
icXmlStrCmp(pNode->name,
"ProfileDeviceSubClass")) {
412 else if (!
icXmlStrCmp(pNode->name,
"DataColourSpace")) {
418 else if (!
icXmlStrCmp(pNode->name,
"CreationDateTime")) {
419 if (pNode && pNode->children && pNode->children->content) {
420 const char *datetime = (
const char*)pNode->children->content;
424 memset(&m_Header.date, 0,
sizeof(m_Header.date));
426 else if (!
icXmlStrCmp(pNode->name,
"PrimaryPlatform")) {
429 else if (!
icXmlStrCmp(pNode->name,
"ProfileFlags")) {
455 m_Header.flags |= vendor;
458 else if (!
icXmlStrCmp(pNode->name,
"DeviceManufacturer")) {
461 else if (!
icXmlStrCmp(pNode->name,
"DeviceModel")) {
464 else if (!
icXmlStrCmp(pNode->name,
"DeviceAttributes")) {
467 else if (!
icXmlStrCmp(pNode->name,
"RenderingIntent")) {
468 if (!strcmp((
const char*)pNode->children->content,
"Perceptual"))
470 else if (!strcmp((
const char*)pNode->children->content,
"Relative Colorimetric") || !strcmp((
const char*)pNode->children->content,
"Relative"))
472 else if (!strcmp((
const char*)pNode->children->content,
"Saturation"))
474 else if (!strcmp((
const char*)pNode->children->content,
"Absolute Colorimetric") || !strcmp((
const char*)pNode->children->content,
"Absolute"))
478 else if (!
icXmlStrCmp(pNode->name,
"PCSIlluminant")) {
479 xmlNode *xyzNode =
icXmlFindNode(pNode->children,
"XYZNumber");
491 else if (!
icXmlStrCmp(pNode->name,
"ProfileCreator")) {
495 if (pNode->children && pNode->children->content)
496 icXmlGetHexData(&m_Header.profileID.ID8, (
const char*)pNode->children->content,
sizeof(m_Header.profileID.ID8));
498 memset(&m_Header.profileID.ID8, 0,
sizeof(m_Header.profileID.ID8));
500 else if (!
icXmlStrCmp(pNode->name,
"SpectralPCS")) {
503 else if (!
icXmlStrCmp(pNode->name,
"SpectralRange")) {
504 xmlNode *xyzNode =
icXmlFindNode(pNode->children,
"Wavelengths");
510 if (start && end && steps) {
516 else if (!
icXmlStrCmp(pNode->name,
"BiSpectralRange")) {
517 xmlNode *xyzNode =
icXmlFindNode(pNode->children,
"Wavelengths");
523 if (start && end && steps) {
532 else if (!
icXmlStrCmp(pNode->name,
"ProfileDeviceSubClass")) {
536 if (pNode->children && pNode->content)
537 icXmlGetHexData(&m_Header.reserved, (
const char*)pNode->children->content,
sizeof(m_Header.reserved));
539 memset(&m_Header.reserved, 0,
sizeof(m_Header.reserved));
542 parseStr +=
"Unknown Profile Header attribute: ";
543 parseStr += (
const char*)pNode->name;
545 if (pNode->children && pNode->children->content)
546 parseStr += (
const char*)pNode->children->content;
578 if (pNode->type != XML_ELEMENT_NODE) {
579 parseStr +=
"Invalid Tag Node: ";
580 parseStr += (
const char *)pNode->name;
587 std::string nodeName = (
icChar*)pNode->name;
591 if (nodeName ==
"PrivateTag") {
597 parseStr +=
"Invalid TagSignature for PrivateTag\n";
606 if (!strcmp(sameAs,
"PrivateTag") || sigParentTag ==
icSigUnknownTag) {
607 const char *sameAsSig =
icXmlAttrValue(pNode,
"SameAsSignature",
"");
612 parseStr +=
"Invalid SameAsSignature for PrivateTag\n";
616 pTag = this->FindTag(sigParentTag);
618 AttachTag(sigTag, pTag);
621 parseStr +=
"SameAs tag ";
624 parseStr += nodeName +
" does not exist\n";
632 for (pTypeNode = pNode->children; pTypeNode; pTypeNode = pTypeNode->next) {
633 if (pTypeNode->type == XML_ELEMENT_NODE) {
639 parseStr +=
"No tag type node defined for ";
640 parseStr += nodeName;
663 if (pXmlTag->
ParseXml(pTypeNode->children, parseStr)) {
667 AttachTag(sigTag, pTag);
671 parseStr +=
"Unable to Parse \"";
672 parseStr += (
const char*)pTypeNode->name;
674 parseStr += nodeName;
675 sprintf(str,
") Tag on line %d\n", pTypeNode->line);
682 parseStr +=
"Invalid tag extension for \"";
683 parseStr += (
const char*)pTypeNode->name;
685 sprintf(str,
") Tag on line %d\n", pTypeNode->line);
711 if (pXmlTag->
ParseXml(pNode->children, parseStr)) {
716 for (xmlNode *tagSigNode = pNode->children; tagSigNode; tagSigNode = tagSigNode->next) {
717 if (tagSigNode->type == XML_ELEMENT_NODE && !
icXmlStrCmp(tagSigNode->name,
"TagSignature")) {
719 AttachTag(sigTag, pTag);
725 parseStr +=
"Unable to Parse \"";
728 parseStr += nodeName;
729 sprintf(str,
") Tag on line %d\n", pNode->line);
736 parseStr +=
"Invalid tag extension for \"";
739 parseStr += nodeName;
740 sprintf(str,
") Tag on line %d\n", pNode->line);
752 ((
CIccMBB*)pTag)->SetColorSpaces(m_Header.colorSpace, m_Header.pcs);
760 ((
CIccMBB*)pTag)->SetColorSpaces(m_Header.pcs, m_Header.colorSpace);
768 ((
CIccMBB*)pTag)->SetColorSpaces(m_Header.pcs, m_Header.pcs);
786 m_Header.spectralPCS,
787 &m_Header.spectralRange,
788 &m_Header.biSpectralRange);
810 if (!hdrNode || !
ParseBasic(hdrNode, parseStr))
818 for (tagNode = tagNode->children; tagNode; tagNode = tagNode->next) {
819 if (tagNode->type == XML_ELEMENT_NODE) {
832 xmlNode *root_element = NULL;
835 doc = xmlReadFile(szFilename, NULL, 0);
840 if (szRelaxNGDir && szRelaxNGDir[0]) {
841 xmlRelaxNGParserCtxt* rlxParser;
843 rlxParser = xmlRelaxNGNewParserCtxt (szRelaxNGDir);
847 xmlRelaxNG* relaxNG = xmlRelaxNGParse(rlxParser);
849 xmlRelaxNGValidCtxt* validCtxt = xmlRelaxNGNewValidCtxt(relaxNG);
851 int result = xmlRelaxNGValidateDoc(validCtxt, doc);
853 printf(
"\nError: %d: '%s' is an invalid XML file.\n", result, szFilename);
867 std::string my_parseStr;
870 parseStr = &my_parseStr;
875 root_element = xmlDocGetRootElement(doc);
877 bool rv =
ParseXml(root_element, *parseStr);
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
static unsigned char parseVersion(const char *szVer)
std::map< icUInt32Number, icTagSignature > IccOffsetTagSigMap
IIccArray * icGetTagArrayHandler(CIccTag *pTag)
icFloatNumber icFtoD(icS15Fixed16Number num)
const icChar * icGetColorSigStr(icChar *pBuf, icUInt32Number nSig)
icFloat16Number icFtoF16(icFloat32Number num)
icS15Fixed16Number icDtoF(icFloatNumber num)
icUInt32Number icGetSigVal(const icChar *pBuf)
icFloatNumber icF16toF(icFloat16Number num)
const icChar * icGetSigStr(icChar *pBuf, icUInt32Number nSig)
const std::string icGetDeviceAttrName(icUInt64Number devAttr)
icDateTimeNumber icGetDateTimeValue(const icChar *str)
xmlAttr * icXmlFindAttr(xmlNode *pNode, const char *szAttrName)
xmlNode * icXmlFindNode(xmlNode *pNode, const char *szNodeName)
icUInt32Number icXmlGetHexData(void *pBuf, const char *szText, icUInt32Number nBufSize)
icTagTypeSignature icGetTypeNameTagSig(const icChar *szTagType)
icUInt32Number icXmlGetChildSigVal(xmlNode *pNode)
const icChar * icGetTagSigTypeName(icTagTypeSignature tagTypeSig)
icTagSignature icGetTagNameSig(const icChar *szName)
icUInt64Number icGetDeviceAttrValue(xmlNode *pNode)
const std::string icGetHeaderFlagsName(icUInt32Number flags, bool bUsesMCS)
const char * icFixXml(std::string &buf, const char *szStr)
const char * icXmlAttrValue(xmlAttr *attr, const char *szDefault)
#define icXmlStrCmp(x, y)
unsigned int icUInt32Number
Class: CIccArrayNamedColor.
void SetColorSpaces(icColorSpaceSignature csPcs, icColorSpaceSignature csDevice, icSpectralColorSignature csSpectralPCS=icSigNoSpectralData, const icSpectralRange *pSpectralRange=NULL, const icSpectralRange *pBiSPectralRange=NULL)
const icChar * GetVersionName(icUInt32Number val)
const icChar * GetTagSigName(icTagSignature sig)
const icChar * GetTagTypeSigName(icTagTypeSignature sig)
const icChar * GetSubClassVersionName(icUInt32Number val)
const icChar * GetRenderingIntentName(icRenderingIntent val, bool bIsV5=false)
bool LoadXml(const char *szFilename, const char *szRelaxNGDir, std::string *parseStr=NULL)
bool ToXmlWithBlanks(std::string &xmlString, std::string blanks)
bool ParseTag(xmlNode *pNode, std::string &parseStr)
Name: CIccProfileXml::ParseTag.
bool ParseBasic(xmlNode *pNode, std::string &parseStr)
Name: CIccProfileXml::ParseBasic.
bool ToXml(std::string &xmlString)
bool ParseXml(xmlNode *pNode, std::string &parseStr)
virtual icTagTypeSignature GetType() const
Function: GetType()
icUInt32Number m_nReserved
static CIccTag * Create(icTagTypeSignature sig)
Name: CIccTag::Create.
virtual IIccExtensionTag * GetExtension()
virtual icArraySignature GetTagArrayType() const
Class: CIccTagNamedColor2.
virtual bool ToXml(std::string &xml, std::string blanks="")=0
virtual bool ParseXml(xmlNode *pNode, std::string &parseStr)=0
virtual const char * GetExtClassName() const =0