§
    GÂj$  ã                  ó8  — d Z ddlmZ ddlZddlZddlmZ ddlZddlZddl	Z	ddl
Z
ddlmZmZmZmZmZ ddlmZ ddlZ eg d¢¦  «        ZdZdZ	 	 	 d0d1d„Zd2d„Zd3d„Z	 	 	 	 d4d5d$„Z	 	 	 	 d6d7d*„Zd8d-„Zd9d.„Ze d/k    r e
j!         e¦   «         ¦  «         dS dS ):zû
FreeExile ASTC 4x4 Mobile Texture Compression Engine (Apple Metal iOS).
Converts Power-of-Two PNG Atlases into canonical 16-byte header ASTC 4x4 binary containers.
Complies with Apple Metal MTLPixelFormatASTC_4x4_sRGB and MTLPixelFormatASTC_4x4_LDR.
é    )ÚannotationsN)ÚPath)ÚDictÚAnyÚListÚOptionalÚUnion)ÚImage)é   é«   é¡   é\   é   é   é   ÚwidthÚintÚheightÚblock_xÚblock_yÚblock_zÚreturnÚbytesc                óÖ   — |                       dd¬¦  «        }|                      dd¬¦  «        }|                      dd¬¦  «        }t          |||g¦  «        }t          |z   |z   |z   |z   S )a¦  
    Generates canonical 16-byte ASTC container header.
    Byte 0..3:   0x13, 0xAB, 0xA1, 0x5C (Magic)
    Byte 4:      blockdim_x (e.g. 4 for 4x4)
    Byte 5:      blockdim_y (e.g. 4 for 4x4)
    Byte 6:      blockdim_z (e.g. 1 for 2D texture)
    Byte 7..9:   xsize (24-bit little-endian integer)
    Byte 10..12: ysize (24-bit little-endian integer)
    Byte 13..15: zsize (24-bit little-endian integer, 1 for 2D)
    é   Úlittle©Ú	byteorder)Úto_bytesr   Ú
ASTC_MAGIC)	r   r   r   r   r   Úw_bytesÚh_bytesÚd_bytesÚdimss	            ú=C:\Projects\FreeExile\tools\asset_pipeline\astc_compressor.pyÚcreate_astc_headerr&      st   € ð" �nŠn˜Q¨(ˆnÑ3Ô3€GØ�oŠo˜a¨8ˆoÑ4Ô4€GØ×Ò˜q¨HÐÑ5Ô5€GÝ�'˜7 GÐ,Ñ-Ô-€DÝ˜Ñ˜wÑ&¨Ñ0°7Ñ:Ð:ó    Úheader_bytesúDict[str, Any]c                ó|  — t          | ¦  «        t          k     r(t          dt          | ¦  «        › dt          › d�¦  «        ‚| dd…         }|t          k    }| d         }| d         }| d         }t                               | dd	…         d
¬¦  «        }t                               | d	d…         d
¬¦  «        }t                               | dd…         d
¬¦  «        }|dk    r||z   dz
  |z  nd}	|dk    r||z   dz
  |z  nd}
|	|
z  |pdz  }|t          z  }||                     ¦   «         |||||||	|
||t          |z   dœS )z0Parses and validates a 16-byte ASTC file header.zHeader too short: z bytes (expected ú)r   r   é   é   é   é
   r   r   é   r   r   )Úmagic_validÚmagicr   r   r   r   r   ÚdepthÚblocks_xÚblocks_yÚtotal_blocksÚexpected_payload_bytesÚexpected_total_size)ÚlenÚASTC_HEADER_SIZEÚ
ValueErrorr    r   Ú
from_bytesÚASTC_BLOCK_BYTESÚhex)r(   r2   r1   r   r   r   r   r   r3   r4   r5   r6   Úexpected_data_sizes                r%   Úparse_astc_headerr@   2   st  € å
ˆ<ÑÔÕ+Ò+Ð+ÝÐe­c°,Ñ.?Ô.?ÐeÐeÕRbÐeÐeÐeÑfÔfÐfà˜˜1˜Ô€EØ�JÒ&€KØ˜1Œo€GØ˜1Œo€GØ˜1Œo€GÝ�NŠN˜<¨¨"¨Ô-¸ˆNÑBÔB€EÝ�^Š^˜L¨¨B¨Ô/¸8ˆ^ÑDÔD€FÝ�NŠN˜<¨¨2¨Ô.¸(ˆNÑCÔC€Eà3:¸Q²;°;�˜‘ !Ñ#¨Ñ/Ð/ÀA€HØ4;¸a²K°K�˜Ñ  1Ñ$¨Ñ0Ð0ÀQ€HØ˜hÑ&¨%¨*°1Ñ5€LØ%Õ(8Ñ8Ðð #Ø—’‘”ØØØØØØØØØ$Ø"4Ý/Ð2DÑDðð ð r'   ÚrÚgÚbÚac                ó®   — d}|                      dd¬¦  «        }| dz  | z  }|dz  |z  }|dz  |z  }|dz  |z  }	t          j        d||||	¦  «        }
||
z   S )a(  
    Encodes a 16-byte (128-bit) ASTC Void-Extent LDR block per Khronos ASTC Specification.
    Void-extent blocks encode a constant RGBA color across the 4x4 texels with zero compression distortion.
    Bits 0..8:   0b111111100 (0x1FC: Void-extent mode)
    Bit 9:       0 (LDR mode)
    Bits 10..63: 0xFFFF across 4 coordinates (all texels covered)
    Bits 64..79:  R (16-bit unorm: (r << 8) | r)
    Bits 80..95:  G (16-bit unorm: (g << 8) | g)
    Bits 96..111: B (16-bit unorm: (b << 8) | b)
    Bits 112..127: A (16-bit unorm: (a << 8) | a)
    l   ü}ÿÿÿ é   r   r   z<HHHH)r   ÚstructÚpack)rA   rB   rC   rD   Úlower64Úlower_bytesÚr16Úg16Úb16Úa16Úupper_bytess              r%   Úencode_astc_void_extent_blockrP   V   sx   € ð V€GØ×"Ò" 1°Ð"Ñ9Ô9€Kà�‰6�Q‰,€CØ�‰6�Q‰,€CØ�‰6�Q‰,€CØ�‰6�Q‰,€CÝ”+˜g s¨C°°cÑ:Ô:€Kà˜Ñ$Ð$r'   ÚmediumÚpng_pathúUnion[str, Path]Úoutput_pathúOptional[Union[str, Path]]ÚqualityÚstrr   c                óÈ  — t          | ¦  «                             ¦   «         }|                     ¦   «         st          d|› �¦  «        ‚|€|                     d¦  «        }n!t          |¦  «                             ¦   «         }|j                             dd¬¦  «         t          j        |¦  «        5 }| 	                    d¦  «        }|j
        \  }	}
ddd¦  «         n# 1 swxY w Y   t          j        d¦  «        pt          j        d¦  «        }|r—	 |d	t          |¦  «        t          |¦  «        |› d
|› �d|› �g}t          j        |ddd¬¦  «        }|j        dk    r8|                     ¦   «         r$|                     ¦   «         j        t&          k    r|S n# t(          $ r Y nw xY wt+          |	|
||d¬¦  «        }t-          j        |t,          j        ¬¦  «        }|	|z   dz
  |z  }|
|z   dz
  |z  }g }t3          |¦  «        D ]ø}||z  }t5          ||z   |
¦  «        }t3          |¦  «        D ]Î}||z  }t5          ||z   |	¦  «        }|||…||…f         }|                     d¬¦  «                             t,          j        ¦  «        }t;          t=          |d         ¦  «        t=          |d         ¦  «        t=          |d         ¦  «        t=          |d         ¦  «        ¦  «        }|                     |¦  «         ŒÏŒùt          |d¦  «        5 }|                      |¦  «         |                      d !                    |¦  «        ¦  «         ddd¦  «         n# 1 swxY w Y   |S )zæ
    Compresses a PNG image into an ASTC 4x4 binary container.
    If 'astcenc' CLI is installed in PATH, invokes official ARM astcenc encoder.
    Otherwise, generates canonical specification-compliant ASTC binary container.
    zSource PNG not found: Nú.astcT©ÚparentsÚexist_okÚRGBAÚastcenczastcenc-nativez-clÚxú-éx   )Úcapture_outputÚtextÚtimeoutr   r   )r   r   r   )Údtype)r   r   )Úaxisé   r   Úwbr'   )"r   ÚresolveÚexistsÚFileNotFoundErrorÚwith_suffixÚparentÚmkdirr
   ÚopenÚconvertÚsizeÚshutilÚwhichrW   Ú
subprocessÚrunÚ
returncodeÚstatÚst_sizer:   Ú	Exceptionr&   ÚnpÚarrayÚuint8ÚrangeÚminÚmeanÚastyperP   r   ÚappendÚwriteÚjoin)rR   rT   r   r   rV   Úsrc_pathÚout_pathÚimgÚrgba_imgr   r   Úastcenc_exeÚcmdÚresÚheaderÚnp_imgr4   r5   Úpayload_partsÚbyÚy0Úy1ÚbxÚx0Úx1Úblock_pixelsÚ	avg_colorÚblock_bytesÚfs                                r%   Úcompress_png_to_astcr˜   p   sç  € õ �H‰~Œ~×%Ò%Ñ'Ô'€HØ�?Š?ÑÔð EÝÐ C¸Ð CÐ CÑDÔDÐDàÐØ×'Ò'¨Ñ0Ô0ˆˆå˜Ñ$Ô$×,Ò,Ñ.Ô.ˆØ„O×Ò $°ÐÑ6Ô6Ð6å	Œ�HÑ	Ô	ð & Ø—;’;˜vÑ&Ô&ˆØ œ‰ˆˆvð&ð &ð &ñ &ô &ð &ð &ð &ð &ð &ð &øøøð &ð &ð &ð &õ
 ”,˜yÑ)Ô)ÐK­V¬\Ð:JÑ-KÔ-K€KØð ð	àØÝ�H‘”Ý�H‘”ØÐ&Ð&˜WÐ&Ð&Ø�G��ðˆCõ ”. °TÀÈcÐRÑRÔRˆCØŒ~ Ò"Ð" x§¢Ñ'8Ô'8Ð"¸X¿]º]¹_¼_Ô=TÕWgÒ=gÐ=gØ�øøÝð 	ð 	ð 	ØˆDð	øøøõ    v°wÈÐYZÐ[Ñ[Ô[€FÝŒX�h¥b¤hÐ/Ñ/Ô/€Fà˜‘ !Ñ#¨Ñ/€HØ˜Ñ  1Ñ$¨Ñ0€Hà€MÝ�H‰oŒoð .ð .ˆØ�'‰\ˆÝ��g‘˜vÑ&Ô&ˆÝ˜‘/”/ð 	.ð 	.ˆBØ�g‘ˆBÝ�R˜'‘\ 5Ñ)Ô)ˆBØ! " R %¨¨B¨ ,Ô/ˆLà$×)Ò)¨vÐ)Ñ6Ô6×=Ò=½b¼hÑGÔGˆIÝ7Ý�I˜a”LÑ!Ô!Ý�I˜a”LÑ!Ô!Ý�I˜a”LÑ!Ô!Ý�I˜a”LÑ!Ô!ñ	ô ˆKð × Ò  Ñ-Ô-Ð-Ð-ð	.õ 
ˆh˜Ñ	Ô	ð ) Ø	�Š�‰ŒˆØ	�Š�—’˜Ñ'Ô'Ñ(Ô(Ð(ð)ð )ð )ñ )ô )ð )ð )ð )ð )ð )ð )øøøð )ð )ð )ð )ð €Os7   Â1 CÃC!Ã$C!ÄBF Æ
F&Æ%F&Ì>MÍMÍMú*.pngÚ
source_dirÚ
output_dirÚpatternú
List[Path]c                ó¦  — t          | ¦  «                             ¦   «         }|r!t          |¦  «                             ¦   «         n|}|                     dd¬¦  «         g }|                     |¦  «        D ][}|                     ¦   «         rE||                     d¦  «        j        z  }	t          ||	||¬¦  «        }
|                     |
¦  «         Œ\|S )zIBatch compresses all matching PNG images in directory to ASTC containers.TrZ   rY   ©r   r   )	r   ri   rn   ÚglobÚis_filerl   Únamer˜   r�   )rš   r›   rœ   r   r   ÚsrcÚdstÚresultsÚpng_fileÚtarget_fileÚout_ps              r%   Úbatch_compress_directoryr©   ¼   sÔ   € õ ˆzÑ
Ô
×
"Ò
"Ñ
$Ô
$€CØ(2Ð
;�$ˆzÑ
Ô
×
"Ò
"Ñ
$Ô
$Ð
$¸€CØ‡I‚I�d T€IÑ*Ô*Ð*à€GØ—H’H˜WÑ%Ô%ð "ð "ˆØ×ÒÑÔð 	"Ø × 4Ò 4°WÑ =Ô =Ô BÑBˆKÝ(¨°;ÈÐY`ÐaÑaÔaˆEØ�NŠN˜5Ñ!Ô!Ð!øØ€Nr'   Ú	astc_pathÚboolc                ó´  — t          | ¦  «                             ¦   «         }|                     ¦   «         r"|                     ¦   «         j        t
          k     rdS t          |d¦  «        5 }|                     t
          ¦  «        }ddd¦  «         n# 1 swxY w Y   t          |¦  «        }|d         sdS |                     ¦   «         j        }||d         k    S )z\Verifies that an ASTC file is valid and matches expected header dimensions and payload size.FÚrbNr1   r8   )	r   ri   rj   rw   rx   r:   ro   Úreadr@   )rª   Úpr—   r(   ÚinfoÚactual_sizes         r%   Úverify_astc_filer²   Ñ   sö   € åˆY‰Œ×ÒÑ!Ô!€AØ�8Š8‰:Œ:ð ˜Ÿš™œÔ)Õ,<Ò<Ð<ØˆuÝ	ˆa�‰Œð 0˜!Ø—v’vÕ.Ñ/Ô/ˆð0ð 0ð 0ñ 0ô 0ð 0ð 0ð 0ð 0ð 0ð 0øøøð 0ð 0ð 0ð 0å˜\Ñ*Ô*€DØ�Ôð ØˆuØ—&’&‘(”(Ô"€KØ˜$Ð4Ô5Ò5Ð5s   Á*BÂBÂBc            	     ó†  — t          j        d¬¦  «        } |                      dd¬¦  «         |                      ddd¬¦  «         |                      d	t          d
d¬¦  «         |                      dt          d
d¬¦  «         |                      ddd¬¦  «         |                      ddd¬¦  «         |                      ¦   «         }t          |j        ¦  «        }|j        r.t          |¦  «        }t          d|rdnd› d|› �¦  «         |rdndS |j
        s|                     ¦   «         rFt          ||j        |j        |j        ¬¦  «        }t          dt!          |¦  «        › d|› �¦  «         dS t#          ||j        |j        |j        ¬¦  «        }t          d|› d|› d |                     ¦   «         j        › d!�¦  «         dS )"Nz@FreeExile ASTC 4x4 Mobile Texture Compressor for Apple Metal iOS)ÚdescriptionÚinputzInput PNG file or directory)Úhelpz-oz--outputzOutput ASTC file or directoryz	--block-xr   zBlock width (default: 4))ÚtypeÚdefaultr¶   z	--block-yzBlock height (default: 4)z--batchÚ
store_truezBatch process directory)Úactionr¶   z--verifyzVerify ASTC file integrityú[ÚVALIDÚINVALIDz] ASTC file: r   r   rŸ   z[OK] Batch compressed z ASTC textures from z[OK] Compressed z -> z (z bytes))ÚargparseÚArgumentParserÚadd_argumentr   Ú
parse_argsr   rµ   Úverifyr²   ÚprintÚbatchÚis_dirr©   Úoutputr   r   r9   r˜   rw   rx   )ÚparserÚargsÚinpÚvalidr¥   Úouts         r%   ÚmainrÌ   ß   så  € ÝÔ$Ð1sÐtÑtÔt€FØ
×Ò˜Ð&CÐÑDÔDÐDØ
×Ò˜˜jÐ/NÐÑOÔOÐOØ
×Ò˜­#°qÐ?YÐÑZÔZÐZØ
×Ò˜­#°qÐ?ZÐÑ[Ô[Ð[Ø
×Ò˜	¨,Ð=VÐÑWÔWÐWØ
×Ò˜
¨<Ð>ZÐÑ[Ô[Ð[à×ÒÑÔ€DÝ
ˆtŒzÑ
Ô
€Cà„{ð !Ý  Ñ%Ô%ˆÝÐE˜UÐ1�'�'¨	ÐEÐEÀÐEÐEÑFÔFÐFØÐ ˆqˆq˜qÐ à„zð �S—Z’Z‘\”\ð Ý*¨3°´ÀTÄ\Ð[_Ô[gÐhÑhÔhˆÝÐN¥s¨7¡|¤|ÐNÐNÈÐNÐNÑOÔOÐOØˆqå
˜s D¤K¸¼ÈtÌ|Ð
\Ñ
\Ô
\€CÝ	Ð
H˜SÐ
HÐ
H cÐ
HÐ
H¨S¯XªX©Z¬ZÔ-?Ð
HÐ
HÐ
HÑIÔIÐIØˆ1r'   Ú__main__)r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   )r(   r   r   r)   )
rA   r   rB   r   rC   r   rD   r   r   r   )Nr   r   rQ   )rR   rS   rT   rU   r   r   r   r   rV   rW   r   r   )Nr™   r   r   )rš   rS   r›   rU   rœ   rW   r   r   r   r   r   r�   )rª   rS   r   r«   )r   r   )"Ú__doc__Ú
__future__r   r¾   ÚosÚpathlibr   rr   rG   rt   ÚsysÚtypingr   r   r   r   r	   ÚPILr
   Únumpyrz   r   r    r:   r=   r&   r@   rP   r˜   r©   r²   rÌ   Ú__name__Úexit© r'   r%   ú<module>rÙ      sÖ  ððð ð #Ð "Ð "Ð "Ð "Ð "Ø €€€Ø 	€	€	€	Ø Ð Ð Ð Ð Ð Ø €€€Ø €€€Ø Ð Ð Ð Ø 
€
€
€
Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð ð ˆUÐ+Ð+Ð+Ñ,Ô,€
ØÐ ØÐ ð ØØð;ð ;ð ;ð ;ð ;ð0!ð !ð !ð !ðH%ð %ð %ð %ð8 /3ØØØðIð Ið Ið Ið Ið\ .2ØØØðð ð ð ð ð*6ð 6ð 6ð 6ðð ð ð ð6 ˆzÒÐØ€C„HˆTˆT‰VŒVÑÔÐÐÐð Ðr'   