> > 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/lcms-user