
    e<                       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	e      Z G d
 de      Z G d de      Zd Zd$dZd Zd Z G d de      Zd Z G d dej                        Z G d dej.                        Z G d de      Z G d de      Z G d dej6                        Zd Z e
j<                  ej>                  ee        e
j@                  ej>                  d         e
jB                  d!e        e
jB                  d"e        e
jD                  ej>                  e        e
jF                  d#e       y)%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                      e Zd ZdZy)Formatr   N)__name__
__module____qualname__JPEG     4/usr/lib/python3/dist-packages/PIL/BlpImagePlugin.pyr
   r
   )   s    Dr   r
   c                      e Zd ZdZdZdZy)Encodingr         N)r   r   r   UNCOMPRESSEDDXTUNCOMPRESSED_RAW_BGRAr   r   r   r   r   -   s    L
Cr   r   c                      e Zd ZdZdZdZy)AlphaEncodingr   r      N)r   r   r   DXT1DXT3DXT5r   r   r   r   r   3   s    DDDr   r   c                <    | dz	  dz  dz  | dz	  dz  dz  | dz  dz  fS )N      r      ?   r   r   )is    r   
unpack_565r%   9   s2    "W"a1f_$:QX!OKKr   c           	        t        |       dz  }t               t               t               t               f}t        |      D ]/  }|dz  }t        j                  d| |      \  }}}t        |      \  }	}
}t        |      \  }}}t        d      D ]  }t        d      D ]  }|dz  }|dz	  }d}|dk(  r|	|
|}}}n|dk(  r|||}}}nx|dk(  r@||kD  r"d|	z  |z   dz  }d|
z  |z   dz  }d|z  |z   dz  }nL|	|z   dz  }|
|z   dz  }||z   dz  }n3|dk(  r.||kD  r"d|z  |	z   dz  }d|z  |
z   dz  }d|z  |z   dz  }nd	\  }}}}|r||   j                  |g       ||   j                  g         2 |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bs                         r   decode_dxt1rG   =   s   
 Y!^F;	Y[)+
>Cv *-ai%11&$D'
B'
B q  	-A1X - (qya< "b!qA\ "b!qA\Vb[Q.Vb[Q.Vb[Q."WN"WN"WN\Vb[Q.Vb[Q.Vb[Q.%/
1aFMM1aA,/FMM1a),?- 	-*-X Jr   c           	     &   t        |       dz  }t               t               t               t               f}t        |      D ]M  }|dz  }| ||dz    }t        j                  d|      }t        j                  d|d      \  }}t        j                  d|d      \  }t        |      \  }	}
}t        |      \  }}}t        d      D ]  }d}t        d      D ]  }d|z  |z   d	z  }||   }|rd}|dz  }nd
}|dz  }|dz  }|d	d|z  |z   z  z	  dz  }|dk(  r|	|
|}}}nY|dk(  r|||}}}nM|d	k(  r"d	|	z  |z   dz  }d	|
z  |z   dz  }d	|z  |z   dz  }n&|dk(  r!d	|z  |	z   dz  }d	|z  |
z   dz  }d	|z  |z   dz  }||   j                  |g         P |S )r'      z<8B<HHr(   <I   r)   Fr   T      r   r   r   r+   )r2   r4   r5   r6   r7   r:   r8   r9   coder;   r<   r=   r>   r?   r@   rA   highr$   alphacode_indexrC   
color_coderD   rE   rF   s                           r   decode_dxt3rS   t   s   
 Y"_F;	Y[)+
>Cv (,bjS38$!!%/++E5!<$$T5"5'
B'
Bq 	,AD1X ,#$q519"2) D!GADHAR"a1q519o5=
? "b!qA1_ "b!qA1_R"*AR"*AR"*A1_R"*AR"*AR"*AAq!Ql+5,	,(,T Jr   c           	     z   t        |       dz  }t               t               t               t               f}t        |      D ]  }|dz  }| ||dz    }t        j                  d|      \  }}t        j                  d|d      }|d   |d   dz  z  |d   dz  z  |d   d	z  z  }|d
   |d   dz  z  }	t        j                  d|d      \  }
}t        j                  d|d      \  }t        |
      \  }}}t        |      \  }}}t        d      D ])  }t        d      D ]  }dd|z  |z   z  }|dk  r	|	|z	  dz  }n|dk(  r|	dz	  |dz  dz  z  }n||dz
  z	  dz  }|d
k(  r|}nF|dk(  r|}n>||kD  rd|z
  |z  |dz
  |z  z   dz  }n$|dk(  rd
}n|dk(  rd}nd|z
  |z  |dz
  |z  z   dz  }|dd|z  |z   z  z	  dz  }|d
k(  r|||}}}nY|dk(  r|||}}}nM|dk(  r"d|z  |z   dz  }d|z  |z   dz  }d|z  |z   dz  }n&|dk(  r!d|z  |z   dz  }d|z  |z   dz  }d|z  |z   dz  }||   j                  |g        ,  |S )zG
    input: one "row" of data (i.e. will produce 4 * width pixels)
    rI   z<BBz<6Br   r   r(   r)   r"      r   r   rJ   rK   rL   r   rM      r*   r+   )r2   r4   r5   r6   r7   a0a1r:   
alphacode1
alphacode2r8   r9   rO   r;   r<   r=   r>   r?   r@   rA   r$   rQ   	alphacoderC   rR   rD   rE   rF   s                               r   decode_dxt5r\      s   
 Y"_F;	Y[)+
>Cv 9,bjS38$##E51B!!%2!WQ1-aB?47b=Q
!WQ1-
++E5!<$$T5"5'
B'
Bq (	,A1X ',"#q1uqy/"b(!+!>$ FI$*!+r!1zQ$6N OI!+"0D!E MI>A!^A"Wi-2-Q"0DDJA!^A!^Ai-2-Q"0DDJA"a1q519o5=
? "b!qA1_ "b!qA1_R"*AR"*AR"*A1_R"*AR"*AR"*AAq!Ql+O',(	,#9,v Jr   c                      e Zd Zy)BLPFormatErrorN)r   r   r   r   r   r   r^   r^      s    r   r^   c                    | d d dv S )Nr)      BLP1   BLP2r   )prefixs    r   _acceptrd      s    "1:+++r   c                      e Zd ZdZdZdZd Zy)BlpImageFilez 
    Blizzard Mipmap Format
    BLPzBlizzard Mipmap Formatc                   | j                   j                  d      | _        | j                   j                  dt        j
                         t        j                  d| j                   j                  d            \  | _        | j                   j                  dt        j
                         t        j                  d| j                   j                  d            | _	        | j                  dv r| j                  j                         }n#d	t        | j                         }t        |      | j                  rd
nd| _        |d| j                  z   d| j                  ddffg| _        y )Nr)   r"   <br   r   <IIr(   r`   zBad BLP magic RGBARGBr   r   r   )fpreadmagicseekosSEEK_CURr/   unpack_blp_alpha_depth_sizedecodereprr^   _modesizemodetile)selfdecodermsgs      r   _openzBlpImageFile._open   s    WW\\!_
Q$#)==tww||A#G 	Q$]]5$'',,q/:
::++jj'')G"4

#3"45C %%#44V%
v		11tyy!Q6GHI	r   N)r   r   r   __doc__formatformat_descriptionr   r   r   r   rf   rf      s     F1Jr   rf   c                  .    e Zd ZdZd Zd Zd Zd Zd Zy)_BLPBaseDecoderTc                    	 | j                          | j                          y# t        j                  $ r}d}t	        |      |d }~ww xY w)NzTruncated BLP file)r   )_read_blp_header_loadr/   errorOSError)r}   bufferer   s       r   rw   z_BLPBaseDecoder.decode  sH    	&!!#JJL  || 	&&C#,A%	&s    # A	AA	c                   | j                   j                  d       t        j                  d| j	                  d            \  | _        t        j                  d| j	                  d            \  | _        t        j                  d| j	                  d            \  | _        t        j                  d| j	                  d            \  | _        | j                   j                  dt        j                         t        j                  d| j	                  d            | _        t        | t              rVt        j                  d| j	                  d            \  | _        | j                   j                  dt        j                         t        j                  d| j	                  d            | _        t        j                  d| j	                  d            | _        y )	Nr)   <iri   r   rj   r(   <16I@   )fdrq   r/   rt   
_safe_read_blp_compression_blp_encodingru   _blp_alpha_encodingrr   rs   rz   
isinstanceBLP1Decoder_blp_offsets_blp_lengths)r}   s    r   r   z _BLPBaseDecoder._read_blp_header  s5   Q#)==tq7I#J 	 &dDOOA4F G	#)==tq7I#J 	&,mmD$//!:L&M#	!Q$MM%);<	dK($*MM$8J$K!TGGLLBKK("MM&$//&2IJ"MM&$//&2IJr   c                B    t        j                  | j                  |      S )N)r   r   r   )r}   lengths     r   r   z_BLPBaseDecoder._safe_read1  s    ##DGGV44r   c                    g }t        d      D ]B  }	 t        j                  d| j                  d            \  }}}}|j                  ||||f       D |S # t        j                  $ r Y  |S w xY w)N   <4Br)   )r.   r/   rt   r   r   append)r}   r5   r$   rF   rE   rD   rC   s          r   _read_palettez_BLPBaseDecoder._read_palette4  sz    s 	%A#]]5$//!2DE
1a JJ1a|$	% 
 << 
s   *AA-,A-c                P   t               }t        | j                  | j                  d               }	 	 t	        j
                  d|j                  d            \  }||   \  }}}}|||f}	| j                  r|	|fz  }	|j                  |	       [# t        j                  $ r Y |S w xY w)Nr   <Br   )
r-   r   r   r   r/   rt   ro   r   ru   r1   )
r}   paletter2   _dataoffsetrF   rE   rD   rC   ds
             r   
_read_bgraz_BLPBaseDecoder._read_bgra>  s    {(9(9!(<=>"MM$

1>	 !JAq!QAq	A$$aT	KKN  <<  s   'B B%$B%N)	r   r   r   	_pulls_fdrw   r   r   r   r   r   r   r   r   r     s!    IK&5r   r   c                      e Zd Zd Zd Zy)r   c                   | j                   t        j                  k(  r| j                          y | j                   dk(  rm| j                  dv r<| j                         }| j                  |      }| j                  t        |             y 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_rawbytesrx   r^   )r}   r   r2   r   s       r   r   zBLP1Decoder._loadO  s      FKK/$$&""a'!!V+,,.w/d,1$t7I7I2J1KL$S))0d6H6H1I0JKC %%r   c                   ddl m} t        j                  d| j	                  d            \  }| j	                  |      }| j	                  | j
                  d   | j                  j                         z
         | j	                  | j                  d         }||z   }t        |      } ||      }t        j                  |j                         |j                  dk(  r%|j                  d   \  }}}}	||||	d   dffg|_        |j                  d      j!                         \  }
}}t        j"                  d|||
f      }| j%                  |j'                                y )Nr   )JpegImageFilerK   r)   r   CMYKrl   )JpegImagePluginr   r/   rt   r   r   r   tellr   r   r   _decompression_bomb_checkrz   r{   r|   convertsplitmerger   tobytes)r}   r   jpeg_header_sizejpeg_headerr2   imagedecoder_nameextentsr   argsrD   rE   rF   s                r   r   zBLP1Decoder._decode_jpeg_stream_  s"   2$mmD$//!2DE	oo&67))!,tww||~=>t0034T!t}d#''

3::27**Q-/L'64'&47F:KLMEJ--&,,.1aEAq!9-(r   N)r   r   r   r   r   r   r   r   r   r   N  s    & )r   r   c                      e Zd Zd Zy)BLP2Decoderc                d   | j                         }| j                  j                  | j                  d          | j                  dk(  r+| j
                  t        j                  k(  r| j                  |      }n| j
                  t        j                  k(  rt               }| j                  t        j                  k(  rv| j                  d   dz   dz  dz  }t        | j                  d   dz   dz        D ];  }t!        | j#                  |      t%        | j&                              D ]  }||z  }	 = nc| j                  t        j(                  k(  r`| j                  d   dz   dz  dz  }t        | j                  d   dz   dz        D ]&  }t+        | j#                  |            D ]  }||z  }	 ( n| j                  t        j,                  k(  r`| j                  d   dz   dz  dz  }t        | j                  d   dz   dz        D ]&  }t/        | j#                  |            D ]  }||z  }	 ( nidt1        | j                         }t3        |      d	t1        | j
                         }t3        |      d
t1        | j                         }t3        |      | j5                  t7        |             y )Nr   r   r   r)   r(   )r3   rI   zUnsupported alpha encoding zUnknown BLP encoding zUnknown BLP compression )r   r   rq   r   r   r   r   r   r   r   r-   r   r   r   rz   r.   rG   r   boolru   r   rS   r   r\   rx   r^   r   r   )r}   r   r2   linesizeybr   r   s          r   r   zBLP2Decoder._loads  s}   $$&T&&q)*  A% !!X%:%::w/##x||3 {++}/A/AA $		!q 0Q6:H#TYYq\A%5!$;< &!, OOH5T$BWBW=X" &A !AID&& --1C1CC $		!q 0Q6;H#TYYq\A%5!$;< &!,T__X-F!G &A AID&& --1C1CC $		!q 0Q6;H#TYYq\A%5!$;< &!,T__X-F!G &A AID&& 8T=U=U8V7WXC(---d43E3E.F-GH$S)) -T$2G2G-H,IJC %%d$r   N)r   r   r   r   r   r   r   r   r   r  s    +%r   r   c                      e Zd ZdZd Zd Zy)
BLPEncoderTc           	        d}| j                   j                  dd      }t        t        |      dz        D ]1  }||dz  |dz   dz   \  }}}}|t	        j
                  d||||      z  }3 t        |      dk  r|dz  }t        |      dk  r|S )Nr   rk   r)   r   r   i   s       )im
getpaletter.   r,   r/   pack)r}   r2   r   r$   rD   rE   rF   rC   s           r   _write_palettezBLPEncoder._write_palette  s    ''$$VV4s7|q() 	3A Q!a%15JAq!QFKKq!Q22D	3 $i'!KD $i'!r   c           
        | j                         }dt        |      z   }t        j                  d|gd }| j                  j
                  \  }}|t        j                  d||z  gd z  }||z  }t        |      D ]F  }t        |      D ]6  }|t        j                  d| j                  j                  ||f            z  }8 H t        |      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   rz   r.   getpixel)	r}   bufsizepalette_datar   r2   whyxs	            r   encodezBLPEncoder.encode  s    **, 3|#44{{668Y8ww||1FAE8Y88q 	DA1X DD$''*:*:Aq6*BCCD	D 4y!T!!r   N)r   r   r   
_pushes_fdr   r   r   r   r   r   r     s    J"r   r   c                   | j                   dk7  rd}t        |      | j                  j                  d      dk(  rdnd}|j	                  |       |j	                  t        j                  dd             |j	                  t        j                  d	t        j                               |j	                  t        j                  d	| j                  j                   d
k(  rdnd             |j	                  t        j                  d	d             |j	                  t        j                  d	d             |j	                  t        j                  dg| j                          |dk(  rJ|j	                  t        j                  dd             |j	                  t        j                  dd             t        j                  | |dd| j                  z   d| j                   fg       y )NPzUnsupported BLP image modeblp_versionBLP1ra   rb   r   r   ri   rk   r   rj   r"   rg   rm   )r{   
ValueErrorencoderinfogetwriter/   r   r   r   r   rz   r   _save)r   rn   filenamer   rp   s        r   r   r     sK   	ww#~*o~~))-8FBGEHHUOHHV[[q!"HHV[[x4456HHV[[BJJOOv$=q1EFHHV[[q!"HHV[[q!"HHV[[))*
T1%&
T1%&OOBeVbgg%5q"''BCDr   z.blpr   BLP2rg   )F)$r   
__future__r   rr   r/   enumr   ior    r   r   r
   r   r   r%   rG   rS   r\   NotImplementedErrorr^   rd   rf   	PyDecoderr   r   r   	PyEncoderr   r   register_openr   register_extensionregister_decoderregister_saveregister_encoderr   r   r   <module>r      sH  < # 	    W w G L4n2jCL	( 	,J9&& J69i)) 9x!)/ !)H,%/ ,%^"$$ ">E*   L''w ?   ,,f 5   v{ +   v{ +   L'' /   uj )r   