From b3e24660c9583afec0a83e631b89635877ca3bf1 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 21 Sep 2026 18:41:37 +1000 Subject: [PATCH] Ignore putpalette rawmode if data is an ImagePalette --- Tests/test_image_putpalette.py | 5 +++++ src/PIL/GifImagePlugin.py | 2 +- src/PIL/Image.py | 16 +++++++++------- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Tests/test_image_putpalette.py b/Tests/test_image_putpalette.py index 237de63305a..7e9b4928b54 100644 --- a/Tests/test_image_putpalette.py +++ b/Tests/test_image_putpalette.py @@ -56,6 +56,11 @@ def test_imagepalette() -> None: im.putpalette(ImagePalette.wedge()) assert_image_equal_tofile(im.convert("RGB"), "Tests/images/palette_wedge.png") + # Check that rawmode is ignored + im.putpalette(ImagePalette.wedge(), "RGBA") + assert im.palette is not None + assert im.palette.mode == "RGB" + def test_putpalette_with_alpha_values() -> None: with Image.open("Tests/images/transparent.gif") as im: diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index 0e05d8761be..61a0c82c475 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -720,7 +720,7 @@ def _write_multiple_frames( background_im = Image.new("P", im_frame.size, background) first_palette = im_frames[0].im.palette assert first_palette is not None - background_im.putpalette(first_palette, first_palette.mode) + background_im.putpalette(first_palette) bbox = _getbbox(background_im, im_frame)[1] else: bbox = (0, 0, *im_frame.size) diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 873de8607bf..c614c8ab58e 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -1145,7 +1145,7 @@ def convert_transparency( trns_im = new(self.mode, (1, 1)) if self.mode == "P": assert self.palette is not None - trns_im.putpalette(self.palette, self.palette.mode) + trns_im.putpalette(self.palette) if isinstance(t, tuple): err = "Couldn't allocate a palette color for transparency" assert trns_im.palette is not None @@ -2151,9 +2151,10 @@ def putpalette( Alternatively, an 8-bit string may be used instead of an integer sequence. - :param data: A palette sequence (either a list or a string). + :param data: A palette sequence (either a list or a string) or an ImagePalette. :param rawmode: The raw mode of the palette. Either "RGB", "RGBA", "CMYK", or a mode that can be transformed to one of those modes (e.g. "R", "RGBA;L"). + Ignored if ``data`` is an ImagePalette. """ from . import ImagePalette @@ -2161,15 +2162,16 @@ def putpalette( msg = "illegal image mode" raise ValueError(msg) if isinstance(data, ImagePalette.ImagePalette): - palette = ImagePalette.raw(data.rawmode or "RGB", data.palette) + palette = data.copy() + palette.dirty = 1 else: palette = ImagePalette.raw(rawmode, data) + if rawmode.startswith("CMYK"): + palette.mode = "CMYK" + elif "A" in rawmode: + palette.mode = "RGBA" self._mode = "PA" if "A" in self.mode else "P" self.palette = palette - if rawmode.startswith("CMYK"): - self.palette.mode = "CMYK" - elif "A" in rawmode: - self.palette.mode = "RGBA" self.load() # install new palette def putpixel(