U
     Ӕe<                     @  sd  d Z ddlm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 G dd	 d	eZG d
d deZG dd de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& 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.
    )annotationsN)IntEnum)BytesIO   )Image	ImageFilec                   @  s   e Zd ZdZdS )Formatr   N)__name__
__module____qualname__JPEG r   r   1lib/python3.8/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*   | d? d@ d> | d? d@ d> | d@ d> fS )N      r      ?   r   r   )ir   r   r   
unpack_5659   s    r   Fc              	   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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_dxt1=   sD    



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)   r+   r,   r-   r.   r1   r/   r0   coder2   r3   r4   r5   r6   r7   r8   Zhighr   alphacode_indexr9   
color_coder:   r;   r<   r   r   r   decode_dxt3t   sH    




rG   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)
    r>   z<BBz<6Br   r   r    r!   r      r   r   r?   r@   rA   r   rB      r"   r#   )r)   r+   r,   r-   r.   Za0Za1r1   Z
alphacode1Z
alphacode2r/   r0   rD   r2   r3   r4   r5   r6   r7   r8   r   rE   Z	alphacoder9   rF   r:   r;   r<   r   r   r   decode_dxt5   s^    ,










rJ   c                   @  s   e Zd ZdS )BLPFormatErrorN)r	   r
   r   r   r   r   r   rK      s   rK   c                 C  s   | d d dkS )Nr!      BLP1   BLP2r   )prefixr   r   r   _accept   s    rP   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   <br   r   <IIr    rL   zBad BLP magic RGBARGBr   r   r   )fpreadmagicseekosSEEK_CURr'   unpack_blp_alpha_depthZ_sizedecodereprrK   _modesizemodetile)selfdecodermsgr   r   r   _open   s    
zBlpImageFile._openN)r	   r
   r   __doc__formatZformat_descriptionri   r   r   r   r   rQ      s   rQ   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   z|    |   W n2 tjk
rF } zd}t||W 5 d }~X Y nX dS )NzTruncated BLP file)r   )_read_blp_header_loadr'   errorOSError)rf   buffererh   r   r   r   r`     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!   <irS   r   rT   r    <16I@   )fdr[   r'   r^   
_safe_read_blp_compression_blp_encodingr_   _blp_alpha_encodingr\   r]   rc   
isinstanceBLP1Decoder_blp_offsets_blp_lengths)rf   r   r   r   rn     s    
z _BLPBaseDecoder._read_blp_headerc                 C  s   t | j|S )N)r   rx   rw   )rf   Zlengthr   r   r   rx   1  s    z_BLPBaseDecoder._safe_readc              	   C  sd   g }t dD ]R}ztd| d\}}}}W n tjk
rJ   Y  q`Y nX |||||f q|S )N   <4Br!   )r&   r'   r^   rx   rp   append)rf   r,   r   r<   r;   r:   r9   r   r   r   _read_palette4  s    z_BLPBaseDecoder._read_palettec           
      C  s   t  }t| | jd }ztd|d\}W n tjk
rL   Y qY nX || \}}}}|||f}	| jrx|	|f7 }	|	|	 q|S )Nr   <Br   )
r%   r   rx   r   r'   r^   rY   rp   r_   r(   )
rf   paletter)   _dataoffsetr<   r;   r:   r9   dr   r   r   
_read_bgra>  s    


z_BLPBaseDecoder._read_bgraN)	r	   r
   r   Z	_pulls_fdr`   rn   rx   r   r   r   r   r   r   rl     s   	
rl   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 )ry   r   r   _decode_jpeg_streamrz   r   r   
set_as_rawbytesra   rK   )rf   r   r)   rh   r   r   r   ro   O  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   )JpegImageFiler@   r!   r   ZCMYKrV   )ZJpegImagePluginr   r'   r^   rx   r~   rw   tellr   r   r   Z_decompression_bomb_checkrc   rd   re   Zconvertsplitmerger   tobytes)rf   r   Zjpeg_header_sizeZjpeg_headerr)   ZimageZdecoder_nameZextentsr   argsr:   r;   r<   r   r   r   r   _  s    

zBLP1Decoder._decode_jpeg_streamN)r	   r
   r   ro   r   r   r   r   r   r}   N  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 }t| jd d d D ]*}t| |t| jdD ]}||7 }qqn| jtjkr| jd d d d }t| jd d d D ]"}t| |D ]}||7 }qqnz| jtjkr|| jd d d d }t| jd d d D ]$}t| |D ]}||7 }qfqTndt| j }t|nd	t| j }t|nd
t| j }t|| t| d S )Nr   r   r   r!   r    )r*   r>   zUnsupported alpha encoding zUnknown BLP encoding zUnknown BLP compression )r   rw   r[   r~   ry   rz   r   r   r   r   r%   r{   r   r   rc   r&   r=   rx   boolr_   r   rG   r   rJ   ra   rK   r   r   )rf   r   r)   ZlinesizeZybr   rh   r   r   r   ro   s  s@     


zBLP2Decoder._loadN)r	   r
   r   ro   r   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  sx   d}| j dd}tt|d D ]:}||d |d d  \}}}}|td||||7 }q"t|dk rt|d7 }q^|S )N    rU   r!   r   r   i   s       )imZ
getpaletter&   r$   r'   pack)rf   r)   r   r   r:   r;   r<   r9   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 }t|D ].}t|D ] }|td| j||f7 }qhq\t|d|fS )N   ru   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r$   r'   r   r   rc   r&   Zgetpixel)	rf   bufsizeZpalette_datar   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   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BLP1rM   rN   rt   r   rS   rU   r   rT   r   rR   rW   )rT   )rd   
ValueErrorZencoderinfogetwriter'   r   r   r   r   rc   r   _save)r   rX   filenamerh   rZ   r   r   r   r     s    

"r   z.blpr   ZBLP2rR   )F)$rj   Z
__future__r   r\   r'   enumr   ior    r   r   r   r   r   r   r=   rG   rJ   NotImplementedErrorrK   rP   rQ   Z	PyDecoderrl   r}   r   Z	PyEncoderr   r   Zregister_openrk   Zregister_extensionZregister_decoderZregister_saveZregister_encoderr   r   r   r   <module>   s6   
75F<$/