B
    eAd{>                 @   sn  d Z ddlZddlZddlmZ ddlmZ ddlmZm	Z	 ddl
mZ G dd	 d	eZG d
d deZG dd deZdd Zdd Zd-ddZdd Zdd ZG dd deZdd 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G d%d& d&e	jZd.d'd(Zeej ee e!ej d) e"d*e e"d+e e#ej 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)IntEnum)BytesIO   )Image	ImageFile)	deprecatec               @   s   e Zd ZdZdS )Formatr   N)__name__
__module____qualname__JPEG r   r   D/var/www/html/venv/lib/python3.7/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   -   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   3   s   r   c             C   s   xlt dtdtdi D ]T\}}| |r| t|d  } | |jkrt| |  d|j d|   ||  S qW dt d|  d}t	|d S )	NZBLP_FORMAT_ZBLP_ENCODING_ZBLP_ALPHA_ENCODING_
   .zmodule 'z' has no attribute '')
r   r   r   items
startswithlen__members__r   r	   AttributeError)nameenumprefixmsgr   r   r   __getattr__9   s    

 r%   c             C   s*   | d? d@ d> | d? d@ d> | d@ d> fS )N      r      ?   r   r   )ir   r   r   
unpack_565H   s    r+   Fc          	   C   s  t | d }t t t t f}xt|D ]}|d }td| |\}}}t|\}	}
}t|\}}}x`tdD ]R}xJtdD ]<}|d@ }|d? }d}|dkr|	|
|  }}}n|dkr|||  }}}n|dkrB||krd|	 | d }d|
 | d }d| | d }n$|	| d }|
| d }|| d }nR|dkr||krd| |	 d }d| |
 d }d| | d }nd	\}}}}|r|| ||||g q|| |||g qW qvW q,W |S )
zE
    input: one "row" of data (i.e. will produce 4*width pixels)
       z<HHI   r   r      r   r   )r   r   r   r   )r   	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_dxt1L   sD    



 rI   c          	   C   s  t | d }t t t t f}xt|D ]}|d }| ||d  }td|}td|d\}}td|d\}t|\}	}
}t|\}}}xFtdD ]8}d}x,tdD ]}d| | d	 }|| }|rd}|dL }nd
}|dM }|d9 }|d	d| |  ? d@ }|dkr.|	|
|  }}}n|dkrJ|||  }}}nv|d	krd	|	 | d }d	|
 | d }d	| | d }n:|dkrd	| |	 d }d	| |
 d }d	| | d }|| ||||g qW qW q,W |S )zE
    input: one "row" of data (i.e. will produce 4*width pixels)
       z<8Bz<HHr,   z<I   r-   Fr   T      r   r   r   )r   r/   r0   r1   r2   r+   r3   )r4   r6   r7   r8   r9   r<   r:   r;   coder=   r>   r?   r@   rA   rB   rC   highr*   alphacode_indexrE   
color_coderF   rG   rH   r   r   r   decode_dxt3   sH    




"rR   c          	   C   s  t | d }t t t t f}xt|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|\}}}xtdD ]}xtdD ]}dd| |  }|dkr2|	|? d@ }n0|dkrR|	d? |d> d@ B }n||d ? d@ }|d
krr|}nt|dkr|}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r6|||  }}}nv|dkrrd| | d }d| | d }d| | d }n:|dkrd| | d }d| | d }d| | d }|| ||||g qW qW q,W |S )zG
    input: one "row" of data (i.e. will produce 4 * width pixels)
    rJ   z<BBz<6Br   r   r,   r-   r(      r   r   z<HHz<IrK   r   rL      r.   )r   r/   r0   r1   r2   r+   r3   )r4   r6   r7   r8   r9   Za0Za1r<   Z
alphacode1Z
alphacode2r:   r;   rN   r=   r>   r?   r@   rA   rB   rC   r*   rP   Z	alphacoderE   rQ   rF   rG   rH   r   r   r   decode_dxt5   s^    ,










$rU   c               @   s   e Zd ZdS )BLPFormatErrorN)r	   r
   r   r   r   r   r   rV      s   rV   c             C   s   | d d dkS )Nr-   )s   BLP1s   BLP2r   )r#   r   r   r   _accept  s    rW   c               @   s    e Zd ZdZdZdZdd ZdS )BlpImageFilez 
    Blizzard Mipmap Format
    BLPzBlizzard Mipmap Formatc             C   s   | j d| _| j dtj td| j d\| _| j dtj td| j d| _	| jdkrr| j
 }nd	t| j }t|| jrd
nd| _|d| j d| jddffg| _d S )Nr-   r(   z<br   r   z<IIr,   )s   BLP1s   BLP2zBad BLP magic RGBARGB)r   r   r   )fpreadmagicseekosSEEK_CURr1   unpack_blp_alpha_depth_sizedecodereprrV   modesizetile)selfdecoderr$   r   r   r   _open  s    
zBlpImageFile._openN)r	   r
   r   __doc__formatformat_descriptionrl   r   r   r   r   rX     s   rX   c               @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )_BLPBaseDecoderTc          
   C   sL   y|    |   W n2 tjk
rF } zd}t||W d d }~X Y nX dS )NzTruncated BLP file)r   )_read_blp_header_loadr1   errorOSError)rj   bufferer$   r   r   r   re   $  s    z_BLPBaseDecoder.decodec             C   s   | j d td| d\| _td| d\| _td| d\| _td| d\| _| j dt	j
 td| d| _t| trtd| d\| _| j dt	j
 td| d| _td| d| _d S )	Nr-   z<iz<br   z<IIr,   z<16I@   )fdr_   r1   rb   
_safe_read_blp_compression_blp_encodingrc   _blp_alpha_encodingr`   ra   rh   
isinstanceBLP1Decoder_blp_offsets_blp_lengths)rj   r   r   r   rr   -  s    
z _BLPBaseDecoder._read_blp_headerc             C   s   t | j|S )N)r   rz   ry   )rj   lengthr   r   r   rz   @  s    z_BLPBaseDecoder._safe_readc          	   C   sd   g }xZt dD ]N}ytd| d\}}}}W n tjk
rH   P Y nX |||||f qW |S )N   z<4Br-   )r0   r1   rb   rz   rt   append)rj   r7   r*   rH   rG   rF   rE   r   r   r   _read_paletteC  s    z_BLPBaseDecoder._read_palettec       
      C   s   t  }t| | jd }xjytd|d\}W n tjk
rL   P Y nX || \}}}}|||f}	| jrx|	|f7 }	|	|	 qW |S )Nr   z<Br   )
r/   r   rz   r   r1   rb   r]   rt   rc   r3   )
rj   paletter4   _dataoffsetrH   rG   rF   rE   dr   r   r   
_read_bgraM  s    

z_BLPBaseDecoder._read_bgraN)	r	   r
   r   Z	_pulls_fdre   rr   rz   r   r   r   r   r   r   rp   !  s   	
rp   c               @   s   e Zd Zdd Zdd ZdS )r   c             C   s   | j tjkr|   nh| j dkrf| jdkrL|  }| |}| t| q~dt	| j }t
|ndt	| j }t
|d S )Nr   )r-   r(   zUnsupported BLP encoding zUnsupported BLP compression )r{   r   r   _decode_jpeg_streamr|   r   r   
set_as_rawbytesrf   rV   )rj   r   r4   r$   r   r   r   rs   ^  s    




zBLP1Decoder._loadc             C   s   ddl m} td| d\}| |}| | jd | j   | | jd }|| }t	|}||}t
|j |jdkr|jd \}}}}	||||	d dffg|_|d \}
}}t
d|||
f}| |  d S )Nr   )JpegImageFilez<Ir-   r   ZCMYKr[   )ZJpegImagePluginr   r1   rb   rz   r   ry   tellr   r   r   Z_decompression_bomb_checkrh   rg   ri   convertsplitmerger   tobytes)rj   r   Zjpeg_header_sizeZjpeg_headerr4   imageZdecoder_nameZextentsr   argsrF   rG   rH   r   r   r   r   n  s    

zBLP1Decoder._decode_jpeg_streamN)r	   r
   r   rs   r   r   r   r   r   r   ]  s   r   c               @   s   e Zd Zdd ZdS )BLP2Decoderc             C   s  |   }| j| jd  | jdkr| jtjkr@| |}q| jtj	krt
 }| jtjkr| jd d d d }xHt| jd d d D ].}x(t| |t| jdD ]}||7 }qW qW n| jtjkr*| jd d d d }xt| jd d d D ]&}x t| |D ]}||7 }qW qW n| jtjkr| jd d d d }x\t| jd d d D ](}x t| |D ]}||7 }qzW qfW ndt| j }t|nd	t| j }t|nd
t| j }t|| t| d S )Nr   r   r   r-   r,   )r5   rJ   zUnsupported alpha encoding zUnknown BLP encoding zUnknown BLP compression )r   ry   r_   r   r{   r|   r   r   r   r   r/   r}   r   r   rh   r0   rI   rz   boolrc   r   rR   r   rU   rf   rV   r   r   )rj   r   r4   ZlinesizeZybr   r$   r   r   r   rs     s<    

zBLP2Decoder._loadN)r	   r
   r   rs   r   r   r   r   r     s   r   c               @   s    e Zd ZdZdd Zdd ZdS )
BLPEncoderTc          	   C   s^   d}| j dd}xFtdD ]:}||d |d d  \}}}}|td||||7 }qW |S )N    rZ   r   r-   r   z<4B)imZ
getpaletter0   r1   pack)rj   r4   r   r*   rF   rG   rH   rE   r   r   r   _write_palette  s     zBLPEncoder._write_palettec       	   
   C   s   |   }dt| }tjd|fd }| jj\}}|tjd|| fd 7 }||7 }x>t|D ]2}x,t|D ] }|td| j||f7 }qlW q^W t|d|fS )N   z<16I)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   z<Br   )r   r   r1   r   r   rh   r0   Zgetpixel)	rj   bufsizeZpalette_datar   r4   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   c             C   s
  | j dkrd}t|| jddkr*dnd}|| |tdd |td	tj |td	| j	j d
krxdnd |td	d |td	d |tjd| j
  |dkr|tdd |tdd t| |dd| j
 d| j fg d S )NPzUnsupported BLP image modeZblp_versionBLP1s   BLP1s   BLP2z<ir   z<brZ   r   <IIr(   rY   )r   r   )r   )rg   
ValueErrorZencoderinfogetwriter1   r   r   r   r   rh   r   _save)r   r\   filenameZsave_allr$   r^   r   r   r   r     s    

"r   z.blpr   ZBLP2rY   )F)F)%rm   r`   r1   r"   r   ior    r   r   Z
_deprecater   r   r   r   r%   r+   rI   rR   rU   NotImplementedErrorrV   rW   rX   Z	PyDecoderrp   r   r   Z	PyEncoderr   r   Zregister_openrn   Zregister_extensionZregister_decoderZregister_saveZregister_encoderr   r   r   r   <module>   s8   
75F<$/
