Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The cmsCreateTransform may modify the profile in some way #273

Closed
mrserb opened this issue Aug 19, 2021 · 2 comments
Closed

The cmsCreateTransform may modify the profile in some way #273

mrserb opened this issue Aug 19, 2021 · 2 comments

Comments

@mrserb
Copy link
Contributor

mrserb commented Aug 19, 2021

I have found this issue while working on lcms support in the OpenJDK. Some profiles cannot be saved to the memory if they were used by the cmsCreateTransform(). Tested on LittleCMS 2.12.

For example this profile:
https://github.com/openjdk/jdk/blob/master/src/java.desktop/share/classes/sun/java2d/cmm/profiles/PYCC.pf

The test code:

#include "lcms2.h"
#include <stdlib.h>

void LogErrorHandler(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text){
    fprintf(stderr, "%s\n", Text);
}

void check(cmsHPROFILE hProfile) {
    cmsUInt32Number pfSize = 0;
    cmsHPROFILE pfSanity = NULL;
    if (cmsSaveProfileToMem(hProfile, NULL, &pfSize)) {
        void* buf = malloc((pfSize));
        if (buf != NULL) {
            if (cmsSaveProfileToMem(hProfile, buf, &pfSize)) {
                pfSanity = cmsOpenProfileFromMem(buf, pfSize);
                cmsCloseProfile(pfSanity);
                fprintf(stderr, "This step passed\n");
            }
            free(buf);
        }
    }
}

int main(void) {
    cmsSetLogErrorHandler(LogErrorHandler);
    cmsHPROFILE hInProfile = cmsOpenProfileFromFile("/.../.../PYCC.pf", "r");
    cmsHPROFILE hOutProfile = cmsCreate_sRGBProfile();

    //// Comment the block below to solve the error
    cmsHTRANSFORM hTransform = cmsCreateTransform(hInProfile, PT_ANY,
                                                  hOutProfile, PT_ANY,
                                                  0, 0);
    cmsDeleteTransform(hTransform);
    //// Comment the block above to solve the error

    check(hInProfile);
    check(hOutProfile);
    cmsCloseProfile(hInProfile);
    cmsCloseProfile(hOutProfile);

    return 0;
}

The code above will print:

LUT is not suitable to be saved as LutAToB
Couldn't write type 'mAB '

But if the block of code is commented(or just remove the cmsCreateTransform and cmsDeleteTransform) out in the example, then cmsSaveProfileToMem/cmsOpenProfileFromMem will work fine.

@mm2
Copy link
Owner

mm2 commented Aug 27, 2021

Hi,
Back from holidays, I apologize for the delay.

After investigation, I found the profile PYCC.pf is broken. It uses for Tag AToB0, which is of type LutAToBType, the following sequence:

A ->CLUT->M->Matrix

This is not allowed in the ICC spec, https://www.color.org/specification/ICC1v43_2010-12.pdf
See "10.10.1 lutAToBType, general". The closest allowed configuration does include a "B" step which this profile is missing. Also I tried using the profile inspector tool from ICC. It complains on this tag as well.

To explain this weird behaviour, lcms is relaxed when reading files and strict when writing them. It accepts the profile for read but it cannot write it. Why sometimes you can save it? If you just save the profile after opening it, lcms does not decode the tags but just does a blind memory copy. This is required to make things go fast when embedding profiles. If you use the profile, then parsing happens and the tag cannot be saved anymore.

I agree this is very confusing and should be fixed somehow. I will try to allow saving this profile by using an indentity for B matrix.

@mm2
Copy link
Owner

mm2 commented Jan 7, 2022

I was going to make lcms to refuse this profile, as it is wrong, but after thinking on that I guess it is better to keep accepting it as a matter of compatibility. The actual behavior is correct, opening such a broken profile is a plus. Allowing to save it would be an error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants