diff --git a/Tests/images/uncompressed_l.dds b/Tests/images/uncompressed_l.dds new file mode 100644 index 00000000000..b82282587ec Binary files /dev/null and b/Tests/images/uncompressed_l.dds differ diff --git a/Tests/images/uncompressed_l.png b/Tests/images/uncompressed_l.png new file mode 100644 index 00000000000..9d22a26a446 Binary files /dev/null and b/Tests/images/uncompressed_l.png differ diff --git a/Tests/images/uncompressed_la.dds b/Tests/images/uncompressed_la.dds new file mode 100644 index 00000000000..30bf93576fd Binary files /dev/null and b/Tests/images/uncompressed_la.dds differ diff --git a/Tests/images/uncompressed_la.png b/Tests/images/uncompressed_la.png new file mode 100644 index 00000000000..0d4ea602fc3 Binary files /dev/null and b/Tests/images/uncompressed_la.png differ diff --git a/Tests/test_file_dds.py b/Tests/test_file_dds.py index 4b9f8949ef5..cac4108a8f0 100644 --- a/Tests/test_file_dds.py +++ b/Tests/test_file_dds.py @@ -22,6 +22,8 @@ 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_L = "Tests/images/uncompressed_l.dds" +TEST_FILE_UNCOMPRESSED_L_WITH_ALPHA = "Tests/images/uncompressed_la.dds" TEST_FILE_UNCOMPRESSED_RGB = "Tests/images/hopper.dds" TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA = "Tests/images/uncompressed_rgb.dds" @@ -194,26 +196,24 @@ def test_unimplemented_dxgi_format(): pass -def test_uncompressed_rgb(): - """Check uncompressed RGB images can be opened""" - - # convert -format dds -define dds:compression=none hopper.jpg hopper.dds - with Image.open(TEST_FILE_UNCOMPRESSED_RGB) as im: - assert im.format == "DDS" - assert im.mode == "RGB" - assert im.size == (128, 128) - - assert_image_equal_tofile(im, "Tests/images/hopper.png") +@pytest.mark.parametrize( + ("mode", "size", "test_file"), + [ + ("L", (128, 128), TEST_FILE_UNCOMPRESSED_L), + ("LA", (128, 128), TEST_FILE_UNCOMPRESSED_L_WITH_ALPHA), + ("RGB", (128, 128), TEST_FILE_UNCOMPRESSED_RGB), + ("RGBA", (800, 600), TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA), + ], +) +def test_uncompressed(mode, size, test_file): + """Check uncompressed images can be opened""" - # Test image with alpha - with Image.open(TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA) as im: + with Image.open(test_file) as im: assert im.format == "DDS" - assert im.mode == "RGBA" - assert im.size == (800, 600) + assert im.mode == mode + assert im.size == size - assert_image_equal_tofile( - im, TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA.replace(".dds", ".png") - ) + assert_image_equal_tofile(im, test_file.replace(".dds", ".png")) def test__accept_true(): @@ -305,6 +305,8 @@ def test_save_unsupported_mode(tmp_path): @pytest.mark.parametrize( ("mode", "test_file"), [ + ("L", "Tests/images/linear_gradient.png"), + ("LA", "Tests/images/uncompressed_la.png"), ("RGB", "Tests/images/hopper.png"), ("RGBA", "Tests/images/pil123rgba.png"), ], diff --git a/docs/releasenotes/9.4.0.rst b/docs/releasenotes/9.4.0.rst index ccbe62a6bcd..0068f281608 100644 --- a/docs/releasenotes/9.4.0.rst +++ b/docs/releasenotes/9.4.0.rst @@ -70,7 +70,8 @@ TODO Other Changes ============= -TODO -^^^^ +Added support for DDS L and LA images +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -TODO +Support has been added to read and write L and LA DDS images in the uncompressed +format, known as "luminance" textures. diff --git a/src/PIL/DdsImagePlugin.py b/src/PIL/DdsImagePlugin.py index eea6e31534c..f78c8b17cbd 100644 --- a/src/PIL/DdsImagePlugin.py +++ b/src/PIL/DdsImagePlugin.py @@ -135,11 +135,19 @@ def _open(self): fourcc = header.read(4) (bitcount,) = struct.unpack("