diff --git a/Tests/test_image.py b/Tests/test_image.py index 82efefc1e6c..0e085d6e4cd 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -606,7 +606,7 @@ def _make_new(base_image, im, palette_result=None): else: assert new_im.palette is None - _make_new(im, im_p, im_p.palette) + _make_new(im, im_p, ImagePalette.ImagePalette(list(range(256)) * 3)) _make_new(im_p, im, None) _make_new(im, blank_p, ImagePalette.ImagePalette()) _make_new(im, blank_pa, ImagePalette.ImagePalette()) diff --git a/Tests/test_imagepalette.py b/Tests/test_imagepalette.py index 17d32cbf3c1..b36362af2d2 100644 --- a/Tests/test_imagepalette.py +++ b/Tests/test_imagepalette.py @@ -11,12 +11,14 @@ def test_sanity(): assert len(palette.colors) == 256 with pytest.raises(ValueError): - ImagePalette.ImagePalette("RGB", list(range(256)) * 2) + ImagePalette.ImagePalette("RGB", list(range(256)) * 3, 10) def test_getcolor(): palette = ImagePalette.ImagePalette() + assert len(palette.palette) == 0 + assert len(palette.colors) == 0 test_map = {} for i in range(256): diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 8fb7ea57698..0df5e1218b0 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -1039,6 +1039,10 @@ def convert_transparency(m, v): raise ValueError("illegal conversion") from e new_im = self._new(im) + if mode == "P" and palette != ADAPTIVE: + from . import ImagePalette + + new_im.palette = ImagePalette.ImagePalette("RGB", list(range(256)) * 3) if delete_trns: # crash fail if we leave a bytes transparency in an rgb/l mode. del new_im.info["transparency"] @@ -1700,7 +1704,7 @@ def putpalette(self, data, rawmode="RGB"): Attaches a palette to this image. The image must be a "P", "PA", "L" or "LA" image. - The palette sequence must contain either 768 integer values, or 1024 + The palette sequence must contain at most 768 integer values, or 1024 integer values if alpha is included. Each group of values represents the red, green, blue (and alpha if included) values for the corresponding pixel index. Instead of an integer sequence, you can use diff --git a/src/PIL/ImagePalette.py b/src/PIL/ImagePalette.py index 4d223cc068d..a525f59120d 100644 --- a/src/PIL/ImagePalette.py +++ b/src/PIL/ImagePalette.py @@ -39,11 +39,9 @@ class ImagePalette: def __init__(self, mode="RGB", palette=None, size=0): self.mode = mode self.rawmode = None # if set, palette contains raw data - self.palette = palette or bytearray(range(256)) * len(self.mode) + self.palette = palette or bytearray() self.dirty = None - if (size == 0 and len(self.mode) * 256 != len(self.palette)) or ( - size != 0 and size != len(self.palette) - ): + if size != 0 and size != len(self.palette): raise ValueError("wrong palette size") @property @@ -113,13 +111,16 @@ def getcolor(self, color): # allocate new color slot if isinstance(self.palette, bytes): self._palette = bytearray(self.palette) - index = len(self.colors) + index = len(self.palette) // 3 if index >= 256: raise ValueError("cannot allocate more than 256 colors") from e self.colors[color] = index - self._palette[index] = color[0] - self._palette[index + 256] = color[1] - self._palette[index + 512] = color[2] + if index * 3 < len(self.palette): + self._palette[index * 3] = color[0] + self._palette[index * 3 + 1] = color[1] + self._palette[index * 3 + 2] = color[2] + else: + self._palette += bytes(color) self.dirty = 1 return index else: