diff --git a/Tests/images/bc4_typeless.dds b/Tests/images/bc4_typeless.dds new file mode 100644 index 00000000000..27f87889f43 Binary files /dev/null and b/Tests/images/bc4_typeless.dds differ diff --git a/Tests/images/bc4_unorm.dds b/Tests/images/bc4_unorm.dds new file mode 100644 index 00000000000..13da711bd13 Binary files /dev/null and b/Tests/images/bc4_unorm.dds differ diff --git a/Tests/images/bc4_unorm.png b/Tests/images/bc4_unorm.png new file mode 100644 index 00000000000..71d536c8453 Binary files /dev/null and b/Tests/images/bc4_unorm.png differ diff --git a/Tests/test_file_dds.py b/Tests/test_file_dds.py index bb9af7967b7..e9fb045887b 100644 --- a/Tests/test_file_dds.py +++ b/Tests/test_file_dds.py @@ -12,6 +12,8 @@ TEST_FILE_DXT5 = "Tests/images/dxt5-argb-8bbp-interpolatedalpha_MipMaps-1.dds" TEST_FILE_ATI1 = "Tests/images/ati1.dds" TEST_FILE_ATI2 = "Tests/images/ati2.dds" +TEST_FILE_DX10_BC4_TYPELESS = "Tests/images/bc4_typeless.dds" +TEST_FILE_DX10_BC4_UNORM = "Tests/images/bc4_unorm.dds" TEST_FILE_DX10_BC5_TYPELESS = "Tests/images/bc5_typeless.dds" TEST_FILE_DX10_BC5_UNORM = "Tests/images/bc5_unorm.dds" TEST_FILE_DX10_BC5_SNORM = "Tests/images/bc5_snorm.dds" @@ -82,6 +84,27 @@ def test_sanity_ati1(): assert_image_equal_tofile(im, TEST_FILE_ATI1.replace(".dds", ".png")) +@pytest.mark.parametrize( + "image_path", + ( + TEST_FILE_DX10_BC4_UNORM, + # hexeditted to be typeless + TEST_FILE_DX10_BC4_TYPELESS, + ), +) +def test_dx10_bc4(image_path): + """Check DX10 BC4 images can be opened""" + + with Image.open(image_path) as im: + im.load() + + assert im.format == "DDS" + assert im.mode == "L" + assert im.size == (64, 64) + + assert_image_equal_tofile(im, TEST_FILE_DX10_BC4_UNORM.replace(".dds", ".png")) + + @pytest.mark.parametrize( "image_path", ( diff --git a/src/PIL/DdsImagePlugin.py b/src/PIL/DdsImagePlugin.py index 54f358c7f9a..faf6a4e436c 100644 --- a/src/PIL/DdsImagePlugin.py +++ b/src/PIL/DdsImagePlugin.py @@ -98,6 +98,8 @@ DXGI_FORMAT_R8G8B8A8_TYPELESS = 27 DXGI_FORMAT_R8G8B8A8_UNORM = 28 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29 +DXGI_FORMAT_BC4_TYPELESS = 79 +DXGI_FORMAT_BC4_UNORM = 80 DXGI_FORMAT_BC5_TYPELESS = 82 DXGI_FORMAT_BC5_UNORM = 83 DXGI_FORMAT_BC5_SNORM = 84 @@ -190,7 +192,11 @@ def _open(self): # ignoring flags which pertain to volume textures and cubemaps (dxgi_format,) = struct.unpack("