The cmsReadRawTag returns different data for the same tag, depending on whether
this tag was converted in internal representation, or not. Following
scenario makes the
problem visible:
a) open profile:
all tags are in raw representation at the moment.
b) read a tag (grayTRC in this test) as raw data:
returned data has length 14 and contain all required parts of a
tag's data:
type signature, reserved dword, and curve data.
c) read the tag using cmsReadTag in order to force a conversion of the tag
into an internal representation.
d) read raw data of the tag again:
Note that now reported data size is 8 bytes shorter and the data does not
contain the type signature and the reserved dword. It happens because
in case of 'cooked' tag, raw data is obtained as a result of
serialization of
an internal structure, and at this codepath tag signature is missed.
Note that the step c) can be done implicitly by, for example, a
transform creation.
Attached test demonstrates the difference in the length of raw tag data.
This problem is present in latest version of sources, available via git.
A suggested fix is to explicitly add a tag signature and reserved dword
to tag raw tag data, in order to comply the ICC spec:
diff --git a/src/cmsio0.c b/src/cmsio0.c
old mode 100644
new mode 100755
index 770e986..c05e5b7
--- a/src/cmsio0.c
+++ b/src/cmsio0.c
@@ -1656,6 +1656,18 @@ cmsInt32Number CMSEXPORT
cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig
// Serialize
TypeHandler ->ContextID = Icc ->ContextID;
TypeHandler ->ICCVersion = Icc ->Version;
+
+ // write type signature
+ if (!_cmsWriteUInt32Number(MemIO, TypeHandler->Signature)) {
+ cmsCloseIOhandler(MemIO);
+ return 0;
+ }
+ // write reserved field
+ if (!_cmsWriteUInt32Number(MemIO, 0)) {
+ cmsCloseIOhandler(MemIO);
+ return 0;
+ }
+
if (!TypeHandler ->WritePtr(TypeHandler, MemIO, Object,
TagDescriptor ->ElemCount)) {
cmsCloseIOhandler(MemIO);
return 0;
Thanks,
Andrew
#include "stdafx.h"
#include <lcms2.h>
void errorHandler(cmsContext contextID, cmsUInt32Number errorCode, const char *errorText) {
printf("Error %d, %s\n", errorCode, errorText);
}
int _tmain(int argc, _TCHAR* argv[])
{
cmsSetLogErrorHandler(errorHandler);
cmsHPROFILE pf = cmsOpenProfileFromFile("test.pf", "r");
if (pf != NULL) {
cmsTagSignature theTag = cmsSigGrayTRCTag;
cmsUInt32Number origSize = 0;
cmsUInt32Number cookedSize = 0;
// dump available tags
cmsUInt32Number numTags = cmsGetTagCount(pf);
for (cmsUInt32Number i = 0; i < numTags; i++) {
cmsTagSignature sig = cmsGetTagSignature(pf, i);
printf("Tag %d: %X: %C%C%C%C\n", i, sig,
char(0xff & (sig >> 24)),
char(0xff & (sig >> 16)),
char(0xff & (sig >> 8)),
char(0xff & (sig )));
}
origSize = cmsReadRawTag(pf, theTag, NULL, 0);
printf("Tag data size: %d\n", origSize);
void* cookedTag = cmsReadTag(pf, theTag);
if (cookedTag != NULL) {
cookedSize = cmsReadRawTag(pf, theTag, NULL, 0);
printf("Tag data size after cooking : %d\n", cookedSize);
if (cookedSize != origSize) {
printf("cooked size is wrong.\n");
}
} else {
printf("Unable to cook the tag");
}
cmsCloseProfile(pf);
}
return 0;
}
------------------------------------------------------------------------------
Simplify data backup and recovery for your virtual environment with vRanger.
Installation's a snap, and flexible recovery options mean your data is safe,
secure and there when you need it. Discover what all the cheering's about.
Get your free trial download today.
http://p.sf.net/sfu/quest-dev2dev2
_______________________________________________
Lcms-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/lcms-user