> > Hi everyone, > > I am trying to find a generic approach for reading the 'lumi' tag > > accurately, using Little CMS 2.7. I use ICC profiles that are > > generated with XRite i1 display pro, and it seems that the X & Z > > values of the CIEXYZ 'lumi' value are not 0 (making the profile > > wrong according to the ICC spec). > > I am under the impression that little CMS applies a kind of > > correction whenever this kind of 'lumi' tag is detected (diving X, > > Y, and Z by 100.0 ? ). > > > Hello Vicent, > > LittleCMS does nothing with the contents of luminance tag. It just > returns the XYZ contained it it. Make sure to use the right type, which > is cmsCIEXYZ. Otherwise yes, you can mix read raw with read cooked, but > what you say closing and reopening the handle gives you different > values is very suspicious. Could you show us the portion of code that > reads that tag? Thanks. Oh, also make sure to try the latest code from > GIT, there are some fixes that may be relevant. > > Regards > Marti >
Hi Marti, The "correction" that I mentioned would be the NormalizeXYZ function that is used in _cmsReadXYZNumber: [...] XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X)); XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y)); XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z)); NormalizeXYZ(XYZ); [...] I think that this may be the reason why the luminance of my profile is not read correctly. So I tried to bypass this and observed the behavior I described. Sample code: /* Open profile handle */ cmsHPROFILE hProfile = cmsOpenProfileFromFile("testProfile.icc", "r"); /* Read luminance in a "classic" way */ cmsCIEXYZ *lumi = (cmsCIEXYZ*)cmsReadTag(hProfile, cmsSigLuminanceTag); cout << lumi->X << lumi->Y << lumi->Z << endl; /* Read luminance from raw data */ cmsS15Fixed16Number buffer_s15f16[20]; cmsReadRawTag(hProfile, cmsSigLuminanceTag, buffer_s15f16, 20); lumi->X = cms15Fixed16toDouble(cmsAdjustEndianess32(buffer_s15f16[2])); lumi->Y = cms15Fixed16toDouble(cmsAdjustEndianess32(buffer_s15f16[3])); lumi->Z = cms15Fixed16toDouble(cmsAdjustEndianess32(buffer_s15f16[4])); cout << lumi->X << lumi->Y << lumi->Z << endl; This produces the following output: 0.527483 0.571429 0.697399 0.527481 0.571426 0.697403 However, that is not the case with the following code (that is practically the same except for closing/reopening the profile between the two calls): /* Open profile handle */ cmsHPROFILE hProfile = cmsOpenProfileFromFile("testProfile.icc", "r"); /* Read luminance in a "classic" way */ cmsCIEXYZ *lumi = (cmsCIEXYZ*)cmsReadTag(hProfile, cmsSigLuminanceTag); cout << lumi->X << lumi->Y << lumi->Z << endl; /* Close then reopen */ cmsCloseProfile(hProfile); hProfile = cmsOpenProfileFromFile("testProfile.icc", "r"); /* Read luminance from raw data */ cmsS15Fixed16Number buffer_s15f16[20]; cmsReadRawTag(hProfile, cmsSigLuminanceTag, buffer_s15f16, 20); lumi->X = cms15Fixed16toDouble(cmsAdjustEndianess32(buffer_s15f16[2])); lumi->Y = cms15Fixed16toDouble(cmsAdjustEndianess32(buffer_s15f16[3])); lumi->Z = cms15Fixed16toDouble(cmsAdjustEndianess32(buffer_s15f16[4])); cout << lumi->X << lumi->Y << lumi->Z << endl; This version produces this output:0.527483 0.571429 0.697399 527.483 571.429 697.399 I can make my code work fine by using only the version that reads the tag from raw data, but I could not, for example, make an algorithm that goes: 1) Open profile 2) Read Luminance in a "classic" way3) Sanity check of the obtained values4) If the value is not correct, read luminance from raw data Without having a close/reopen step in between. I will definitely give a try to the code on GIT, thanks ! Best regards, Vincent
------------------------------------------------------------------------------
_______________________________________________ Lcms-user mailing list Lcms-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lcms-user