o
    Z#ûaé8  ã                   @   sü   d Z ddlZddlmZ ddlmZmZ dZdZdZ	dZ
dZdZdZd	d
„ Zd!dd„Zdd„ Zdd„ ZG dd„ deƒZG dd„ dejƒZG dd„ dejƒZG dd„ deƒZG dd„ deƒZdd„ Ze ejee¡ e ejd¡ e de¡ e d e¡ dS )"aÑ  
Blizzard Mipmap Format (.blp)
Jerome Leclanche <jerome@leclan.ch>

The contents of this file are hereby released in the public domain (CC0)
Full text of the CC0 license:
  https://creativecommons.org/publicdomain/zero/1.0/

BLP1 files, used mostly in Warcraft III, are not fully supported.
All types of BLP2 files used in World of Warcraft are supported.

The BLP file structure consists of a header, up to 16 mipmaps of the
texture

Texture sizes must be powers of two, though the two dimensions do
not have to be equal; 512x256 is valid, but 512x200 is not.
The first mipmap (mipmap #0) is the full size image; each subsequent
mipmap halves both dimensions. The final mipmap should be 1x1.

BLP files come in many different flavours:
* JPEG-compressed (type == 0) - only supported for BLP1.
* RAW images (type == 1, encoding == 1). Each mipmap is stored as an
  array of 8-bit values, one per pixel, left to right, top to bottom.
  Each value is an index to the palette.
* DXT-compressed (type == 1, encoding == 2):
- DXT1 compression is used if alpha_encoding == 0.
  - An additional alpha bit is used if alpha_depth == 1.
  - DXT3 compression is used if alpha_encoding == 1.
  - DXT5 compression is used if alpha_encoding == 7.
é    N)ÚBytesIOé   )ÚImageÚ	ImageFileé   é   é   c                 C   s*   | d? d@ d> | d? d@ d> | d@ d> fS )Né   é   r   é   é?   r   © )Úir   r   ú4/usr/lib/python3/dist-packages/PIL/BlpImagePlugin.pyÚ
unpack_5650   s   *r   Fc              	   C   s´  t | ƒd }tƒ tƒ tƒ tƒ f}t|ƒD ]Ã}|d }t d| |¡\}}}t|ƒ\}	}
}t|ƒ\}}}tdƒD ] }tdƒD ]™}|d@ }|d? }d}|dkrU|	|
|}}}nh|dkrb|||}}}n[|dkr–||krƒd|	 | d }d|
 | d }d| | d }n:|	| d }|
| d }|| d }n'|dkr½||kr·d| |	 d }d| |
 d }d| | d }nd	\}}}}|rË||  ||||g¡ q<||  |||g¡ q<q6q|S )
úE
    input: one "row" of data (i.e. will produce 4*width pixels)
    é   z<HHIé   r   r   éÿ   r   r   )r   r   r   r   ©ÚlenÚ	bytearrayÚrangeÚstructZunpack_fromr   Úextend)ÚdataÚalphaÚblocksÚretÚblockÚidxÚcolor0Úcolor1ÚbitsÚr0Úg0Úb0Úr1Úg1Úb1Újr   ZcontrolÚaÚrÚgÚbr   r   r   Údecode_dxt14   sH   áÿ"r/   c              	   C   sÆ  t | ƒd }tƒ tƒ tƒ tƒ f}t|ƒD ]Ì}|d }| ||d … }t d|¡}t d|d¡\}}t d|d¡\}t|ƒ\}	}
}t|ƒ\}}}tdƒD ]”}d}tdƒD ]‹}d| | d	 }|| }|rjd}|dL }nd
}|dM }|d9 }|d	d| |  ? d@ }|dkr|	|
|}}}nF|dkrš|||}}}n9|d	kr·d	|	 | d }d	|
 | d }d	| | d }n|dkrÓd	| |	 d }d	| |
 d }d	| | d }||  ||||g¡ qSqKq|S )r   é   z<8Bú<HHr   ú<Ié   r   Fr   Té   é   r   r   r   r   )r   r   r   r   r    r#   r!   r"   Úcoder$   r%   r&   r'   r(   r)   r*   Zhighr   Úalphacode_indexr+   Ú
color_coder,   r-   r.   r   r   r   Údecode_dxt3k   sL   
æþr9   c              	   C   s¬  t | ƒd }tƒ tƒ tƒ tƒ f}t|ƒD ]>}|d }| ||d … }t d|¡\}}t d|d¡}|d |d d> B |d d> B |d d	> B }|d
 |d d> B }	t d|d¡\}
}t d|d¡\}t|
ƒ\}}}t|ƒ\}}}tdƒD ]Ý}tdƒD ]Ö}dd| |  }|dkr|	|? d@ }n|dkrŸ|	d? |d> d@ B }n||d ? d@ }|d
kr®|}n6|dkrµ|}n/||krÈd| | |d |  d }n|dkrÏd
}n|dkrÖd}nd| | |d |  d }|dd| |  ? d@ }|d
krý|||}}}nI|dkr|||}}}n;|dkr)d| | d }d| | d }d| | d }n|dkrFd| | d }d| | d }d| | d }||  ||||g¡ q{quq|S )zG
    input: one "row" of data (i.e. will produce 4 * width pixels)
    r0   z<BBz<6Br   r   r   r   r   é   r   r   r1   r2   r3   r   r4   é   r   r   )r   r   r   r   r    Za0Za1r#   Z
alphacode1Z
alphacode2r!   r"   r6   r$   r%   r&   r'   r(   r)   r*   r   r7   Z	alphacoder+   r8   r,   r-   r.   r   r   r   Údecode_dxt5    sb   ,


Ùÿ*r<   c                   @   s   e Zd ZdS )ÚBLPFormatErrorN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r=   æ   s    r=   c                   @   s(   e Zd ZdZdZdZdd„ Zdd„ ZdS )	ÚBlpImageFilez 
    Blizzard Mipmap Format
    ZBLPzBlizzard Mipmap Formatc                 C   s‚   | j  d¡| _|  ¡  | jdkrd}d| _n| jdkr&d}| jr"dnd| _n
tdt| jƒ› ƒ‚|d	| j d
| jd
dffg| _	d S )Nr   ó   BLP1ÚBLP1ZRGBó   BLP2ÚBLP2ZRGBAzBad BLP magic ©r   r   r   r   )
ÚfpÚreadÚmagicÚ_read_blp_headerÚmodeÚ_blp_alpha_depthr=   ÚreprÚsizeÚtile)ÚselfÚdecoderr   r   r   Ú_openò   s   

"zBlpImageFile._openc                 C   sø   t  d| j d¡¡\| _t  d| j d¡¡\| _t  d| j d¡¡\| _t  d| j d¡¡\| _t  d| j d¡¡\| _t  d| j d¡¡| _	| j
dkrdt  d| j d¡¡\| _t  d| j d¡¡\| _t  d| j d	¡¡| _t  d| j d	¡¡| _d S ©
Nz<ir   z<br   z<IIr   rB   z<16Ié@   )r   ÚunpackrG   rH   Ú_blp_compressionÚ_blp_encodingrL   Ú_blp_alpha_encodingÚ	_blp_mipsÚ_sizerI   Ú_blp_subtypeÚ_blp_offsetsÚ_blp_lengths©rP   r   r   r   rJ     s   
zBlpImageFile._read_blp_headerN)r>   r?   r@   Ú__doc__ÚformatZformat_descriptionrR   rJ   r   r   r   r   rA   ê   s    rA   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )Ú_BLPBaseDecoderTc              
   C   sV   z| j  d¡ | j  d¡| _|  ¡  |  ¡  W dS  tjy* } ztdƒ|‚d }~ww )Nr   r   zTruncated Blp filerF   )	ÚfdÚseekrH   rI   rJ   Ú_loadr   ÚerrorÚOSError)rP   ÚbufferÚer   r   r   Údecode  s   
þ
€ÿz_BLPBaseDecoder.decodec                 C   s   t  | j|¡S )N)r   Ú
_safe_readrb   )rP   Úlengthr   r   r   rj   !  s   z_BLPBaseDecoder._safe_readc              	   C   s`   g }t dƒD ]'}zt d|  d¡¡\}}}}W n tjy#   Y  |S w | ||||f¡ q|S )Né   z<4Br   )r   r   rU   rj   re   Úappend)rP   r   r   r.   r-   r,   r+   r   r   r   Ú_read_palette$  s   ýz_BLPBaseDecoder._read_palettec                 C   sä   t  d|  d¡¡\| _t  d|  d¡¡\| _t  d|  d¡¡\| _t  d|  d¡¡\| _t  d|  d¡¡\| _t  d|  d¡¡| _| j	dkr\t  d|  d¡¡\| _t  d|  d¡¡\| _
t  d|  d	¡¡| _t  d|  d	¡¡| _d S rS   )r   rU   rj   rV   rW   rL   rX   rY   rN   rI   r[   r\   r]   r^   r   r   r   rJ   .  s   
z _BLPBaseDecoder._read_blp_headerN)r>   r?   r@   Z	_pulls_fdri   rj   rn   rJ   r   r   r   r   ra     s    

ra   c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚBLP1Decoderc           	      C   sØ   | j tkr|  ¡  d S | j dkrb| jdv rXtƒ }|  ¡ }t|  | jd ¡ƒ}	 zt	 
d| d¡¡\}W n
 t	jy=   Y nw || \}}}}| |||g¡ q'|  t|ƒ¡ d S tdt| jƒ› ƒ‚tdt| jƒ› ƒ‚)Nr   )r   r   r   Tú<BzUnsupported BLP encoding zUnsupported BLP compression )rV   ÚBLP_FORMAT_JPEGÚ_decode_jpeg_streamrW   r   rn   r   rj   r]   r   rU   rH   re   r   Ú
set_as_rawÚbytesr=   rM   )	rP   r   ÚpaletteÚ_dataÚoffsetr.   r-   r,   r+   r   r   r   rd   B  s.   


ÿúÿÿzBLP1Decoder._loadc                 C   s”   ddl m} t d|  d¡¡\}|  |¡}|  | jd | j ¡  ¡ |  | jd ¡}|| }t	|ƒ}||ƒ}t
 |j¡ |j| _|j| _|j| _d S )Nr   )ÚJpegImageFiler2   r   )ZPIL.JpegImagePluginrx   r   rU   rj   r\   rb   Útellr]   r   r   Z_decompression_bomb_checkrN   rO   rG   rK   )rP   rx   Zjpeg_header_sizeZjpeg_headerr   Zimager   r   r   rr   ]  s   
zBLP1Decoder._decode_jpeg_streamN)r>   r?   r@   rd   rr   r   r   r   r   ro   A  s    ro   c                   @   s   e Zd Zdd„ ZdS )ÚBLP2Decoderc                 C   s  |   ¡ }tƒ }| j | jd ¡ | jdkró| jtkrNt|  	| j
d ¡ƒ}	 zt d| d¡¡\}W n
 tjy;   Y nw || \}}}}| |||f¡ q%n¯| jtkré| jtkr…| jd d d d }	t| jd d d ƒD ]}
t|  	|	¡t| jƒdD ]}||7 }q|qnnx| jtkr²| jd d d d	 }	t| jd d d ƒD ]}
t|  	|	¡ƒD ]}||7 }q©q nK| jtkrß| jd d d d	 }	t| jd d d ƒD ]}
t|  	|	¡ƒD ]}||7 }qÖqÍntd
t| jƒ› ƒ‚tdt| jƒ› ƒ‚tdt| jƒ› ƒ‚|  t|ƒ¡ d S )Nr   r   Trp   r   r   r   )r   r0   zUnsupported alpha encoding zUnknown BLP encoding zUnknown BLP compression ) rn   r   rb   rc   r\   rV   rW   ÚBLP_ENCODING_UNCOMPRESSEDr   rj   r]   r   rU   rH   re   r   ÚBLP_ENCODING_DXTrX   ÚBLP_ALPHA_ENCODING_DXT1rN   r   r/   ÚboolrL   ÚBLP_ALPHA_ENCODING_DXT3r9   ÚBLP_ALPHA_ENCODING_DXT5r<   r=   rM   rs   rt   )rP   ru   r   rv   rw   r.   r-   r,   r+   ZlinesizeZybÚdr   r   r   rd   n  s`   

ÿú


ÿ
ýÿ

ÿÿ

ÿÿÿÿzBLP2Decoder._loadN)r>   r?   r@   rd   r   r   r   r   rz   m  s    rz   c                 C   s   | d d… dv S )Nr   )rB   rD   r   )Úprefixr   r   r   Ú_accept¤  s   rƒ   z.blprC   rE   )F)r_   r   Úior   Ú r   r   rq   r{   r|   Z"BLP_ENCODING_UNCOMPRESSED_RAW_BGRAr}   r   r€   r   r/   r9   r<   ÚNotImplementedErrorr=   rA   Z	PyDecoderra   ro   rz   rƒ   Zregister_openr`   Zregister_extensionZregister_decoderr   r   r   r   Ú<module>   s2    
75F*-,7