Added BC2 loading and saving

This commit is contained in:
Andrew Murray 2025-03-15 12:56:32 +11:00
parent f1a61a1e76
commit b0315cc603
2 changed files with 27 additions and 4 deletions

View File

@ -115,6 +115,19 @@ def test_sanity_ati1_bc4u(image_path: str) -> None:
assert_image_equal_tofile(im, TEST_FILE_ATI1.replace(".dds", ".png"))
def test_dx10_bc2(tmp_path: Path) -> None:
out = str(tmp_path / "temp.dds")
with Image.open(TEST_FILE_DXT3) as im:
im.save(out, pixel_format="BC2")
with Image.open(out) as reloaded:
assert reloaded.format == "DDS"
assert reloaded.mode == "RGBA"
assert reloaded.size == (256, 256)
assert_image_similar(im, reloaded, 3.81)
def test_dx10_bc3(tmp_path: Path) -> None:
out = str(tmp_path / "temp.dds")
with Image.open(TEST_FILE_DXT5) as im:

View File

@ -419,6 +419,10 @@ class DdsImageFile(ImageFile.ImageFile):
self._mode = "RGBA"
self.pixel_format = "BC1"
n = 1
elif dxgi_format in (DXGI_FORMAT.BC2_TYPELESS, DXGI_FORMAT.BC2_UNORM):
self._mode = "RGBA"
self.pixel_format = "BC2"
n = 2
elif dxgi_format in (DXGI_FORMAT.BC3_TYPELESS, DXGI_FORMAT.BC3_UNORM):
self._mode = "RGBA"
self.pixel_format = "BC3"
@ -526,7 +530,7 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
bitcount = len(im.getbands()) * 8
pixel_format = im.encoderinfo.get("pixel_format")
args: tuple[int] | str
if pixel_format in ("DXT1", "DXT3", "BC3", "DXT5"):
if pixel_format in ("DXT1", "BC2", "DXT3", "BC3", "DXT5"):
codec_name = "bcn"
flags |= DDSD.LINEARSIZE
pitch = (im.width + 3) * 4
@ -538,10 +542,16 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
elif pixel_format == "DXT3":
fourcc = D3DFMT.DXT3
args = (2,)
else:
fourcc = D3DFMT.DXT5 if pixel_format == "DXT5" else D3DFMT.DX10
elif pixel_format == "DXT5":
fourcc = D3DFMT.DXT5
args = (3,)
if fourcc == D3DFMT.DX10:
else:
fourcc = D3DFMT.DX10
if pixel_format == "BC2":
args = (2,)
dxgi_format = DXGI_FORMAT.BC2_TYPELESS
else:
args = (3,)
dxgi_format = DXGI_FORMAT.BC3_TYPELESS
else:
codec_name = "raw"