1
1
from __future__ import annotations
2
2
3
3
import struct
4
- from copy import copy
5
4
from io import BytesIO
6
5
from threading import Lock
7
- from typing import TYPE_CHECKING , Dict , Optional , Tuple , Union
6
+ from typing import TYPE_CHECKING , Any , Callable , Dict , Optional , Tuple , Union
8
7
9
8
import astc_encoder
10
9
import texture2ddecoder
11
10
from PIL import Image
11
+ from typing_extensions import Unpack
12
12
13
13
from ..enums import BuildTarget , TextureFormat
14
14
from ..helpers import TextureSwizzler
@@ -65,15 +65,15 @@ def pad_image(img: Image.Image, pad_width: int, pad_height: int) -> Image.Image:
65
65
if pad_width != ori_width :
66
66
right_strip = img .crop ((ori_width - 1 , 0 , ori_width , ori_height ))
67
67
right_strip = right_strip .resize (
68
- (pad_width - ori_width , ori_height ), resample = Image .NEAREST
68
+ (pad_width - ori_width , ori_height ), resample = Image .Resampling . NEAREST
69
69
)
70
70
pad_img .paste (right_strip , (ori_width , 0 ))
71
71
72
72
# Fill the bottom border: duplicate the last row
73
73
if pad_height != ori_height :
74
74
bottom_strip = img .crop ((0 , ori_height - 1 , ori_width , ori_height ))
75
75
bottom_strip = bottom_strip .resize (
76
- (ori_width , pad_height - ori_height ), resample = Image .NEAREST
76
+ (ori_width , pad_height - ori_height ), resample = Image .Resampling . NEAREST
77
77
)
78
78
pad_img .paste (bottom_strip , (0 , ori_height ))
79
79
@@ -145,7 +145,7 @@ def image_to_texture2d(
145
145
target_texture_format = TextureFormat (target_texture_format )
146
146
147
147
if flip :
148
- img = img .transpose (Image .FLIP_TOP_BOTTOM )
148
+ img = img .transpose (Image .Transpose . FLIP_TOP_BOTTOM )
149
149
150
150
# defaults
151
151
compress_func = None
@@ -286,15 +286,15 @@ def get_image_from_texture2d(
286
286
texture_2d .m_Width ,
287
287
texture_2d .m_Height ,
288
288
texture_2d .m_TextureFormat ,
289
- texture_2d .object_reader . version ,
290
- texture_2d .object_reader . platform ,
289
+ getattr ( texture_2d .object_reader , " version" , ( 0 , 0 , 0 , 0 )) ,
290
+ getattr ( texture_2d .object_reader , " platform" , BuildTarget . UnknownPlatform ) ,
291
291
getattr (texture_2d , "m_PlatformBlob" , None ),
292
292
flip ,
293
293
)
294
294
295
295
296
296
def parse_image_data (
297
- image_data : bytes ,
297
+ image_data : Union [ bytes , bytearray , memoryview ] ,
298
298
width : int ,
299
299
height : int ,
300
300
texture_format : Union [int , TextureFormat ],
@@ -306,7 +306,6 @@ def parse_image_data(
306
306
if not width or not height :
307
307
return Image .new ("RGBA" , (0 , 0 ))
308
308
309
- image_data = copy (bytes (image_data ))
310
309
if not image_data :
311
310
raise ValueError ("Texture2D has no image data" )
312
311
@@ -339,11 +338,13 @@ def parse_image_data(
339
338
340
339
selection = CONV_TABLE [texture_format ]
341
340
342
- if len ( selection ) == 0 :
341
+ if not selection :
343
342
raise NotImplementedError (f"Not implemented texture format: { texture_format } " )
344
343
344
+ if not isinstance (image_data , bytes ):
345
+ image_data = bytes (image_data )
346
+
345
347
if "Crunched" in texture_format .name :
346
- version = version
347
348
if (
348
349
version [0 ] > 2017
349
350
or (version [0 ] == 2017 and version [1 ] >= 3 ) # 2017.3 and up
@@ -360,15 +361,16 @@ def parse_image_data(
360
361
img = img .crop ((0 , 0 , original_width , original_height ))
361
362
362
363
if img and flip :
363
- return img .transpose (Image .FLIP_TOP_BOTTOM )
364
+ return img .transpose (Image .Transpose . FLIP_TOP_BOTTOM )
364
365
365
366
return img
366
367
367
368
368
- def swap_bytes_for_xbox (image_data : bytes ) -> bytes :
369
+ def swap_bytes_for_xbox (image_data : Union [ bytes , bytearray , memoryview ] ) -> bytearray :
369
370
"""swaps the texture bytes
370
371
This is required for textures deployed on XBOX360.
371
372
"""
373
+ image_data = bytearray (image_data )
372
374
for i in range (0 , len (image_data ), 2 ):
373
375
image_data [i : i + 2 ] = image_data [i : i + 2 ][::- 1 ]
374
376
return image_data
@@ -414,6 +416,7 @@ def astc(image_data: bytes, width: int, height: int, block_size: tuple) -> Image
414
416
context .decompress (
415
417
image_data [:texture_size ], image , astc_encoder .ASTCSwizzle .from_str ("RGBA" )
416
418
)
419
+ assert image .data is not None , "Decompression failed, image data is None"
417
420
418
421
return Image .frombytes ("RGBA" , (width , height ), image .data , "raw" , "RGBA" )
419
422
@@ -539,90 +542,88 @@ def rgb9e5float(image_data: bytes, width: int, height: int) -> Image.Image:
539
542
return Image .frombytes ("RGB" , (width , height ), rgb , "raw" , "RGB" )
540
543
541
544
542
- CONV_TABLE = {
545
+ # The type for the conversion table
546
+ CONV_TABLE : Dict [TextureFormat , Optional [Tuple [Callable , Unpack [Tuple [Any , ...]]]]] = {
543
547
# FORMAT FUNC #ARGS.....
544
548
# ----------------------- -------- -------- ------------ ----------------- ------------ ----------
545
- ( TF .Alpha8 , pillow , "RGBA" , "raw" , "A" ),
546
- ( TF .ARGB4444 , pillow , "RGBA" , "raw" , "RGBA;4B" , (2 , 1 , 0 , 3 )),
547
- ( TF .RGB24 , pillow , "RGB" , "raw" , "RGB" ),
548
- ( TF .RGBA32 , pillow , "RGBA" , "raw" , "RGBA" ),
549
- ( TF .ARGB32 , pillow , "RGBA" , "raw" , "ARGB" ),
550
- ( TF .ARGBFloat , pillow , "RGBA" , "raw" , "RGBAF" , (2 , 1 , 0 , 3 )),
551
- ( TF .RGB565 , pillow , "RGB" , "raw" , "BGR;16" ),
552
- ( TF .BGR24 , pillow , "RGB" , "raw" , "BGR" ),
553
- ( TF .R8 , pillow , "RGB" , "raw" , "R" ),
554
- ( TF .R16 , pillow , "RGB" , "raw" , "R;16" ),
555
- ( TF .RG16 , rg , "RGB" , "raw" , "RG" ),
556
- ( TF .DXT1 , pillow , "RGBA" , "bcn" , 1 ),
557
- ( TF .DXT3 , pillow , "RGBA" , "bcn" , 2 ),
558
- ( TF .DXT5 , pillow , "RGBA" , "bcn" , 3 ),
559
- ( TF .RGBA4444 , pillow , "RGBA" , "raw" , "RGBA;4B" , (3 , 2 , 1 , 0 )),
560
- ( TF .BGRA32 , pillow , "RGBA" , "raw" , "BGRA" ),
561
- ( TF .RHalf , half , "R" , "raw" , "R" ),
562
- ( TF .RGHalf , rg , "RGB" , "raw" , "RGE" ),
563
- ( TF .RGBAHalf , half , "RGB" , "raw" , "RGB" ),
564
- ( TF .RFloat , pillow , "RGB" , "raw" , "RF" ),
565
- ( TF .RGFloat , rg , "RGB" , "raw" , "RGF" ),
566
- ( TF .RGBAFloat , pillow , "RGBA" , "raw" , "RGBAF" ),
567
- ( TF .YUY2 ,) ,
568
- ( TF .RGB9e5Float , rgb9e5float ),
569
- ( TF .BC4 , pillow , "L" , "bcn" , 4 ),
570
- ( TF .BC5 , pillow , "RGB" , "bcn" , 5 ),
571
- ( TF .BC6H , pillow , "RGBA" , "bcn" , 6 ),
572
- ( TF .BC7 , pillow , "RGBA" , "bcn" , 7 ),
573
- ( TF .DXT1Crunched , pillow , "RGBA" , "bcn" , 1 ),
574
- ( TF .DXT5Crunched , pillow , "RGBA" , "bcn" , 3 ),
575
- ( TF .PVRTC_RGB2 , pvrtc , True ),
576
- ( TF .PVRTC_RGBA2 , pvrtc , True ),
577
- ( TF .PVRTC_RGB4 , pvrtc , False ),
578
- ( TF .PVRTC_RGBA4 , pvrtc , False ),
579
- ( TF .ETC_RGB4 , etc , (1 ,)),
580
- ( TF .ATC_RGB4 , atc , False ),
581
- ( TF .ATC_RGBA8 , atc , True ),
582
- ( TF .EAC_R , eac , "EAC_R" ),
583
- ( TF .EAC_R_SIGNED , eac , "EAC_R:SIGNED" ),
584
- ( TF .EAC_RG , eac , "EAC_RG" ),
585
- ( TF .EAC_RG_SIGNED , eac , "EAC_RG_SIGNED" ),
586
- ( TF .ETC2_RGB , etc , (2 , "RGB" )),
587
- ( TF .ETC2_RGBA1 , etc , (2 , "A1" )),
588
- ( TF .ETC2_RGBA8 , etc , (2 , "A8" )),
589
- ( TF .ASTC_RGB_4x4 , astc , (4 , 4 )),
590
- ( TF .ASTC_RGB_5x5 , astc , (5 , 5 )),
591
- ( TF .ASTC_RGB_6x6 , astc , (6 , 6 )),
592
- ( TF .ASTC_RGB_8x8 , astc , (8 , 8 )),
593
- ( TF .ASTC_RGB_10x10 , astc , (10 , 10 )),
594
- ( TF .ASTC_RGB_12x12 , astc , (12 , 12 )),
595
- ( TF .ASTC_RGBA_4x4 , astc , (4 , 4 )),
596
- ( TF .ASTC_RGBA_5x5 , astc , (5 , 5 )),
597
- ( TF .ASTC_RGBA_6x6 , astc , (6 , 6 )),
598
- ( TF .ASTC_RGBA_8x8 , astc , (8 , 8 )),
599
- ( TF .ASTC_RGBA_10x10 , astc , (10 , 10 )),
600
- ( TF .ASTC_RGBA_12x12 , astc , (12 , 12 )),
601
- ( TF .ETC_RGB4_3DS , etc , (1 ,)),
602
- ( TF .ETC_RGBA8_3DS , etc , (1 ,)),
603
- ( TF .ETC_RGB4Crunched , etc , (1 ,)),
604
- ( TF .ETC2_RGBA8Crunched , etc , (2 , "A8" )),
605
- ( TF .ASTC_HDR_4x4 , astc , (4 , 4 )),
606
- ( TF .ASTC_HDR_5x5 , astc , (5 , 5 )),
607
- ( TF .ASTC_HDR_6x6 , astc , (6 , 6 )),
608
- ( TF .ASTC_HDR_8x8 , astc , (8 , 8 )),
609
- ( TF .ASTC_HDR_10x10 , astc , (10 , 10 )),
610
- ( TF .ASTC_HDR_12x12 , astc , (12 , 12 )),
611
- ( TF .RG32 , rg , "RGB" , "raw" , "RG;16" ),
612
- ( TF .RGB48 , pillow , "RGB" , "raw" , "RGB;16" ),
613
- ( TF .RGBA64 , pillow , "RGBA" , "raw" , "RGBA;16" ),
614
- ( TF .R8_SIGNED , pillow , "R" , "raw" , "R;8s" ),
615
- ( TF .RG16_SIGNED , rg , "RGB" , "raw" , "RG;8s" ),
616
- ( TF .RGB24_SIGNED , pillow , "RGB" , "raw" , "RGB;8s" ),
617
- ( TF .RGBA32_SIGNED , pillow , "RGBA" , "raw" , "RGBA;8s" ),
618
- ( TF .R16_SIGNED , pillow , "R" , "raw" , "R;16s" ),
619
- ( TF .RG32_SIGNED , rg , "RGB" , "raw" , "RG;16s" ),
620
- ( TF .RGB48_SIGNED , pillow , "RGB" , "raw" , "RGB;16s" ),
621
- ( TF .RGBA64_SIGNED , pillow , "RGBA" , "raw" , "RGBA;16s" ),
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" ),
622
626
}
623
627
624
- # format conv_table to a dict
625
- CONV_TABLE = {line [0 ]: line [1 :] for line in CONV_TABLE }
626
-
627
628
# XBOX Swap Formats
628
629
XBOX_SWAP_FORMATS = [TF .RGB565 , TF .DXT1 , TF .DXT1Crunched , TF .DXT5 , TF .DXT5Crunched ]
0 commit comments