From 99e401123bab56bf9c64314b506750a4ea6a9e79 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 13 Aug 2022 19:46:07 +1000 Subject: [PATCH 1/3] Corrected palette size when saving --- Tests/test_file_tga.py | 12 ++++++++++++ src/PIL/TgaImagePlugin.py | 5 +++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Tests/test_file_tga.py b/Tests/test_file_tga.py index 0c8c9f30485..fff127421d2 100644 --- a/Tests/test_file_tga.py +++ b/Tests/test_file_tga.py @@ -123,6 +123,18 @@ def test_save(tmp_path): assert test_im.size == (100, 100) +def test_small_palette(tmp_path): + im = Image.new("P", (1, 1)) + colors = [0, 0, 0] + im.putpalette(colors) + + out = str(tmp_path / "temp.tga") + im.save(out) + + with Image.open(out) as reloaded: + assert reloaded.getpalette() == colors + + def test_save_wrong_mode(tmp_path): im = hopper("PA") out = str(tmp_path / "temp.tga") diff --git a/src/PIL/TgaImagePlugin.py b/src/PIL/TgaImagePlugin.py index 59b89e9885f..7f5075317c8 100644 --- a/src/PIL/TgaImagePlugin.py +++ b/src/PIL/TgaImagePlugin.py @@ -193,7 +193,8 @@ def _save(im, fp, filename): warnings.warn("id_section has been trimmed to 255 characters") if colormaptype: - colormapfirst, colormaplength, colormapentry = 0, 256, 24 + palette = im.im.getpalette("RGB", "BGR") + colormapfirst, colormaplength, colormapentry = 0, len(palette) // 3, 24 else: colormapfirst, colormaplength, colormapentry = 0, 0, 0 @@ -225,7 +226,7 @@ def _save(im, fp, filename): fp.write(id_section) if colormaptype: - fp.write(im.im.getpalette("RGB", "BGR")) + fp.write(palette) if rle: ImageFile._save( From 5d4fbdfab4fa5dc05f4b3de3304fffdeddb9ff4f Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 13 Aug 2022 19:46:46 +1000 Subject: [PATCH 2/3] Simplified code --- src/PIL/TgaImagePlugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PIL/TgaImagePlugin.py b/src/PIL/TgaImagePlugin.py index 7f5075317c8..cd454b755c0 100644 --- a/src/PIL/TgaImagePlugin.py +++ b/src/PIL/TgaImagePlugin.py @@ -194,9 +194,9 @@ def _save(im, fp, filename): if colormaptype: palette = im.im.getpalette("RGB", "BGR") - colormapfirst, colormaplength, colormapentry = 0, len(palette) // 3, 24 + colormaplength, colormapentry = len(palette) // 3, 24 else: - colormapfirst, colormaplength, colormapentry = 0, 0, 0 + colormaplength, colormapentry = 0, 0 if im.mode in ("LA", "RGBA"): flags = 8 @@ -211,7 +211,7 @@ def _save(im, fp, filename): o8(id_len) + o8(colormaptype) + o8(imagetype) - + o16(colormapfirst) + + o16(0) # colormapfirst + o16(colormaplength) + o8(colormapentry) + o16(0) From 8b2d70d17a4791d68df6c10d8337d769290c6528 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 13 Sep 2022 09:10:03 +1000 Subject: [PATCH 3/3] Corrected BMP palette size when saving --- Tests/test_file_bmp.py | 12 ++++++++++++ src/PIL/BmpImagePlugin.py | 20 ++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Tests/test_file_bmp.py b/Tests/test_file_bmp.py index d58666b4476..4c964fbeac7 100644 --- a/Tests/test_file_bmp.py +++ b/Tests/test_file_bmp.py @@ -51,6 +51,18 @@ def test_save_to_bytes(): assert reloaded.format == "BMP" +def test_small_palette(tmp_path): + im = Image.new("P", (1, 1)) + colors = [0, 0, 0, 125, 125, 125, 255, 255, 255] + im.putpalette(colors) + + out = str(tmp_path / "temp.bmp") + im.save(out) + + with Image.open(out) as reloaded: + assert reloaded.getpalette() == colors + + def test_save_too_large(tmp_path): outfile = str(tmp_path / "temp.bmp") with Image.new("RGB", (1, 1)) as im: diff --git a/src/PIL/BmpImagePlugin.py b/src/PIL/BmpImagePlugin.py index 7bb73fc9388..1041ab763d2 100644 --- a/src/PIL/BmpImagePlugin.py +++ b/src/PIL/BmpImagePlugin.py @@ -375,6 +375,16 @@ def _save(im, fp, filename, bitmap_header=True): header = 40 # or 64 for OS/2 version 2 image = stride * im.size[1] + if im.mode == "1": + palette = b"".join(o8(i) * 4 for i in (0, 255)) + elif im.mode == "L": + palette = b"".join(o8(i) * 4 for i in range(256)) + elif im.mode == "P": + palette = im.im.getpalette("RGB", "BGRX") + colors = len(palette) // 4 + else: + palette = None + # bitmap header if bitmap_header: offset = 14 + header + colors * 4 @@ -405,14 +415,8 @@ def _save(im, fp, filename, bitmap_header=True): fp.write(b"\0" * (header - 40)) # padding (for OS/2 format) - if im.mode == "1": - for i in (0, 255): - fp.write(o8(i) * 4) - elif im.mode == "L": - for i in range(256): - fp.write(o8(i) * 4) - elif im.mode == "P": - fp.write(im.im.getpalette("RGB", "BGRX")) + if palette: + fp.write(palette) ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, stride, -1))])