mm2 / Little-CMS

A free, open source, CMM engine. It provides fast transforms between ICC profiles.
https://www.littlecms.com
MIT License
571 stars 176 forks source link

Different results depending on endianess #395

Closed sommerluk closed 1 year ago

sommerluk commented 1 year ago

Setup

Consider the following code:

    cmsHPROFILE rgbProfileHandle = cmsCreate_sRGBProfile();
    cmsHPROFILE cielabD50ProfileHandle = cmsCreateLab4Profile(nullptr); // nullptr means: Default white point (D50)
    auto m_transformRgbToCielabD50Handle = cmsCreateTransform(
        rgbProfileHandle, // input profile handle
        TYPE_RGB_DBL, // input buffer format
        cielabD50ProfileHandle, // output profile handle
        TYPE_Lab_DBL, // output buffer format
        INTENT_ABSOLUTE_COLORIMETRIC,
        cmsFLAGS_NOCACHE);
    cmsCloseProfile(cielabD50ProfileHandle);
    cmsCloseProfile(rgbProfileHandle);

    cmsFloat64Number rgb[3] = {red, green, blue};
    cmsCIELab cielabD50;
    cmsDoTransform(m_transformRgbToCielabD50Handle, // handle to transform
                   &rgb, // input
                   &cielabD50, // output
                   1 // convert exactly 1 value
    );

Using LCMS 2.12.0 on Ubuntu Linux 22.04 LTS.

Actual result

For red, green and blue = 0, depending if you are on a big endian or a little endian machine, the value of cielabD50 lightness is different:

Expected results

Additional information

For red, green and blue = 0,001, this results in cielabD50 6.991457e-02 7.569790e-06 7.569790e-06 on both, little endian and big endian machines. Also, for all other higher values, the result on little endian and big endian seem to give identical results.

mm2 commented 1 year ago

Hi. Thanks for reporting, unfortunately I have no way to access a big endian machine anymore. Have you tried with 2.15? Could you run the testbed on the big endian machine? i.e "make check" Does it pass the tests? Thanks!

sommerluk commented 1 year ago

Well, I have no direct access to a bigendian machine either. I use Docker + qemu to emulate one within the CI. This can be done also for LittleCMS: https://github.com/sommerluk/Little-CMS/blob/1ee56666795bf695c2e1b24c4a034343bfde0b44/.circleci/config.yml

Result for current lcms master: log.txt

mm2 commented 1 year ago

Finally I have been able to check the testbed on an very old PowerPC that is true big endian. There is no issue there. Maybe is something on the emulation? Keep in mind a very small negative number on L* can happen on profiles where the zero is calculated. Floating point zero is quite difficult to obtain when it comes from a complex calculation, and we are talking about 0.00000000000000022

sommerluk commented 1 year ago

Indeed, the difference is very small. I only noticed it because I had a failing unit test that checked that the results of a function that relies on LittleCMS are within the given range.

Should we close this report as non-issue?

mm2 commented 1 year ago

Should we close this report as non-issue?

Sure. Closed as I cannot reproduce it anyway.