1
- from __future__ import annotations
1
+ from __future__ import annotations
2
2
3
3
import struct
4
4
from io import BytesIO
8
8
import astc_encoder
9
9
import texture2ddecoder
10
10
from PIL import Image
11
- from typing_extensions import Unpack
12
11
13
12
from ..enums import BuildTarget , TextureFormat
14
13
from ..helpers import TextureSwizzler
@@ -235,11 +234,11 @@ def image_to_texture2d(
235
234
assert platform_blob is not None
236
235
gobsPerBlock = TextureSwizzler .get_switch_gobs_per_block (platform_blob )
237
236
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
240
239
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
243
242
pil_mode = "BGRA"
244
243
block_size = TextureSwizzler .TEXTUREFORMAT_BLOCK_SIZE_MAP [s_tex_format ]
245
244
width , height = TextureSwizzler .get_padded_texture_size (
@@ -311,10 +310,10 @@ def parse_image_data(
311
310
# due to earlier check platform_blob can't be None
312
311
assert platform_blob is not None
313
312
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
318
317
block_size = TextureSwizzler .TEXTUREFORMAT_BLOCK_SIZE_MAP [texture_format ]
319
318
width , height = TextureSwizzler .get_padded_texture_size (
320
319
width , height , * block_size , gobsPerBlock
@@ -325,11 +324,6 @@ def parse_image_data(
325
324
else :
326
325
width , height = get_compressed_image_size (width , height , texture_format )
327
326
328
- selection = CONV_TABLE [texture_format ]
329
-
330
- if not selection :
331
- raise NotImplementedError (f"Not implemented texture format: { texture_format } " )
332
-
333
327
image_data = bytes (image_data )
334
328
335
329
if "Crunched" in texture_format .name :
@@ -343,7 +337,13 @@ def parse_image_data(
343
337
else :
344
338
image_data = texture2ddecoder .unpack_crunch (image_data )
345
339
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 )
347
347
348
348
if original_width != width or original_height != height :
349
349
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:
443
443
return Image .frombytes ("RGBA" , (width , height ), image_data , "raw" , "BGRA" )
444
444
445
445
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" :
448
448
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 )
456
455
else :
457
- raise NotImplementedError ("unknown etc mode" )
456
+ raise NotImplementedError (f"Unknown ETC mode: { fmt } " )
457
+
458
458
return Image .frombytes ("RGBA" , (width , height ), image_data , "raw" , "BGRA" )
459
459
460
460
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 :
462
462
if fmt == "EAC_R" :
463
463
image_data = texture2ddecoder .decode_eacr (image_data , width , height )
464
464
elif fmt == "EAC_R_SIGNED" :
@@ -467,6 +467,9 @@ def eac(image_data: bytes, width: int, height: int, fmt: list) -> Image.Image:
467
467
image_data = texture2ddecoder .decode_eacrg (image_data , width , height )
468
468
elif fmt == "EAC_RG_SIGNED" :
469
469
image_data = texture2ddecoder .decode_eacrg_signed (image_data , width , height )
470
+ else :
471
+ raise NotImplementedError (f"Unknown EAC mode: { fmt } " )
472
+
470
473
return Image .frombytes ("RGBA" , (width , height ), image_data , "raw" , "BGRA" )
471
474
472
475
@@ -530,87 +533,85 @@ def rgb9e5float(image_data: bytes, width: int, height: int) -> Image.Image:
530
533
return Image .frombytes ("RGB" , (width , height ), rgb , "raw" , "RGB" )
531
534
532
535
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" )),
614
615
}
615
616
616
617
# XBOX Swap Formats
0 commit comments