Pillow icon indicating copy to clipboard operation
Pillow copied to clipboard

Image CMS modes

Open Yay295 opened this issue 1 year ago • 5 comments

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.

https://github.com/python-pillow/Pillow/blob/e63ae380f1fae30dc8e078f6d588949387e45cbe/src/_imagingcms.c#L214-L244

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.

Yay295 avatar Apr 23 '24 19:04 Yay295

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?

radarhere avatar Apr 24 '24 00:04 radarhere

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.

Yay295 avatar Apr 24 '24 01:04 Yay295

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)

radarhere avatar Apr 25 '24 02:04 radarhere

Would updating the documentation be sufficient to resolve this?

radarhere avatar Apr 28 '24 03:04 radarhere

I've created https://github.com/python-pillow/Pillow/pull/8031 to resolve this by deprecating the unexpected modes, and adding replacements for some.

radarhere avatar Apr 29 '24 12:04 radarhere

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

hugovk avatar Jun 28 '24 06:06 hugovk

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.

Yay295 avatar Jun 28 '24 07:06 Yay295