Skip to content

Image CMS modes #8007

Description

@Yay295

When the C code checks the given input and output modes it checks against this list: RGB, RGBA, RGBX, RGBA;16B, CMYK, L, L;16, L;16B, YCCA, YCC, and LAB.

Pillow/src/_imagingcms.c

Lines 214 to 244 in e63ae38

static cmsUInt32Number
findLCMStype(char *PILmode) {
if (strcmp(PILmode, "RGB") == 0) {
return TYPE_RGBA_8;
} else if (strcmp(PILmode, "RGBA") == 0) {
return TYPE_RGBA_8;
} else if (strcmp(PILmode, "RGBX") == 0) {
return TYPE_RGBA_8;
} else if (strcmp(PILmode, "RGBA;16B") == 0) {
return TYPE_RGBA_16;
} else if (strcmp(PILmode, "CMYK") == 0) {
return TYPE_CMYK_8;
} else if (strcmp(PILmode, "L") == 0) {
return TYPE_GRAY_8;
} else if (strcmp(PILmode, "L;16") == 0) {
return TYPE_GRAY_16;
} else if (strcmp(PILmode, "L;16B") == 0) {
return TYPE_GRAY_16_SE;
} else if (strcmp(PILmode, "YCCA") == 0) {
return TYPE_YCbCr_8;
} else if (strcmp(PILmode, "YCC") == 0) {
return TYPE_YCbCr_8;
} else if (strcmp(PILmode, "LAB") == 0) {
// LabX equivalent like ALab, but not reversed -- no #define in lcms2
return (COLORSPACE_SH(PT_LabV2) | CHANNELS_SH(3) | BYTES_SH(1) | EXTRA_SH(1));
}
else {
/* take a wild guess... */
return TYPE_GRAY_8;
}
}

However, only RGB, RGBA, RGBX, CMYK, L, and LAB are actual imaging modes. RGBA;16B, L;16, and L;16B are rawmodes, YCCA partially exists as a rawmode named YCCA;P, and YCC is a mode but is named YCbCr. That last one is easy enough to fix by just using the correct name, but it doesn't seem like it's possible to use the other four.

Activity

  1. radarhere commented on Apr 24, 2024

    @radarhere
    Member

    it doesn't seem like it's possible to use the other four.

    The following code will reach one of those lines.

    from PIL import ImageCms
    source_profile = ImageCms.createProfile("sRGB")
    destination_profile = ImageCms.createProfile("sRGB")
    ImageCms.buildTransform(source_profile, destination_profile, "RGB", "YCC")

    But it will raise an error afterwards.

    I'm guessing you meant reach those lines without error?

  2. Yay295 commented on Apr 24, 2024

    @Yay295
    ContributorAuthor

    You can't use the ImageCmsTransform that creates because YCC isn't a valid image mode, so you can't create an image with that mode to apply the transform to.

  3. radarhere commented on Apr 25, 2024

    @radarhere
    Member

    From a documentation perspective, https://pillow.readthedocs.io/en/stable/reference/ImageCms.html#PIL.ImageCms.buildTransform describes inMode and outMode as

    String, as a valid PIL mode that the appropriate profile also supports (i.e. “RGB”, “RGBA”, “CMYK”, etc.)

    Those are the modes that are passed to findLCMStype(), so I think there's an argument that these options are undocumented, and that YCCA shouldn't be renamed to YCCA;P.

    However, from a practical perspective, the following code runs without an error.

    from PIL import Image, ImageCms
    for inMode in ("L;16", "L;16B"):
        source_profile = ImageCms.getOpenProfile("/Users/andrewmurray/pillow/Pillow/Tests/icc/sGrey-v2-nano.icc")
        destination_profile = ImageCms.createProfile("sRGB")
        transform = ImageCms.buildTransform(source_profile, destination_profile, inMode, "RGB")
    
        im = Image.new("RGB", (1, 1))
        ImageCms.applyTransform(im, transform)
    
    source_profile = ImageCms.getOpenProfile("/Users/andrewmurray/pillow/Pillow/Tests/icc/sRGB_v4_ICC_preference.icc")
    destination_profile = ImageCms.createProfile("sRGB")
    transform = ImageCms.buildTransform(source_profile, destination_profile, "RGBA;16B", "RGB")
    
    im = Image.new("RGB", (1, 1))
    ImageCms.applyTransform(im, transform)
  4. radarhere commented on Apr 28, 2024

    @radarhere
    Member

    Would updating the documentation be sufficient to resolve this?

  5. radarhere commented on Apr 29, 2024

    @radarhere
    Member

    I've created #8031 to resolve this by deprecating the unexpected modes, and adding replacements for some.

  6. hugovk commented on Jun 28, 2024

    @hugovk
    Member

    @Yay295 What do you think about documentation vs. deprecation?

  7. Yay295 commented on Jun 28, 2024

    @Yay295
    ContributorAuthor

    I think deprecation is probably the better option. Though if someone files an issue saying they're actually using it for something it could be un-deprecated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions