1- from __future__ import annotations
1+ from __future__ import annotations
22
33import struct
44from io import BytesIO
88import astc_encoder
99import texture2ddecoder
1010from PIL import Image
11- from typing_extensions import Unpack
1211
1312from ..enums import BuildTarget , TextureFormat
1413from ..helpers import TextureSwizzler
@@ -237,11 +236,11 @@ def image_to_texture2d(
237236 assert platform_blob is not None
238237 gobsPerBlock = TextureSwizzler .get_switch_gobs_per_block (platform_blob )
239238 s_tex_format = tex_format
240- if tex_format == TextureFormat .RGB24 :
241- s_tex_format = TextureFormat .RGBA32
239+ if tex_format == TF .RGB24 :
240+ s_tex_format = TF .RGBA32
242241 pil_mode = "RGBA"
243- elif tex_format == TextureFormat .BGR24 :
244- s_tex_format = TextureFormat .BGRA32
242+ elif tex_format == TF .BGR24 :
243+ s_tex_format = TF .BGRA32
245244 pil_mode = "BGRA"
246245 block_size = TextureSwizzler .TEXTUREFORMAT_BLOCK_SIZE_MAP [s_tex_format ]
247246 width , height = TextureSwizzler .get_padded_texture_size (
@@ -322,10 +321,10 @@ def parse_image_data(
322321 # due to earlier check platform_blob can't be None
323322 assert platform_blob is not None
324323 gobsPerBlock = TextureSwizzler .get_switch_gobs_per_block (platform_blob )
325- if texture_format == TextureFormat .RGB24 :
326- texture_format = TextureFormat .RGBA32
327- elif texture_format == TextureFormat .BGR24 :
328- texture_format = TextureFormat .BGRA32
324+ if texture_format == TF .RGB24 :
325+ texture_format = TF .RGBA32
326+ elif texture_format == TF .BGR24 :
327+ texture_format = TF .BGRA32
329328 block_size = TextureSwizzler .TEXTUREFORMAT_BLOCK_SIZE_MAP [texture_format ]
330329 width , height = TextureSwizzler .get_padded_texture_size (
331330 width , height , * block_size , gobsPerBlock
@@ -336,11 +335,6 @@ def parse_image_data(
336335 else :
337336 width , height = get_compressed_image_size (width , height , texture_format )
338337
339- selection = CONV_TABLE [texture_format ]
340-
341- if not selection :
342- raise NotImplementedError (f"Not implemented texture format: { texture_format } " )
343-
344338 if not isinstance (image_data , bytes ):
345339 image_data = bytes (image_data )
346340
@@ -355,7 +349,13 @@ def parse_image_data(
355349 else :
356350 image_data = texture2ddecoder .unpack_crunch (image_data )
357351
358- img = selection [0 ](image_data , width , height , * selection [1 :])
352+ if texture_format not in CONV_TABLE :
353+ raise NotImplementedError (
354+ f"Not implemented texture format: { texture_format .name } "
355+ )
356+ conv_func , conv_args = CONV_TABLE [texture_format ]
357+
358+ img = conv_func (image_data , width , height , * conv_args )
359359
360360 if original_width != width or original_height != height :
361361 img = img .crop ((0 , 0 , original_width , original_height ))
@@ -455,22 +455,22 @@ def pvrtc(image_data: bytes, width: int, height: int, fmt: bool) -> Image.Image:
455455 return Image .frombytes ("RGBA" , (width , height ), image_data , "raw" , "BGRA" )
456456
457457
458- def etc (image_data : bytes , width : int , height : int , fmt : list ) -> Image .Image :
459- if fmt [ 0 ] == 1 :
458+ def etc (image_data : bytes , width : int , height : int , fmt : str ) -> Image .Image :
459+ if fmt == "ETC1" :
460460 image_data = texture2ddecoder .decode_etc1 (image_data , width , height )
461- elif fmt [0 ] == 2 :
462- if fmt [1 ] == "RGB" :
463- image_data = texture2ddecoder .decode_etc2 (image_data , width , height )
464- elif fmt [1 ] == "A1" :
465- image_data = texture2ddecoder .decode_etc2a1 (image_data , width , height )
466- elif fmt [1 ] == "A8" :
467- image_data = texture2ddecoder .decode_etc2a8 (image_data , width , height )
461+ elif fmt == "ETC2_RGB" :
462+ image_data = texture2ddecoder .decode_etc2 (image_data , width , height )
463+ elif fmt == "ETC2_A1" :
464+ image_data = texture2ddecoder .decode_etc2a1 (image_data , width , height )
465+ elif fmt == "ETC2_A8" :
466+ image_data = texture2ddecoder .decode_etc2a8 (image_data , width , height )
468467 else :
469- raise NotImplementedError ("unknown etc mode" )
468+ raise NotImplementedError (f"Unknown ETC mode: { fmt } " )
469+
470470 return Image .frombytes ("RGBA" , (width , height ), image_data , "raw" , "BGRA" )
471471
472472
473- def eac (image_data : bytes , width : int , height : int , fmt : list ) -> Image .Image :
473+ def eac (image_data : bytes , width : int , height : int , fmt : str ) -> Image .Image :
474474 if fmt == "EAC_R" :
475475 image_data = texture2ddecoder .decode_eacr (image_data , width , height )
476476 elif fmt == "EAC_R_SIGNED" :
@@ -479,6 +479,9 @@ def eac(image_data: bytes, width: int, height: int, fmt: list) -> Image.Image:
479479 image_data = texture2ddecoder .decode_eacrg (image_data , width , height )
480480 elif fmt == "EAC_RG_SIGNED" :
481481 image_data = texture2ddecoder .decode_eacrg_signed (image_data , width , height )
482+ else :
483+ raise NotImplementedError (f"Unknown EAC mode: { fmt } " )
484+
482485 return Image .frombytes ("RGBA" , (width , height ), image_data , "raw" , "BGRA" )
483486
484487
@@ -542,87 +545,85 @@ def rgb9e5float(image_data: bytes, width: int, height: int) -> Image.Image:
542545 return Image .frombytes ("RGB" , (width , height ), rgb , "raw" , "RGB" )
543546
544547
545- # The type for the conversion table
546- CONV_TABLE : Dict [TextureFormat , Optional [Tuple [Callable , Unpack [Tuple [Any , ...]]]]] = {
547- # FORMAT FUNC #ARGS.....
548- # ----------------------- -------- -------- ------------ ----------------- ------------ ----------
549- TF .Alpha8 : (pillow , "RGBA" , "raw" , "A" ),
550- TF .ARGB4444 : (pillow , "RGBA" , "raw" , "RGBA;4B" , (2 , 1 , 0 , 3 )),
551- TF .RGB24 : (pillow , "RGB" , "raw" , "RGB" ),
552- TF .RGBA32 : (pillow , "RGBA" , "raw" , "RGBA" ),
553- TF .ARGB32 : (pillow , "RGBA" , "raw" , "ARGB" ),
554- TF .ARGBFloat : (pillow , "RGBA" , "raw" , "RGBAF" , (2 , 1 , 0 , 3 )),
555- TF .RGB565 : (pillow , "RGB" , "raw" , "BGR;16" ),
556- TF .BGR24 : (pillow , "RGB" , "raw" , "BGR" ),
557- TF .R8 : (pillow , "RGB" , "raw" , "R" ),
558- TF .R16 : (pillow , "RGB" , "raw" , "R;16" ),
559- TF .RG16 : (rg , "RGB" , "raw" , "RG" ),
560- TF .DXT1 : (pillow , "RGBA" , "bcn" , 1 ),
561- TF .DXT3 : (pillow , "RGBA" , "bcn" , 2 ),
562- TF .DXT5 : (pillow , "RGBA" , "bcn" , 3 ),
563- TF .RGBA4444 : (pillow , "RGBA" , "raw" , "RGBA;4B" , (3 , 2 , 1 , 0 )),
564- TF .BGRA32 : (pillow , "RGBA" , "raw" , "BGRA" ),
565- TF .RHalf : (half , "R" , "raw" , "R" ),
566- TF .RGHalf : (rg , "RGB" , "raw" , "RGE" ),
567- TF .RGBAHalf : (half , "RGB" , "raw" , "RGB" ),
568- TF .RFloat : (pillow , "RGB" , "raw" , "RF" ),
569- TF .RGFloat : (rg , "RGB" , "raw" , "RGF" ),
570- TF .RGBAFloat : (pillow , "RGBA" , "raw" , "RGBAF" ),
571- TF .YUY2 : None ,
572- TF .RGB9e5Float : (rgb9e5float ,),
573- TF .BC4 : (pillow , "L" , "bcn" , 4 ),
574- TF .BC5 : (pillow , "RGB" , "bcn" , 5 ),
575- TF .BC6H : (pillow , "RGBA" , "bcn" , 6 ),
576- TF .BC7 : (pillow , "RGBA" , "bcn" , 7 ),
577- TF .DXT1Crunched : (pillow , "RGBA" , "bcn" , 1 ),
578- TF .DXT5Crunched : (pillow , "RGBA" , "bcn" , 3 ),
579- TF .PVRTC_RGB2 : (pvrtc , True ),
580- TF .PVRTC_RGBA2 : (pvrtc , True ),
581- TF .PVRTC_RGB4 : (pvrtc , False ),
582- TF .PVRTC_RGBA4 : (pvrtc , False ),
583- TF .ETC_RGB4 : (etc , (1 ,)),
584- TF .ATC_RGB4 : (atc , False ),
585- TF .ATC_RGBA8 : (atc , True ),
586- TF .EAC_R : (eac , "EAC_R" ),
587- TF .EAC_R_SIGNED : (eac , "EAC_R:SIGNED" ),
588- TF .EAC_RG : (eac , "EAC_RG" ),
589- TF .EAC_RG_SIGNED : (eac , "EAC_RG_SIGNED" ),
590- TF .ETC2_RGB : (etc , (2 , "RGB" )),
591- TF .ETC2_RGBA1 : (etc , (2 , "A1" )),
592- TF .ETC2_RGBA8 : (etc , (2 , "A8" )),
593- TF .ASTC_RGB_4x4 : (astc , (4 , 4 )),
594- TF .ASTC_RGB_5x5 : (astc , (5 , 5 )),
595- TF .ASTC_RGB_6x6 : (astc , (6 , 6 )),
596- TF .ASTC_RGB_8x8 : (astc , (8 , 8 )),
597- TF .ASTC_RGB_10x10 : (astc , (10 , 10 )),
598- TF .ASTC_RGB_12x12 : (astc , (12 , 12 )),
599- TF .ASTC_RGBA_4x4 : (astc , (4 , 4 )),
600- TF .ASTC_RGBA_5x5 : (astc , (5 , 5 )),
601- TF .ASTC_RGBA_6x6 : (astc , (6 , 6 )),
602- TF .ASTC_RGBA_8x8 : (astc , (8 , 8 )),
603- TF .ASTC_RGBA_10x10 : (astc , (10 , 10 )),
604- TF .ASTC_RGBA_12x12 : (astc , (12 , 12 )),
605- TF .ETC_RGB4_3DS : (etc , (1 ,)),
606- TF .ETC_RGBA8_3DS : (etc , (1 ,)),
607- TF .ETC_RGB4Crunched : (etc , (1 ,)),
608- TF .ETC2_RGBA8Crunched : (etc , (2 , "A8" )),
609- TF .ASTC_HDR_4x4 : (astc , (4 , 4 )),
610- TF .ASTC_HDR_5x5 : (astc , (5 , 5 )),
611- TF .ASTC_HDR_6x6 : (astc , (6 , 6 )),
612- TF .ASTC_HDR_8x8 : (astc , (8 , 8 )),
613- TF .ASTC_HDR_10x10 : (astc , (10 , 10 )),
614- TF .ASTC_HDR_12x12 : (astc , (12 , 12 )),
615- TF .RG32 : (rg , "RGB" , "raw" , "RG;16" ),
616- TF .RGB48 : (pillow , "RGB" , "raw" , "RGB;16" ),
617- TF .RGBA64 : (pillow , "RGBA" , "raw" , "RGBA;16" ),
618- TF .R8_SIGNED : (pillow , "R" , "raw" , "R;8s" ),
619- TF .RG16_SIGNED : (rg , "RGB" , "raw" , "RG;8s" ),
620- TF .RGB24_SIGNED : (pillow , "RGB" , "raw" , "RGB;8s" ),
621- TF .RGBA32_SIGNED : (pillow , "RGBA" , "raw" , "RGBA;8s" ),
622- TF .R16_SIGNED : (pillow , "R" , "raw" , "R;16s" ),
623- TF .RG32_SIGNED : (rg , "RGB" , "raw" , "RG;16s" ),
624- TF .RGB48_SIGNED : (pillow , "RGB" , "raw" , "RGB;16s" ),
625- TF .RGBA64_SIGNED : (pillow , "RGBA" , "raw" , "RGBA;16s" ),
548+ # Mapping TextureFormat -> (converter function, (additional args, ...))
549+ CONV_TABLE : Dict [TF , Tuple [Callable [..., Image .Image ], Tuple [Any , ...]]] = {
550+ TF .Alpha8 : (pillow , ("RGBA" , "raw" , "A" )),
551+ TF .ARGB4444 : (pillow , ("RGBA" , "raw" , "RGBA;4B" , (2 , 1 , 0 , 3 ))),
552+ TF .RGB24 : (pillow , ("RGB" , "raw" , "RGB" )),
553+ TF .RGBA32 : (pillow , ("RGBA" , "raw" , "RGBA" )),
554+ TF .ARGB32 : (pillow , ("RGBA" , "raw" , "ARGB" )),
555+ TF .ARGBFloat : (pillow , ("RGBA" , "raw" , "RGBAF" , (2 , 1 , 0 , 3 ))),
556+ TF .RGB565 : (pillow , ("RGB" , "raw" , "BGR;16" )),
557+ TF .BGR24 : (pillow , ("RGB" , "raw" , "BGR" )),
558+ TF .R8 : (pillow , ("RGB" , "raw" , "R" )),
559+ TF .R16 : (pillow , ("RGB" , "raw" , "R;16" )),
560+ TF .RG16 : (rg , ("RGB" , "raw" , "RG" )),
561+ TF .DXT1 : (pillow , ("RGBA" , "bcn" , 1 )),
562+ TF .DXT3 : (pillow , ("RGBA" , "bcn" , 2 )),
563+ TF .DXT5 : (pillow , ("RGBA" , "bcn" , 3 )),
564+ TF .RGBA4444 : (pillow , ("RGBA" , "raw" , "RGBA;4B" , (3 , 2 , 1 , 0 ))),
565+ TF .BGRA32 : (pillow , ("RGBA" , "raw" , "BGRA" )),
566+ TF .RHalf : (half , ("R" , "raw" , "R" )),
567+ TF .RGHalf : (rg , ("RGB" , "raw" , "RGE" )),
568+ TF .RGBAHalf : (half , ("RGB" , "raw" , "RGB" )),
569+ TF .RFloat : (pillow , ("RGB" , "raw" , "RF" )),
570+ TF .RGFloat : (rg , ("RGB" , "raw" , "RGF" )),
571+ TF .RGBAFloat : (pillow , ("RGBA" , "raw" , "RGBAF" )),
572+ # TF.YUY2: NotImplementedError("YUY2 not implemented"),
573+ TF .RGB9e5Float : (rgb9e5float , ()),
574+ TF .BC4 : (pillow , ("L" , "bcn" , 4 )),
575+ TF .BC5 : (pillow , ("RGB" , "bcn" , 5 )),
576+ TF .BC6H : (pillow , ("RGBA" , "bcn" , 6 )),
577+ TF .BC7 : (pillow , ("RGBA" , "bcn" , 7 )),
578+ TF .DXT1Crunched : (pillow , ("RGBA" , "bcn" , 1 )),
579+ TF .DXT5Crunched : (pillow , ("RGBA" , "bcn" , 3 )),
580+ TF .PVRTC_RGB2 : (pvrtc , (True ,)),
581+ TF .PVRTC_RGBA2 : (pvrtc , (True ,)),
582+ TF .PVRTC_RGB4 : (pvrtc , (False ,)),
583+ TF .PVRTC_RGBA4 : (pvrtc , (False ,)),
584+ TF .ETC_RGB4 : (etc , ("ETC1" ,)),
585+ TF .ATC_RGB4 : (atc , (False ,)),
586+ TF .ATC_RGBA8 : (atc , (True ,)),
587+ TF .EAC_R : (eac , ("EAC_R" ,)),
588+ TF .EAC_R_SIGNED : (eac , ("EAC_R_SIGNED" ,)),
589+ TF .EAC_RG : (eac , ("EAC_RG" ,)),
590+ TF .EAC_RG_SIGNED : (eac , ("EAC_RG_SIGNED" ,)),
591+ TF .ETC2_RGB : (etc , ("ETC2_RGB" ,)),
592+ TF .ETC2_RGBA1 : (etc , ("ETC2_A1" ,)),
593+ TF .ETC2_RGBA8 : (etc , ("ETC2_A8" ,)),
594+ TF .ASTC_RGB_4x4 : (astc , ((4 , 4 ))),
595+ TF .ASTC_RGB_5x5 : (astc , ((5 , 5 ))),
596+ TF .ASTC_RGB_6x6 : (astc , ((6 , 6 ))),
597+ TF .ASTC_RGB_8x8 : (astc , ((8 , 8 ))),
598+ TF .ASTC_RGB_10x10 : (astc , ((10 , 10 ))),
599+ TF .ASTC_RGB_12x12 : (astc , ((12 , 12 ))),
600+ TF .ASTC_RGBA_4x4 : (astc , ((4 , 4 ))),
601+ TF .ASTC_RGBA_5x5 : (astc , ((5 , 5 ))),
602+ TF .ASTC_RGBA_6x6 : (astc , ((6 , 6 ))),
603+ TF .ASTC_RGBA_8x8 : (astc , ((8 , 8 ))),
604+ TF .ASTC_RGBA_10x10 : (astc , ((10 , 10 ))),
605+ TF .ASTC_RGBA_12x12 : (astc , ((12 , 12 ))),
606+ TF .ETC_RGB4_3DS : (etc , ("ETC1" ,)),
607+ TF .ETC_RGBA8_3DS : (etc , ("ETC1" ,)),
608+ TF .ETC_RGB4Crunched : (etc , ("ETC1" ,)),
609+ TF .ETC2_RGBA8Crunched : (etc , ("ETC2_A8" ,)),
610+ TF .ASTC_HDR_4x4 : (astc , ((4 , 4 ))),
611+ TF .ASTC_HDR_5x5 : (astc , ((5 , 5 ))),
612+ TF .ASTC_HDR_6x6 : (astc , ((6 , 6 ))),
613+ TF .ASTC_HDR_8x8 : (astc , ((8 , 8 ))),
614+ TF .ASTC_HDR_10x10 : (astc , ((10 , 10 ))),
615+ TF .ASTC_HDR_12x12 : (astc , ((12 , 12 ))),
616+ TF .RG32 : (rg , ("RGB" , "raw" , "RG;16" )),
617+ TF .RGB48 : (pillow , ("RGB" , "raw" , "RGB;16" )),
618+ TF .RGBA64 : (pillow , ("RGBA" , "raw" , "RGBA;16" )),
619+ TF .R8_SIGNED : (pillow , ("R" , "raw" , "R;8s" )),
620+ TF .RG16_SIGNED : (rg , ("RGB" , "raw" , "RG;8s" )),
621+ TF .RGB24_SIGNED : (pillow , ("RGB" , "raw" , "RGB;8s" )),
622+ TF .RGBA32_SIGNED : (pillow , ("RGBA" , "raw" , "RGBA;8s" )),
623+ TF .R16_SIGNED : (pillow , ("R" , "raw" , "R;16s" )),
624+ TF .RG32_SIGNED : (rg , ("RGB" , "raw" , "RG;16s" )),
625+ TF .RGB48_SIGNED : (pillow , ("RGB" , "raw" , "RGB;16s" )),
626+ TF .RGBA64_SIGNED : (pillow , ("RGBA" , "raw" , "RGBA;16s" )),
626627}
627628
628629# XBOX Swap Formats
0 commit comments