Small refactor

This commit is contained in:
REDxEYE 2022-08-25 15:45:48 +03:00
parent 7c25e0bbda
commit 91664c9d8e
2 changed files with 50 additions and 37 deletions

View File

@ -9,30 +9,33 @@ import sys
import sysconfig import sysconfig
import tempfile import tempfile
from io import BytesIO from io import BytesIO
from typing import List
import pytest import pytest
from packaging.version import parse as parse_version 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__) logger = logging.getLogger(__name__)
HAS_UPLOADER = False HAS_UPLOADER = False
if os.environ.get("SHOW_ERRORS"): if os.environ.get("SHOW_ERRORS"):
# local img.show for errors. # local img.show for errors.
HAS_UPLOADER = True HAS_UPLOADER = True
class test_image_results: class test_image_results:
@staticmethod @staticmethod
def upload(a, b): def upload(a, b):
a.show() diff = ImageChops.difference(a.convert("RGB"), b.convert("RGB"))
b.show() c = concat_h([a, b, diff])
c.show()
elif "GITHUB_ACTIONS" in os.environ: elif "GITHUB_ACTIONS" in os.environ:
HAS_UPLOADER = True HAS_UPLOADER = True
class test_image_results: class test_image_results:
@staticmethod @staticmethod
def upload(a, b): def upload(a, b):
@ -52,6 +55,19 @@ else:
pass 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): def convert_to_comparable(a, b):
new_a, new_b = a, b new_a, new_b = a, b
if a.mode == "P": if a.mode == "P":

View File

@ -9,7 +9,7 @@ The contents of this file are hereby released in the public domain (CC0)
Full text of the CC0 license: Full text of the CC0 license:
https://creativecommons.org/publicdomain/zero/1.0/ https://creativecommons.org/publicdomain/zero/1.0/
""" """
import io
import struct import struct
from enum import IntEnum, IntFlag from enum import IntEnum, IntFlag
from io import BytesIO from io import BytesIO
@ -305,99 +305,96 @@ class DdsImageFile(ImageFile.ImageFile):
fourcc = D3DFMT(fourcc_) fourcc = D3DFMT(fourcc_)
masks = struct.unpack("<4I", header.read(16)) masks = struct.unpack("<4I", header.read(16))
if flags & DDSD.CAPS: if flags & DDSD.CAPS:
(caps1_, caps2_, caps3, caps4, _,) = struct.unpack("<5I", header.read(20)) header.seek(20, io.SEEK_CUR)
else: extents = (0, 0) + self.size
(caps1_, caps2_, caps3, caps4, _,) = (0, 0, 0, 0, 0,)
_ = DDSCAPS(caps1_)
_ = DDSCAPS2(caps2_)
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 == 24:
rawmode = masks[0x00FF0000] + masks[0x0000FF00] + masks[0x000000FF] rawmode = masks[0x00FF0000] + masks[0x0000FF00] + masks[0x000000FF]
self.mode = "RGB" 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: elif bitcount == 32 and pfflags & DDPF.ALPHAPIXELS:
self.mode = "RGBA" self.mode = "RGBA"
rawmode = (masks[0xFF000000] + rawmode = (masks[0xFF000000] +
masks[0x00FF0000] + masks[0x00FF0000] +
masks[0x0000FF00] + masks[0x0000FF00] +
masks[0x000000FF]) masks[0x000000FF])
self.tile = [("raw", (0, 0) + self.size, 0, (rawmode[::-1], 0, 1))] self.tile = [("raw", extents, 0, (rawmode[::-1], 0, 1))]
else: else:
raise OSError(f"Unsupported bitcount {bitcount} for {pfflags} DDS texture") raise OSError(f"Unsupported bitcount {bitcount} for {pfflags}")
elif pfflags & DDPF.LUMINANCE: elif pfflags & DDPF.LUMINANCE:
if bitcount == 8: if bitcount == 8:
self.mode = "L" 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: elif bitcount == 16 and pfflags & DDPF.ALPHAPIXELS:
self.mode = "LA" self.mode = "LA"
self.tile = [("raw", (0, 0) + self.size, 0, ("LA", 0, 1))] self.tile = [("raw", extents, 0, ("LA", 0, 1))]
else: else:
raise OSError(f"Unsupported bitcount {bitcount} for {pfflags} DDS texture") raise OSError(f"Unsupported bitcount {bitcount} for {pfflags}")
elif pfflags & DDPF.FOURCC: elif pfflags & DDPF.FOURCC:
data_start = header_size + 4 data_offs = header_size + 4
if fourcc == D3DFMT.DXT1: if fourcc == D3DFMT.DXT1:
self.mode = "RGBA" self.mode = "RGBA"
self.pixel_format = "DXT1" 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: elif fourcc == D3DFMT.DXT3:
self.mode = "RGBA" self.mode = "RGBA"
self.pixel_format = "DXT3" 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: elif fourcc == D3DFMT.DXT5:
self.mode = "RGBA" self.mode = "RGBA"
self.pixel_format = "DXT5" 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: elif fourcc == D3DFMT.ATI1:
self.mode = "L" self.mode = "L"
self.pixel_format = "BC4" 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: elif fourcc == D3DFMT.BC5S:
self.mode = "RGB" self.mode = "RGB"
self.pixel_format = "BC5S" 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: elif fourcc == D3DFMT.ATI2:
self.mode = "RGB" self.mode = "RGB"
self.pixel_format = "BC5" 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: elif fourcc == D3DFMT.DX10:
data_start += 20 data_offs += 20
# ignoring flags which pertain to volume textures and cubemaps # ignoring flags which pertain to volume textures and cubemaps
(dxgi_format,) = struct.unpack("<I", self.fp.read(4)) (dxgi_format,) = struct.unpack("<I", self.fp.read(4))
self.fp.read(16) self.fp.read(16)
if dxgi_format in (DXGI_FORMAT.BC5_TYPELESS, DXGI_FORMAT.BC5_UNORM): if dxgi_format in (DXGI_FORMAT.BC5_TYPELESS, DXGI_FORMAT.BC5_UNORM):
self.mode = "RGB" self.mode = "RGB"
self.pixel_format = "BC5" 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: elif dxgi_format == DXGI_FORMAT.BC5_SNORM:
self.mode = "RGB" self.mode = "RGB"
self.pixel_format = "BC5S" 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 == DXGI_FORMAT.BC6H_UF16: elif dxgi_format == DXGI_FORMAT.BC6H_UF16:
self.mode = "RGB" self.mode = "RGB"
self.pixel_format = "BC6H" self.pixel_format = "BC6H"
tile = Image.Tile("bcn", (0, 0) + self.size, data_start, (6, self.pixel_format)) tile = Image.Tile("bcn", extents, data_offs, (6, self.pixel_format))
elif dxgi_format == DXGI_FORMAT.BC6H_SF16: elif dxgi_format == DXGI_FORMAT.BC6H_SF16:
self.mode = "RGB" self.mode = "RGB"
self.pixel_format = "BC6HS" self.pixel_format = "BC6HS"
tile = Image.Tile("bcn", (0, 0) + self.size, data_start, (6, self.pixel_format)) tile = Image.Tile("bcn", extents, data_offs, (6, self.pixel_format))
elif dxgi_format in (DXGI_FORMAT.BC7_TYPELESS, DXGI_FORMAT.BC7_UNORM): elif dxgi_format in (DXGI_FORMAT.BC7_TYPELESS, DXGI_FORMAT.BC7_UNORM):
self.mode = "RGBA" self.mode = "RGBA"
self.pixel_format = "BC7" 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: elif dxgi_format == DXGI_FORMAT.BC7_UNORM_SRGB:
self.mode = "RGBA" self.mode = "RGBA"
self.pixel_format = "BC7" self.pixel_format = "BC7"
self.info["gamma"] = 1 / 2.2 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 ( elif dxgi_format in (
DXGI_FORMAT.R8G8B8A8_TYPELESS, DXGI_FORMAT.R8G8B8A8_TYPELESS,
DXGI_FORMAT.R8G8B8A8_UNORM, DXGI_FORMAT.R8G8B8A8_UNORM,
DXGI_FORMAT.R8G8B8A8_UNORM_SRGB, DXGI_FORMAT.R8G8B8A8_UNORM_SRGB,
): ):
self.mode = "RGBA" 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: if dxgi_format == DXGI_FORMAT.R8G8B8A8_UNORM_SRGB:
self.info["gamma"] = 1 / 2.2 self.info["gamma"] = 1 / 2.2
else: else: