mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 18:06:18 +03:00
Added reading non-JPEG BLP1 as RGBA
This commit is contained in:
parent
3ec928251c
commit
1859bc3462
|
@ -288,15 +288,12 @@ class BlpImageFile(ImageFile.ImageFile):
|
||||||
self.fp.seek(2, os.SEEK_CUR)
|
self.fp.seek(2, os.SEEK_CUR)
|
||||||
self._size = struct.unpack("<II", self.fp.read(8))
|
self._size = struct.unpack("<II", self.fp.read(8))
|
||||||
|
|
||||||
if self.magic == b"BLP1":
|
if self.magic in (b"BLP1", b"BLP2"):
|
||||||
decoder = "BLP1"
|
decoder = self.magic.decode()
|
||||||
self.mode = "RGB"
|
|
||||||
elif self.magic == b"BLP2":
|
|
||||||
decoder = "BLP2"
|
|
||||||
self.mode = "RGBA" if self._blp_alpha_depth else "RGB"
|
|
||||||
else:
|
else:
|
||||||
raise BLPFormatError(f"Bad BLP magic {repr(self.magic)}")
|
raise BLPFormatError(f"Bad BLP magic {repr(self.magic)}")
|
||||||
|
|
||||||
|
self.mode = "RGBA" if self._blp_alpha_depth else "RGB"
|
||||||
self.tile = [(decoder, (0, 0) + self.size, 0, (self.mode, 0, 1))]
|
self.tile = [(decoder, (0, 0) + self.size, 0, (self.mode, 0, 1))]
|
||||||
|
|
||||||
|
|
||||||
|
@ -311,19 +308,6 @@ class _BLPBaseDecoder(ImageFile.PyDecoder):
|
||||||
raise OSError("Truncated BLP file") from e
|
raise OSError("Truncated BLP file") from e
|
||||||
return 0, 0
|
return 0, 0
|
||||||
|
|
||||||
def _safe_read(self, length):
|
|
||||||
return ImageFile._safe_read(self.fd, length)
|
|
||||||
|
|
||||||
def _read_palette(self):
|
|
||||||
ret = []
|
|
||||||
for i in range(256):
|
|
||||||
try:
|
|
||||||
b, g, r, a = struct.unpack("<4B", self._safe_read(4))
|
|
||||||
except struct.error:
|
|
||||||
break
|
|
||||||
ret.append((b, g, r, a))
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def _read_blp_header(self):
|
def _read_blp_header(self):
|
||||||
self.fd.seek(4)
|
self.fd.seek(4)
|
||||||
(self._blp_compression,) = struct.unpack("<i", self._safe_read(4))
|
(self._blp_compression,) = struct.unpack("<i", self._safe_read(4))
|
||||||
|
@ -343,6 +327,34 @@ class _BLPBaseDecoder(ImageFile.PyDecoder):
|
||||||
self._blp_offsets = struct.unpack("<16I", self._safe_read(16 * 4))
|
self._blp_offsets = struct.unpack("<16I", self._safe_read(16 * 4))
|
||||||
self._blp_lengths = struct.unpack("<16I", self._safe_read(16 * 4))
|
self._blp_lengths = struct.unpack("<16I", self._safe_read(16 * 4))
|
||||||
|
|
||||||
|
def _safe_read(self, length):
|
||||||
|
return ImageFile._safe_read(self.fd, length)
|
||||||
|
|
||||||
|
def _read_palette(self):
|
||||||
|
ret = []
|
||||||
|
for i in range(256):
|
||||||
|
try:
|
||||||
|
b, g, r, a = struct.unpack("<4B", self._safe_read(4))
|
||||||
|
except struct.error:
|
||||||
|
break
|
||||||
|
ret.append((b, g, r, a))
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def _read_bgra(self, palette):
|
||||||
|
data = bytearray()
|
||||||
|
_data = BytesIO(self._safe_read(self._blp_lengths[0]))
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
(offset,) = struct.unpack("<B", _data.read(1))
|
||||||
|
except struct.error:
|
||||||
|
break
|
||||||
|
b, g, r, a = palette[offset]
|
||||||
|
d = (r, g, b)
|
||||||
|
if self._blp_alpha_depth:
|
||||||
|
d += (a,)
|
||||||
|
data.extend(d)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
class BLP1Decoder(_BLPBaseDecoder):
|
class BLP1Decoder(_BLPBaseDecoder):
|
||||||
def _load(self):
|
def _load(self):
|
||||||
|
@ -351,17 +363,8 @@ class BLP1Decoder(_BLPBaseDecoder):
|
||||||
|
|
||||||
elif self._blp_compression == 1:
|
elif self._blp_compression == 1:
|
||||||
if self._blp_encoding in (4, 5):
|
if self._blp_encoding in (4, 5):
|
||||||
data = bytearray()
|
|
||||||
palette = self._read_palette()
|
palette = self._read_palette()
|
||||||
_data = BytesIO(self._safe_read(self._blp_lengths[0]))
|
data = self._read_bgra(palette)
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
(offset,) = struct.unpack("<B", _data.read(1))
|
|
||||||
except struct.error:
|
|
||||||
break
|
|
||||||
b, g, r, a = palette[offset]
|
|
||||||
data.extend([r, g, b])
|
|
||||||
|
|
||||||
self.set_as_raw(bytes(data))
|
self.set_as_raw(bytes(data))
|
||||||
else:
|
else:
|
||||||
raise BLPFormatError(
|
raise BLPFormatError(
|
||||||
|
@ -392,26 +395,16 @@ class BLP2Decoder(_BLPBaseDecoder):
|
||||||
def _load(self):
|
def _load(self):
|
||||||
palette = self._read_palette()
|
palette = self._read_palette()
|
||||||
|
|
||||||
data = bytearray()
|
|
||||||
self.fd.seek(self._blp_offsets[0])
|
self.fd.seek(self._blp_offsets[0])
|
||||||
|
|
||||||
if self._blp_compression == 1:
|
if self._blp_compression == 1:
|
||||||
# Uncompressed or DirectX compression
|
# Uncompressed or DirectX compression
|
||||||
|
|
||||||
if self._blp_encoding == Encoding.UNCOMPRESSED:
|
if self._blp_encoding == Encoding.UNCOMPRESSED:
|
||||||
_data = BytesIO(self._safe_read(self._blp_lengths[0]))
|
data = self._read_bgra(palette)
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
(offset,) = struct.unpack("<B", _data.read(1))
|
|
||||||
except struct.error:
|
|
||||||
break
|
|
||||||
b, g, r, a = palette[offset]
|
|
||||||
d = (r, g, b)
|
|
||||||
if self._blp_alpha_depth:
|
|
||||||
d += (a,)
|
|
||||||
data.extend(d)
|
|
||||||
|
|
||||||
elif self._blp_encoding == Encoding.DXT:
|
elif self._blp_encoding == Encoding.DXT:
|
||||||
|
data = bytearray()
|
||||||
if self._blp_alpha_encoding == AlphaEncoding.DXT1:
|
if self._blp_alpha_encoding == AlphaEncoding.DXT1:
|
||||||
linesize = (self.size[0] + 3) // 4 * 8
|
linesize = (self.size[0] + 3) // 4 * 8
|
||||||
for yb in range((self.size[1] + 3) // 4):
|
for yb in range((self.size[1] + 3) // 4):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user