Skip to content

Commit

Permalink
Small refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
REDxEYE committed Aug 25, 2022
1 parent b996c51 commit faebb96
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 35 deletions.
36 changes: 26 additions & 10 deletions Tests/helper.py
Expand Up @@ -9,30 +9,33 @@
import sysconfig
import tempfile
from io import BytesIO
from typing import List

import pytest
from packaging.version import parse as parse_version

from PIL import Image, ImageMath, features
from PIL import Image, ImageMath, features, ImageChops

logger = logging.getLogger(__name__)


HAS_UPLOADER = False

if os.environ.get("SHOW_ERRORS", None):
# local img.show for errors.
HAS_UPLOADER = True


class test_image_results:
@staticmethod
def upload(a, b):
a.show()
b.show()
diff = ImageChops.difference(a.convert("RGB"), b.convert("RGB"))
c = concat_h([a, b, diff])
c.show()

elif "GITHUB_ACTIONS" in os.environ:
HAS_UPLOADER = True


class test_image_results:
@staticmethod
def upload(a, b):
Expand All @@ -52,6 +55,19 @@ def upload(a, b):
pass


def concat_h(images: List[Image.Image]):
new_size = images[0].size
for image in images[1:]:
assert image.height == new_size[1]
new_size = (new_size[0] + image.width, new_size[1])
dst = Image.new('RGBA', new_size)
x_offset = 0
for image in images:
dst.paste(image, (x_offset, 0))
x_offset += image.width
return dst


def convert_to_comparable(a, b):
new_a, new_b = a, b
if a.mode == "P":
Expand All @@ -75,12 +91,12 @@ def assert_deep_equal(a, b, msg=None):
def assert_image(im, mode, size, msg=None):
if mode is not None:
assert im.mode == mode, (
msg or f"got mode {repr(im.mode)}, expected {repr(mode)}"
msg or f"got mode {repr(im.mode)}, expected {repr(mode)}"
)

if size is not None:
assert im.size == size, (
msg or f"got size {repr(im.size)}, expected {repr(size)}"
msg or f"got size {repr(im.size)}, expected {repr(size)}"
)


Expand Down Expand Up @@ -119,8 +135,8 @@ def assert_image_similar(a, b, epsilon, msg=None):
ave_diff = diff / (a.size[0] * a.size[1])
try:
assert epsilon >= ave_diff, (
(msg or "")
+ f" average pixel value difference {ave_diff:.4f} > epsilon {epsilon:.4f}"
(msg or "")
+ f" average pixel value difference {ave_diff:.4f} > epsilon {epsilon:.4f}"
)
except Exception as e:
if HAS_UPLOADER:
Expand Down Expand Up @@ -179,8 +195,8 @@ def mark_if_feature_version(mark, feature, version_blacklist, reason=None):
version_required = parse_version(version_blacklist)
version_available = parse_version(features.version(feature))
if (
version_available.major == version_required.major
and version_available.minor == version_required.minor
version_available.major == version_required.major
and version_available.minor == version_required.minor
):
return mark(reason=reason)
return pytest.mark.pil_noop_mark()
Expand Down
47 changes: 22 additions & 25 deletions src/PIL/DdsImagePlugin.py
Expand Up @@ -9,7 +9,7 @@
Full text of the CC0 license:
https://creativecommons.org/publicdomain/zero/1.0/
"""

import io
import struct
from enum import IntEnum, IntFlag
from io import BytesIO
Expand Down Expand Up @@ -302,91 +302,88 @@ def _open(self):
fourcc = D3DFMT(fourcc_)
masks = struct.unpack("<4I", header.read(16))
if flags & DDSD.CAPS:
(caps1_, caps2_, caps3, caps4, _,) = struct.unpack("<5I", header.read(20))
else:
(caps1_, caps2_, caps3, caps4, _,) = (0, 0, 0, 0, 0,)
_ = DDSCAPS(caps1_)
_ = DDSCAPS2(caps2_)
header.seek(20, io.SEEK_CUR)
extents = (0, 0) + self.size
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:
rawmode = masks[0x00FF0000] + masks[0x0000FF00] + masks[0x000000FF]
self.mode = "RGB"
self.tile = [("raw", (0, 0) + self.size, 0, (rawmode[::-1], 0, 1))]
self.tile = [("raw", extents, 0, (rawmode[::-1], 0, 1))]
elif bitcount == 32 and pfflags & DDPF.ALPHAPIXELS:
self.mode = "RGBA"
rawmode = (masks[0xFF000000] +
masks[0x00FF0000] +
masks[0x0000FF00] +
masks[0x000000FF])
self.tile = [("raw", (0, 0) + self.size, 0, (rawmode[::-1], 0, 1))]
self.tile = [("raw", extents, 0, (rawmode[::-1], 0, 1))]
else:
raise OSError(f"Unsupported bitcount {bitcount} for {pfflags} DDS texture")
raise OSError(f"Unsupported bitcount {bitcount} for {pfflags}")
elif pfflags & DDPF.LUMINANCE:
if bitcount == 8:
self.mode = "L"
self.tile = [("raw", (0, 0) + self.size, 0, ("L", 0, 1))]
self.tile = [("raw", extents, 0, ("L", 0, 1))]
elif bitcount == 16 and pfflags & DDPF.ALPHAPIXELS:
self.mode = "LA"
self.tile = [("raw", (0, 0) + self.size, 0, ("LA", 0, 1))]
self.tile = [("raw", extents, 0, ("LA", 0, 1))]
else:
raise OSError(f"Unsupported bitcount {bitcount} for {pfflags} DDS texture")
raise OSError(f"Unsupported bitcount {bitcount} for {pfflags}")
elif pfflags & DDPF.FOURCC:
data_start = header_size + 4
data_offs = header_size + 4
if fourcc == D3DFMT.DXT1:
self.mode = "RGBA"
self.pixel_format = "DXT1"
tile = Image.Tile("bcn", (0, 0) + self.size, data_start, (1, self.pixel_format))
tile = Image.Tile("bcn", extents, data_offs, (1, self.pixel_format))
elif fourcc == D3DFMT.DXT3:
self.mode = "RGBA"
self.pixel_format = "DXT3"
tile = Image.Tile("bcn", (0, 0) + self.size, data_start, (2, self.pixel_format))
tile = Image.Tile("bcn", extents, data_offs, (2, self.pixel_format))
elif fourcc == D3DFMT.DXT5:
self.mode = "RGBA"
self.pixel_format = "DXT5"
tile = Image.Tile("bcn", (0, 0) + self.size, data_start, (3, self.pixel_format))
tile = Image.Tile("bcn", extents, data_offs, (3, self.pixel_format))
elif fourcc == D3DFMT.ATI1:
self.mode = "L"
self.pixel_format = "BC4"
tile = Image.Tile("bcn", (0, 0) + self.size, data_start, (4, self.pixel_format))
tile = Image.Tile("bcn", extents, data_offs, (4, self.pixel_format))
elif fourcc == D3DFMT.BC5S:
self.mode = "RGB"
self.pixel_format = "BC5S"
tile = Image.Tile("bcn", (0, 0) + self.size, data_start, (5, self.pixel_format))
tile = Image.Tile("bcn", extents, data_offs, (5, self.pixel_format))
elif fourcc == D3DFMT.ATI2:
self.mode = "RGB"
self.pixel_format = "BC5"
tile = Image.Tile("bcn", (0, 0) + self.size, data_start, (5, self.pixel_format))
tile = Image.Tile("bcn", extents, data_offs, (5, self.pixel_format))
elif fourcc == D3DFMT.DX10:
data_start += 20
data_offs += 20
# ignoring flags which pertain to volume textures and cubemaps
(dxgi_format,) = struct.unpack("<I", self.fp.read(4))
self.fp.read(16)
if dxgi_format in (DXGI_FORMAT.BC5_TYPELESS, DXGI_FORMAT.BC5_UNORM):
self.mode = "RGB"
self.pixel_format = "BC5"
tile = Image.Tile("bcn", (0, 0) + self.size, data_start, (5, self.pixel_format))
tile = Image.Tile("bcn", extents, data_offs, (5, self.pixel_format))
elif dxgi_format == DXGI_FORMAT.BC5_SNORM:
self.mode = "RGB"
self.pixel_format = "BC5S"
tile = Image.Tile("bcn", (0, 0) + self.size, data_start, (5, self.pixel_format))
tile = Image.Tile("bcn", extents, data_offs, (5, self.pixel_format))
elif dxgi_format in (DXGI_FORMAT.BC7_TYPELESS, DXGI_FORMAT.BC7_UNORM):
self.mode = "RGBA"
self.pixel_format = "BC7"
tile = Image.Tile("bcn", (0, 0) + self.size, data_start, (7, self.pixel_format))
tile = Image.Tile("bcn", extents, data_offs, (7, self.pixel_format))
elif dxgi_format == DXGI_FORMAT.BC7_UNORM_SRGB:
self.mode = "RGBA"
self.pixel_format = "BC7"
self.info["gamma"] = 1 / 2.2
tile = Image.Tile("bcn", (0, 0) + self.size, data_start, (7, self.pixel_format))
tile = Image.Tile("bcn", extents, data_offs, (7, self.pixel_format))
elif dxgi_format in (
DXGI_FORMAT.R8G8B8A8_TYPELESS,
DXGI_FORMAT.R8G8B8A8_UNORM,
DXGI_FORMAT.R8G8B8A8_UNORM_SRGB,
):
self.mode = "RGBA"
tile = Image.Tile("raw", (0, 0) + self.size, 0, ("RGBA", 0, 1))
tile = Image.Tile("raw", extents, 0, ("RGBA", 0, 1))
if dxgi_format == DXGI_FORMAT.R8G8B8A8_UNORM_SRGB:
self.info["gamma"] = 1 / 2.2
else:
Expand Down

0 comments on commit faebb96

Please sign in to comment.