Merge pull request #3673 from radarhere/dds

Add reading of DDS uncompressed RGB data
This commit is contained in:
Hugo 2019-03-11 12:04:47 +02:00 committed by GitHub
commit 5da0d5beee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 71 additions and 39 deletions

BIN
Tests/images/uncompressed_rgb.dds Executable file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Binary file not shown.

View File

@ -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_DXT3 = "Tests/images/dxt3-argb-8bbp-explicitalpha_MipMaps-1.dds"
TEST_FILE_DXT5 = "Tests/images/dxt5-argb-8bbp-interpolatedalpha_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_DX10_BC7 = "Tests/images/bc7-argb-8bpp_MipMaps-1.dds"
TEST_FILE_UNCOMPRESSED_RGB = "Tests/images/uncompressed_rgb.dds"
class TestFileDds(PillowTestCase): class TestFileDds(PillowTestCase):
@ -67,6 +68,24 @@ class TestFileDds(PillowTestCase):
self.assert_image_equal(target, im) 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): def test__validate_true(self):
"""Check valid prefix""" """Check valid prefix"""
# Arrange # Arrange
@ -110,3 +129,7 @@ class TestFileDds(PillowTestCase):
im.load() im.load()
self.assertRaises(IOError, short_file) self.assertRaises(IOError, short_file)
def test_unimplemented_pixel_format(self):
self.assertRaises(NotImplementedError, Image.open,
"Tests/images/unimplemented_pixel_format.dds")

View File

@ -849,8 +849,8 @@ DDS
DDS is a popular container texture format used in video games and natively DDS is a popular container texture format used in video games and natively
supported by DirectX. supported by DirectX.
Currently, DXT1, DXT3, and DXT5 pixel formats are supported and only in ``RGBA`` Currently, uncompressed RGB data and DXT1, DXT3, and DXT5 pixel formats are
mode. supported, and only in ``RGBA`` mode.
.. versionadded:: 3.4.0 DXT3 .. versionadded:: 3.4.0 DXT3

View File

@ -110,7 +110,7 @@ Pillow now supports reading and writing the DIB "Device Independent Bitmap" file
Other Changes Other Changes
============= =============
TODO Reading new DDS image format
^^^^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TODO Pillow can now read uncompressed RGB data from DDS images.

View File

@ -123,9 +123,18 @@ class DdsImageFile(ImageFile.ImageFile):
# pixel format # pixel format
pfsize, pfflags = struct.unpack("<2I", header.read(8)) pfsize, pfflags = struct.unpack("<2I", header.read(8))
fourcc = header.read(4) fourcc = header.read(4)
bitcount, rmask, gmask, bmask, amask = struct.unpack("<5I", bitcount, = struct.unpack("<I", header.read(4))
header.read(20)) masks = struct.unpack("<4I", header.read(16))
if pfflags & 0x40:
# DDPF_RGB - Texture contains uncompressed RGB data
masks = {mask: ["R", "G", "B", "A"][i] for i, mask in enumerate(masks)}
rawmode = ""
if bitcount == 32:
rawmode += masks[0xff000000]
rawmode += masks[0xff0000] + masks[0xff00] + masks[0xff]
self.tile = [("raw", (0, 0) + self.size, 0, (rawmode, 0, 1))]
else:
data_start = header_size + 4 data_start = header_size + 4
n = 0 n = 0
if fourcc == b"DXT1": if fourcc == b"DXT1":