Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f02429d

Browse files
isHarryhK0lb3
authored andcommittedMay 31, 2025·
refactor(Texture2DConverter): converter table
1 parent 1b30650 commit f02429d

File tree

1 file changed

+109
-108
lines changed

1 file changed

+109
-108
lines changed
 

‎UnityPy/export/Texture2DConverter.py

Lines changed: 109 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from __future__ import annotations
1+
from __future__ import annotations
22

33
import struct
44
from io import BytesIO
@@ -8,7 +8,6 @@
88
import astc_encoder
99
import texture2ddecoder
1010
from PIL import Image
11-
from typing_extensions import Unpack
1211

1312
from ..enums import BuildTarget, TextureFormat
1413
from ..helpers import TextureSwizzler
@@ -235,11 +234,11 @@ def image_to_texture2d(
235234
assert platform_blob is not None
236235
gobsPerBlock = TextureSwizzler.get_switch_gobs_per_block(platform_blob)
237236
s_tex_format = tex_format
238-
if tex_format == TextureFormat.RGB24:
239-
s_tex_format = TextureFormat.RGBA32
237+
if tex_format == TF.RGB24:
238+
s_tex_format = TF.RGBA32
240239
pil_mode = "RGBA"
241-
elif tex_format == TextureFormat.BGR24:
242-
s_tex_format = TextureFormat.BGRA32
240+
elif tex_format == TF.BGR24:
241+
s_tex_format = TF.BGRA32
243242
pil_mode = "BGRA"
244243
block_size = TextureSwizzler.TEXTUREFORMAT_BLOCK_SIZE_MAP[s_tex_format]
245244
width, height = TextureSwizzler.get_padded_texture_size(
@@ -311,10 +310,10 @@ def parse_image_data(
311310
# due to earlier check platform_blob can't be None
312311
assert platform_blob is not None
313312
gobsPerBlock = TextureSwizzler.get_switch_gobs_per_block(platform_blob)
314-
if texture_format == TextureFormat.RGB24:
315-
texture_format = TextureFormat.RGBA32
316-
elif texture_format == TextureFormat.BGR24:
317-
texture_format = TextureFormat.BGRA32
313+
if texture_format == TF.RGB24:
314+
texture_format = TF.RGBA32
315+
elif texture_format == TF.BGR24:
316+
texture_format = TF.BGRA32
318317
block_size = TextureSwizzler.TEXTUREFORMAT_BLOCK_SIZE_MAP[texture_format]
319318
width, height = TextureSwizzler.get_padded_texture_size(
320319
width, height, *block_size, gobsPerBlock
@@ -325,11 +324,6 @@ def parse_image_data(
325324
else:
326325
width, height = get_compressed_image_size(width, height, texture_format)
327326

328-
selection = CONV_TABLE[texture_format]
329-
330-
if not selection:
331-
raise NotImplementedError(f"Not implemented texture format: {texture_format}")
332-
333327
image_data = bytes(image_data)
334328

335329
if "Crunched" in texture_format.name:
@@ -343,7 +337,13 @@ def parse_image_data(
343337
else:
344338
image_data = texture2ddecoder.unpack_crunch(image_data)
345339

346-
img = selection[0](image_data, width, height, *selection[1:])
340+
if texture_format not in CONV_TABLE:
341+
raise NotImplementedError(
342+
f"Not implemented texture format: {texture_format.name}"
343+
)
344+
conv_func, conv_args = CONV_TABLE[texture_format]
345+
346+
img = conv_func(image_data, width, height, *conv_args)
347347

348348
if original_width != width or original_height != height:
349349
img = img.crop((0, 0, original_width, original_height))
@@ -443,22 +443,22 @@ def pvrtc(image_data: bytes, width: int, height: int, fmt: bool) -> Image.Image:
443443
return Image.frombytes("RGBA", (width, height), image_data, "raw", "BGRA")
444444

445445

446-
def etc(image_data: bytes, width: int, height: int, fmt: list) -> Image.Image:
447-
if fmt[0] == 1:
446+
def etc(image_data: bytes, width: int, height: int, fmt: str) -> Image.Image:
447+
if fmt == "ETC1":
448448
image_data = texture2ddecoder.decode_etc1(image_data, width, height)
449-
elif fmt[0] == 2:
450-
if fmt[1] == "RGB":
451-
image_data = texture2ddecoder.decode_etc2(image_data, width, height)
452-
elif fmt[1] == "A1":
453-
image_data = texture2ddecoder.decode_etc2a1(image_data, width, height)
454-
elif fmt[1] == "A8":
455-
image_data = texture2ddecoder.decode_etc2a8(image_data, width, height)
449+
elif fmt == "ETC2_RGB":
450+
image_data = texture2ddecoder.decode_etc2(image_data, width, height)
451+
elif fmt == "ETC2_A1":
452+
image_data = texture2ddecoder.decode_etc2a1(image_data, width, height)
453+
elif fmt == "ETC2_A8":
454+
image_data = texture2ddecoder.decode_etc2a8(image_data, width, height)
456455
else:
457-
raise NotImplementedError("unknown etc mode")
456+
raise NotImplementedError(f"Unknown ETC mode: {fmt}")
457+
458458
return Image.frombytes("RGBA", (width, height), image_data, "raw", "BGRA")
459459

460460

461-
def eac(image_data: bytes, width: int, height: int, fmt: list) -> Image.Image:
461+
def eac(image_data: bytes, width: int, height: int, fmt: str) -> Image.Image:
462462
if fmt == "EAC_R":
463463
image_data = texture2ddecoder.decode_eacr(image_data, width, height)
464464
elif fmt == "EAC_R_SIGNED":
@@ -467,6 +467,9 @@ def eac(image_data: bytes, width: int, height: int, fmt: list) -> Image.Image:
467467
image_data = texture2ddecoder.decode_eacrg(image_data, width, height)
468468
elif fmt == "EAC_RG_SIGNED":
469469
image_data = texture2ddecoder.decode_eacrg_signed(image_data, width, height)
470+
else:
471+
raise NotImplementedError(f"Unknown EAC mode: {fmt}")
472+
470473
return Image.frombytes("RGBA", (width, height), image_data, "raw", "BGRA")
471474

472475

@@ -530,87 +533,85 @@ def rgb9e5float(image_data: bytes, width: int, height: int) -> Image.Image:
530533
return Image.frombytes("RGB", (width, height), rgb, "raw", "RGB")
531534

532535

533-
# The type for the conversion table
534-
CONV_TABLE: Dict[TextureFormat, Optional[Tuple[Callable, Unpack[Tuple[Any, ...]]]]] = {
535-
# FORMAT FUNC #ARGS.....
536-
# ----------------------- -------- -------- ------------ ----------------- ------------ ----------
537-
TF.Alpha8: (pillow, "RGBA", "raw", "A"),
538-
TF.ARGB4444: (pillow, "RGBA", "raw", "RGBA;4B", (2, 1, 0, 3)),
539-
TF.RGB24: (pillow, "RGB", "raw", "RGB"),
540-
TF.RGBA32: (pillow, "RGBA", "raw", "RGBA"),
541-
TF.ARGB32: (pillow, "RGBA", "raw", "ARGB"),
542-
TF.ARGBFloat: (pillow, "RGBA", "raw", "RGBAF", (2, 1, 0, 3)),
543-
TF.RGB565: (pillow, "RGB", "raw", "BGR;16"),
544-
TF.BGR24: (pillow, "RGB", "raw", "BGR"),
545-
TF.R8: (pillow, "RGB", "raw", "R"),
546-
TF.R16: (pillow, "RGB", "raw", "R;16"),
547-
TF.RG16: (rg, "RGB", "raw", "RG"),
548-
TF.DXT1: (pillow, "RGBA", "bcn", 1),
549-
TF.DXT3: (pillow, "RGBA", "bcn", 2),
550-
TF.DXT5: (pillow, "RGBA", "bcn", 3),
551-
TF.RGBA4444: (pillow, "RGBA", "raw", "RGBA;4B", (3, 2, 1, 0)),
552-
TF.BGRA32: (pillow, "RGBA", "raw", "BGRA"),
553-
TF.RHalf: (half, "R", "raw", "R"),
554-
TF.RGHalf: (rg, "RGB", "raw", "RGE"),
555-
TF.RGBAHalf: (half, "RGB", "raw", "RGB"),
556-
TF.RFloat: (pillow, "RGB", "raw", "RF"),
557-
TF.RGFloat: (rg, "RGB", "raw", "RGF"),
558-
TF.RGBAFloat: (pillow, "RGBA", "raw", "RGBAF"),
559-
TF.YUY2: None,
560-
TF.RGB9e5Float: (rgb9e5float,),
561-
TF.BC4: (pillow, "L", "bcn", 4),
562-
TF.BC5: (pillow, "RGB", "bcn", 5),
563-
TF.BC6H: (pillow, "RGBA", "bcn", 6),
564-
TF.BC7: (pillow, "RGBA", "bcn", 7),
565-
TF.DXT1Crunched: (pillow, "RGBA", "bcn", 1),
566-
TF.DXT5Crunched: (pillow, "RGBA", "bcn", 3),
567-
TF.PVRTC_RGB2: (pvrtc, True),
568-
TF.PVRTC_RGBA2: (pvrtc, True),
569-
TF.PVRTC_RGB4: (pvrtc, False),
570-
TF.PVRTC_RGBA4: (pvrtc, False),
571-
TF.ETC_RGB4: (etc, (1,)),
572-
TF.ATC_RGB4: (atc, False),
573-
TF.ATC_RGBA8: (atc, True),
574-
TF.EAC_R: (eac, "EAC_R"),
575-
TF.EAC_R_SIGNED: (eac, "EAC_R:SIGNED"),
576-
TF.EAC_RG: (eac, "EAC_RG"),
577-
TF.EAC_RG_SIGNED: (eac, "EAC_RG_SIGNED"),
578-
TF.ETC2_RGB: (etc, (2, "RGB")),
579-
TF.ETC2_RGBA1: (etc, (2, "A1")),
580-
TF.ETC2_RGBA8: (etc, (2, "A8")),
581-
TF.ASTC_RGB_4x4: (astc, (4, 4)),
582-
TF.ASTC_RGB_5x5: (astc, (5, 5)),
583-
TF.ASTC_RGB_6x6: (astc, (6, 6)),
584-
TF.ASTC_RGB_8x8: (astc, (8, 8)),
585-
TF.ASTC_RGB_10x10: (astc, (10, 10)),
586-
TF.ASTC_RGB_12x12: (astc, (12, 12)),
587-
TF.ASTC_RGBA_4x4: (astc, (4, 4)),
588-
TF.ASTC_RGBA_5x5: (astc, (5, 5)),
589-
TF.ASTC_RGBA_6x6: (astc, (6, 6)),
590-
TF.ASTC_RGBA_8x8: (astc, (8, 8)),
591-
TF.ASTC_RGBA_10x10: (astc, (10, 10)),
592-
TF.ASTC_RGBA_12x12: (astc, (12, 12)),
593-
TF.ETC_RGB4_3DS: (etc, (1,)),
594-
TF.ETC_RGBA8_3DS: (etc, (1,)),
595-
TF.ETC_RGB4Crunched: (etc, (1,)),
596-
TF.ETC2_RGBA8Crunched: (etc, (2, "A8")),
597-
TF.ASTC_HDR_4x4: (astc, (4, 4)),
598-
TF.ASTC_HDR_5x5: (astc, (5, 5)),
599-
TF.ASTC_HDR_6x6: (astc, (6, 6)),
600-
TF.ASTC_HDR_8x8: (astc, (8, 8)),
601-
TF.ASTC_HDR_10x10: (astc, (10, 10)),
602-
TF.ASTC_HDR_12x12: (astc, (12, 12)),
603-
TF.RG32: (rg, "RGB", "raw", "RG;16"),
604-
TF.RGB48: (pillow, "RGB", "raw", "RGB;16"),
605-
TF.RGBA64: (pillow, "RGBA", "raw", "RGBA;16"),
606-
TF.R8_SIGNED: (pillow, "R", "raw", "R;8s"),
607-
TF.RG16_SIGNED: (rg, "RGB", "raw", "RG;8s"),
608-
TF.RGB24_SIGNED: (pillow, "RGB", "raw", "RGB;8s"),
609-
TF.RGBA32_SIGNED: (pillow, "RGBA", "raw", "RGBA;8s"),
610-
TF.R16_SIGNED: (pillow, "R", "raw", "R;16s"),
611-
TF.RG32_SIGNED: (rg, "RGB", "raw", "RG;16s"),
612-
TF.RGB48_SIGNED: (pillow, "RGB", "raw", "RGB;16s"),
613-
TF.RGBA64_SIGNED: (pillow, "RGBA", "raw", "RGBA;16s"),
536+
# Mapping TextureFormat -> (converter function, (additional args, ...))
537+
CONV_TABLE: Dict[TF, Tuple[Callable[..., Image.Image], Tuple[Any, ...]]] = {
538+
TF.Alpha8: (pillow, ("RGBA", "raw", "A")),
539+
TF.ARGB4444: (pillow, ("RGBA", "raw", "RGBA;4B", (2, 1, 0, 3))),
540+
TF.RGB24: (pillow, ("RGB", "raw", "RGB")),
541+
TF.RGBA32: (pillow, ("RGBA", "raw", "RGBA")),
542+
TF.ARGB32: (pillow, ("RGBA", "raw", "ARGB")),
543+
TF.ARGBFloat: (pillow, ("RGBA", "raw", "RGBAF", (2, 1, 0, 3))),
544+
TF.RGB565: (pillow, ("RGB", "raw", "BGR;16")),
545+
TF.BGR24: (pillow, ("RGB", "raw", "BGR")),
546+
TF.R8: (pillow, ("RGB", "raw", "R")),
547+
TF.R16: (pillow, ("RGB", "raw", "R;16")),
548+
TF.RG16: (rg, ("RGB", "raw", "RG")),
549+
TF.DXT1: (pillow, ("RGBA", "bcn", 1)),
550+
TF.DXT3: (pillow, ("RGBA", "bcn", 2)),
551+
TF.DXT5: (pillow, ("RGBA", "bcn", 3)),
552+
TF.RGBA4444: (pillow, ("RGBA", "raw", "RGBA;4B", (3, 2, 1, 0))),
553+
TF.BGRA32: (pillow, ("RGBA", "raw", "BGRA")),
554+
TF.RHalf: (half, ("R", "raw", "R")),
555+
TF.RGHalf: (rg, ("RGB", "raw", "RGE")),
556+
TF.RGBAHalf: (half, ("RGB", "raw", "RGB")),
557+
TF.RFloat: (pillow, ("RGB", "raw", "RF")),
558+
TF.RGFloat: (rg, ("RGB", "raw", "RGF")),
559+
TF.RGBAFloat: (pillow, ("RGBA", "raw", "RGBAF")),
560+
# TF.YUY2: NotImplementedError("YUY2 not implemented"),
561+
TF.RGB9e5Float: (rgb9e5float, ()),
562+
TF.BC4: (pillow, ("L", "bcn", 4)),
563+
TF.BC5: (pillow, ("RGB", "bcn", 5)),
564+
TF.BC6H: (pillow, ("RGBA", "bcn", 6)),
565+
TF.BC7: (pillow, ("RGBA", "bcn", 7)),
566+
TF.DXT1Crunched: (pillow, ("RGBA", "bcn", 1)),
567+
TF.DXT5Crunched: (pillow, ("RGBA", "bcn", 3)),
568+
TF.PVRTC_RGB2: (pvrtc, (True,)),
569+
TF.PVRTC_RGBA2: (pvrtc, (True,)),
570+
TF.PVRTC_RGB4: (pvrtc, (False,)),
571+
TF.PVRTC_RGBA4: (pvrtc, (False,)),
572+
TF.ETC_RGB4: (etc, ("ETC1",)),
573+
TF.ATC_RGB4: (atc, (False,)),
574+
TF.ATC_RGBA8: (atc, (True,)),
575+
TF.EAC_R: (eac, ("EAC_R",)),
576+
TF.EAC_R_SIGNED: (eac, ("EAC_R_SIGNED",)),
577+
TF.EAC_RG: (eac, ("EAC_RG",)),
578+
TF.EAC_RG_SIGNED: (eac, ("EAC_RG_SIGNED",)),
579+
TF.ETC2_RGB: (etc, ("ETC2_RGB",)),
580+
TF.ETC2_RGBA1: (etc, ("ETC2_A1",)),
581+
TF.ETC2_RGBA8: (etc, ("ETC2_A8",)),
582+
TF.ASTC_RGB_4x4: (astc, ((4, 4),)),
583+
TF.ASTC_RGB_5x5: (astc, ((5, 5),)),
584+
TF.ASTC_RGB_6x6: (astc, ((6, 6),)),
585+
TF.ASTC_RGB_8x8: (astc, ((8, 8),)),
586+
TF.ASTC_RGB_10x10: (astc, ((10, 10),)),
587+
TF.ASTC_RGB_12x12: (astc, ((12, 12),)),
588+
TF.ASTC_RGBA_4x4: (astc, ((4, 4),)),
589+
TF.ASTC_RGBA_5x5: (astc, ((5, 5),)),
590+
TF.ASTC_RGBA_6x6: (astc, ((6, 6),)),
591+
TF.ASTC_RGBA_8x8: (astc, ((8, 8),)),
592+
TF.ASTC_RGBA_10x10: (astc, ((10, 10),)),
593+
TF.ASTC_RGBA_12x12: (astc, ((12, 12),)),
594+
TF.ETC_RGB4_3DS: (etc, ("ETC1",)),
595+
TF.ETC_RGBA8_3DS: (etc, ("ETC1",)),
596+
TF.ETC_RGB4Crunched: (etc, ("ETC1",)),
597+
TF.ETC2_RGBA8Crunched: (etc, ("ETC2_A8",)),
598+
TF.ASTC_HDR_4x4: (astc, ((4, 4),)),
599+
TF.ASTC_HDR_5x5: (astc, ((5, 5),)),
600+
TF.ASTC_HDR_6x6: (astc, ((6, 6),)),
601+
TF.ASTC_HDR_8x8: (astc, ((8, 8),)),
602+
TF.ASTC_HDR_10x10: (astc, ((10, 10),)),
603+
TF.ASTC_HDR_12x12: (astc, ((12, 12),)),
604+
TF.RG32: (rg, ("RGB", "raw", "RG;16")),
605+
TF.RGB48: (pillow, ("RGB", "raw", "RGB;16")),
606+
TF.RGBA64: (pillow, ("RGBA", "raw", "RGBA;16")),
607+
TF.R8_SIGNED: (pillow, ("R", "raw", "R;8s")),
608+
TF.RG16_SIGNED: (rg, ("RGB", "raw", "RG;8s")),
609+
TF.RGB24_SIGNED: (pillow, ("RGB", "raw", "RGB;8s")),
610+
TF.RGBA32_SIGNED: (pillow, ("RGBA", "raw", "RGBA;8s")),
611+
TF.R16_SIGNED: (pillow, ("R", "raw", "R;16s")),
612+
TF.RG32_SIGNED: (rg, ("RGB", "raw", "RG;16s")),
613+
TF.RGB48_SIGNED: (pillow, ("RGB", "raw", "RGB;16s")),
614+
TF.RGBA64_SIGNED: (pillow, ("RGBA", "raw", "RGBA;16s")),
614615
}
615616

616617
# XBOX Swap Formats

0 commit comments

Comments
 (0)
Please sign in to comment.