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

Reply via email to