From f9a3178bb34e6b28bc46d42ef88f5069ebabde32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20S=2E=20O=2E=20Bueno?= Date: Sun, 9 Oct 2022 11:47:24 -0300 Subject: [PATCH 1/3] Fix #6652: Handle translucent color used in RGB ImagePallete --- Tests/test_imagepalette.py | 9 +++++++++ src/PIL/ImagePalette.py | 8 ++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Tests/test_imagepalette.py b/Tests/test_imagepalette.py index 475d249ed09..0583154f732 100644 --- a/Tests/test_imagepalette.py +++ b/Tests/test_imagepalette.py @@ -50,6 +50,15 @@ def test_getcolor(): palette.getcolor("unknown") +def test_getcolor_raises_on_incompatible_color(): + palette = ImagePalette.ImagePalette(mode="RGB") + # Opaque RGBA colors should work + palette.getcolor((0, 0, 0, 255)) + assert palette.getcolor((0, 0, 0)) == palette.getcolor((0, 0, 0, 255)) + with pytest.raises(ValueError): + palette.getcolor((0, 0, 0, 128)) + + @pytest.mark.parametrize( "index, palette", [ diff --git a/src/PIL/ImagePalette.py b/src/PIL/ImagePalette.py index b73b2cd9dd0..e407bbcd17a 100644 --- a/src/PIL/ImagePalette.py +++ b/src/PIL/ImagePalette.py @@ -114,9 +114,13 @@ def getcolor(self, color, image=None): if self.rawmode: raise ValueError("palette contains raw palette data") if isinstance(color, tuple): - if self.mode == "RGB": - if len(color) == 4 and color[3] == 255: + if self.mode == "RGB" and len(color) == 4: + if color[3] == 255: color = color[:3] + else: + raise ValueError( + "RGB ImagePalette can't handle non-opaque RGBA colors" + ) elif self.mode == "RGBA": if len(color) == 3: color += (255,) From 982d7c49e318339444fb53d29ac04d19f4a68691 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 10 Oct 2022 11:46:33 +1100 Subject: [PATCH 2/3] Corrected test --- Tests/test_image_access.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Tests/test_image_access.py b/Tests/test_image_access.py index bb09a77088a..a000cb64c70 100644 --- a/Tests/test_image_access.py +++ b/Tests/test_image_access.py @@ -345,13 +345,14 @@ def test_reference_counting(self): @pytest.mark.parametrize("mode", ("P", "PA")) def test_p_putpixel_rgb_rgba(self, mode): - for color in [(255, 0, 0), (255, 0, 0, 127)]: + for color in ((255, 0, 0), (255, 0, 0, 127 if mode == "PA" else 255)): im = Image.new(mode, (1, 1)) access = PyAccess.new(im, False) access.putpixel((0, 0), color) - alpha = color[3] if len(color) == 4 and mode == "PA" else 255 - assert im.convert("RGBA").getpixel((0, 0)) == (255, 0, 0, alpha) + if len(color) == 3: + color += (255,) + assert im.convert("RGBA").getpixel((0, 0)) == color class TestImagePutPixelError(AccessTest): From 0b2cef5b03fed477f6988ee60ef5d4b7a6084a38 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 10 Oct 2022 12:02:10 +1100 Subject: [PATCH 3/3] Updated error message --- Tests/test_imagepalette.py | 11 ++++++----- src/PIL/ImagePalette.py | 12 ++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Tests/test_imagepalette.py b/Tests/test_imagepalette.py index 0583154f732..5bda2811717 100644 --- a/Tests/test_imagepalette.py +++ b/Tests/test_imagepalette.py @@ -50,11 +50,12 @@ def test_getcolor(): palette.getcolor("unknown") -def test_getcolor_raises_on_incompatible_color(): - palette = ImagePalette.ImagePalette(mode="RGB") - # Opaque RGBA colors should work - palette.getcolor((0, 0, 0, 255)) - assert palette.getcolor((0, 0, 0)) == palette.getcolor((0, 0, 0, 255)) +def test_getcolor_rgba_color_rgb_palette(): + palette = ImagePalette.ImagePalette("RGB") + + # Opaque RGBA colors are converted + assert palette.getcolor((0, 0, 0, 255)) == palette.getcolor((0, 0, 0)) + with pytest.raises(ValueError): palette.getcolor((0, 0, 0, 128)) diff --git a/src/PIL/ImagePalette.py b/src/PIL/ImagePalette.py index e407bbcd17a..fe76c86f40e 100644 --- a/src/PIL/ImagePalette.py +++ b/src/PIL/ImagePalette.py @@ -114,13 +114,13 @@ def getcolor(self, color, image=None): if self.rawmode: raise ValueError("palette contains raw palette data") if isinstance(color, tuple): - if self.mode == "RGB" and len(color) == 4: - if color[3] == 255: + if self.mode == "RGB": + if len(color) == 4: + if color[3] != 255: + raise ValueError( + "cannot add non-opaque RGBA color to RGB palette" + ) color = color[:3] - else: - raise ValueError( - "RGB ImagePalette can't handle non-opaque RGBA colors" - ) elif self.mode == "RGBA": if len(color) == 3: color += (255,)