diff --git a/Tests/images/uncompressed_rgb.dds b/Tests/images/uncompressed_rgb.dds new file mode 100755 index 000000000..cd5189532 Binary files /dev/null and b/Tests/images/uncompressed_rgb.dds differ diff --git a/Tests/images/uncompressed_rgb.png b/Tests/images/uncompressed_rgb.png new file mode 100644 index 000000000..50bca09ee Binary files /dev/null and b/Tests/images/uncompressed_rgb.png differ diff --git a/Tests/images/unimplemented_dxgi_format.dds b/Tests/images/unimplemented_dxgi_format.dds new file mode 100644 index 000000000..5ecb42006 Binary files /dev/null and b/Tests/images/unimplemented_dxgi_format.dds differ diff --git a/Tests/images/unimplemented_pixel_format.dds b/Tests/images/unimplemented_pixel_format.dds new file mode 100755 index 000000000..41a343886 Binary files /dev/null and b/Tests/images/unimplemented_pixel_format.dds differ diff --git a/Tests/test_file_dds.py b/Tests/test_file_dds.py index af2524c4a..605c5f69b 100644 --- a/Tests/test_file_dds.py +++ b/Tests/test_file_dds.py @@ -7,6 +7,7 @@ TEST_FILE_DXT1 = "Tests/images/dxt1-rgb-4bbp-noalpha_MipMaps-1.dds" TEST_FILE_DXT3 = "Tests/images/dxt3-argb-8bbp-explicitalpha_MipMaps-1.dds" 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_UNCOMPRESSED_RGB = "Tests/images/uncompressed_rgb.dds" class TestFileDds(PillowTestCase): @@ -67,6 +68,24 @@ class TestFileDds(PillowTestCase): self.assert_image_equal(target, im) + def test_unimplemented_dxgi_format(self): + self.assertRaises(NotImplementedError, Image.open, + "Tests/images/unimplemented_dxgi_format.dds") + + def test_uncompressed_rgb(self): + """Check uncompressed RGB images can be opened""" + + target = Image.open(TEST_FILE_UNCOMPRESSED_RGB.replace('.dds', '.png')) + + im = Image.open(TEST_FILE_UNCOMPRESSED_RGB) + im.load() + + self.assertEqual(im.format, "DDS") + self.assertEqual(im.mode, "RGBA") + self.assertEqual(im.size, (800, 600)) + + self.assert_image_equal(target, im) + def test__validate_true(self): """Check valid prefix""" # Arrange @@ -110,3 +129,7 @@ class TestFileDds(PillowTestCase): im.load() self.assertRaises(IOError, short_file) + + def test_unimplemented_pixel_format(self): + self.assertRaises(NotImplementedError, Image.open, + "Tests/images/unimplemented_pixel_format.dds") diff --git a/docs/handbook/image-file-formats.rst b/docs/handbook/image-file-formats.rst index 0fff91bb5..8f53291c3 100644 --- a/docs/handbook/image-file-formats.rst +++ b/docs/handbook/image-file-formats.rst @@ -849,8 +849,8 @@ DDS DDS is a popular container texture format used in video games and natively supported by DirectX. -Currently, DXT1, DXT3, and DXT5 pixel formats are supported and only in ``RGBA`` -mode. +Currently, uncompressed RGB data and DXT1, DXT3, and DXT5 pixel formats are +supported, and only in ``RGBA`` mode. .. versionadded:: 3.4.0 DXT3 diff --git a/docs/releasenotes/6.0.0.rst b/docs/releasenotes/6.0.0.rst index f16c718a1..85427d0bf 100644 --- a/docs/releasenotes/6.0.0.rst +++ b/docs/releasenotes/6.0.0.rst @@ -110,7 +110,7 @@ Pillow now supports reading and writing the DIB "Device Independent Bitmap" file Other Changes ============= -TODO -^^^^ +Reading new DDS image format +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -TODO +Pillow can now read uncompressed RGB data from DDS images. diff --git a/src/PIL/DdsImagePlugin.py b/src/PIL/DdsImagePlugin.py index edc1b7aa3..3954a1d6e 100644 --- a/src/PIL/DdsImagePlugin.py +++ b/src/PIL/DdsImagePlugin.py @@ -123,43 +123,52 @@ class DdsImageFile(ImageFile.ImageFile): # pixel format pfsize, pfflags = struct.unpack("<2I", header.read(8)) fourcc = header.read(4) - bitcount, rmask, gmask, bmask, amask = struct.unpack("<5I", - header.read(20)) + bitcount, = struct.unpack("