mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 02:16:19 +03:00
Added BLP saving
This commit is contained in:
parent
747029bea9
commit
169025df6c
|
@ -2,7 +2,7 @@ import pytest
|
||||||
|
|
||||||
from PIL import BlpImagePlugin, Image
|
from PIL import BlpImagePlugin, Image
|
||||||
|
|
||||||
from .helper import assert_image_equal_tofile
|
from .helper import assert_image_equal, assert_image_equal_tofile, hopper
|
||||||
|
|
||||||
|
|
||||||
def test_load_blp1():
|
def test_load_blp1():
|
||||||
|
@ -25,6 +25,19 @@ def test_load_blp2_dxt1a():
|
||||||
assert_image_equal_tofile(im, "Tests/images/blp/blp2_dxt1a.png")
|
assert_image_equal_tofile(im, "Tests/images/blp/blp2_dxt1a.png")
|
||||||
|
|
||||||
|
|
||||||
|
def test_save(tmp_path):
|
||||||
|
im = hopper("P")
|
||||||
|
f = str(tmp_path / "temp.blp")
|
||||||
|
im.save(f)
|
||||||
|
|
||||||
|
with Image.open(f) as reloaded:
|
||||||
|
assert_image_equal(im.convert("RGB"), reloaded)
|
||||||
|
|
||||||
|
im = hopper()
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
im.save(f)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_file",
|
"test_file",
|
||||||
[
|
[
|
||||||
|
|
|
@ -267,6 +267,10 @@ class BLPFormatError(NotImplementedError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def _accept(prefix):
|
||||||
|
return prefix[:4] in (b"BLP1", b"BLP2")
|
||||||
|
|
||||||
|
|
||||||
class BlpImageFile(ImageFile.ImageFile):
|
class BlpImageFile(ImageFile.ImageFile):
|
||||||
"""
|
"""
|
||||||
Blizzard Mipmap Format
|
Blizzard Mipmap Format
|
||||||
|
@ -304,7 +308,7 @@ class _BLPBaseDecoder(ImageFile.PyDecoder):
|
||||||
self._read_blp_header()
|
self._read_blp_header()
|
||||||
self._load()
|
self._load()
|
||||||
except struct.error as e:
|
except struct.error as e:
|
||||||
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):
|
def _safe_read(self, length):
|
||||||
|
@ -439,12 +443,54 @@ class BLP2Decoder(_BLPBaseDecoder):
|
||||||
self.set_as_raw(bytes(data))
|
self.set_as_raw(bytes(data))
|
||||||
|
|
||||||
|
|
||||||
def _accept(prefix):
|
class BLP2Encoder(ImageFile.PyEncoder):
|
||||||
return prefix[:4] in (b"BLP1", b"BLP2")
|
_pushes_fd = True
|
||||||
|
|
||||||
|
def _write_palette(self):
|
||||||
|
data = b""
|
||||||
|
palette = self.im.getpalette("RGBA", "RGBA")
|
||||||
|
for i in range(256):
|
||||||
|
r, g, b, a = palette[i * 4 : (i + 1) * 4]
|
||||||
|
data += struct.pack("<4B", b, g, r, a)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def encode(self, bufsize):
|
||||||
|
palette_data = self._write_palette()
|
||||||
|
|
||||||
|
offset = 20 + 16 * 4 * 2 + len(palette_data)
|
||||||
|
data = struct.pack("<16I", offset, *((0,) * 15))
|
||||||
|
|
||||||
|
w, h = self.im.size
|
||||||
|
data += struct.pack("<16I", w * h, *((0,) * 15))
|
||||||
|
|
||||||
|
data += palette_data
|
||||||
|
|
||||||
|
for y in range(h):
|
||||||
|
for x in range(w):
|
||||||
|
data += struct.pack("<B", self.im.getpixel((x, y)))
|
||||||
|
|
||||||
|
return len(data), 0, data
|
||||||
|
|
||||||
|
|
||||||
|
def _save(im, fp, filename, save_all=False):
|
||||||
|
if im.mode != "P":
|
||||||
|
raise ValueError("Unsupported BLP image mode")
|
||||||
|
|
||||||
|
fp.write(b"BLP2")
|
||||||
|
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
|
||||||
|
fp.write(struct.pack("<II", *im.size))
|
||||||
|
|
||||||
|
ImageFile._save(im, fp, [("BLP2", (0, 0) + im.size, 0, im.mode)])
|
||||||
|
|
||||||
|
|
||||||
Image.register_open(BlpImageFile.format, BlpImageFile, _accept)
|
Image.register_open(BlpImageFile.format, BlpImageFile, _accept)
|
||||||
Image.register_extension(BlpImageFile.format, ".blp")
|
Image.register_extension(BlpImageFile.format, ".blp")
|
||||||
|
|
||||||
Image.register_decoder("BLP1", BLP1Decoder)
|
Image.register_decoder("BLP1", BLP1Decoder)
|
||||||
Image.register_decoder("BLP2", BLP2Decoder)
|
Image.register_decoder("BLP2", BLP2Decoder)
|
||||||
|
|
||||||
|
Image.register_save(BlpImageFile.format, _save)
|
||||||
|
Image.register_encoder("BLP2", BLP2Encoder)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user