o
    Ԧ/f<                     @  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   2lib/python3.10/site-packages/PIL/BlpImagePlugin.pyr   *   s    r   c                   @     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   .       r   c                   @  r   )AlphaEncodingr   r      N)r	   r
   r   DXT1DXT3DXT5r   r   r   r   r   4   r   r   c                 C  s*   | d? d@ d> | d? d@ d> | d@ d> fS )N      r      ?   r   r   )ir   r   r   
unpack_565:   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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>   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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/   r0   r3   r1   r2   coder4   r5   r6   r7   r8   r9   r:   Zhighr   alphacode_indexr;   
color_coder<   r=   r>   r   r   r   decode_dxt3u   sL   
rI   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)
    r@   z<BBz<6Br   r   r"   r#   r      r   r   rA   rB   rC   r   rD      r$   r%   )r+   r-   r.   r/   r0   Za0Za1r3   Z
alphacode1Z
alphacode2r1   r2   rF   r4   r5   r6   r7   r8   r9   r:   r   rG   Z	alphacoder;   rH   r<   r=   r>   r   r   r   decode_dxt5   sb   ,


*rL   c                   @  s   e Zd ZdS )BLPFormatErrorN)r	   r
   r   r   r   r   r   rM      s    rM   c                 C  s   | d d dv S )Nr#      BLP1   BLP2r   )prefixr   r   r   _accept   s   rR   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v r9| j
 }nd	t| j }t|| jrJd
nd| _|d| j d| jddffg| _d S )Nr#   r   <br   r   <IIr"   rN   zBad BLP magic RGBARGBr   r   r   )fpreadmagicseekosSEEK_CURr)   unpack_blp_alpha_depth_sizedecodereprrM   _modesizemodetile)selfdecodermsgr   r   r   _open   s   
"zBlpImageFile._openN)r	   r
   r   __doc__formatZformat_descriptionrl   r   r   r   r   rS      s
    rS   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  s@   z|    |   W dS  tjy } zd}t||d }~ww )NzTruncated BLP file)r   )_read_blp_header_loadr)   errorOSError)ri   buffererk   r   r   r   rc     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r\td| d\| _| j dt	j
 td| d| _td| d| _d S )	Nr#   <irU   r   rV   r"   <16I@   )fdr]   r)   r`   
_safe_read_blp_compression_blp_encodingra   _blp_alpha_encodingr^   r_   rf   
isinstanceBLP1Decoder_blp_offsets_blp_lengths)ri   r   r   r   rq     s   
z _BLPBaseDecoder._read_blp_headerc                 C  s   t | j|S )N)r   r{   rz   )ri   lengthr   r   r   r{   2  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   <4Br#   )r(   r)   r`   r{   rs   append)ri   r.   r   r>   r=   r<   r;   r   r   r   _read_palette5  s   z_BLPBaseDecoder._read_palettec           
      C  s   t  }t| | jd }	 ztd|d\}W n tjy%   Y |S w || \}}}}|||f}	| jr;|	|f7 }	|	|	 q)Nr   T<Br   )
r'   r   r{   r   r)   r`   r[   rs   ra   r*   )
ri   paletter+   _dataoffsetr>   r=   r<   r;   dr   r   r   
_read_bgra?  s   


z_BLPBaseDecoder._read_bgraN)	r	   r
   r   Z	_pulls_fdrc   rq   r{   r   r   r   r   r   r   ro     s    	
ro   c                   @  s   e Zd Zdd Zdd ZdS )r   c                 C  s|   | j tjkr|   d S | j dkr2| jdv r&|  }| |}| | d S dt| j }t	|dt| j }t	|)Nr   )r#   r   zUnsupported BLP encoding zUnsupported BLP compression )
r|   r   r   _decode_jpeg_streamr}   r   r   
set_as_rawrd   rM   )ri   r   r+   rk   r   r   r   rr   P  s   


zBLP1Decoder._loadc                 C  s   ddl m} td| d\}| |}| | jd | j   | | jd }|| }t	|}||}t
|j |jdkrV|jd \}}}}	||||	d dffg|_|d \}
}}t
d|||
f}| |  d S )Nr   )JpegImageFilerB   r#   r   ZCMYKrX   )ZJpegImagePluginr   r)   r`   r{   r   rz   tellr   r   r   Z_decompression_bomb_checkrf   rg   rh   ZconvertsplitZmerger   tobytes)ri   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   rr   r   r   r   r   r   r   O  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| |}n| jtj	krt
 }| jtjkrZ| jd d d d }t| jd d d D ]}t| |t| jdD ]}||7 }qQqCn| jtjkr| jd d d d }t| jd d d D ]}t| |D ]}||7 }qqvnR| jtjkr| jd d d d }t| jd d d D ]}t| |D ]}||7 }qqn$dt| j }t|d	t| j }t|d
t| j }t|| | d S )Nr   r   r   r#   r"   )r,   r@   zUnsupported alpha encoding zUnknown BLP encoding zUnknown BLP compression )r   rz   r]   r   r|   r}   r   r   r   r   r'   r~   r   r   rf   r(   r?   r{   boolra   r   rI   r   rL   rd   rM   r   )ri   r   r+   ZlinesizeZybr   rk   r   r   r   rr   t  sJ   




zBLP2Decoder._loadN)r	   r
   r   rr   r   r   r   r   r   s  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}tt|d D ]}||d |d d  \}}}}|td||||7 }qt|dk r?|d7 }t|dk s5|S )N    rW   r#   r   r   i   s       )imZ
getpaletter(   r&   r)   pack)ri   r+   r   r   r<   r=   r>   r;   r   r   r   _write_palette  s    zBLPEncoder._write_palettec           	   
   C  s   |   }dt| }tjd|gdR  }| jj\}}|tjd|| gdR  7 }||7 }t|D ]}t|D ]}|td| j||f7 }q6q0t|d|fS )N   rx   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r&   r)   r   r   rf   r(   Zgetpixel)	ri   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r<dnd |td	d |td	d |tjdg| j
R   |dkru|tdd |tdd t| |dd| j
 d| j fg d S )NPzUnsupported BLP image modeZblp_versionBLP1rO   rP   rw   r   rU   rW   r   rV   r   rT   rY   )rg   
ValueErrorZencoderinfogetwriter)   r   r   r   r   rf   r   _save)r   rZ   filenamerk   r\   r   r   r   r     s   

"$r   z.blpr   ZBLP2rT   )F)$rm   Z
__future__r   r^   r)   enumr   ior    r   r   r   r   r   r    r?   rI   rL   NotImplementedErrorrM   rR   rS   Z	PyDecoderro   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<$/