diff --git a/Tests/images/pal8_offset.bmp b/Tests/images/pal8_offset.bmp deleted file mode 100644 index 24be65f22c3..00000000000 Binary files a/Tests/images/pal8_offset.bmp and /dev/null differ diff --git a/Tests/test_file_bmp.py b/Tests/test_file_bmp.py index 2e0394b3b2a..c8ac4652434 100644 --- a/Tests/test_file_bmp.py +++ b/Tests/test_file_bmp.py @@ -42,7 +42,7 @@ def test_fallback_if_mmap_errors() -> None: # This image has been truncated, # so that the buffer is not large enough when using mmap with Image.open("Tests/images/mmap_error.bmp") as im: - assert_image_equal_tofile(im, "Tests/images/pal8_offset.bmp") + assert_image_equal_tofile(im, "Tests/images/bmp/g/pal8.bmp") def test_save_to_bytes() -> None: @@ -238,11 +238,21 @@ def test_unsupported_bmp_bitfields_layout() -> None: Image.open(fp) -def test_offset() -> None: - # This image has been hexedited - # to exclude the palette size from the pixel data offset - with Image.open("Tests/images/pal8_offset.bmp") as im: - assert_image_equal_tofile(im, "Tests/images/bmp/g/pal8.bmp") +@pytest.mark.parametrize( + "offset, path", + ( + (26, "pal8os2.bmp"), + (54, "pal8.bmp"), + ), +) +def test_offset(offset: int, path: str) -> None: + image_path = "Tests/images/bmp/g/" + path + # Exclude the palette size from the pixel data offset + with open(image_path, "rb") as fp: + data = fp.read() + data = data[:10] + o32(offset) + data[14:] + with Image.open(io.BytesIO(data)) as im: + assert_image_equal_tofile(im, image_path) def test_use_raw_alpha(monkeypatch: pytest.MonkeyPatch) -> None: diff --git a/src/PIL/BmpImagePlugin.py b/src/PIL/BmpImagePlugin.py index 5ee61b35b17..a6724cab437 100644 --- a/src/PIL/BmpImagePlugin.py +++ b/src/PIL/BmpImagePlugin.py @@ -179,14 +179,12 @@ def _bitmap(self, header: int = 0, offset: int = 0) -> None: # ------- If color count was not found in the header, compute from bits assert isinstance(file_info["bits"], int) - file_info["colors"] = ( - file_info["colors"] - if file_info.get("colors", 0) - else (1 << file_info["bits"]) - ) + if not file_info.get("colors", 0): + file_info["colors"] = 1 << file_info["bits"] + assert isinstance(file_info["palette_padding"], int) assert isinstance(file_info["colors"], int) if offset == 14 + file_info["header_size"] and file_info["bits"] <= 8: - offset += 4 * file_info["colors"] + offset += file_info["palette_padding"] * file_info["colors"] # ---------------------- Check bit depth for unusual unsupported values self._mode, raw_mode = BIT2MODE.get(file_info["bits"], ("", "")) @@ -265,7 +263,6 @@ def _bitmap(self, header: int = 0, offset: int = 0) -> None: msg = f"Unsupported BMP Palette size ({file_info['colors']})" raise OSError(msg) else: - assert isinstance(file_info["palette_padding"], int) padding = file_info["palette_padding"] palette = read(padding * file_info["colors"]) grayscale = True