U
    &^9k                     @   s  d dl Z d dlZd dlZd dlZddlmZmZmZ ddlm	Z	m
ZmZmZmZ e eZedjZdZddd	d
ddddddddddddZedZejZde Zdd ZdBddZG dd dZ G dd  d e!Z"G d!d" d"Z#G d#d$ d$e Z$d%d& Z%G d'd( d(ejZ&d)d*d+d,d-d.d/d/d0d1d2d3d4d5d6Z'd7d8 Z(G d9d: d:Z)e(fd;d<Z*d=d> Z+e,e&j-e&e% e.e&j-e* e/e&j-d?d@g e0e&j-dA dS )C    N   )Image	ImageFileImagePalette)i8i16bei32beo16beo32bes   \w\w\w\ws   PNG

)1r   )LL;2)r   L;4)r   r   )II;16B)RGBr   )r   zRGB;16B)PP;1)r   P;2)r   P;4)r   r   )LAr   )RGBAzLA;16B)r   r   )r   zRGBA;16B))r   r   )   r   )   r   )   r   )   r   )r   r   )r   r   )r      )r   r   )r   r   )r   r   )r   r   )r   r   )r      )r   r   s   ^* *$@   c                 C   s&   t  }|| t}|jr"td|S )NzDecompressed Data Too Large)zlibdecompressobj
decompressMAX_TEXT_CHUNKunconsumed_tail
ValueError)sZdobj	plaintext r'   6/tmp/pip-install-a1j0c_p1/Pillow/PIL/PngImagePlugin.py_safe_zlib_decompressT   s
    r)   c                 C   s   t | |d@ S )Nl    )r   crc32)dataseedr'   r'   r(   _crc32\   s    r-   c                   @   s^   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd ZdddZdS )ChunkStreamc                 C   s   || _ g | _d S N)fpqueueselfr0   r'   r'   r(   __init__e   s    zChunkStream.__init__c                 C   sz   d}| j r(| j  \}}}| j| n*| jd}|dd }| j }t|}t|sptj	spt
dt| |||fS )z.Fetch a new chunk. Returns header information.Nr   r   zbroken PNG file (chunk %s))r1   popr0   seekreadtelli32is_cidr   LOAD_TRUNCATED_IMAGESSyntaxErrorrepr)r3   cidposlengthr%   r'   r'   r(   r7   j   s    
zChunkStream.readc                 C   s   | S r/   r'   r3   r'   r'   r(   	__enter__}   s    zChunkStream.__enter__c                 G   s   |    d S r/   )close)r3   argsr'   r'   r(   __exit__   s    zChunkStream.__exit__c                 C   s   d  | _  | _| _d S r/   )r1   crcr0   rA   r'   r'   r(   rC      s    zChunkStream.closec                 C   s   | j |||f d S r/   )r1   appendr3   r>   r?   r@   r'   r'   r(   push   s    zChunkStream.pushc                 C   s*   t d||| t| d|d ||S )z"Call the appropriate chunk handlerzSTREAM %r %s %sZchunk_ascii)loggerdebuggetattrdecoderH   r'   r'   r(   call   s    zChunkStream.callc                 C   s   t jr*t|d d? d@ r*| || dS z6t|t|}t| jd}||kr^td| W n" t	j
k
r   td| Y nX dS )zRead and verify checksumr      r   Nr   z+broken PNG file (bad header checksum in %r)z+broken PNG file (incomplete checksum in %r))r   r;   r   crc_skipr-   r9   r0   r7   r<   structerror)r3   r>   r+   Zcrc1Zcrc2r'   r'   r(   rF      s    zChunkStream.crcc                 C   s   | j d dS )z3Read checksum.  Used if the C module is not presentr   N)r0   r7   r3   r>   r+   r'   r'   r(   rQ      s    zChunkStream.crc_skip   IENDc                 C   sf   g }z|   \}}}W n tjk
r4   tdY nX ||kr@qb| |t| j| || q|S )Nztruncated PNG file)	r7   rR   rS   OSErrorrF   r   
_safe_readr0   rG   )r3   ZendchunkZcidsr>   r?   r@   r'   r'   r(   verify   s    zChunkStream.verifyN)rU   )__name__
__module____qualname__r4   r7   rB   rE   rC   rI   rO   rF   rQ   rX   r'   r'   r'   r(   r.   d   s   r.   c                   @   s   e Zd ZdZedddZdS )iTXtzq
    Subclass of string to allow iTXt chunks to look like strings while
    keeping their extra information

    Nc                 C   s   t | |}||_||_|S )z
        :param cls: the class to use when creating the instance
        :param text: value for this key
        :param lang: language code
        :param tkey: UTF-8 version of the key name
        )str__new__langtkey)clstextr_   r`   r3   r'   r'   r(   r^      s    	ziTXt.__new__)NN)rY   rZ   r[   __doc__staticmethodr^   r'   r'   r'   r(   r\      s   r\   c                   @   s4   e Zd ZdZdd Zdd Zddd	Zdd
dZdS )PngInfoz<
    PNG chunk container (for use with save(pnginfo=))

    c                 C   s
   g | _ d S r/   )chunksrA   r'   r'   r(   r4      s    zPngInfo.__init__c                 C   s   | j ||f dS )zAppends an arbitrary chunk. Use with caution.

        :param cid: a byte string, 4 bytes long.
        :param data: a byte string of the encoded data

        N)rf   rG   rT   r'   r'   r(   add   s    zPngInfo.add Fc                 C   s   t |ts|dd}t |ts,|dd}t |tsB|dd}t |tsX|dd}|r| d|d | d | d t|  n$| d|d | d | d |  dS )	zAppends an iTXt chunk.

        :param key: latin-1 encodable text key name
        :param value: value for this key
        :param lang: language code
        :param tkey: UTF-8 version of the key name
        :param zip: compression flag

        latin-1strictutf-8   iTXts         s      N)
isinstancebytesencoderg   r   compress)r3   keyvaluer_   r`   zipr'   r'   r(   add_itxt   s    



 zPngInfo.add_itxtc                 C   s   t |tr"| j|||j|j|dS t |tsbz|dd}W n$ tk
r`   | j|||d Y S X t |tsx|dd}|r| d|d t	
|  n| d|d |  dS )	zAppends a text chunk.

        :param key: latin-1 encodable text key name
        :param value: value for this key, text or an
           :py:class:`PIL.PngImagePlugin.iTXt` instance
        :param zip: compression flag

        )rt   ri   rj      zTXt        tEXtrm   N)rn   r\   ru   r_   r`   ro   rp   UnicodeErrorrg   r   rq   )r3   rr   rs   rt   r'   r'   r(   add_text  s    	


zPngInfo.add_textN)rh   rh   F)F)rY   rZ   r[   rc   r4   rg   ru   rz   r'   r'   r'   r(   re      s
   

re   c                       s   e Zd Z fddZdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Z  ZS )#	PngStreamc                    s@   t  | i | _i | _d| _d | _d | _d | _d | _d| _	d S )Nr   r   r   )
superr4   im_infoim_textim_sizeim_modeim_tile
im_paletteim_custom_mimetypetext_memoryr2   	__class__r'   r(   r4   "  s    zPngStream.__init__c                 C   s*   |  j |7  _ | j tkr&td| j  d S )Nz7Too much memory used in text chunks: %s>MAX_TEXT_MEMORY)r   MAX_TEXT_MEMORYr$   )r3   Zchunklenr'   r'   r(   check_text_memory0  s    
zPngStream.check_text_memoryc                 C   s   t | j|}|d}td|d |  tdt||  t|| }|dkr`td| zt||d d  }W n: t	k
r   t j
rd }n Y n tjk
r   d }Y nX || jd< |S )Nrm   ziCCP profile name %rzCompression method %sr   z+Unknown compression method %s in iCCP chunkr   icc_profile)r   rW   r0   findrK   rL   r   r<   r)   r$   r;   r   rS   r~   )r3   r?   r@   r%   icomp_methodr   r'   r'   r(   
chunk_iCCP8  s&    


zPngStream.chunk_iCCPc                 C   s   t | j|}t|t|dd  f| _z(tt|d t|d f \| _| _W n t	k
rd   Y nX t|d r|d| j
d< t|d rtd|S )	Nr   r   	      r   	interlace   zunknown filter category)r   rW   r0   r9   r   _MODESr   r   
im_rawmode	Exceptionr~   r<   r3   r?   r@   r%   r'   r'   r(   
chunk_IHDRU  s    (
zPngStream.chunk_IHDRc                 C   s&   dd| j  || jfg| _|| _td S )Nrt   r|   )r   r   r   Zim_idatEOFErrorr3   r?   r@   r'   r'   r(   
chunk_IDATd  s    zPngStream.chunk_IDATc                 C   s   t d S r/   )r   r   r'   r'   r(   
chunk_IENDk  s    zPngStream.chunk_IENDc                 C   s&   t | j|}| jdkr"d|f| _|S )Nr   r   )r   rW   r0   r   r   r   r'   r'   r(   
chunk_PLTEp  s    

zPngStream.chunk_PLTEc                 C   s   t | j|}| jdkrLt|r@|d}|dkrJ|| jd< q|| jd< nP| jdkrft|| jd< n6| jdkrt|t|dd  t|dd  f| jd< |S )	Nr   rm   r   transparencyr   r   r   r   r   r   )	r   rW   r0   r   _simple_palettematchr   r~   i16)r3   r?   r@   r%   r   r'   r'   r(   
chunk_tRNSx  s    




,zPngStream.chunk_tRNSc                 C   s$   t | j|}t|d | jd< |S )N     j@gamma)r   rW   r0   r9   r~   r   r'   r'   r(   
chunk_gAMA  s    zPngStream.chunk_gAMAc                 C   sB   t | j|}tdt|d  |}tdd |D | jd< |S )Nz>%dIr   c                 s   s   | ]}|d  V  qdS )r   Nr'   ).0eltr'   r'   r(   	<genexpr>  s     z'PngStream.chunk_cHRM.<locals>.<genexpr>Zchromaticity)r   rW   r0   rR   unpacklentupler~   )r3   r?   r@   r%   Zraw_valsr'   r'   r(   
chunk_cHRM  s    zPngStream.chunk_cHRMc                 C   s    t | j|}t|| jd< |S )NZsrgb)r   rW   r0   r   r~   r   r'   r'   r(   
chunk_sRGB  s    zPngStream.chunk_sRGBc                 C   s   t | j|}t|t|dd   }}t|d }|dkrht|d d t|d d f}|| jd< n|dkr~||f| jd< |S )	Nr   r   r   
F%u?      ?dpir   Zaspect)r   rW   r0   r9   r   intr~   )r3   r?   r@   r%   Zpxpyunitr   r'   r'   r(   
chunk_pHYs  s     zPngStream.chunk_pHYsc                 C   s   t | j|}z|dd\}}W n tk
r>   |}d}Y nX |r~|dd}|dd}| | j|< | j|< | t	| |S )Nrm   r       ri   rj   replace)
r   rW   r0   splitr$   rN   r~   r   r   r   )r3   r?   r@   r%   kvr'   r'   r(   
chunk_tEXt  s    
zPngStream.chunk_tEXtc                 C   s   t | j|}z|dd\}}W n tk
r>   |}d}Y nX |rRt|d }nd}|dkrjtd| zt|dd  }W n: tk
r   t jrd}n Y n t	j
k
r   d}Y nX |r|dd}|dd}| | j|< | j|< | t| |S )	Nrm   r   r   r   z+Unknown compression method %s in zTXt chunkri   rj   r   )r   rW   r0   r   r$   r   r<   r)   r;   r   rS   rN   r~   r   r   r   )r3   r?   r@   r%   r   r   r   r'   r'   r(   
chunk_zTXt  s6    

zPngStream.chunk_zTXtc                 C   s  t | j| }}z|dd\}}W n tk
r>   | Y S X t|dk rP|S t|d t|d |dd    }}}z|dd\}}	}
W n tk
r   | Y S X |dkr|dkr
zt|
}
W n> tk
r   t jr| Y S  Y n t	j
k
r   | Y S X n|S z4|dd}|dd}|	dd}	|
dd}
W n tk
r\   | Y S X t|
||	 | j|< | j|< | t|
 |S )Nrm   r   r   r   ri   rj   rk   )r   rW   r0   r   r$   r   r   r)   r;   r   rS   rN   ry   r\   r~   r   r   )r3   r?   r@   rr%   r   cfcmr_   Ztkr   r'   r'   r(   
chunk_iTXt  sB    
(



zPngStream.chunk_iTXtc                 C   s    t | j|}d| | jd< |S )N   Exif  exif)r   rW   r0   r~   r   r'   r'   r(   
chunk_eXIf  s    zPngStream.chunk_eXIfc                 C   s   t | j|}d| _|S )Nz
image/apng)r   rW   r0   r   r   r'   r'   r(   
chunk_acTL  s    zPngStream.chunk_acTL)rY   rZ   r[   r4   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r'   r'   r   r(   r{   !  s"   	$)r{   c                 C   s   | d d t kS )Nr   )_MAGIC)prefixr'   r'   r(   _accept$  s    r   c                   @   sX   e Zd ZdZdZdd Zedd Zdd Zd	d
 Z	dd Z
dd Zdd Zdd ZdS )PngImageFileZPNGzPortable network graphicsc              	   C   s  | j dtkrtdt| j | _| j \}}}z| j|||}W nH tk
r`   Y qY n2 tk
r   t	
d||| t| j |}Y nX | j|| q$| jj| _| jj| _| jj| _d | _| jj| _| jj| _| jjr| jj\}}t||| _|| _d S )Nr   znot a PNG file%r %s %s (unknown))r0   r7   r   r<   r{   pngrO   r   AttributeErrorrK   rL   r   rW   rF   r   moder   _sizer~   info_textr   tiler   Zcustom_mimetyper   r   rawpalette_PngImageFile__prepare_idat)r3   r>   r?   r@   r%   rawmoder+   r'   r'   r(   _open1  s,    	




zPngImageFile._openc                 C   s   | j d kr|   | j S r/   )r   loadrA   r'   r'   r(   rb   `  s    
zPngImageFile.textc                 C   sZ   | j dkrtd| j | jd d d  | j  | j  | jrP| j   d| _ dS )zVerify PNG fileNz)verify must be called directly after openr   r   r   )r0   RuntimeErrorr6   r   r   rX   rC   Z_exclusive_fprA   r'   r'   r(   rX   i  s    



zPngImageFile.verifyc                 C   s0   | j dr| jd | _| j| _tj|  dS )z"internal: prepare to read PNG filer   )r   N)r   getZdecoderconfigr   _PngImageFile__idatr   load_preparerA   r'   r'   r(   r   y  s    zPngImageFile.load_preparec                 C   s~   | j dkrJ| jd | j \}}}|dkrB| j||| dS || _ q |dkrZ| j }nt|| j }| j | | _ | j|S )zinternal: read more image datar   r   )   IDATs   DDATr   )r   r0   r7   r   rI   min)r3   
read_bytesr>   r?   r@   r'   r'   r(   	load_read  s    
zPngImageFile.load_readc              	   C   s   | j d z| j \}}}W n tjtfk
r>   Y qY nX |dkrJqz| j||| W q  tk
rv   Y qY q  tk
r   t	
| j | Y q  tk
r   td||| t	
| j | Y q X q | jj| _| j  d| _dS )z%internal: finished reading image datar   rU   r   N)r0   r7   r   rR   rS   r<   rO   UnicodeDecodeErrorr   r   rW   r   rK   rL   r   r   rC   rH   r'   r'   r(   load_end  s&    


zPngImageFile.load_endc                 C   s,   d| j kr|   d| j kr d S t|  S Nr   )r   r   dictgetexifrA   r'   r'   r(   _getexif  s
    

zPngImageFile._getexifc                 C   s   d| j kr|   tj| S r   )r   r   r   r   rA   r'   r'   r(   r     s    
zPngImageFile.getexifN)rY   rZ   r[   formatformat_descriptionr   propertyrb   rX   r   r   r   r   r   r'   r'   r'   r(   r   ,  s   /
	r   )r       )L;1r   )r   s    )r   s    )r   s    )r   s   )r   s    )r   s   )r   s   )r   s   )r   s   )r   s   )r   s   )r   r   r   r   r   r   r   zI;16r   r   r   r   r   r   c                 G   sJ   d |}| tt||  | | t|t|}| t| dS )z'Write a PNG chunk (including CRC field)r   N)joinwriteo32r   r-   r0   r>   r+   rF   r'   r'   r(   putchunk  s
    

r   c                   @   s   e Zd Zdd Zdd ZdS )_idatc                 C   s   || _ || _d S r/   )r0   chunk)r3   r0   r   r'   r'   r(   r4     s    z_idat.__init__c                 C   s   |  | jd| d S )Nr   )r   r0   r3   r+   r'   r'   r(   r     s    z_idat.writeN)rY   rZ   r[   r4   r   r'   r'   r'   r(   r     s   r   c              	   C   s  | j }|dkrd| jkr(d| jd > }n.| jrRttt| j d d dd}nd}|dkrdd}n |dkrrd}n|dkrd}nd	}|d	krd
||f }| jdd| jdd| jdd| jddf| _zt	| \}}W n  t
k
r   td| Y nX |t ||dt| jd t| jd |ddd dddddg}| jd| jd}	|	rd}
|
d t|	 }||d| |d | jd}|rd d!d"d#g}|jD ]B\}}||kr|| |||| n||kr|||| q| j dkrDd| d }| jd$d | }t||k r8|d7 }q||d%| | jd&| jd&d }|sl|dkrP| j dkrd| }t|tr||d'|d |  n0tdtd(|}d)| d }||d'|d |  nz| j d*krtdtd+|}||d't| nL| j d$kr:|\}}}||d't|t| t|  nd&| jkrtd,nF| j dkr| j d-kr| jd-d.}d| }||d'|d |  | jd/}|r||d0tt|d d1 d2 tt|d d1 d2 d3 |r d4d5g}|jD ]*\}}||kr|| |||| q| jd6| jd6}|rxt|tjrT|d	}|d7rl|d8d  }||d9| t !| t"||d:d;| j d|fg ||d<d t#|d=r|$  d S )>Nr   bitsr   r      r   r   r   r   z%s;%doptimizeFZcompress_levelcompress_type
dictionaryr   zcannot write mode %s as PNGs   IHDRr   rm   s   cHRMs   gAMAs   sBITs   sRGBs   tIMEr   s   ICC Profilerw   s   iCCPZpnginfos   sPLTrl   rx   rv   r   s   PLTEr   s   tRNS      r   i  z%cannot use transparency for this moder   Ar   s   pHYsr   r      s   bKGDs   hISTr   r   r   s   eXIfrt   r|   rU   flush)%r   encoderinfor   maxr   r   Zgetdatar   Zencoderconfig	_OUTMODESKeyErrorrV   r   r   r   sizer   r   rq   removerf   imZ
getpalettern   ro   o16Zgetpalettemoder   r   ZExiftobytes
startswithr   _saver   hasattrr   )r  r0   filenamer   r   colorsr   r   rf   Ziccnamer+   r   Zchunks_multiple_allowedr>   Zpalette_byte_numberZpalette_bytesr   Zalpha_bytesalphaZredZgreenZbluer   r   r'   r'   r(   r    s    
$





"



$r  c                 K   sB   G dd d}dd }| }z|| _ t| |d| W 5 | ` X |jS )z4Return a list of PNG chunks representing this image.c                   @   s    e Zd Zg Zdd Zdd ZdS )zgetchunks.<locals>.collectorc                 S   s   d S r/   r'   r   r'   r'   r(   r     s    z"getchunks.<locals>.collector.writec                 S   s   | j | d S r/   )r+   rG   )r3   r   r'   r'   r(   rG     s    z#getchunks.<locals>.collector.appendN)rY   rZ   r[   r+   r   rG   r'   r'   r'   r(   	collector  s   r  c                 W   s0   d |}tt|t|}| |||f d S )Nr   )r   r   r-   rG   r   r'   r'   r(   rG     s    
zgetchunks.<locals>.appendN)r   r  r+   )r  paramsr  rG   r0   r'   r'   r(   	getchunks  s    	r  z.pngz.apngz	image/png)r   )1loggingrerR   r   rh   r   r   r   _binaryr   r   r   r   r9   r	   r  r
   r   	getLoggerrY   rK   compiler   r:   r   r   r   Z	SAFEBLOCKr"   r   r)   r-   r.   r]   r\   re   r{   r   r   r   r   r   r  r  Zregister_openr   Zregister_saveZregister_extensionsZregister_mimer'   r'   r'   r(   <module>"   s|   


XO    "