diff --git a/Tests/test_image.py b/Tests/test_image.py index 82efefc1e..0e085d6e4 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -606,7 +606,7 @@ class TestImage: 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 17d32cbf3..b36362af2 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 8fb7ea576..0df5e1218 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -1039,6 +1039,10 @@ class Image: 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 @@ class Image: 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 4d223cc06..a525f5912 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 @@ class ImagePalette: # 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: