a
    h@                     @  s  d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	 ddl
mZ ddlmZmZ G d	d
 d
eZG dd deZG dd deZdddddZd:ddddddZdddddZdddddZG d d! d!eZddd"d#d$ZG d%d& d&ejZG d'd( d(ejejZG d)d* d*eZG d+d, d,eZG d-d. d.ejZ d/d0d1d2d3d4d5Z!e"ej#ee e$ej#d6 e%d7e e%d8e e&ej#e! e'd9e  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.
    )annotationsN)IntEnum)BytesIO)IO   )Image	ImageFilec                   @  s   e Zd ZdZdS )Formatr   N)__name__
__module____qualname__JPEG r   r   @/var/www/auris/lib/python3.9/site-packages/PIL/BlpImagePlugin.pyr	   ,   s   r	   c                   @  s   e Zd ZdZdZdZdS )Encodingr         N)r
   r   r   UNCOMPRESSEDDXTZUNCOMPRESSED_RAW_BGRAr   r   r   r   r   0   s   r   c                   @  s   e Zd ZdZdZdZdS )AlphaEncodingr   r      N)r
   r   r   DXT1DXT3DXT5r   r   r   r   r   6   s   r   intztuple[int, int, int])ireturnc                 C  s*   | d? d@ d> | d? d@ d> | d@ d> fS )N      r      ?   r   r   )r   r   r   r   
unpack_565<   s    r!   Fbytesboolz1tuple[bytearray, bytearray, bytearray, bytearray])dataalphar   c              	   C  s  t | d }t t t t f}t|D ]}|d }td| |\}}}t|\}	}
}t|\}}}tdD ]L}tdD ]<}|d@ }|d? }d}|dkr|	|
|  }}}n|dkr|||  }}}n|dkr6||krd|	 | d }d|
 | d }d| | d }n$|	| d }|
| d }|| d }nR|dkr||kr|d| |	 d }d| |
 d }d| | d }nd	\}}}}|r|| ||||g q||| |||g q|qnq(|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)r$   r%   blocksretblock_indexidxcolor0color1bitsr0g0b0r1g1b1jr   controlargbr   r   r   decode_dxt1@   sD    



rD   )r$   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 ]2}d}tdD ]}d| | d	 }|| }|rd}|dL }nd
}|dM }|d9 }|	d	d| |  ? d@ }|dkr"|
||  }}}n|dkr>|||  }}}nv|d	krzd	|
 | d }d	| | d }d	| | d }n:|dkrd	| |
 d }d	| | d }d	| | d }|| ||||g qqq(|S )r&      z<8B<HHr'   <I   r(   Fr   T      r   r   r   r*   )r$   r1   r2   r3   r4   blockr7   r5   r6   coder8   r9   r:   r;   r<   r=   r>   highr   alphacode_indexr@   
color_coderA   rB   rC   r   r   r   decode_dxt3y   sH    




rP   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@ }n0|dkrF|
d? |	d> d@ B }n|	|d ? d@ }|d
krf|}nt|dkrv|}nd||krd| | |d |  d }n<|dkrd
}n,|dkrd}nd| | |d |  d }|dd| |  ? d@ }|d
kr|||  }}}n|dkr*|||  }}}nv|dkrfd| | d }d| | d }d| | d }n:|dkrd| | d }d| | d }d| | d }|| ||||g qqq(|S )zG
    input: one "row" of data (i.e. will produce 4 * width pixels)
    rE   z<BBz<6Br   r   r'   r(   r      r   r   rF   rG   rH   r   rI      r)   r*   )r$   r1   r2   r3   r4   rK   Za0Za1r7   Z
alphacode1Z
alphacode2r5   r6   rL   r8   r9   r:   r;   r<   r=   r>   r   rN   Z	alphacoder@   rO   rA   rB   rC   r   r   r   decode_dxt5   s^    ,










rS   c                   @  s   e Zd ZdS )BLPFormatErrorN)r
   r   r   r   r   r   r   rT      s   rT   )prefixr   c                 C  s
   |  dS )N)   BLP1   BLP2)
startswith)rU   r   r   r   _accept   s    rY   c                   @  s&   e Zd ZdZdZdZddddZdS )	BlpImageFilez 
    Blizzard Mipmap Format
    BLPzBlizzard Mipmap FormatNoner   c           	      C  sn  | j d| _t| js0dt| j }t|td| j dd }| jdkrptd| j dd dk}n\td| j dd }td| j dd dk}td| j dd }| j dt	j
 td	| j d
| _| jdkr&td| j dd }| j dt	j
 |||f}d}n||||f}d}| j }|rJdnd| _t|d| j ||g| _d S )Nr(   zBad BLP magic <ir   rV   rG   <br   <IIr'         RGBARGBr   r   )fpreadmagicrY   reprrT   r.   unpackseekosSEEK_CUR_sizedecode_moder   _Tilesizetile)	selfmsgcompressionr%   encodingZalpha_encodingargsoffsetdecoderr   r   r   _open  s,    



zBlpImageFile._openN)r
   r   r   __doc__formatformat_descriptionr{   r   r   r   r   rZ      s   rZ   c                   @  sr   e Zd ZdZdddddZejddd	d
ZddddZdddddZ	ddddZ
ddddddZdS )_BLPBaseDecoderTz$bytes | Image.SupportsArrayInterfaceztuple[int, int])bufferr   c              
   C  sN   z|    |   W n4 tjyH } zd}t||W Y d }~n
d }~0 0 dS )NzTruncated BLP file)r   )_read_header_loadr.   errorOSError)rt   r   eru   r   r   r   ro   )  s     z_BLPBaseDecoder.decoder\   r]   c                 C  s   d S Nr   rt   r   r   r   r   2  s    z_BLPBaseDecoder._loadc                 C  s,   t d| d| _t d| d| _d S )N<16I@   )r.   rj   
_safe_read_offsets_lengthsr   r   r   r   r   6  s    z_BLPBaseDecoder._read_headerr   r"   )lengthr   c                 C  s   | j d usJ t| j |S r   )fdr   r   )rt   r   r   r   r   r   :  s    z_BLPBaseDecoder._safe_readzlist[tuple[int, int, int, int]]c              	   C  sb   g }t dD ]P}ztd| d\}}}}W n tjyH   Y  q^Y n0 |||||f q|S )N   <4Br(   )r-   r.   rj   r   r   append)rt   r2   r   rC   rB   rA   r@   r   r   r   _read_palette>  s    z_BLPBaseDecoder._read_paletter#   r,   )paletter%   r   c                 C  s   t  }t| | jd }ztd|d\}W n tjyJ   Y qY n0 || \}}}}	|||f}
|rt|
|	f7 }
||
 q|S )Nr   <Br   )	r,   r   r   r   r.   rj   rg   r   r0   )rt   r   r%   r$   _datary   rC   rB   rA   r@   dr   r   r   
_read_bgraH  s    


z_BLPBaseDecoder._read_bgraN)r
   r   r   Z	_pulls_fdro   abcabstractmethodr   r   r   r   r   r   r   r   r   r   &  s   	
r   c                   @  s(   e Zd ZddddZddddZdS )BLP1Decoderr\   r]   c                 C  s   | j \| _| _}| jtjkr&|   nf| jdkrt| jdv rZ|  }| ||}| | qdt	| j }t
|ndt	| j }t
|d S )Nr   )r(   r   zUnsupported BLP encoding zUnsupported BLP compression )rx   _compression	_encodingr	   r   _decode_jpeg_streamr   r   
set_as_rawri   rT   )rt   r%   r   r$   ru   r   r   r   r   [  s    



zBLP1Decoder._loadc                 C  s   ddl m} td| d\}| |}| jd us8J | | jd | j   | | jd }|| }|t	|}t
|j |jdkr|jd j}t|tsJ |jd j|d dfdg|_| |d d	 d S )
Nr   )JpegImageFilerG   r(   r   ZCMYK)rx   rd   ZBGR)ZJpegImagePluginr   r.   rj   r   r   r   tellr   r   r   Z_decompression_bomb_checkrr   moders   rx   
isinstancetuple_replacer   converttobytes)rt   r   Zjpeg_header_sizeZjpeg_headerr$   imagerx   r   r   r   r   m  s    

zBLP1Decoder._decode_jpeg_streamN)r
   r   r   r   r   r   r   r   r   r   Z  s   r   c                   @  s   e Zd ZddddZdS )BLP2Decoderr\   r]   c                 C  s  | j \| _| _}| _|  }| jd us*J | j| jd  | jdkr| jtj	krd| 
||}q| jtjkrt }| jtjkr| jjd d d }t| jjd d D ]"}t| ||D ]}||7 }qqn| jtjkr0| jjd d d }t| jjd d D ]$}t| |D ]}||7 }qqnv| jtjkr| jjd d d }t| jjd d D ]$}t| |D ]}||7 }qxqfndt| j }t|ndt| j }t|nd	t| j }t|| | d S )
Nr   r   r   r(   r'   rE   zUnsupported alpha encoding zUnknown BLP encoding zUnknown BLP compression )rx   r   r   Z_alpha_encodingr   r   rk   r   r   r   r   r   r,   r   r   stateZxsizer-   ZysizerD   r   r   rP   r   rS   ri   rT   r   )rt   r%   r   r$   ZlinesizeZybr   ru   r   r   r   r     s>    

zBLP2Decoder._loadN)r
   r   r   r   r   r   r   r   r     s   r   c                   @  s.   e Zd ZdZddddZdddd	d
ZdS )
BLPEncoderTr"   r]   c              	   C  s   d}| j d usJ | j dd}tt|d D ]:}||d |d d  \}}}}|td||||7 }q0t|dk r|d7 }ql|S )N    rc   r(   r   r   i   s       )imZ
getpaletter-   r+   r.   pack)rt   r$   r   r   rA   rB   rC   r@   r   r   r   _write_palette  s     
zBLPEncoder._write_paletter   ztuple[int, int, bytes])bufsizer   c           	   
   C  s   |   }dt| }tjd|gdR  }| jd us6J | jj\}}|tjd|| gdR  7 }||7 }t|D ].}t|D ] }|td| j||f7 }qzqnt|d|fS )N   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r+   r.   r   r   rr   r-   Zgetpixel)	rt   r   Zpalette_datary   r$   whyxr   r   r   encode  s     zBLPEncoder.encodeN)r
   r   r   Z
_pushes_fdr   r   r   r   r   r   r     s   r   zImage.Imagez	IO[bytes]zstr | bytesr\   )r   rf   filenamer   c              
   C  sB  | j dkrd}t|| jddkr*dnd}|| | jd usFJ |tdd | jj d	krhdnd
}|dkr|td| nJ|tdtj	 |td| |tdd
 |tdd
 |tjdg| j
R   |dkr|tdd |tdd
 t| |tdd| j
 d
| j g d S )NPzUnsupported BLP image modeZblp_versionBLP1rV   rW   r^   r   rc   r   z<Lr_   r`   r   r[   re   )r   
ValueErrorZencoderinfogetwriter   r.   r   r   r   rr   r   _saverq   )r   rf   r   ru   rh   Zalpha_depthr   r   r   r     s&    


r   z.blpr   ZBLP2r[   )F)(r|   
__future__r   r   rl   r.   enumr   ior   typingr    r   r   r	   r   r   r!   rD   rP   rS   NotImplementedErrorrT   rY   rZ   ABCZ	PyDecoderr   r   r   Z	PyEncoderr   r   Zregister_openr}   Zregister_extensionZregister_decoderZregister_saveZregister_encoderr   r   r   r   <module>   s<    95F*4%0!