From 852859476b07d4ca8244e5701377c1cc85df44a5 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 17 Feb 2022 10:04:43 +1100 Subject: [PATCH 1/5] Added rawmode argument to getpalette() --- Tests/test_image_getpalette.py | 27 +++++++++++++++++++++++++++ src/PIL/Image.py | 6 ++++-- src/libImaging/Pack.c | 1 + 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Tests/test_image_getpalette.py b/Tests/test_image_getpalette.py index 1818adca234..1690e411ce8 100644 --- a/Tests/test_image_getpalette.py +++ b/Tests/test_image_getpalette.py @@ -1,3 +1,5 @@ +from PIL import Image + from .helper import hopper @@ -17,3 +19,28 @@ def palette(mode): assert palette("RGBA") is None assert palette("CMYK") is None assert palette("YCbCr") is None + + +def test_palette_rawmode(): + im = Image.new("P", (1, 1)) + im.putpalette((1, 2, 3)) + + rgb = im.getpalette("RGB") + assert len(rgb) == 256 * 3 + assert rgb[:3] == [1, 2, 3] + + # Convert the RGB palette to RGBA + rgba = im.getpalette("RGBA") + assert len(rgba) == 256 * 4 + assert rgba[:4] == [1, 2, 3, 255] + + im.putpalette((1, 2, 3, 4), "RGBA") + + # Convert the RGBA palette to RGB + rgb = im.getpalette("RGB") + assert len(rgb) == 256 * 3 + assert rgb[:3] == [1, 2, 3] + + rgba = im.getpalette("RGBA") + assert len(rgba) == 256 * 4 + assert rgba[:4] == [1, 2, 3, 4] diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 8d36e8871b0..cabcf435a93 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -1401,19 +1401,21 @@ def getim(self): self.load() return self.im.ptr - def getpalette(self): + def getpalette(self, rawmode="RGB"): """ Returns the image palette as a list. + :param rawmode: The mode in which to return the palette. :returns: A list of color values [r, g, b, ...], or None if the image has no palette. """ self.load() try: - return list(self.im.getpalette()) + mode = self.im.getpalettemode() except ValueError: return None # no palette + return list(self.im.getpalette(mode, rawmode)) def getpixel(self, xy): """ diff --git a/src/libImaging/Pack.c b/src/libImaging/Pack.c index 0c7c0497efe..01760e742be 100644 --- a/src/libImaging/Pack.c +++ b/src/libImaging/Pack.c @@ -574,6 +574,7 @@ static struct { /* true colour */ {"RGB", "RGB", 24, ImagingPackRGB}, {"RGB", "RGBX", 32, copy4}, + {"RGB", "RGBA", 32, copy4}, {"RGB", "XRGB", 32, ImagingPackXRGB}, {"RGB", "BGR", 24, ImagingPackBGR}, {"RGB", "BGRX", 32, ImagingPackBGRX}, From 6be87277f71948bc7e4b945c46660cac3e5ce919 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 17 Feb 2022 10:35:13 +1100 Subject: [PATCH 2/5] Allow rawmode None to return the palette in the current mode --- Tests/test_image_getpalette.py | 14 ++++++++------ src/PIL/Image.py | 5 ++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Tests/test_image_getpalette.py b/Tests/test_image_getpalette.py index 1690e411ce8..1a84b69280c 100644 --- a/Tests/test_image_getpalette.py +++ b/Tests/test_image_getpalette.py @@ -25,9 +25,10 @@ def test_palette_rawmode(): im = Image.new("P", (1, 1)) im.putpalette((1, 2, 3)) - rgb = im.getpalette("RGB") - assert len(rgb) == 256 * 3 - assert rgb[:3] == [1, 2, 3] + for rawmode in ("RGB", None): + rgb = im.getpalette(rawmode) + assert len(rgb) == 256 * 3 + assert rgb[:3] == [1, 2, 3] # Convert the RGB palette to RGBA rgba = im.getpalette("RGBA") @@ -41,6 +42,7 @@ def test_palette_rawmode(): assert len(rgb) == 256 * 3 assert rgb[:3] == [1, 2, 3] - rgba = im.getpalette("RGBA") - assert len(rgba) == 256 * 4 - assert rgba[:4] == [1, 2, 3, 4] + for rawmode in ("RGBA", None): + rgba = im.getpalette(rawmode) + assert len(rgba) == 256 * 4 + assert rgba[:4] == [1, 2, 3, 4] diff --git a/src/PIL/Image.py b/src/PIL/Image.py index cabcf435a93..305ef445b84 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -1405,7 +1405,8 @@ def getpalette(self, rawmode="RGB"): """ Returns the image palette as a list. - :param rawmode: The mode in which to return the palette. + :param rawmode: The mode in which to return the palette. ``None`` will + return the palette in its current mode. :returns: A list of color values [r, g, b, ...], or None if the image has no palette. """ @@ -1415,6 +1416,8 @@ def getpalette(self, rawmode="RGB"): mode = self.im.getpalettemode() except ValueError: return None # no palette + if rawmode is None: + rawmode = mode return list(self.im.getpalette(mode, rawmode)) def getpixel(self, xy): From da451e5beaa05addec02ed99b7500838520ce5a9 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 19 Feb 2022 22:55:23 +1100 Subject: [PATCH 3/5] Record the version the rawmode argument was added --- src/PIL/Image.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 305ef445b84..934c75b5fa5 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -1407,6 +1407,9 @@ def getpalette(self, rawmode="RGB"): :param rawmode: The mode in which to return the palette. ``None`` will return the palette in its current mode. + + .. versionadded:: 9.1.0 + :returns: A list of color values [r, g, b, ...], or None if the image has no palette. """ From 737fe769a67d9934c972215d8fea44c63c3bb417 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 19 Feb 2022 23:01:19 +1100 Subject: [PATCH 4/5] Added release notes --- docs/releasenotes/9.1.0.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/releasenotes/9.1.0.rst b/docs/releasenotes/9.1.0.rst index cbf9fe6e1bd..0096e8f9c7b 100644 --- a/docs/releasenotes/9.1.0.rst +++ b/docs/releasenotes/9.1.0.rst @@ -45,6 +45,13 @@ At present, the information within each block is merely returned as a dictionary "data" entry. This will allow more useful information to be added in the future without breaking backwards compatibility. +Added rawmode argument to Image.getpalette() +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, :py:meth:`~PIL.Image.Image.getpalette` returns RGB data from the palette. +A ``rawmode`` argument has been added, to allow the mode to be chosen instead. ``None`` +can be used to return data in the current mode of the palette. + Other Changes ============= From 11948050ae55febce4d65006c6eb5f01add4d804 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sun, 20 Feb 2022 23:54:12 +1100 Subject: [PATCH 5/5] Updated tests in light of #6060 --- Tests/test_image_getpalette.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Tests/test_image_getpalette.py b/Tests/test_image_getpalette.py index 1a84b69280c..58a6dacbbbb 100644 --- a/Tests/test_image_getpalette.py +++ b/Tests/test_image_getpalette.py @@ -27,22 +27,18 @@ def test_palette_rawmode(): for rawmode in ("RGB", None): rgb = im.getpalette(rawmode) - assert len(rgb) == 256 * 3 - assert rgb[:3] == [1, 2, 3] + assert rgb == [1, 2, 3] # Convert the RGB palette to RGBA rgba = im.getpalette("RGBA") - assert len(rgba) == 256 * 4 - assert rgba[:4] == [1, 2, 3, 255] + assert rgba == [1, 2, 3, 255] im.putpalette((1, 2, 3, 4), "RGBA") # Convert the RGBA palette to RGB rgb = im.getpalette("RGB") - assert len(rgb) == 256 * 3 - assert rgb[:3] == [1, 2, 3] + assert rgb == [1, 2, 3] for rawmode in ("RGBA", None): rgba = im.getpalette(rawmode) - assert len(rgba) == 256 * 4 - assert rgba[:4] == [1, 2, 3, 4] + assert rgba == [1, 2, 3, 4]