U
    Evf"                     @  s<  d dl mZ 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	 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%G dd  d e	Z&G d!d" d"e	Z'd#d$ Z(dSd%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/d0 Z/G d1d2 d2ejZ0d3d4d5d6d7d8d9d9d9d:d;d<d=d>d?d@Z1dAdB Z2G dCdD dDZ3G dEdF dFZ4dGdH Z5dIdJ Z6e2dKfdLdMZ7dNdO Z8e9e0j:e0e/ e;e0j:e7 e<e0j:e6 e=e0j:dPdQg e>e0j:dR dS )T    )annotationsN)IntEnum   )Image
ImageChops	ImageFileImagePaletteImageSequence)i16be)i32be)o8)o16be)o32bes   \w\w\w\ws   PNG

)1r   )LL;2)r   L;4)r   r   )I;16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                   @  s   e Zd ZdZdZdZdS )Disposalr   r   r   N)__name__
__module____qualname__OP_NONEOP_BACKGROUNDOP_PREVIOUS r*   r*   6/tmp/pip-unpacked-wheel-ciywl2yd/PIL/PngImagePlugin.pyr#   c   s   r#   c                   @  s   e Zd ZdZdZdS )Blendr   r   N)r$   r%   r&   	OP_SOURCEOP_OVERr*   r*   r*   r+   r,   x   s   r,   c                 C  s*   t  }|| t}|jr&d}t||S )NzDecompressed Data Too Large)zlibdecompressobj
decompressMAX_TEXT_CHUNKunconsumed_tail
ValueError)sZdobj	plaintextmsgr*   r*   r+   _safe_zlib_decompress   s    r8   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|sxtj	sxdt
| d}t||||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reprSyntaxError)rB   cidposlengthr5   r7   r*   r*   r+   rG      s    
zChunkStream.readc                 C  s   | S r>   r*   rB   r*   r*   r+   	__enter__   s    zChunkStream.__enter__c                 G  s   |    d S r>   )close)rB   argsr*   r*   r+   __exit__   s    zChunkStream.__exit__c                 C  s   d  | _ | _d S r>   )r@   r?   rQ   r*   r*   r+   rS      s    zChunkStream.closec                 C  s   | j |||f d S r>   )r@   appendrB   rN   rO   rP   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decoderW   r*   r*   r+   call   s    zChunkStream.callc              
   C  s   t jr&|d d? d@ r&| || dS zBt|t|}t| jd}||krfdt| d}t|W n> t	j
k
r } zdt| d}t||W 5 d}~X Y nX dS )	zRead and verify checksumr      r   Nr   z(broken PNG file (bad header checksum in rD   z(broken PNG file (incomplete checksum in )r   rK   crc_skipr<   rI   r?   rG   rL   rM   structerror)rB   rN   r:   Zcrc1Zcrc2r7   er*   r*   r+   crc   s    zChunkStream.crcc                 C  s   | j d dS )zRead checksumr   N)r?   rG   )rB   rN   r:   r*   r*   r+   r`      s    zChunkStream.crc_skip   IENDc              
   C  sz   g }z|   \}}}W n2 tjk
rH } zd}t||W 5 d }~X Y nX ||krTqv| |t| j| || q|S )Nztruncated PNG file)	rG   ra   rb   OSErrorrd   r   
_safe_readr?   rV   )rB   ZendchunkZcidsrN   rO   rP   rc   r7   r*   r*   r+   verify   s    zChunkStream.verifyN)re   )r$   r%   r&   rC   rG   rR   rU   rS   rX   r^   rd   r`   rh   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textrl   rm   rB   r*   r*   r+   rk      s    	ziTXt.__new__)NN)r$   r%   r&   __doc__staticmethodrk   r*   r*   r*   r+   ri      s   ri   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 r>   )chunksrQ   r*   r*   r+   rC     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)rV   rs   tuple)rB   rN   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

        latin-1strictutf-8   iTXts         s      N)
isinstancebytesencoderw   r/   compress)rB   keyvaluerl   rm   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

        )r   ry   rz      zTXt        tEXtr}   N)r~   ri   r   rl   rm   r   r   UnicodeErrorrw   r/   r   )rB   r   r   r   r*   r*   r+   add_text:  s    	


zPngInfo.add_textN)F)rx   rx   F)F)r$   r%   r&   rp   rC   rw   r   r   r*   r*   r*   r+   rr     s
   

rr   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   )superrC   im_infoim_textim_sizeim_modeim_tile
im_paletteim_custom_mimetypeim_n_frames_seq_numrewind_statetext_memoryrA   	__class__r*   r+   rC   [  s    zPngStream.__init__c                 C  s2   |  j |7  _ | j tkr.d| j  d}t|d S )Nz%Too much memory used in text chunks: z>MAX_TEXT_MEMORY)r   MAX_TEXT_MEMORYr4   )rB   Zchunklenr7   r*   r*   r+   check_text_memoryl  s
    
zPngStream.check_text_memoryc                 C  s   | j  | j| jd| _d S )N)infotileseq_num)r   copyr   r   r   rQ   r*   r*   r+   save_rewindu  s    zPngStream.save_rewindc                 C  s,   | j d  | _| j d | _| j d | _d S )Nr   r   r   )r   r   r   r   r   rQ   r*   r*   r+   rewind|  s    zPngStream.rewindc                 C  s   t | j|}|d}td|d |  ||d  }td| |dkr`d| d}t|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 )
Nr}   ziCCP profile name %rr   zCompression method %sr   Unknown compression method z in iCCP chunkr   icc_profile)r   rg   r?   findrZ   r[   rM   r8   r4   rK   r/   rb   r   )rB   rO   rP   r5   icomp_methodr7   r   r*   r*   r+   
chunk_iCCP  s$    


zPngStream.chunk_iCCPc                 C  s   t | j|}|dk r,t jr |S d}t|t|dt|df| _z t|d |d f \| _| _	W n t
k
rv   Y nX |d rd| jd	< |d
 rd}t||S )N   zTruncated IHDR chunkr   r   r   	      r   	interlace   zunknown filter category)r   rg   r?   rK   r4   rI   r   _MODESr   
im_rawmode	Exceptionr   rM   rB   rO   rP   r5   r7   r*   r*   r+   
chunk_IHDR  s"     
zPngStream.chunk_IHDRc                 C  sh   d| j kr"d| j d || jfg}n*| jd k	r6d| j d< dd| j || jfg}|| _|| _d}t|d S )Nbboxr   Tdefault_imager   zimage data found)r   r   r   r   r   Zim_idatEOFError)rB   rO   rP   r   r7   r*   r*   r+   
chunk_IDAT  s    


zPngStream.chunk_IDATc                 C  s   d}t |d S )Nzend of PNG image)r   )rB   rO   rP   r7   r*   r*   r+   
chunk_IEND  s    zPngStream.chunk_IENDc                 C  s&   t | j|}| jdkr"d|f| _|S )Nr   r   )r   rg   r?   r   r   rB   rO   rP   r5   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   r}   r   transparency)r   r   r   r   r   r   )	r   rg   r?   r   _simple_palettematchr   r   i16)rB   rO   rP   r5   r   r*   r*   r+   
chunk_tRNS  s    




 zPngStream.chunk_tRNSc                 C  s$   t | j|}t|d | jd< |S )N     j@gamma)r   rg   r?   rI   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   rg   r?   ra   unpacklenrt   r   )rB   rO   rP   r5   Zraw_valsr*   r*   r+   
chunk_cHRM  s    zPngStream.chunk_cHRMc                 C  s>   t | j|}|dk r,t jr |S d}t||d | jd< |S )Nr   zTruncated sRGB chunkr   Zsrgb)r   rg   r?   rK   r4   r   r   r*   r*   r+   
chunk_sRGB  s    zPngStream.chunk_sRGBc           	      C  s   t | j|}|dk r,t jr |S d}t|t|dt|d }}|d }|dkrn|d |d f}|| jd< n|dkr||f| jd	< |S )
Nr   zTruncated pHYs chunkr   r   r   r   
F%u?dpiZaspect)r   rg   r?   rK   r4   rI   r   )	rB   rO   rP   r5   r7   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}|dkrh|n|| j|< || j|< | t	| |S )Nr}   r       ry   rz   replaceexif)
r   rg   r?   splitr4   r]   r   r   r   r   )rB   rO   rP   r5   kvZv_strr*   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 |rN|d }nd}|dkrnd| d}t|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 )
Nr}   r   r   r   r   z in zTXt chunkry   rz   r   )r   rg   r?   r   r4   rM   r8   rK   r/   rb   r]   r   r   r   r   )rB   rO   rP   r5   r   r   r   r7   r*   r*   r+   
chunk_zTXt  s4    


zPngStream.chunk_zTXtc                 C  s  t | j| }}z|dd\}}W n tk
r>   | Y S X t|dk rP|S |d |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
rT   | Y S X t|
||	 | j|< | j|< | t|
 |S )Nr}   r   r   r   ry   rz   r{   )r   rg   r?   r   r4   r   r8   rK   r/   rb   r]   r   ri   r   r   r   )rB   rO   rP   rr5   r   cfcmrl   Ztkr   r*   r*   r+   
chunk_iTXtA  sB    
 



zPngStream.chunk_iTXtc                 C  s    t | j|}d| | jd< |S )N   Exif  r   )r   rg   r?   r   r   r*   r*   r+   
chunk_eXIfi  s    zPngStream.chunk_eXIfc                 C  s   t | j|}|dk r,t jr |S d}t|| jd k	rJd | _td |S t|}|dksb|dkrptd |S || _t|d| j	d< d| _
|S )	Nr   z"APNG contains truncated acTL chunkz4Invalid APNG, will use default PNG image if possibler   l        r   loopz
image/apng)r   rg   r?   rK   r4   r   warningswarnrI   r   r   )rB   rO   rP   r5   r7   n_framesr*   r*   r+   
chunk_acTLo  s$    


zPngStream.chunk_acTLc                 C  sB  t | j|}|dk r,t jr |S d}t|t|}| jd krF|dks^| jd k	rj| j|d krjd}t||| _t|dt|d }}t|dt|d	 }}	| j\}
}|| |
ks|	| |krd
}t|||	|| |	| f| j	d< t
|dt
|d }}|dkrd}t|t| d | j	d< |d | j	d< |d | j	d< |S )N   z"APNG contains truncated fcTL chunkr   r   #APNG contains frame sequence errorsr   r   r   r   zAPNG contains invalid framesr         d     duration   disposal   blend)r   rg   r?   rK   r4   rI   r   rM   r   r   r   float)rB   rO   rP   r5   r7   seqwidthheightr   r   Zim_wZim_hZ	delay_numZ	delay_denr*   r*   r+   
chunk_fcTL  s:    

zPngStream.chunk_fcTLc                 C  sv   |dk r,t jr t | j|}|S d}t|t | jd}t|}| j|d kr\d}t||| _| |d |d S )Nr   z"APNG contains truncated fDAT chunkr   r   )	r   rK   rg   r?   r4   rI   r   rM   r   )rB   rO   rP   r5   r7   r   r*   r*   r+   
chunk_fdAT  s    zPngStream.chunk_fdAT)r$   r%   r&   rC   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+   r   Z  s*   		"(r   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  ZS )PngImageFileZPNGzPortable network graphicsc              	   C  s  t | jdsd}t|| j| _d| _g | _t| j| _| j \}}}z| j	|||}W nh t
k
rx   Y qY nR tk
r   td||| t| j|}|dd  r| j||f Y nX | j|| q<| jj| _| jj| _| jj| _d | _| jj| _| jj| _| jjpd| _| j dd| _!| jj"rV| jj"\}}t#$||| _%|d	krl|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   %r %s %s (unknown)r   r   r   F   fdATr   ).r   r?   rG   rM   _fp_PngImageFile__frameprivate_chunksr   pngr^   r   AttributeErrorrZ   r[   r   rg   islowerrV   rd   r   _moder   _sizer   r   _textr   r   r   Zcustom_mimetyper   r   getr   r   r   rawpalette_PngImageFile__prepare_idatZ!_close_exclusive_fp_after_loadingr   _PngImageFile__rewind_idatrH   _PngImageFile__rewind_seekis_animated)rB   r7   rN   rO   rP   r5   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   rF   r   load)rB   framer*   r*   r+   ro     s    

zPngImageFile.textc                 C  s^   | j dkrd}t|| j | jd d d  | j  | j  | jrT| j   d| _ dS )zVerify PNG fileNz)verify must be called directly after openr   r   r   )r?   RuntimeErrorrF   r   r   rh   rS   Z_exclusive_fp)rB   r7   r*   r*   r+   rh     s    



zPngImageFile.verifyc                 C  s   |  |sd S || jk r$| dd | j}t| jd |d D ]N}z| | W q> tk
r } z| | d}t||W 5 d }~X Y q>X q>d S )Nr   Tr   zno more images in APNG file)Z_seek_checkr   r	  ranger   rF   )rB   r  Z
last_framefrc   r7   r*   r*   r+   rF   #  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rd| }t||   | jr| j| j| j | j | _| j | _| jrt| j| j d| _d}| jd	 z| j \}}}W n" tjtfk
rb   Y qHY nX |d
krzd}t ||dkr|rd}t|d}z| j!||| W n t"k
r   Y qHY nz t k
r   |dkr|d	8 }|r|| _Y qHt| j| Y n4 t#k
rB   t$%d||| t| j| Y nX q || _| jj| _| j
d| _| j
d| _| j
d| _| jsd}t || jd kr| jt&j'krt&j(| _| jt&j'kr| j | _| )| j| j| _n<| jt&j(krt*j+,| j-| j.| _| )| j| j| _nd | _d S )Nr   r   Fr   r   r   r   zcannot seek to frame r   re   zNo more images in APNG file   fcTLzAPNG missing frame dataTr   r   zimage not found in APNG frame)/r   rF   r  r   r   r  r  impyaccessr   r   r   r   r?   _prev_imdisposer  r   Z
dispose_opblend_opdispose_extentr   r4   r  paster   r   rg   rG   ra   rb   rM   r   r^   UnicodeDecodeErrorr   rZ   r[   r#   r)   r(   _cropr   corefillmodesize)rB   r  r   r7   Zframe_startrN   rO   rP   r*   r*   r+   r	  2  s    









zPngImageFile._seekc                 C  s   | j S r>   )r   rQ   r*   r*   r+   rH     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_preparerQ   r*   r*   r+   r!    s    zPngImageFile.load_preparec                 C  s   | j dkr| jd | j \}}}|dkrB| j||| dS |dkrz| j||| W n tk
rr   Y nX |d | _ q || _ q |dkr| j }nt|| j }| j | | _ | j|S )zinternal: read more image datar   r   )   IDATs   DDATr   r   r   )r   r?   rG   r   rX   r^   r   min)rB   
read_bytesrN   rO   rP   r*   r*   r+   	load_read  s$    
zPngImageFile.load_readc                 C  s<  | j dkr| j| j  | jd z| j \}}}W n  tjtfk
rX   Y qY nX |dkrhqn(|dkr| jrd| _| j	||| qz| j
||| W q tk
r   Y qY q tk
r4   |dkr|d8 }zt| j| W n> tk
r. } ztjrW Y Y qn|W 5 d}~X Y nX Y q tk
r   td||| t| j|}|dd	  r| j||d
f Y qX q| jj| _| js| j  d| _n| jr8| jtjkr8| | j| j }| jj!dkrd| j"kr|#d| j"d }n
|$d}| j%|| j | | j| _| j&r8d| _&dS )z%internal: finished reading image datar   r   re   r  r   Nr   r   r   Tr   r   r   )'r   r?   rG   r   ra   rb   rM   r
  r  rX   r^   r  r   r   rg   rf   rK   r   rZ   r[   r   r   rV   r   r  rS   r  r  r,   r.   r  r  r  r  r   Zconvert_transparentconvertr  r  )rB   rN   rO   rP   rc   r5   updatedmaskr*   r*   r+   load_end  s^    



 
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_dictrQ   r*   r*   r+   _getexif  s
    
zPngImageFile._getexifc                   s   d| j kr|   t  S )Nr   )r   r  r   r*  rQ   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_getxmprQ   r*   r*   r+   getxmp  s    	zPngImageFile.getxmp)F)r$   r%   r&   formatformat_descriptionr  propertyro   rh   rF   r	  rH   r!  r%  r)  r+  r*  r,  r   r*   r*   r   r+   r     s   C

^	!9r   )r       )L;1r0  )r   s    )r   s    )r   s    )r   s   )r   s    )r   s   )r   s   )r   s   )r   s   )r   s   )r   s   )r   r1  r   r   r   r   Ir   r   r   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<   r?   rN   r:   rd   r*   r*   r+   putchunk(  s
    

r7  c                   @  s   e Zd Zdd Zdd ZdS )_idatc                 C  s   || _ || _d S r>   )r?   rv   )rB   r?   rv   r*   r*   r+   rC   6  s    z_idat.__init__c                 C  s   |  | jd| d S )Nr"  )rv   r?   rB   r:   r*   r*   r+   r4  :  s    z_idat.writeNr$   r%   r&   rC   r4  r*   r*   r*   r+   r8  3  s   r8  c                   @  s   e Zd Zdd Zdd ZdS )_fdatc                 C  s   || _ || _|| _d S r>   )r?   rv   r   )rB   r?   rv   r   r*   r*   r+   rC   A  s    z_fdat.__init__c                 C  s*   |  | jdt| j| |  jd7  _d S )Nr   r   )rv   r?   r5  r   r9  r*   r*   r+   r4  F  s    z_fdat.writeNr:  r*   r*   r*   r+   r;  >  s   r;  c                 C  s@  | j d| jdd}| j d| jdd}| j d| jdtj}| j d| jdtj}	|rtt|}
nt| g|}
g }d}|
D ]}t	
|D ]}|j|kr| }n
||}| j  }t|ttfr|| |d< t|ttfr|| |d< t|	ttfr|	| |d< |d7 }|rX|d }|d d}|d d}|tjkrpt|d	k rptj}|tjkr|d
  }tjd| jd}|d }|r||}n
d| j }||| n"|tjkr|d d
 }n|d
 }t|d|d}|jdd}|s\||dkr\||dkr\|d d  |d|7  < qnd }d|krn||d< ||||d qqt|dkr|s|d d
 S ||dtt|t| |r| j|kr| |} t | t!||dd| j d|fg d}t"|D ].\}}|d
 }|d s2d|j }n|d }||}|j}|d }t#t$|d }|d|}|d|	}||dt|t|d t|d t|d t|d t%|t%dt&|t&| |d7 }|dkr|st |t!||dd|j d|fg n0t'|||}t ||dd|j d|fg |j(}q
d S )Nr   r   r   r   r   r   encoderinfor   r  r   )r   r   r   r   r   r   F)Z
alpha_only)r  r   r=  s   acTLr   r  r   ))r=  r  r   r#   r'   r,   r-   	itertoolschainr	   Iteratorr  r   r&  r~   listrt   r)   r   r(   r   r  r  r  Zcropr  r   Zsubtract_moduloZgetbboxrV   r5  r   _saver8  	enumerateintroundo16r   r;  r   )r  r?   rv   r  r   append_imagesr   r   r   r   r@  Z	im_framesZframe_countim_seqim_framer=  previousZprev_disposalZ
prev_blendZbase_imr  r   deltar   r  Z
frame_datar  Zframe_durationZframe_disposalZframe_blendZfdat_chunksr*   r*   r+   _write_multiple_framesK  s    





  


$





rM  c                 C  s   t | ||dd d S )NT)save_all)rC  )r  r?   filenamer*   r*   r+   	_save_all  s    rP  Fc           $   
     s4  |r| j d| jd}t }t  | j dg }t| g|D ],}t|D ]}	||	j	  |	j
 qPqBdD ]}
|
|krt qqt| }
t fddtdD }n| j
}| j	}
|
dkrLd| j krtd	| j d > d
}n0| jrttt| j d	 d d
d	}nd
}|dkrL|dkr*d	}n|dkr:d}nd}|
 d| }
| j dd| j dd| j dd| j ddf| _zt|
 \}}
W n: tk
r } zd|
 d}t||W 5 d }~X Y nX |t ||dt|d t|d	 |
ddd dddddg}| j d | jd }|rTd!}|d" t| }||d#| |d | j d$}|rd%d&d'd(g}|jD ]}|d d \}}||kr|| |||| nH||kr|||| n0|d	d  rx|dd }|sx|||| qx| j	dkrH|d }| j d)d | }t||k r<|d7 }q"||d*| | j d+| jd+d }|sp|dkrT| j	dkr|}t!|t"r||d,|d |  n0tdtd-|}d.| d }||d,|d |  n~| j	d/krtdtd0|}||d,t#| nP| j	d)kr:|\}} }!||d,t#|t#|  t#|!  nd+| j krd1}t|nB| j	dkr| j$ d2kr| j d2d3}|}||d,|d |  | j d4}"|"r||d5tt%|"d d6 d7 tt%|"d	 d6 d7 d8 |r,d9d:g}|jD ]6}|d d \}}||kr|| |||| q| j d;}#|#rzt!|#t&j'rV|#(d<}#|#)d=rn|#d>d  }#||d?|# |rt*| |||||} | rt+,| t-||d@dA| j
 d|fg |r|jD ]F}|d d \}}|d	d  r|dd }|r|||| q||dBd t.|dCr0|/  d S )DNr   rH  )r   r   r   c                 3  s$   | ] t  fd dD V  qdS )c                 3  s   | ]}|  V  qd S r>   r*   )r   
frame_sizer   r*   r+   r     s     z"_save.<locals>.<genexpr>.<genexpr>N)max)r   ZsizesrR  r+   r     s     z_save.<locals>.<genexpr>r   r   bitsr      r    r   r   ;optimizeFZcompress_levelr<  compress_type
dictionaryr   zcannot write mode z as PNGs   IHDRr   r}   s   cHRMs   gAMAs   sBITs   sRGBs   tIMEr   s   ICC Profiler   s   iCCPZpnginfos   sPLTr|   r   r   r   s   PLTEr   s   tRNS      )r   r   r2  r   i  z%cannot use transparency for this moder   Ar   s   pHYsr   g      ?   s   bKGDs   hISTr   r   r   r!   s   eXIfr   r   re   flush)0r=  r  r   setr?  r@  r	   rA  rw   r  r  rE   rt   r  r#  r  rS  r   ZgetdataZencoderconfig	_OUTMODESKeyErrorrf   r4  r   r5  r/   r   removers   r   r  Z
getpaletter~   r   rG  ZgetpalettemoderE  r   ZExiftobytes
startswithrM  r   rC  r8  hasattrr_  )$r  r?   rO  rv   rN  r   modesrH  rI  rJ  r  r  colorsrU  r  rc   r7   rs   Ziccnamer:   r   Zchunks_multiple_allowedZ
info_chunkrN   ru   Zpalette_byte_numberZpalette_bytesr   Zalpha_bytesalphaZredZgreenZbluer   r   r*   rT  r+   rC    s$    


$











"




     $
rC  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*   r9  r*   r*   r+   r4    s    z"getchunks.<locals>.collector.writec                 S  s   | j | d S r>   )r:   rV   )rB   rv   r*   r*   r+   rV     s    z#getchunks.<locals>.collector.appendN)r$   r%   r&   r:   r4  rV   r*   r*   r*   r+   	collector  s   rk  c                 W  s0   d |}tt|t|}| |||f d S )Nr   )r3  r5  r<   rV   r6  r*   r*   r+   rV     s    
zgetchunks.<locals>.appendN)r=  rC  r:   )r  paramsrk  rV   r?   r*   r*   r+   	getchunks  s    	rm  z.pngz.apngz	image/png)r   )?
__future__r   r?  loggingrera   r   r/   enumr   rx   r   r   r   r   r	   _binaryr
   r   r   rI   r   r   rG  r   r5  	getLoggerr$   rZ   compiler   rJ   r   r   r   Z	SAFEBLOCKr2   r   r#   r,   r8   r<   r=   rj   ri   rr   r   r   r   ra  r7  r8  r;  rM  rP  rC  rm  Zregister_openr-  Zregister_saveZregister_save_allZregister_extensionsZregister_mimer*   r*   r*   r+   <module>!   s   

	
YT  \  \  I