Monday, July 27, 2009

Less is more

If you have devoted some time to review the new API, maybe you have discovered an odd thing: there are some functions missing. Ok, you can blame me for remove *that* function doing exactly what you need. Of course that may be my mistake. But please consider perhaps I have good reasons to do that.

Let's take one example:

cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile);

This function no longer exists in lcms 2.0 API.

Well, many people were using this function to retrieve primaries of a profile. So, for example, if you want to know which are the AdobeRGB primaries, just call the function with the right profile and here you go.

Seems easy, and useful, but trust me, it is not. The real reason d'ĂȘtre of this function is somehow surprising. Not because it is handy but because is precise. Please consider this piece of pseudo-code:

cmsXYZTRIPLE Result;
hXYZ = cmsCreateXYZProfile()
xform = cmsCreateTransform(hProfile, TYPE_RGB_DBL, hXYZ, TYPE_XYZ_DBL, INTENT_RELATIVE_COLRIMETRIC, 0)
cmsDoTransform(xform, {{ 1, 0, 0}, {0, 1, 0}, {0,0,1}}, &Result, 3)

Do you follow it? I create a transform from the profile (in RGB) to XYZ. Then I convert max of R, and B to XYZ. I am obtaining the primaries! Despite it seems more complex, this method is much better because is guaranteed to work in *any* profile, not only on matrix-shaper ones.

So, what is the point of having the old function? Easy: lcms 1.x was precission-limited to 16 bits, so you cannot obtain primaries with enough precision with the method described above. But that does not apply with lcms2, where you have an outstanding 64-bit double precission. Less is more in this particular case!

No comments:

Post a Comment