Skip to content

Commit

Permalink
BLP1 uses 4 bytes for alpha depth
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Jan 1, 2025
1 parent aa0f412 commit 745eaa4
Showing 1 changed file with 27 additions and 16 deletions.
43 changes: 27 additions & 16 deletions src/PIL/BlpImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,18 +259,21 @@ class BlpImageFile(ImageFile.ImageFile):

def _open(self) -> None:
self.magic = self.fp.read(4)
if self.magic not in (b"BLP1", b"BLP2"):
msg = f"Bad BLP magic {repr(self.magic)}"
raise BLPFormatError(msg)

self.fp.seek(5, os.SEEK_CUR)
(self._blp_alpha_depth,) = struct.unpack("<b", self.fp.read(1))
if self.magic == b"BLP1":
self.fp.seek(4, os.SEEK_CUR)
(self._blp_alpha_depth,) = struct.unpack("<I", self.fp.read(4))
else:
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.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()
else:
msg = f"Bad BLP magic {repr(self.magic)}"
raise BLPFormatError(msg)
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 745eaa4

Please sign in to comment.