o
    Z#a8                     @   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rd|	 | d }d|
 | d }d| | d }n:|	| d }|
| d }|| d }n'|dkr||krd| |	 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structunpack_fromr   extend)dataalphablocksretblockidxcolor0color1bitsr0g0b0r1g1b1jr   controlargbr   r   r   decode_dxt14   sH   "r1   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rd	|	 | d }d	|
 | d }d	| | d }n|dkrd	| |	 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+   highr   alphacode_indexr-   
color_coder.   r/   r0   r   r   r   decode_dxt3k   sL   
r<   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rd| | |d |  d }n|dkrd
}n|dkrd}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)
    r2   z<BBz<6Br   r   r   r   r      r   r   r3   r4   r5   r   r6      r   r   )r   r   r   r    r!   a0a1r$   
alphacode1
alphacode2r"   r#   r8   r%   r&   r'   r(   r)   r*   r+   r   r:   	alphacoder-   r;   r.   r/   r0   r   r   r   decode_dxt5   sb   ,


*rD   c                   @   s   e Zd ZdS )BLPFormatErrorN)__name__
__module____qualname__r   r   r   r   rE      s    rE   c                   @   s(   e Zd ZdZdZdZdd Zdd ZdS )	BlpImageFilez 
    Blizzard Mipmap Format
    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BLP1RGB   BLP2BLP2RGBAzBad BLP magic r   r   r   r   )
fpreadmagic_read_blp_headermode_blp_alpha_depthrE   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   rK   z<16I@   )r   unpackrR   rS   _blp_compression_blp_encodingrW   _blp_alpha_encoding	_blp_mips_sizerT   _blp_subtype_blp_offsets_blp_lengthsr[   r   r   r   rU     s   
zBlpImageFile._read_blp_headerN)rF   rG   rH   __doc__formatformat_descriptionr]   rU   r   r   r   r   rI      s    rI   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 filerQ   )	fdseekrS   rT   rU   _loadr   errorOSError)r[   bufferer   r   r   decode  s   

z_BLPBaseDecoder.decodec                 C   s   t | j|S )N)r   
_safe_readrn   )r[   lengthr   r   r   rv   !  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   r`   rv   rq   append)r[   r   r   r0   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 r^   )r   r`   rv   ra   rb   rW   rc   rd   rY   rT   rf   rg   rh   ri   r   r   r   rU   .  s   
z _BLPBaseDecoder._read_blp_headerN)rF   rG   rH   	_pulls_fdru   rv   rz   rU   r   r   r   r   rm     s    

rm   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 )ra   BLP_FORMAT_JPEG_decode_jpeg_streamrb   r   rz   r   rv   rh   r   r`   rS   rq   r   
set_as_rawbytesrE   rX   )	r[   r   palette_dataoffsetr0   r/   r.   r-   r   r   r   rp   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   )JpegImageFiler4   r   )PIL.JpegImagePluginr   r   r`   rv   rg   rn   tellrh   r   r   _decompression_bomb_checkrY   rZ   rR   rV   )r[   r   jpeg_header_sizejpeg_headerr   imager   r   r   r   ]  s   
zBLP1Decoder._decode_jpeg_streamN)rF   rG   rH   rp   r   r   r   r   r   r|   A  s    r|   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 }qqnK| jtkr| jd d d d	 }	t| jd d d D ]}
t| 	|	D ]}||7 }qqntd
t| j tdt| j tdt| j | t| d S )Nr   r   Tr}   r   r   r   )r   r2   zUnsupported alpha encoding zUnknown BLP encoding zUnknown BLP compression ) rz   r   rn   ro   rg   ra   rb   BLP_ENCODING_UNCOMPRESSEDr   rv   rh   r   r`   rS   rq   r   BLP_ENCODING_DXTrc   BLP_ALPHA_ENCODING_DXT1rY   r   r1   boolrW   BLP_ALPHA_ENCODING_DXT3r<   BLP_ALPHA_ENCODING_DXT5rD   rE   rX   r   r   )r[   r   r   r   r   r0   r/   r.   r-   linesizeybdr   r   r   rp   n  s`   









zBLP2Decoder._loadN)rF   rG   rH   rp   r   r   r   r   r   m  s    r   c                 C   s   | d d dv S )Nr   )rK   rN   r   )prefixr   r   r   _accept  s   r   z.blprL   rO   )F)rj   r   ior    r   r   r~   r   r   "BLP_ENCODING_UNCOMPRESSED_RAW_BGRAr   r   r   r   r1   r<   rD   NotImplementedErrorrE   rI   	PyDecoderrm   r|   r   r   register_openrk   register_extensionregister_decoderr   r   r   r   <module>   s2    
75F*-,7