From 61b1eeb39f7ecddfe03a6063ae860d2f8950c8a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20S=2E=20O=2E=20Bueno?= Date: Tue, 4 Oct 2022 01:13:50 -0300 Subject: [PATCH] Fix indices of colors read from GIMP Palette file --- Tests/images/custom_gimp_palette.gpl | 16 +++++++-------- Tests/test_file_gimppalette.py | 30 ++++++++++++++++++++++++++++ src/PIL/GimpPaletteFile.py | 21 +++++++++---------- 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/Tests/images/custom_gimp_palette.gpl b/Tests/images/custom_gimp_palette.gpl index 08ea70028..229c45d3e 100644 --- a/Tests/images/custom_gimp_palette.gpl +++ b/Tests/images/custom_gimp_palette.gpl @@ -2,11 +2,11 @@ GIMP Palette Name: custompalette Columns: 4 # - 0 0 0 Index 3 - 65 38 30 Index 4 -103 62 49 Index 6 - 79 73 72 Index 7 -114 101 97 Index 8 -208 127 100 Index 9 -151 144 142 Index 10 -221 207 199 Index 11 + 0 0 0 Index 0 + 65 38 30 Index 1 +103 62 49 Index 2 + 79 73 72 Index 3 +114 101 97 Index 4 +208 127 100 Index 5 +151 144 142 Index 6 +221 207 199 Index 7 diff --git a/Tests/test_file_gimppalette.py b/Tests/test_file_gimppalette.py index caec9cf21..9ecce801e 100644 --- a/Tests/test_file_gimppalette.py +++ b/Tests/test_file_gimppalette.py @@ -30,3 +30,33 @@ def test_get_palette(): # Assert assert mode == "RGB" + + +def test_palette__has_correct_color_indexes(): + # Arrange + with open("Tests/images/custom_gimp_palette.gpl", "rb") as fp: + palette_file = GimpPaletteFile(fp) + + palette, mode = palette_file.getpalette() + + colors_in_test_palette = [ + (0, 0, 0), + (65, 38, 30), + (103, 62, 49), + (79, 73, 72), + (114, 101, 97), + (208, 127, 100), + (151, 144, 142), + (221, 207, 199), + ] + + for i, color in enumerate(colors_in_test_palette): + assert tuple(palette[i * 3: i * 3 + 3]) == color + + +def test_palette_counts_number_of_colors_in_file(): + # Arrange + with open("Tests/images/custom_gimp_palette.gpl", "rb") as fp: + palette_file = GimpPaletteFile(fp) + + assert palette_file.n_colors == 8 diff --git a/src/PIL/GimpPaletteFile.py b/src/PIL/GimpPaletteFile.py index 4d7cfbaba..d26a229a8 100644 --- a/src/PIL/GimpPaletteFile.py +++ b/src/PIL/GimpPaletteFile.py @@ -18,6 +18,8 @@ import re from ._binary import o8 +_str_to_o8 = lambda v: o8(int(v)) + class GimpPaletteFile: """File handler for GIMP's palette format.""" @@ -26,17 +28,13 @@ class GimpPaletteFile: def __init__(self, fp): - self.palette = [o8(i) * 3 for i in range(256)] + palette = bytearray(b"".join([o8(i) * 3 for i in range(256)])) if fp.readline()[:12] != b"GIMP Palette": raise SyntaxError("not a GIMP palette file") - for i in range(256): - - s = fp.readline() - if not s: - break - + index = 0 + for s in fp: # skip fields and comment lines if re.match(rb"\w+:|#", s): continue @@ -44,12 +42,15 @@ class GimpPaletteFile: raise SyntaxError("bad palette file") v = tuple(map(int, s.split()[:3])) - if len(v) != 3: + if len(v) < 3: raise ValueError("bad palette entry") - self.palette[i] = o8(v[0]) + o8(v[1]) + o8(v[2]) + palette[index * 3: index * 3 + 3] = v + index += 1 + + self.palette = bytes(palette) + self.n_colors = index - self.palette = b"".join(self.palette) def getpalette(self):