diff --git a/Tests/images/DXGI_FORMAT_R8G8B8A8_UNORM_SRGB.dds b/Tests/images/DXGI_FORMAT_R8G8B8A8_UNORM_SRGB.dds new file mode 100644 index 00000000000..1da9293de9b Binary files /dev/null and b/Tests/images/DXGI_FORMAT_R8G8B8A8_UNORM_SRGB.dds differ diff --git a/Tests/images/DXGI_FORMAT_R8G8B8A8_UNORM_SRGB.png b/Tests/images/DXGI_FORMAT_R8G8B8A8_UNORM_SRGB.png new file mode 100644 index 00000000000..57177fe2bb8 Binary files /dev/null and b/Tests/images/DXGI_FORMAT_R8G8B8A8_UNORM_SRGB.png differ diff --git a/Tests/images/argb-32bpp_MipMaps-1.dds b/Tests/images/argb-32bpp_MipMaps-1.dds new file mode 100644 index 00000000000..d1d1998b1b3 Binary files /dev/null and b/Tests/images/argb-32bpp_MipMaps-1.dds differ diff --git a/Tests/images/argb-32bpp_MipMaps-1.png b/Tests/images/argb-32bpp_MipMaps-1.png new file mode 100644 index 00000000000..3570ccf355e Binary files /dev/null and b/Tests/images/argb-32bpp_MipMaps-1.png differ diff --git a/Tests/test_file_dds.py b/Tests/test_file_dds.py index 8960edea3dd..aafd1f3b24b 100644 --- a/Tests/test_file_dds.py +++ b/Tests/test_file_dds.py @@ -11,6 +11,8 @@ TEST_FILE_DXT5 = "Tests/images/dxt5-argb-8bbp-interpolatedalpha_MipMaps-1.dds" TEST_FILE_DX10_BC7 = "Tests/images/bc7-argb-8bpp_MipMaps-1.dds" TEST_FILE_DX10_BC7_UNORM_SRGB = "Tests/images/DXGI_FORMAT_BC7_UNORM_SRGB.dds" +TEST_FILE_DX10_R8G8B8A8 = "Tests/images/argb-32bpp_MipMaps-1.dds" +TEST_FILE_DX10_R8G8B8A8_UNORM_SRGB = "Tests/images/DXGI_FORMAT_R8G8B8A8_UNORM_SRGB.dds" TEST_FILE_UNCOMPRESSED_RGB = "Tests/images/uncompressed_rgb.dds" @@ -87,6 +89,37 @@ def test_dx10_bc7_unorm_srgb(): assert_image_equal(target, im) +def test_dx10_r8g8b8a8(): + """Check DX10 images can be opened""" + + with Image.open(TEST_FILE_DX10_R8G8B8A8) as im: + im.load() + + assert im.format == "DDS" + assert im.mode == "RGBA" + assert im.size == (256, 256) + + with Image.open(TEST_FILE_DX10_R8G8B8A8.replace(".dds", ".png")) as target: + assert_image_equal(target, im) + + +def test_dx10_r8g8b8a8_unorm_srgb(): + """Check DX10 unsigned normalized integer images can be opened""" + + with Image.open(TEST_FILE_DX10_R8G8B8A8_UNORM_SRGB) as im: + im.load() + + assert im.format == "DDS" + assert im.mode == "RGBA" + assert im.size == (16, 16) + assert im.info["gamma"] == 1 / 2.2 + + with Image.open( + TEST_FILE_DX10_R8G8B8A8_UNORM_SRGB.replace(".dds", ".png") + ) as target: + assert_image_equal(target, im) + + def test_unimplemented_dxgi_format(): with pytest.raises(NotImplementedError): Image.open("Tests/images/unimplemented_dxgi_format.dds") diff --git a/src/PIL/DdsImagePlugin.py b/src/PIL/DdsImagePlugin.py index 9ba6e0ff842..5e2d516733f 100644 --- a/src/PIL/DdsImagePlugin.py +++ b/src/PIL/DdsImagePlugin.py @@ -94,6 +94,9 @@ # dxgiformat.h +DXGI_FORMAT_R8G8B8A8_TYPELESS = 27 +DXGI_FORMAT_R8G8B8A8_UNORM = 28 +DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29 DXGI_FORMAT_BC7_TYPELESS = 97 DXGI_FORMAT_BC7_UNORM = 98 DXGI_FORMAT_BC7_UNORM_SRGB = 99 @@ -157,6 +160,15 @@ def _open(self): self.pixel_format = "BC7" self.info["gamma"] = 1 / 2.2 n = 7 + elif dxgi_format in ( + DXGI_FORMAT_R8G8B8A8_TYPELESS, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + ): + self.tile = [("raw", (0, 0) + self.size, 0, ("RGBA", 0, 1))] + if dxgi_format == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + self.info["gamma"] = 1 / 2.2 + return else: raise NotImplementedError( "Unimplemented DXGI format %d" % (dxgi_format)