Skip to content

Commit b0315cc

Browse files
committed
Added BC2 loading and saving
1 parent f1a61a1 commit b0315cc

2 files changed

Lines changed: 27 additions & 4 deletions

File tree

Tests/test_file_dds.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,19 @@ def test_sanity_ati1_bc4u(image_path: str) -> None:
115115
assert_image_equal_tofile(im, TEST_FILE_ATI1.replace(".dds", ".png"))
116116

117117

118+
def test_dx10_bc2(tmp_path: Path) -> None:
119+
out = str(tmp_path / "temp.dds")
120+
with Image.open(TEST_FILE_DXT3) as im:
121+
im.save(out, pixel_format="BC2")
122+
123+
with Image.open(out) as reloaded:
124+
assert reloaded.format == "DDS"
125+
assert reloaded.mode == "RGBA"
126+
assert reloaded.size == (256, 256)
127+
128+
assert_image_similar(im, reloaded, 3.81)
129+
130+
118131
def test_dx10_bc3(tmp_path: Path) -> None:
119132
out = str(tmp_path / "temp.dds")
120133
with Image.open(TEST_FILE_DXT5) as im:

src/PIL/DdsImagePlugin.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,10 @@ def _open(self) -> None:
419419
self._mode = "RGBA"
420420
self.pixel_format = "BC1"
421421
n = 1
422+
elif dxgi_format in (DXGI_FORMAT.BC2_TYPELESS, DXGI_FORMAT.BC2_UNORM):
423+
self._mode = "RGBA"
424+
self.pixel_format = "BC2"
425+
n = 2
422426
elif dxgi_format in (DXGI_FORMAT.BC3_TYPELESS, DXGI_FORMAT.BC3_UNORM):
423427
self._mode = "RGBA"
424428
self.pixel_format = "BC3"
@@ -526,7 +530,7 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
526530
bitcount = len(im.getbands()) * 8
527531
pixel_format = im.encoderinfo.get("pixel_format")
528532
args: tuple[int] | str
529-
if pixel_format in ("DXT1", "DXT3", "BC3", "DXT5"):
533+
if pixel_format in ("DXT1", "BC2", "DXT3", "BC3", "DXT5"):
530534
codec_name = "bcn"
531535
flags |= DDSD.LINEARSIZE
532536
pitch = (im.width + 3) * 4
@@ -538,10 +542,16 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
538542
elif pixel_format == "DXT3":
539543
fourcc = D3DFMT.DXT3
540544
args = (2,)
541-
else:
542-
fourcc = D3DFMT.DXT5 if pixel_format == "DXT5" else D3DFMT.DX10
545+
elif pixel_format == "DXT5":
546+
fourcc = D3DFMT.DXT5
543547
args = (3,)
544-
if fourcc == D3DFMT.DX10:
548+
else:
549+
fourcc = D3DFMT.DX10
550+
if pixel_format == "BC2":
551+
args = (2,)
552+
dxgi_format = DXGI_FORMAT.BC2_TYPELESS
553+
else:
554+
args = (3,)
545555
dxgi_format = DXGI_FORMAT.BC3_TYPELESS
546556
else:
547557
codec_name = "raw"

0 commit comments

Comments
 (0)