Skip to content

Commit

Permalink
Merge pull request #7 from radarhere/improved_dds
Browse files Browse the repository at this point in the history
Support RGB bitcount 8
  • Loading branch information
REDxEYE committed Oct 30, 2023
2 parents 2ca9adb + e3ff5eb commit 4c635e4
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 19 deletions.
Binary file added Tests/images/bc1.dds
Binary file not shown.
Binary file added Tests/images/bc1_typeless.dds
Binary file not shown.
Binary file added Tests/images/rgb8.dds
Binary file not shown.
Binary file added Tests/images/unsupported_bitcount_luminance.dds
Binary file not shown.
Binary file added Tests/images/unsupported_bitcount_rgb.dds
Binary file not shown.
36 changes: 32 additions & 4 deletions Tests/test_file_dds.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
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"
TEST_FILE_DX10_BC1 = "Tests/images/bc1.dds"
TEST_FILE_DX10_BC1_TYPELESS = "Tests/images/bc1_typeless.dds"
TEST_FILE_BC5S = "Tests/images/bc5s.dds"
TEST_FILE_BC5U = "Tests/images/bc5u.dds"
TEST_FILE_BC6H = "Tests/images/bc6h.dds"
Expand All @@ -29,11 +31,20 @@
TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA = "Tests/images/uncompressed_rgb.dds"


def test_sanity_dxt1():
@pytest.mark.parametrize(
"image_path",
(
TEST_FILE_DXT1,
# hexeditted to use DX10 FourCC
TEST_FILE_DX10_BC1,
TEST_FILE_DX10_BC1_TYPELESS,
),
)
def test_sanity_bc1(image_path):
"""Check DXT1 images can be opened"""
with Image.open(TEST_FILE_DXT1.replace(".dds", ".png")) as target:
target = target.convert("RGBA")
with Image.open(TEST_FILE_DXT1) as im:
with Image.open(image_path) as im:
im.load()

assert im.format == "DDS"
Expand Down Expand Up @@ -306,8 +317,19 @@ def test_palette():
@pytest.mark.parametrize(
"test_file",
(
"Tests/images/unknown_fourcc.dds",
"Tests/images/unimplemented_fourcc.dds",
"Tests/images/unsupported_bitcount_rgb.dds",
"Tests/images/unsupported_bitcount_luminance.dds",
),
)
def test_unsupported_bitcount(test_file):
with pytest.raises(OSError):
with Image.open(test_file):
pass


@pytest.mark.parametrize(
"test_file",
(
"Tests/images/unimplemented_dxgi_format.dds",
"Tests/images/unimplemented_pfflags.dds",
),
Expand Down Expand Up @@ -340,6 +362,12 @@ def test_open(mode, test_file):
assert_image_equal_tofile(im, test_file.replace(".dds", ".png"))


def test_open_rgb8():
with Image.open("Tests/images/rgb8.dds") as im:
assert im.mode == "L"
assert_image_equal_tofile(im, "Tests/images/mode-l.png")


@pytest.mark.parametrize(
("mode", "test_file"),
[
Expand Down
22 changes: 7 additions & 15 deletions src/PIL/DdsImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,34 +346,27 @@ def _open(self):
# pixel format
pfsize, pfflags, fourcc, bitcount = struct.unpack("<4I", header.read(16))
masks = struct.unpack("<4I", header.read(16))
if flags & DDSD.CAPS:
header.seek(20, io.SEEK_CUR)
n = 0
rawmode = None
if pfflags & DDPF.RGB:
# Texture contains uncompressed RGB data
masks = {mask: ["R", "G", "B", "A"][i] for i, mask in enumerate(masks)}
if bitcount == 24:
if bitcount == 8:
self._mode = "L"
elif bitcount == 24:
self._mode = "RGB"
rawmode = masks[0x00FF0000] + masks[0x0000FF00] + masks[0x000000FF]
rawmode = masks[0x000000FF] + masks[0x0000FF00] + masks[0x00FF0000]
elif bitcount == 32 and pfflags & DDPF.ALPHAPIXELS:
self._mode = "RGBA"
rawmode = (
masks[0xFF000000]
+ masks[0x00FF0000]
masks[0x000000FF]
+ masks[0x0000FF00]
+ masks[0x000000FF]
+ masks[0x00FF0000]
+ masks[0xFF000000]
)
else:
msg = f"Unsupported bitcount {bitcount} for {pfflags}"
raise OSError(msg)
rawmode = rawmode[::-1]
elif pfflags & DDPF.ALPHA:
if bitcount == 8:
self._mode = "L"
else:
msg = f"Unsupported bitcount {bitcount} for {pfflags}"
raise OSError(msg)
elif pfflags & DDPF.LUMINANCE:
if bitcount == 8:
self._mode = "L"
Expand Down Expand Up @@ -418,7 +411,6 @@ def _open(self):
self.fp.read(16)
if dxgi_format in (
DXGI_FORMAT.BC1_UNORM,
DXGI_FORMAT.BC1_UNORM_SRGB,
DXGI_FORMAT.BC1_TYPELESS,
):
self._mode = "RGBA"
Expand Down

0 comments on commit 4c635e4

Please sign in to comment.