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 Lcms-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lcms-user