mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-14 05:36:48 +03:00
Merge pull request #7 from radarhere/improved_dds
Support RGB bitcount 8
This commit is contained in:
commit
4c635e4ffc
BIN
Tests/images/bc1.dds
Executable file
BIN
Tests/images/bc1.dds
Executable file
Binary file not shown.
BIN
Tests/images/bc1_typeless.dds
Executable file
BIN
Tests/images/bc1_typeless.dds
Executable file
Binary file not shown.
BIN
Tests/images/rgb8.dds
Normal file
BIN
Tests/images/rgb8.dds
Normal file
Binary file not shown.
BIN
Tests/images/unsupported_bitcount_luminance.dds
Normal file
BIN
Tests/images/unsupported_bitcount_luminance.dds
Normal file
Binary file not shown.
BIN
Tests/images/unsupported_bitcount_rgb.dds
Normal file
BIN
Tests/images/unsupported_bitcount_rgb.dds
Normal file
Binary file not shown.
|
@ -15,6 +15,8 @@ TEST_FILE_ATI2 = "Tests/images/ati2.dds"
|
||||||
TEST_FILE_DX10_BC5_TYPELESS = "Tests/images/bc5_typeless.dds"
|
TEST_FILE_DX10_BC5_TYPELESS = "Tests/images/bc5_typeless.dds"
|
||||||
TEST_FILE_DX10_BC5_UNORM = "Tests/images/bc5_unorm.dds"
|
TEST_FILE_DX10_BC5_UNORM = "Tests/images/bc5_unorm.dds"
|
||||||
TEST_FILE_DX10_BC5_SNORM = "Tests/images/bc5_snorm.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_BC5S = "Tests/images/bc5s.dds"
|
||||||
TEST_FILE_BC5U = "Tests/images/bc5u.dds"
|
TEST_FILE_BC5U = "Tests/images/bc5u.dds"
|
||||||
TEST_FILE_BC6H = "Tests/images/bc6h.dds"
|
TEST_FILE_BC6H = "Tests/images/bc6h.dds"
|
||||||
|
@ -29,11 +31,20 @@ TEST_FILE_UNCOMPRESSED_RGB = "Tests/images/hopper.dds"
|
||||||
TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA = "Tests/images/uncompressed_rgb.dds"
|
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"""
|
"""Check DXT1 images can be opened"""
|
||||||
with Image.open(TEST_FILE_DXT1.replace(".dds", ".png")) as target:
|
with Image.open(TEST_FILE_DXT1.replace(".dds", ".png")) as target:
|
||||||
target = target.convert("RGBA")
|
target = target.convert("RGBA")
|
||||||
with Image.open(TEST_FILE_DXT1) as im:
|
with Image.open(image_path) as im:
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
assert im.format == "DDS"
|
assert im.format == "DDS"
|
||||||
|
@ -306,8 +317,19 @@ def test_palette():
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_file",
|
"test_file",
|
||||||
(
|
(
|
||||||
"Tests/images/unknown_fourcc.dds",
|
"Tests/images/unsupported_bitcount_rgb.dds",
|
||||||
"Tests/images/unimplemented_fourcc.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_dxgi_format.dds",
|
||||||
"Tests/images/unimplemented_pfflags.dds",
|
"Tests/images/unimplemented_pfflags.dds",
|
||||||
),
|
),
|
||||||
|
@ -340,6 +362,12 @@ def test_open(mode, test_file):
|
||||||
assert_image_equal_tofile(im, test_file.replace(".dds", ".png"))
|
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(
|
@pytest.mark.parametrize(
|
||||||
("mode", "test_file"),
|
("mode", "test_file"),
|
||||||
[
|
[
|
||||||
|
|
|
@ -346,34 +346,27 @@ class DdsImageFile(ImageFile.ImageFile):
|
||||||
# pixel format
|
# pixel format
|
||||||
pfsize, pfflags, fourcc, bitcount = struct.unpack("<4I", header.read(16))
|
pfsize, pfflags, fourcc, bitcount = struct.unpack("<4I", header.read(16))
|
||||||
masks = 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
|
n = 0
|
||||||
rawmode = None
|
rawmode = None
|
||||||
if pfflags & DDPF.RGB:
|
if pfflags & DDPF.RGB:
|
||||||
# Texture contains uncompressed RGB data
|
# Texture contains uncompressed RGB data
|
||||||
masks = {mask: ["R", "G", "B", "A"][i] for i, mask in enumerate(masks)}
|
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"
|
self._mode = "RGB"
|
||||||
rawmode = masks[0x00FF0000] + masks[0x0000FF00] + masks[0x000000FF]
|
rawmode = masks[0x000000FF] + masks[0x0000FF00] + masks[0x00FF0000]
|
||||||
elif bitcount == 32 and pfflags & DDPF.ALPHAPIXELS:
|
elif bitcount == 32 and pfflags & DDPF.ALPHAPIXELS:
|
||||||
self._mode = "RGBA"
|
self._mode = "RGBA"
|
||||||
rawmode = (
|
rawmode = (
|
||||||
masks[0xFF000000]
|
masks[0x000000FF]
|
||||||
+ masks[0x00FF0000]
|
|
||||||
+ masks[0x0000FF00]
|
+ masks[0x0000FF00]
|
||||||
+ masks[0x000000FF]
|
+ masks[0x00FF0000]
|
||||||
|
+ masks[0xFF000000]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
msg = f"Unsupported bitcount {bitcount} for {pfflags}"
|
msg = f"Unsupported bitcount {bitcount} for {pfflags}"
|
||||||
raise OSError(msg)
|
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:
|
elif pfflags & DDPF.LUMINANCE:
|
||||||
if bitcount == 8:
|
if bitcount == 8:
|
||||||
self._mode = "L"
|
self._mode = "L"
|
||||||
|
@ -418,7 +411,6 @@ class DdsImageFile(ImageFile.ImageFile):
|
||||||
self.fp.read(16)
|
self.fp.read(16)
|
||||||
if dxgi_format in (
|
if dxgi_format in (
|
||||||
DXGI_FORMAT.BC1_UNORM,
|
DXGI_FORMAT.BC1_UNORM,
|
||||||
DXGI_FORMAT.BC1_UNORM_SRGB,
|
|
||||||
DXGI_FORMAT.BC1_TYPELESS,
|
DXGI_FORMAT.BC1_TYPELESS,
|
||||||
):
|
):
|
||||||
self._mode = "RGBA"
|
self._mode = "RGBA"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user