U
    
3g                     @  sx  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 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rd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.d]d'd(Z/G d)d* d*Z0G d+d, d,e1Z2G d-d. d.Z3G d/d0 d0e0Z4d1d2d3d4d5Z5G d6d7 d7ejZ6d8d9d:d;d<d=d>d>d>d?d@dAdBdCdDdEZ7dFdG Z8G dHdI dIZ9G dJdK dKZ:dLdM Z;dNdOdPdQdRdSdTZ<e8dUfdVdWZ=dXdY Z>e?e6j@e6e5 eAe6j@e= eBe6j@e< eCe6j@dZd[g eDe6j@d\ dS )^    )annotationsN)IntEnum)IOTYPE_CHECKINGAnyNoReturn   )Image
ImageChops	ImageFileImagePaletteImageSequence)i16be)i32be)o8)o16be)o32be)_imagings   \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-tbvhwjp8/PIL/PngImagePlugin.pyr(   g   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/   r0   r1   |   s   r1   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/   r0   _safe_zlib_decompress   s    r=   c                 C  s   t | |d@ S )Nl    )r4   crc32)dataseedr/   r/   r0   _crc32   s    rA   c                   @  s   e Zd ZdddddZdddd	Zd dd
dZdddddZddddZdddddddZdd Z	ddddddZ
ddddddZd$ddd d!d"Zd#S )%ChunkStream	IO[bytes]None)fpreturnc                 C  s   || _ g | _d S N)rE   queueselfrE   r/   r/   r0   __init__   s    zChunkStream.__init__ztuple[bytes, int, int]rF   c                 C  s   d}| j dk	st| jr6| j \}}}| j | n*| j d}|dd }| j  }t|}t|st	j
sdt| d}t||||fS )z.Fetch a new chunk. Returns header information.Nr#   r"   zbroken PNG file (chunk ))rE   AssertionErrorrH   popseekreadtelli32is_cidr   LOAD_TRUNCATED_IMAGESreprSyntaxError)rJ   cidposlengthr:   r<   r/   r/   r0   rQ      s    
zChunkStream.readc                 C  s   | S rG   r/   rJ   r/   r/   r0   	__enter__   s    zChunkStream.__enter__object)argsrF   c                 G  s   |    d S rG   )close)rJ   r^   r/   r/   r0   __exit__   s    zChunkStream.__exit__c                 C  s   d  | _ | _d S rG   )rH   rE   r[   r/   r/   r0   r_      s    zChunkStream.closebytesint)rX   rY   rZ   rF   c                 C  s$   | j d k	st| j |||f d S rG   )rH   rN   appendrJ   rX   rY   rZ   r/   r/   r0   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decoderd   r/   r/   r0   call   s    zChunkStream.call)rX   r?   rF   c              
   C  s   t jr&|d d? d@ r&| || dS | jdk	s4tzBt|t|}t| jd}||krtd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 rM   z(broken PNG file (incomplete checksum in )r   rU   crc_skiprE   rN   rA   rS   rQ   rV   rW   structerror)rJ   rX   r?   Zcrc1Zcrc2r<   er/   r/   r0   crc   s    zChunkStream.crcc                 C  s   | j dk	st| j d dS )zRead checksumNr"   )rE   rN   rQ   )rJ   rX   r?   r/   r/   r0   rm      s    zChunkStream.crc_skip   IENDzlist[bytes])endchunkrF   c              
   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)	rQ   rn   ro   OSErrorrq   r   
_safe_readrE   rc   )rJ   rs   ZcidsrX   rY   rZ   rp   r<   r/   r/   r0   verify   s    zChunkStream.verifyN)rr   )r)   r*   r+   rK   rQ   r\   r`   r_   re   rk   rq   rm   rv   r/   r/   r/   r0   rB      s   rB   c                   @  s0   e Zd ZU dZded< ded< edddZdS )	iTXtzq
    Subclass of string to allow iTXt chunks to look like strings while
    keeping their extra information

    zstr | bytes | NonelangtkeyNc                 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__rx   ry   )clstextrx   ry   rJ   r/   r/   r0   r{     s    	ziTXt.__new__)NN)r)   r*   r+   __doc____annotations__staticmethodr{   r/   r/   r/   r0   rw      s
   
rw   c                   @  sd   e Zd ZdZddddZdddddd	d
dZddddddddddZddddddddZdS )PngInfoz<
    PNG chunk container (for use with save(pnginfo=))

    rD   rL   c                 C  s
   g | _ d S rG   )chunksr[   r/   r/   r0   rK     s    zPngInfo.__init__Fra   bool)rX   r?   
after_idatrF   c                 C  s   | j |||f 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

        N)r   rc   )rJ   rX   r?   r   r/   r/   r0   add  s    
zPngInfo.add str | bytes)keyvaluerx   ry   ziprF   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)
isinstancera   encoder   r4   compress)rJ   r   r   rx   ry   r   r/   r/   r0   add_itxt&  s    



 zPngInfo.add_itxtzstr | bytes | iTXt)r   r   r   rF   c                 C  s   t |tr>| j|||jdk	r"|jnd|jdk	r4|jnd|dS t |ts~z|dd}W n$ tk
r|   | j|||d Y S X t |ts|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

        N    )r   r   r      zTXt        tEXtr   )r   rw   r   rx   ry   ra   r   UnicodeErrorr   r4   r   )rJ   r   r   r   r/   r/   r0   add_textI  s$    
	

zPngInfo.add_textN)F)r   r   F)F)r)   r*   r+   r~   rK   r   r   r   r/   r/   r/   r0   r     s      $ r   c                      sz  e Zd Z fddZdddddZddd	d
ZddddZddddddZddddddZddddddZ	ddddddZ
ddddddZddddddZddddddZddddddZddddd d!Zddddd"d#Zddddd$d%Zddddd&d'Zddddd(d)Zddddd*d+Zddddd,d-Zddddd.d/Zddddd0d1Z  ZS )2	PngStreamc                   sR   t  | i | _i | _d| _d | _d | _d | _d | _d | _	d | _
d | _d| _d S )Nr   r   r   )superrK   im_infoim_textim_sizeim_modeim_tile
im_paletteim_custom_mimetypeim_n_frames_seq_numrewind_statetext_memoryrI   	__class__r/   r0   rK   r  s    zPngStream.__init__rb   rD   )chunklenrF   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_MEMORYr9   )rJ   r   r<   r/   r/   r0   check_text_memory  s
    
zPngStream.check_text_memoryrL   c                 C  s   | j  | j| jd| _d S )N)infotileseq_num)r   copyr   r   r   r[   r/   r/   r0   save_rewind  s    zPngStream.save_rewindc                 C  s,   | j d  | _| j d | _| j d | _d S )Nr   r   r   )r   r   r   r   r   r[   r/   r/   r0   rewind  s    zPngStream.rewindra   )rY   rZ   rF   c                 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   ru   rE   findrg   rh   rW   r=   r9   rU   r4   ro   r   )rJ   rY   rZ   r:   icomp_methodr<   r   r/   r/   r0   
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   ru   rE   rU   r9   rS   r   _MODESr   
im_rawmode	Exceptionr   rW   rJ   rY   rZ   r:   r<   r/   r/   r0   
chunk_IHDR  s"     
zPngStream.chunk_IHDRr   c                 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)rJ   rY   rZ   r   r<   r/   r/   r0   
chunk_IDAT  s    


zPngStream.chunk_IDATc                 C  s   d}t |d S )Nzend of PNG image)r   )rJ   rY   rZ   r<   r/   r/   r0   
chunk_IEND  s    zPngStream.chunk_IENDc                 C  s&   t | j|}| jdkr"d|f| _|S )Nr   r   )r   ru   rE   r   r   rJ   rY   rZ   r:   r/   r/   r0   
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   ru   rE   r   _simple_palettematchr   r   i16)rJ   rY   rZ   r:   r   r/   r/   r0   
chunk_tRNS  s    




 zPngStream.chunk_tRNSc                 C  s$   t | j|}t|d | jd< |S )N     j@gamma)r   ru   rE   rS   r   r   r/   r/   r0   
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/   r0   	<genexpr>  s     z'PngStream.chunk_cHRM.<locals>.<genexpr>Zchromaticity)r   ru   rE   rn   unpacklentupler   )rJ   rY   rZ   r:   Zraw_valsr/   r/   r0   
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   ru   rE   rU   r9   r   r   r/   r/   r0   
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   ru   rE   rU   r9   rS   r   )	rJ   rY   rZ   r:   r<   pxpyunitr   r/   r/   r0   
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   r   r   r   replaceexif)
r   ru   rE   splitr9   rj   r   r   r   r   )rJ   rY   rZ   r:   kvZv_strr/   r/   r0   
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 chunkr   r   r   )r   ru   rE   r   r9   rW   r=   rU   r4   ro   rj   r   r   r   r   )rJ   rY   rZ   r:   r   r   r   r<   r/   r/   r0   
chunk_zTXt6  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 |dkr|
| j
d< z4|dd}|d	d}|	d	d}	|
d	d}
W n tk
rh   | Y S X t|
||	 | j
|< | j|< | t|
 |S )
Nr   r   r!   r   s   XML:com.adobe.xmpxmpr   r   r   )r   ru   rE   r   r9   r   r=   rU   r4   ro   r   rj   r   rw   r   r   )rJ   rY   rZ   rr:   r   cfcmrx   Ztkr   r/   r/   r0   
chunk_iTXtX  sF    
 





zPngStream.chunk_iTXtc                 C  s    t | j|}d| | jd< |S )N   Exif  r   )r   ru   rE   r   r   r/   r/   r0   
chunk_eXIf  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   ru   rE   rU   r9   r   warningswarnrS   r   r   )rJ   rY   rZ   r:   r<   n_framesr/   r/   r0   
chunk_acTL  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   ru   rE   rU   r9   rS   r   rW   r   r   r   float)rJ   rY   rZ   r:   r<   seqwidthheightr   r   Zim_wZim_hZ	delay_numZ	delay_denr/   r/   r0   
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   rU   ru   rE   r9   rS   r   rW   r   )rJ   rY   rZ   r:   r<   r   r/   r/   r0   
chunk_fdAT  s    zPngStream.chunk_fdAT)r)   r*   r+   rK   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  __classcell__r/   r/   r   r0   r   q  s*   		"*r   ra   r   )prefixrF   c                 C  s   | d d t kS )Nr#   )_MAGIC)r  r/   r/   r0   _accept  s    r  c                      s   e Zd ZdZdZddddZedd Zddd	d
ZdddddZ	d$ddddddZ
ddddZddddZdddddZddddZdddd Zd!d fd"d#Z  ZS )%PngImageFileZPNGzPortable network graphicsrD   rL   c              	   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  rE   rQ   rW   _fp_PngImageFile__frameprivate_chunksr   pngrk   r   AttributeErrorrg   rh   r   ru   islowerrc   rq   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_idatrR   _PngImageFile__rewind_seekis_animated)rJ   r<   rX   rY   rZ   r:   rawmoder?   r/   r/   r0   _open  sR    	








zPngImageFile._openc                 C  sD   | j d kr>| jr&| j}| | jd  |   | jr>| | | j S )Nr   )r  r  r  rP   r   load)rJ   framer/   r/   r0   r}     s    

zPngImageFile.textc                 C  sl   | j dkrd}t|| j | jd d d  | jdk	s>t| j  | j  | jrb| j   d| _ dS )zVerify PNG fileNz)verify must be called directly after openr   r!   r#   )	rE   RuntimeErrorrP   r   r  rN   rv   r_   Z_exclusive_fp)rJ   r<   r/   r/   r0   rv   +  s    



zPngImageFile.verifyrb   )r  rF   c                 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   rP   )rJ   r  Z
last_framefrp   r<   r/   r/   r0   rP   =  s    


zPngImageFile.seekFr   )r  r   rF   c              	   C  s>  | j d k	st|  |dkr|rl| j| j | j   | j| _d | _| j	rPd | _	| 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
rt   Y qZY nX |d
krd}t!||dkr|rd}t |d}z| j "||| W n t#k
r   Y qZY nz t!k
r"   |dkr|d	8 }|r|| _Y qZt| j| Y n4 t$k
rT   t%&d||| t| j| Y nX q2|| _| j j| _| jd| _| jd| _| jd| _| jsd}t!|| jd kr| jt'j(krt'j)| _d | _| jt'j(kr| jr:| j | _| *| j| j| _n4| jt'j)kr:t+j,-| j.| j/| _| *| j| j| _d S )Nr   r   Fr   r   r   r   zcannot seek to frame r"   rr   zNo more images in APNG file   fcTLzAPNG missing frame dataTr
  r	  zimage not found in APNG frame)0r  rN   r  rP   r  r   r  r  impyaccessr   r   r   r   rE   _prev_imdisposer  r   Z
dispose_opblend_opdispose_extentr  r9   r  paster   r   ru   rQ   rn   ro   rW   r   rk   UnicodeDecodeErrorr  rg   rh   r(   r.   r-   _cropr	   corefillmodesize)rJ   r  r   r<   Zframe_startrX   rY   rZ   r/   r/   r0   r  L  s    









zPngImageFile._seekc                 C  s   | j S rG   )r  r[   r/   r/   r0   rR     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_preparer[   r/   r/   r0   r2    s    zPngImageFile.load_preparera   )
read_bytesrF   c                 C  s   | j dk	st| jdkr| jd | j  \}}}|dkrP| j ||| dS |dkrz| j ||| W n tk
r   Y nX |d | _q|| _q|dkr| j}nt|| j}| j| | _| j|S )zinternal: read more image dataNr   r"   )   IDATs   DDATr
  r   r
  )	r  rN   r1  rE   rQ   re   rk   r   min)rJ   r3  rX   rY   rZ   r/   r/   r0   	load_read  s&    
zPngImageFile.load_readc                 C  sJ  | j dk	st| jdkr&| j| j | jd z| j  \}}}W n  tjtfk
rf   Y qY nX |dkrvqn(|dkr| jrd| _	| j 
||| qz| j ||| W q& tk
r   Y qY q& tk
rB   |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rF| jtjkrF| | j | j!}| j j"dkrd| j#kr|$d| j#d }n
|%d}| j&|| j!| | j| _ | j'rFd| _'dS )z%internal: finished reading image dataNr   r"   rr   r#  r
  r	  r   r!   Tr   r   r    )(r  rN   r1  rE   rQ   rn   ro   rW   r  r  re   rk   r+  r   r   ru   rt   rU   r  rg   rh   r  r  rc   r   r  r_   r&  r(  r1   r3   r,  r$  r)  r/  r   Zconvert_transparentconvertr*  r%  )rJ   rX   rY   rZ   rp   r:   updatedmaskr/   r/   r0   load_end  s`    



 
zPngImageFile.load_endzdict[str, Any] | Nonec                 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_dictr[   r/   r/   r0   _getexif  s
    
zPngImageFile._getexifz
Image.Exifc                   s   d| j kr|   t  S )Nr   )r   r  r   r;  r[   r   r/   r0   r;    s    
zPngImageFile.getexif)F)r)   r*   r+   formatformat_descriptionr  propertyr}   rv   rP   r  rR   r2  r6  r:  r<  r;  r  r/   r/   r   r0   r    s   C
a	":r  )r      r   )L;1r@  r   )r      r   )r      r   )r      r   )r   rD  rC  )r      r   )r   r@     )r   rB  rF  )r   rC  rF  )r   rD  rF  )r   rD  rB  )r    rD     )r   rA  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   rA   rE   rX   r?   rq   r/   r/   r0   putchunk:  s
    

rM  c                   @  s$   e Zd Zdd ZdddddZdS )	_idatc                 C  s   || _ || _d S rG   )rE   chunk)rJ   rE   rO  r/   r/   r0   rK   H  s    z_idat.__init__ra   rD   r?   rF   c                 C  s   |  | jd| d S )Nr4  )rO  rE   rJ   r?   r/   r/   r0   rJ  L  s    z_idat.writeNr)   r*   r+   rK   rJ  r/   r/   r/   r0   rN  E  s   rN  c                   @  s$   e Zd Zdd ZdddddZdS )	_fdatc                 C  s   || _ || _|| _d S rG   )rE   rO  r   )rJ   rE   rO  r   r/   r/   r0   rK   S  s    z_fdat.__init__ra   rD   rP  c                 C  s*   |  | jdt| j| |  jd7  _d S )Nr
  r   )rO  rE   rK  r   rQ  r/   r/   r0   rJ  X  s    z_fdat.writeNrR  r/   r/   r/   r0   rS  P  s   rS  c                  C  sN  | j d}| j d| jdd}| j d| jdtj}	| j d| jdtj}
|rht|}nt| g|}g }d}|D ]}t	
|D ]}|j|kr| }n
||}| j  }t|ttfr|| |d< n |d krd|jkr|jd |d< t|	ttfr|	| |d< t|
ttfr4|
| |d< |d7 }|rt|d }|d d}|d d}|tjkrt|d	k rt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}|sx||dkrx||dkrxd|krx|d d  |d 7  < qn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 ]2\}}|d
 }|d s<d|j }n|d }||}|j}|d }t#t$|d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   rU  s   acTLr   r#  r   ))rU  r  r   r(   r,   r1   r2   	itertoolschainr   Iteratorr/  r   r7  r   listr   r.   r   r-   r	   r-  r.  r0  Zcropr*  r
   Zsubtract_moduloZgetbboxrc   rK  r   _saverN  	enumeraterb   roundo16r   rS  r   ) r$  rE   rO  r/  r  r   append_imagesr   r   r   r   rX  Z	im_framesZframe_countim_seqim_framerU  previousZprev_disposalZ
prev_blendZbase_imr'  r   deltar   r  Z
frame_datar0  Zframe_durationZframe_disposalZframe_blendZfdat_chunksr/   r/   r0   _write_multiple_frames]  s    





 

$





rd  zImage.ImagerC   r   rD   )r$  rE   filenamerF   c                 C  s   t | ||dd d S )NT)save_all)r[  )r$  rE   re  r/   r/   r0   	_save_all  s    rg  Fc           '   
     sR  |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rPd| j krtd	| j d > d
}n0| jrttt| j d	 d d
d	}nd
}|dkrP|dkr.d	}n|dkr>d}nd}|d| 7 }| 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 }|r\d!}|d" t| }||d#| |d | j d$}|rd%d&d'd(g}|jD ]}|d d \}}||kr|| |||| nR||kr|||| n:|d	d  rt|dko|d }|s|||| q| j	dkrZ|d }| j d)d | }t||k rN|d7 }q4||d*| | j d+| jd+d }|s|dkrf| 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rL|\}"}#}$||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;}&|&rt!|&t&j'rh|&(d<}&|&)d=r|&d>d  }&||d?|& |rt*| |||
|||} | rt+,| t-||d@dA| j
 d|fg |r.|jD ]P}|d d \}}|d	d  rt|dko|d }|r|||| q||dBd t.|dCrN|/  d S )DNr   r_  )r    r   r   c                 3  s$   | ] t  fd dD V  qdS )c                 3  s   | ]}|  V  qd S rG   r/   )r   
frame_sizer   r/   r0   r     s     z"_save.<locals>.<genexpr>.<genexpr>N)max)r   Zsizesri  r0   r     s     z_save.<locals>.<genexpr>r!   r   bitsr      r%   r$   r"   ;optimizeFZcompress_levelrT  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   rH  r   i  z%cannot use transparency for this moder    Ar   s   pHYsr   g      ?r@  s   bKGDs   hISTr   r#   r   r&   s   eXIfr   r   rr   flush)0rU  r  r   setrW  rX  r   rY  r   r/  r0  rO   r   r!  r5  r  rj  r   ZgetdataZencoderconfig	_OUTMODESKeyErrorrt   rJ  r  rK  r4   r   remover   r  r$  Z
getpaletter   ra   r^  Zgetpalettemoderb   r	   ZExiftobytes
startswithrd  r   r[  rN  hasattrru  )'r$  rE   re  rO  rf  r   modesr_  r`  ra  r/  r0  Zoutmodecolorsrl  r  Z	bit_depthZ
color_typerp   r<   r   Ziccnamer?   r   Zchunks_multiple_allowedZ
info_chunkrX   r   Zpalette_byte_numberZpalette_bytesr   Zalpha_bytesalphaZredZgreenZbluer   r   r/   rk  r0   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                   @  s0   e Zd Zg ZdddddZdddddZd	S )
zgetchunks.<locals>.collectorra   rD   rP  c                 S  s   d S rG   r/   rQ  r/   r/   r0   rJ    s    z"getchunks.<locals>.collector.write)rO  rF   c                 S  s   | j | d S rG   )r?   rc   )rJ   rO  r/   r/   r0   rc     s    z#getchunks.<locals>.collector.appendN)r)   r*   r+   r?   rJ  rc   r/   r/   r/   r0   	collector  s   r  c                 W  s0   d |}tt|t|}| |||f d S )Nr   )rI  rK  rA   rc   rL  r/   r/   r0   rc     s    
zgetchunks.<locals>.appendN)rU  r[  r?   )r$  paramsr  rc   rE   r/   r/   r0   	getchunks  s    	r  z.pngz.apngz	image/png)r   )E
__future__r   rW  loggingrern   r   r4   enumr   typingr   r   r   r   r   r	   r
   r   r   r   _binaryr   r   r   rS   r   r   r^  r   rK  r   	getLoggerr)   rg   compiler   rT   r  r   r   Z	SAFEBLOCKr7   r   r(   r1   r=   rA   rB   rz   rw   r   r   r  r  rw  rM  rN  rS  rd  rg  r[  r  Zregister_openr=  Zregister_saveZregister_save_allZregister_extensionsZregister_mimer/   r/   r/   r0   <module>!   s   

	
]`  ^  U  K