B
    -a                 @   s  d dl Z d dlZ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	m
Z
mZ ddlmZ ddlmZ ddlmZ ddlmZ ddl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 Z"dZ#dZ$d Z%dZ&dd Z'dNd 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/d0d1d2d3d4d4d5d6d7d8d9d:d;Z0d<d= Z1G d>d? d?Z2G d@dA dAZ3dBdC Z4dDdE Z5e1dFfdGdHZ6dIdJ Z7e8e/j9e/e. e:e/j9e6 e;e/j9e5 e<e/j9dKdLg e=e/j9dM dS )O    N   )Image
ImageChops	ImageFileImagePaletteImageSequence)i16be)i32be)o8)o16be)o32bes   \w\w\w\ws   PNG

)1r   )LzL;2)r   zL;4)r   r   )IzI;16B)RGBr   )r   zRGB;16B)PzP;1)r   zP;2)r   z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   ^* *$@   r   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-unpacked-wheel-rysjrues/PIL/PngImagePlugin.py_safe_zlib_decompress   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)selfr+   r#   r#   r$   __init__   s    zChunkStream.__init__c             C   s~   d}| j r(| j  \}}}| j| n*| jd}|dd }| j }t|}t|sttj	stt
dt| d|||fS )z.Fetch a new chunk. Returns header information.Nr   r   zbroken PNG file (chunk ))r,   popr+   seekreadtelli32is_cidr   LOAD_TRUNCATED_IMAGESSyntaxErrorrepr)r-   cidposlengthr!   r#   r#   r$   r2      s    
zChunkStream.readc             C   s   | S )Nr#   )r-   r#   r#   r$   	__enter__   s    zChunkStream.__enter__c             G   s   |    d S )N)close)r-   argsr#   r#   r$   __exit__   s    zChunkStream.__exit__c             C   s   d  | _  | _| _d S )N)r,   crcr+   )r-   r#   r#   r$   r=      s    zChunkStream.closec             C   s   | j |||f d S )N)r,   append)r-   r9   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decode)r-   r9   r:   r;   r#   r#   r$   call   s    zChunkStream.callc          
   C   s   t jr&|d d? d@ r&| || dS y>t|t|}t| jd}||krbtdt| dW n: t	j
k
r } ztdt| d|W dd}~X 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   r6   crc_skipr)   r4   r+   r2   r7   r8   structerror)r-   r9   r'   Zcrc1Zcrc2er#   r#   r$   r@      s    zChunkStream.crcc             C   s   | j d dS )z3Read checksum.  Used if the C module is not presentr   N)r+   r2   )r-   r9   r'   r#   r#   r$   rJ      s    zChunkStream.crc_skip   IENDc          
   C   sz   g }xpy|   \}}}W n. tjk
rF } ztd|W d d }~X Y nX ||krRP | |t| j| || qW |S )Nztruncated PNG file)	r2   rK   rL   OSErrorr@   r   
_safe_readr+   rA   )r-   ZendchunkZcidsr9   r:   r;   rM   r#   r#   r$   verify   s    zChunkStream.verifyN)rN   )__name__
__module____qualname__r.   r2   r<   r?   r=   rB   rH   r@   rJ   rQ   r#   r#   r#   r$   r*      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textrX   rY   r-   r#   r#   r$   rW      s    	ziTXt.__new__)NN)rR   rS   rT   __doc__staticmethodrW   r#   r#   r#   r$   rU      s   rU   c               @   s6   e Zd ZdZdd Zd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 )N)chunks)r-   r#   r#   r$   r.   	  s    zPngInfo.__init__Fc             C   s*   ||g}|r| d | j t| dS )a"  Appends an arbitrary chunk. Use with caution.

        :param cid: a byte string, 4 bytes long.
        :param data: a byte string of the encoded data
        :param after_idat: for use with private chunks. Whether the chunk
                           should be written after IDAT

        TN)rA   r_   tuple)r-   r9   r'   
after_idatchunkr#   r#   r$   add  s    

zPngInfo.add c             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

        zlatin-1strictzutf-8s   iTXts         s      N)
isinstancebytesencoderc   r   compress)r-   keyvaluerX   rY   zipr#   r#   r$   add_itxt  s    



&zPngInfo.add_itxtc             C   s   t |tr"| j|||j|j|dS t |ts^y|dd}W n  tk
r\   | j|||dS X t |tst|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

        )rm   zlatin-1re   s   zTXts     s   tEXtrf   N)rg   rU   rn   rX   rY   rh   ri   UnicodeErrorrc   r   rj   )r-   rk   rl   rm   r#   r#   r$   add_text7  s    	


zPngInfo.add_textN)F)rd   rd   F)F)rR   rS   rT   r\   r.   rc   rn   rp   r#   r#   r#   r$   r^     s
   

r^   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d#d$ Zd%d& Zd'd( Zd)d* Z  ZS )+	PngStreamc                sR   t  | i | _i | _d| _d | _d | _d | _d | _d | _	d | _
d | _d| _d S )N)r   r   r   )superr.   im_infoim_textim_sizeim_modeim_tile
im_paletteim_custom_mimetypeim_n_frames_seq_numrewind_statetext_memory)r-   r+   )	__class__r#   r$   r.   X  s    zPngStream.__init__c             C   s.   |  j |7  _ | j tkr*td| j  dd S )Nz%Too much memory used in text chunks: z>MAX_TEXT_MEMORY)r}   MAX_TEXT_MEMORYr    )r-   Zchunklenr#   r#   r$   check_text_memoryi  s    
zPngStream.check_text_memoryc             C   s   | j  | j| jd| _d S )N)infotileseq_num)rs   copyrw   r{   r|   )r-   r#   r#   r$   save_rewindq  s    zPngStream.save_rewindc             C   s(   | j d | _| j d | _| j d | _d S )Nr   r   r   )r|   rs   rw   r{   )r-   r#   r#   r$   rewindx  s    zPngStream.rewindc             C   s   t | j|}|d}td|d |  td||  || }|dkr\td| dy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 )	Nrf   ziCCP profile name %rzCompression method %sr   zUnknown compression method z in iCCP chunkr   icc_profile)r   rP   r+   findrD   rE   r7   r%   r    r6   r   rL   rs   )r-   r:   r;   r!   icomp_methodr   r#   r#   r$   
chunk_iCCP}  s"    


zPngStream.chunk_iCCPc             C   s   t | j|}t|dt|df| _y t|d |d f \| _| _W n tk
rX   Y nX |d rld| j	d< |d r|t
d	|S )
Nr   r   r   	      r   	interlace   zunknown filter category)r   rP   r+   r4   ru   _MODESrv   
im_rawmode	Exceptionrs   r7   )r-   r:   r;   r!   r#   r#   r$   
chunk_IHDR  s     
zPngStream.chunk_IHDRc             C   s`   d| j kr"d| j d || jfg}n*| jd k	r6d| j d< dd| j || jfg}|| _|| _td S )Nbboxrm   Tdefault_image)r   r   )rs   r   rz   ru   rw   Zim_idatEOFError)r-   r:   r;   r   r#   r#   r$   
chunk_IDAT  s    


zPngStream.chunk_IDATc             C   s   t d S )N)r   )r-   r:   r;   r#   r#   r$   
chunk_IEND  s    zPngStream.chunk_IENDc             C   s&   t | j|}| jdkr"d|f| _|S )Nr   r   )r   rP   r+   rv   rx   )r-   r:   r;   r!   r#   r#   r$   
chunk_PLTE  s    

zPngStream.chunk_PLTEc             C   s   t | j|}| jdkrLt|r@|d}|dkrJ|| jd< q|| jd< nD| jdkrft|| jd< n*| jdkrt|t|dt|df| jd< |S )	Nr   rf   r   transparency)r   r   r   r   r   r   )	r   rP   r+   rv   _simple_palettematchr   rs   i16)r-   r:   r;   r!   r   r#   r#   r$   
chunk_tRNS  s    




 zPngStream.chunk_tRNSc             C   s$   t | j|}t|d | jd< |S )Ng     j@gamma)r   rP   r+   r4   rs   )r-   r:   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 )g     j@Nr#   ).0eltr#   r#   r$   	<genexpr>  s    z'PngStream.chunk_cHRM.<locals>.<genexpr>Zchromaticity)r   rP   r+   rK   unpacklenr`   rs   )r-   r:   r;   r!   Zraw_valsr#   r#   r$   
chunk_cHRM  s    zPngStream.chunk_cHRMc             C   s    t | j|}|d | jd< |S )Nr   Zsrgb)r   rP   r+   rs   )r-   r:   r;   r!   r#   r#   r$   
chunk_sRGB  s    zPngStream.chunk_sRGBc             C   sj   t | j|}t|dt|d }}|d }|dkrP|d |d f}|| jd< n|dkrf||f| jd< |S )Nr   r   r   r   g
F%u?dpiZaspect)r   rP   r+   r4   rs   )r-   r:   r;   r!   pxpyunitr   r#   r#   r$   
chunk_pHYs  s    zPngStream.chunk_pHYsc             C   s   t | j|}y|dd\}}W n tk
r>   |}d}Y nX |r|dd}|dd}|dkrh|n|| j|< || j|< | t	| |S )Nrf   r       zlatin-1re   replaceexif)
r   rP   r+   splitr    rG   rs   rt   r   r   )r-   r:   r;   r!   kvZv_strr#   r#   r$   
chunk_tEXt  s    

zPngStream.chunk_tEXtc             C   s   t | j|}y|dd\}}W n tk
r>   |}d}Y nX |rN|d }nd}|dkrjtd| dy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 )
Nrf   r   r   r   zUnknown compression method z in zTXt chunkzlatin-1re   r   )r   rP   r+   r   r    r7   r%   r6   r   rL   rG   rs   rt   r   r   )r-   r:   r;   r!   r   r   r   r#   r#   r$   
chunk_zTXt  s2    


zPngStream.chunk_zTXtc             C   sj  t | j| }}y|dd\}}W n tk
r:   |S X t|dk rL|S |d |d |dd    }}}y|dd\}}	}
W n tk
r   |S X |dkr|dkryt|
}
W q tk
r   t jr|S  Y q tj	k
r   |S X n|S y4|
dd}|
dd}|	
dd}	|

dd}
W n tk
r:   |S X t|
||	 | j|< | j|< | t|
 |S )Nrf   r   r   r   zlatin-1re   zutf-8)r   rP   r+   r   r    r   r%   r6   r   rL   rG   ro   rU   rs   rt   r   )r-   r:   r;   rr!   r   cfcmrX   tkr   r#   r#   r$   
chunk_iTXt3  sB     zPngStream.chunk_iTXtc             C   s    t | j|}d| | jd< |S )Ns   Exif  r   )r   rP   r+   rs   )r-   r:   r;   r!   r#   r#   r$   
chunk_eXIf\  s    zPngStream.chunk_eXIfc             C   sr   t | j|}| jd k	r,d | _td |S t|}|dksD|dkrRtd |S || _t|d| jd< d| _|S )Nz4Invalid APNG, will use default PNG image if possibler   l        r   loopz
image/apng)	r   rP   r+   rz   warningswarnr4   rs   ry   )r-   r:   r;   r!   n_framesr#   r#   r$   
chunk_acTLb  s    


zPngStream.chunk_acTLc             C   s  t | j|}t|}| jd kr(|dks@| jd k	rH| j|d krHtd|| _t|dt|d }}t|dt|d }}| j\}	}
|| |	ks|| |
krtd|||| || f| jd	< t|d
t|d }}|dkrd}t	|t	| d | jd< |d | jd< |d | jd< |S )Nr   r   z#APNG contains frame sequence errorsr   r   r   r   zAPNG contains invalid framesr         d   i  duration   disposal   blend)
r   rP   r+   r4   r{   r7   ru   rs   r   float)r-   r:   r;   r!   seqwidthheightr   r   Zim_wZim_hZ	delay_numZ	delay_denr#   r#   r$   
chunk_fcTLq  s&    
zPngStream.chunk_fcTLc             C   sF   t | jd}t|}| j|d kr,td|| _| |d |d S )Nr   r   z#APNG contains frame sequence errors)r   rP   r+   r4   r{   r7   r   )r-   r:   r;   r!   r   r#   r#   r$   
chunk_fdAT  s    zPngStream.chunk_fdAT)rR   rS   rT   r.   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r#   r#   )r~   r$   rq   W  s*   	")rq   c             C   s   | d d t kS )Nr   )_MAGIC)prefixr#   r#   r$   _accept  s    r   c                   s   e Zd ZdZdZdd Zedd Zdd Zd	d
 Z	dddZ
dd Zdd Zdd Zdd Zdd Z fddZdd Zdd Z  ZS )PngImageFileZPNGzPortable network graphicsc          	   C   s  t | jdstd| j| _d| _g | _t| j| _x| j \}}}y| j	|||}W nf t
k
rt   P Y nR tk
r   td||| t| j|}|dd  r| j||f Y nX | j|| q:W | jj| _| jj| _| jj| _d | _| jj| _| jj| _| jjpd| _| j dd| _!| jj"rT| jj"\}}t#$||| _%|d	krj|d
 | _&n|| _&| jjd k	rd| _'| j(  | j&| _)| j* | _+| j!r|  jd7  _| ,d | jdk| _-d S )Nr   znot a PNG filer   z%r %s %s (unknown)r   r   r   Fs   fdATr   ).r   r+   r2   r7   _PngImageFile__fp_PngImageFile__frameprivate_chunksrq   pngrH   r   AttributeErrorrD   rE   r   rP   islowerrA   r@   rv   moderu   _sizers   r   _textrw   r   ry   Zcustom_mimetyperz   r   getr   rx   r   rawpalette_PngImageFile__prepare_idatZ!_close_exclusive_fp_after_loadingr   _PngImageFile__rewind_idatr3   _PngImageFile__rewind_seekis_animated)r-   r9   r:   r;   r!   rawmoder'   r#   r#   r$   _open  sR    	








zPngImageFile._openc             C   sD   | j d kr>| jr&| j}| | jd  |   | jr>| | | j S )Nr   )r   r   r   r1   r   load)r-   framer#   r#   r$   r[     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   )r+   RuntimeErrorr1   r   r   rQ   r=   Z_exclusive_fp)r-   r#   r#   r$   rQ     s    



zPngImageFile.verifyc             C   s   |  |sd S || jk r$| dd | j}xbt| jd |d D ]J}y| | W q@ tk
r } z| | td|W d d }~X Y q@X q@W d S )Nr   Tr   zno more images in APNG file)Z_seek_checkr   r   ranger   r1   )r-   r   Z
last_framefrM   r#   r#   r$   r1     s    


zPngImageFile.seekFc          	   C   s  |dkr|rZ| j | j | j  | j| _d | _| jr>d | _| jj	| _
| jj| _| j | _d | _d | _| j
dd| _| j
d| _| j
d| _| j
d| _d| _n|| jd krtd| |   | jr| j| j| j | j | _| j | _| jrt| j| j d| _d}x| jd	 y| j \}}}W n tjtfk
r^   P Y nX |d
krrt d|dkr|rtdd}y| j!||| W n t"k
r   P Y nv t k
r   |dkr|d	8 }|r|| _P t| j| Y n4 t#k
r.   t$%d||| t| j| Y nX q W || _| jj| _| j
d| _| j
d| _| j
d| _| js|t | jd kr| jt&krt'| _| jt&kr| j | _| (| j| j| _n:| jt'krt)j*+| j,| j-| _| (| j| j| _nd | _d S )Nr   r   Fr   r   r   r   zcannot seek to frame r   s   IENDzNo more images in APNG files   fcTLzAPNG missing frame dataTs   fdATz%r %s %s (unknown)).r   r1   r   r   r   r   r   impyaccessrs   r   rw   r   r+   _prev_imdisposer   r   Z
dispose_opblend_opdispose_extentr   r    r   paster   r   rP   r2   rK   rL   r7   r   rH   UnicodeDecodeErrorr   rD   rE   APNG_DISPOSE_OP_PREVIOUSAPNG_DISPOSE_OP_BACKGROUND_cropr   corefillr   size)r-   r   r   Zframe_startr9   r:   r;   r#   r#   r$   r     s    







zPngImageFile._seekc             C   s   | j S )N)r   )r-   r#   r#   r$   r3   l  s    zPngImageFile.tellc             C   s0   | j dr| jd | _| j| _tj|  dS )z"internal: prepare to read PNG filer   )r   N)r   r   Zdecoderconfigr   _PngImageFile__idatr   load_prepare)r-   r#   r#   r$   r   o  s    zPngImageFile.load_preparec             C   s   x| j dkr| jd | j \}}}|dkrD| j||| dS |dkry| j||| W n tk
rt   Y nX |d | _ q|| _ qW |dkr| j }nt|| j }| j | | _ | j|S )zinternal: read more image datar   r   )s   IDATs   DDATs   fdATr   s   fdAT)r   r+   r2   r   rB   rH   r   min)r-   
read_bytesr9   r:   r;   r#   r#   r$   	load_readx  s$    
zPngImageFile.load_readc          	   C   s  | j dkr| j| j  x&| jd y| j \}}}W n tjtfk
rX   P Y nX |dkrfP n&|dkr| jrd| _| j	||| P y| j
||| W q tk
r   P Y q tk
r   |dkr|d8 }t| j| Y q tk
r<   td||| t| j|}|dd  r8| j||d	f Y qX qW | jj| _| jsf| j  d
| _nR| jr| jtkr| | j| j}| j|| j|d | j| _| j rd
| _ d
S )z%internal: finished reading image datar   r   s   IENDs   fcTLs   fdATz%r %s %s (unknown)r   r   TNr   )!r   r+   r2   r   rK   rL   r7   r   r   rB   rH   r   r   r   rP   r   rD   rE   r   r   rA   rt   r   r=   r   r   APNG_BLEND_OP_OVERr   r   r   r   convertr   )r-   r9   r:   r;   r!   updatedr#   r#   r$   load_end  sL    


zPngImageFile.load_endc             C   s6   d| j kr|   d| j kr*d| j kr*d S |   S )Nr   zRaw profile type exif)r   r   getexifZ_get_merged_dict)r-   r#   r#   r$   _getexif  s
    
zPngImageFile._getexifc                s   d| j kr|   t  S )Nr   )r   r   rr   r  )r-   )r~   r#   r$   r    s    
zPngImageFile.getexifc             C   s   d| j kr| | j d S i S )z
        Returns a dictionary containing the XMP tags.
        Requires defusedxml to be installed.
        :returns: XMP tags in a dictionary.
        zXML:com.adobe.xmp)r   Z_getxmp)r-   r#   r#   r$   getxmp  s    zPngImageFile.getxmpc             C   sB   z4y| j | jkr| j   W n tk
r0   Y nX W d d | _ X d S )N)r   r+   r=   r   )r-   r#   r#   r$   
_close__fp  s    
zPngImageFile._close__fp)F)rR   rS   rT   formatformat_descriptionr   propertyr[   rQ   r1   r   r3   r   r   r  r  r  r  r  r   r#   r#   )r~   r$   r     s   D
Z	!/r   )r   s    )zL;1s    )zL;2s    )zL;4s    )r   s    )r   s   )zI;16Bs    )zP;1s   )zP;2s   )zP;4s   )r   s   )r   s   )r   s   )r   zL;1zL;2zL;4r   r   r   zI;16zP;1zP;2zP;4r   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)   )r+   r9   r'   r@   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 )N)r+   rb   )r-   r+   rb   r#   r#   r$   r.     s    z_idat.__init__c             C   s   |  | jd| d S )Ns   IDAT)rb   r+   )r-   r'   r#   r#   r$   r
    s    z_idat.writeN)rR   rS   rT   r.   r
  r#   r#   r#   r$   r    s   r  c               @   s   e Zd Zdd Zdd ZdS )_fdatc             C   s   || _ || _|| _d S )N)r+   rb   r   )r-   r+   rb   r   r#   r#   r$   r.     s    z_fdat.__init__c             C   s*   |  | jdt| j| |  jd7  _d S )Ns   fdATr   )rb   r+   r  r   )r-   r'   r#   r#   r$   r
    s    z_fdat.writeN)rR   rS   rT   r.   r
  r#   r#   r#   r$   r    s   r  c             C   sn  | j d| jd}| j d| jdd}| j d| jdd}| j d| jd}| j d| jd}|rt| j dg }	nt| g| j dg }	g }
d}x*|	D ] }xt|D ]}| }|j| jkr| jdkr|j	| j| j
d	}n|	| j}| j  }t|ttfr6|| |d< t|ttfrR|| |d< t|ttfrn|| |d< |d
7 }|
r|
d }|d d}|d d}|tkrt|
dk rt}|tkr|d }tjd| jd}|d }|r||}n
d| j }||| n |tkr*|
d d }n|d }t|	d|	d}| }|s||dkr||dkr|dd}|rd|d kr|d d  |7  < q||d d< qnd }|
|||d qW qW ||dtt|
t| |rt| t||dd| j d|fg d}xDt|
D ]6\}}|d }|d sVd|j }n|d }||}|j}t t!|d dd}|d dt"}|d dt#}||dt|t|d t|d
 t|d t|d
 t$|t$dt%|t%| |d
7 }|dkr4|s4t|t||dd|j d|fg n0t&|||}t||dd|j d|fg |j'}q.W d S )Nr   r   r   r   r   r   Zappend_imagesr   )r   r   encoderinfor   r   r   )r   r   r   r   r   )r   r   r   )r   r   r  s   acTLrm   s   fcTLi  )(r  r   r   	itertoolschainr   Iteratorr   r   r   r   rg   listr`   r   r   r   r   r   r   r   Zcropr   r   Zsubtract_moduloZgetbboxrA   r  r   _saver  	enumerateintroundAPNG_DISPOSE_OP_NONEAPNG_BLEND_OP_SOURCEo16r
   r  r   )r   r+   rb   r   r   r   r   r   r   r  Z	im_framesZframe_countZim_seqZim_framer  previousZprev_disposalZ
prev_blendZbase_imr   r   deltar   r   Z
frame_datar   Zfdat_chunksr#   r#   r$   _write_multiple_frames$  s    





$






r  c             C   s   t | ||dd d S )NT)save_all)r  )r   r+   filenamer#   r#   r$   	_save_all  s    r"  Fc          
   C   s  | j }|dkrd| jkr.td| jd > d}n.| jrXttt| j d d dd}nd}|dkr|dkrrd}n|dkrd}nd}| d	| }| jd
d| jdd| jdd| jddf| _yt	| \}}W n6 t
k
r }	 ztd| d|	W d d }	~	X 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}|rDd d!d"d#g}x|jD ]}|d d \}}||
kr|
| |||| nH||kr|||| n0|dd  r|dd }|s|||| qW | j dkr|d }| jd$d | }xt||k r|d7 }qnW ||d%| | jd&| jd&d }|s|dkr| j dkr"|}t|tr||d'|d |  n0tdtd(|}d)| d }||d'|d |  nz| j d*krPtdtd+|}||d't| nL| j d$kr|\}}}||d't|t| t|  nd&| jkrtd,nB| j dkr| j d-kr| jd-d.}|}||d'|d |  | jd/}|r*||d0tt|d d1 d2 tt|d d1 d2 d3 |rzd4d5g}
x@|jD ]6}|d d \}}||
kr@|
| |||| q@W | jd6| jd6}|rt|tjr|d7}| d8r|d9d  }||d:| |rt!| ||| n$t"#| t$||d;d<| j d|fg |rdxP|jD ]F}|d d \}}|dd  r|dd }|r|||| qW ||d=d t%|d>r|&  d S )?Nr   bitsr      r   r   r   r   ;optimizeFZcompress_levelr  compress_type
dictionaryr   zcannot write mode z as PNGs   IHDRr   rf   s   cHRMs   gAMAs   sBITs   sRGBs   tIMEr   s   ICC Profiles     s   iCCPZpnginfos   sPLTs   iTXts   tEXts   zTXtr   s   PLTEr   s   tRNS      )r   r   r   i  z%cannot use transparency for this moder   Ar   s   pHYsg
F%u?g      ?   s   bKGDs   hISTr   r   s   Exif  r   s   eXIfrm   )r   r   s   IENDflush)'r   r  r   r   maxr   Zgetdatar   Zencoderconfig	_OUTMODESKeyErrorrO   r
  r   r  r   r   r   rj   remover_   r   r   Z
getpaletterg   rh   r  Zgetpalettemoder  r   ZExiftobytes
startswithr  r   r  r  hasattrr-  )r   r+   r!  rb   r   r   colorsr#  r   rM   r_   Ziccnamer'   r   Zchunks_multiple_allowedZ
info_chunkr9   ra   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 d| ` 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 )Nr#   )r-   r'   r#   r#   r$   r
  `  s    z"getchunks.<locals>.collector.writec             S   s   | j | d S )N)r'   rA   )r-   rb   r#   r#   r$   rA   c  s    z#getchunks.<locals>.collector.appendN)rR   rS   rT   r'   r
  rA   r#   r#   r#   r$   	collector]  s   r8  c             W   s0   d |}tt|t|}| |||f d S )Nr   )r	  r  r)   rA   )r+   r9   r'   r@   r#   r#   r$   rA   f  s    
zgetchunks.<locals>.appendN)r  r  r'   )r   paramsr8  rA   r+   r#   r#   r$   	getchunksZ  s    	r:  z.pngz.apngz	image/png)r   )>r  loggingrerK   r   r   rd   r   r   r   r   r   _binaryr   r   r	   r4   r
   r   r  r   r  	getLoggerrR   rD   compiler   r5   r   r   r   Z	SAFEBLOCKr   r   r  r   r   r  r   r%   r)   r*   rV   rU   r^   rq   r   r   r/  r  r  r  r  r"  r  r:  Zregister_openr  Zregister_saveZregister_save_allZregister_extensionsZregister_mimer#   r#   r#   r$   <module>"   s   


\T  ?  V  3