Skip to content

Commit

Permalink
Corrected BLP1 alpha depth handling
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Jan 1, 2025
1 parent aa0f412 commit b89cc09
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 16 deletions.
1 change: 1 addition & 0 deletions Tests/test_file_blp.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def test_load_blp1() -> None:
assert_image_equal_tofile(im, "Tests/images/blp/blp1_jpeg.png")

with Image.open("Tests/images/blp/blp1_jpeg2.blp") as im:
assert im.mode == "RGBA"
im.load()


Expand Down
43 changes: 27 additions & 16 deletions src/PIL/BlpImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,18 +260,21 @@ class BlpImageFile(ImageFile.ImageFile):
def _open(self) -> None:
self.magic = self.fp.read(4)

self.fp.seek(5, os.SEEK_CUR)
(self._blp_alpha_depth,) = struct.unpack("<b", self.fp.read(1))

self.fp.seek(2, os.SEEK_CUR)
self._size = struct.unpack("<II", self.fp.read(8))

if self.magic in (b"BLP1", b"BLP2"):
decoder = self.magic.decode()
if self.magic == b"BLP1":
self.fp.seek(4, os.SEEK_CUR)
(self._blp_alpha_depth,) = struct.unpack("<I", self.fp.read(4))
elif self.magic == b"BLP2":
self.fp.seek(5, os.SEEK_CUR)
(self._blp_alpha_depth,) = struct.unpack("<b", self.fp.read(1))
self.fp.seek(2, os.SEEK_CUR)
else:
msg = f"Bad BLP magic {repr(self.magic)}"
raise BLPFormatError(msg)

self._size = struct.unpack("<II", self.fp.read(8))

decoder = self.magic.decode()

self._mode = "RGBA" if self._blp_alpha_depth else "RGB"
self.tile = [ImageFile._Tile(decoder, (0, 0) + self.size, 0, self.mode)]

Expand All @@ -297,10 +300,13 @@ def _read_blp_header(self) -> None:
self.fd.seek(4)
(self._blp_compression,) = struct.unpack("<i", self._safe_read(4))

(self._blp_encoding,) = struct.unpack("<b", self._safe_read(1))
(self._blp_alpha_depth,) = struct.unpack("<b", self._safe_read(1))
(self._blp_alpha_encoding,) = struct.unpack("<b", self._safe_read(1))
self.fd.seek(1, os.SEEK_CUR) # mips
if isinstance(self, BLP1Decoder):
(self._blp_alpha_depth,) = struct.unpack("<I", self._safe_read(4))
else:
(self._blp_encoding,) = struct.unpack("<b", self._safe_read(1))
(self._blp_alpha_depth,) = struct.unpack("<b", self._safe_read(1))
(self._blp_alpha_encoding,) = struct.unpack("<b", self._safe_read(1))
self.fd.seek(1, os.SEEK_CUR) # mips

self.size = struct.unpack("<II", self._safe_read(8))

Expand Down Expand Up @@ -472,10 +478,15 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:

assert im.palette is not None
fp.write(struct.pack("<i", 1)) # Uncompressed or DirectX compression
fp.write(struct.pack("<b", Encoding.UNCOMPRESSED))
fp.write(struct.pack("<b", 1 if im.palette.mode == "RGBA" else 0))
fp.write(struct.pack("<b", 0)) # alpha encoding
fp.write(struct.pack("<b", 0)) # mips

alpha_depth = 1 if im.palette.mode == "RGBA" else 0
if magic == b"BLP1":
fp.write(struct.pack("<L", alpha_depth))
else:
fp.write(struct.pack("<b", Encoding.UNCOMPRESSED))
fp.write(struct.pack("<b", alpha_depth))
fp.write(struct.pack("<b", 0)) # alpha encoding
fp.write(struct.pack("<b", 0)) # mips
fp.write(struct.pack("<II", *im.size))
if magic == b"BLP1":
fp.write(struct.pack("<i", 5))
Expand Down

0 comments on commit b89cc09

Please sign in to comment.