Skip to content

Commit b3f3743

Browse files
authored
Merge pull request #7603 from sambvfx/bc4-dds
Added support for reading DX10 BC4 DDS images
2 parents cd2c334 + 8a88e43 commit b3f3743

File tree

5 files changed

+30
-1
lines changed

5 files changed

+30
-1
lines changed

Tests/images/bc4_typeless.dds

2.82 KB
Binary file not shown.

Tests/images/bc4_unorm.dds

2.82 KB
Binary file not shown.

Tests/images/bc4_unorm.png

982 Bytes
Loading

Tests/test_file_dds.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
TEST_FILE_DXT5 = "Tests/images/dxt5-argb-8bbp-interpolatedalpha_MipMaps-1.dds"
1313
TEST_FILE_ATI1 = "Tests/images/ati1.dds"
1414
TEST_FILE_ATI2 = "Tests/images/ati2.dds"
15+
TEST_FILE_DX10_BC4_TYPELESS = "Tests/images/bc4_typeless.dds"
16+
TEST_FILE_DX10_BC4_UNORM = "Tests/images/bc4_unorm.dds"
1517
TEST_FILE_DX10_BC5_TYPELESS = "Tests/images/bc5_typeless.dds"
1618
TEST_FILE_DX10_BC5_UNORM = "Tests/images/bc5_unorm.dds"
1719
TEST_FILE_DX10_BC5_SNORM = "Tests/images/bc5_snorm.dds"
@@ -82,6 +84,27 @@ def test_sanity_ati1():
8284
assert_image_equal_tofile(im, TEST_FILE_ATI1.replace(".dds", ".png"))
8385

8486

87+
@pytest.mark.parametrize(
88+
"image_path",
89+
(
90+
TEST_FILE_DX10_BC4_UNORM,
91+
# hexeditted to be typeless
92+
TEST_FILE_DX10_BC4_TYPELESS,
93+
),
94+
)
95+
def test_dx10_bc4(image_path):
96+
"""Check DX10 BC4 images can be opened"""
97+
98+
with Image.open(image_path) as im:
99+
im.load()
100+
101+
assert im.format == "DDS"
102+
assert im.mode == "L"
103+
assert im.size == (64, 64)
104+
105+
assert_image_equal_tofile(im, TEST_FILE_DX10_BC4_UNORM.replace(".dds", ".png"))
106+
107+
85108
@pytest.mark.parametrize(
86109
"image_path",
87110
(

src/PIL/DdsImagePlugin.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@
9898
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27
9999
DXGI_FORMAT_R8G8B8A8_UNORM = 28
100100
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29
101+
DXGI_FORMAT_BC4_TYPELESS = 79
102+
DXGI_FORMAT_BC4_UNORM = 80
101103
DXGI_FORMAT_BC5_TYPELESS = 82
102104
DXGI_FORMAT_BC5_UNORM = 83
103105
DXGI_FORMAT_BC5_SNORM = 84
@@ -190,7 +192,11 @@ def _open(self):
190192
# ignoring flags which pertain to volume textures and cubemaps
191193
(dxgi_format,) = struct.unpack("<I", self.fp.read(4))
192194
self.fp.read(16)
193-
if dxgi_format in (DXGI_FORMAT_BC5_TYPELESS, DXGI_FORMAT_BC5_UNORM):
195+
if dxgi_format in (DXGI_FORMAT_BC4_TYPELESS, DXGI_FORMAT_BC4_UNORM):
196+
self.pixel_format = "BC4"
197+
n = 4
198+
self._mode = "L"
199+
elif dxgi_format in (DXGI_FORMAT_BC5_TYPELESS, DXGI_FORMAT_BC5_UNORM):
194200
self.pixel_format = "BC5"
195201
n = 5
196202
self._mode = "RGB"

0 commit comments

Comments
 (0)