o
    Ԧ/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*   2lib/python3.10/site-packages/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dobjZ	plaintextmsgr*   r*   r+   _safe_zlib_decompress   s   r7   c                 C  s   t | |d@ S )Nl    )r/   crc32)dataZseedr*   r*   r+   _crc32      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__      
zChunkStream.__init__c                 C  s   d}| j r| j  \}}}| j| n| jd}|dd }| j }t|}t|s<tj	s<d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)rA   cidposlengthr5   r6   r*   r*   r+   rG      s   

zChunkStream.readc                 C  s   | S r=   r*   rA   r*   r*   r+   	__enter__      zChunkStream.__enter__c                 G  s   |    d S r=   )close)rA   argsr*   r*   r+   __exit__   s   zChunkStream.__exit__c                 C  s   d  | _ | _d S r=   )r?   r>   rQ   r*   r*   r+   rT      r;   zChunkStream.closec                 C  s   | j |||f d S r=   )r?   appendrA   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decoderX   r*   r*   r+   call   s   zChunkStream.callc              
   C  s   t jr|d d? d@ r| || dS z"t|t|}t| jd}||kr3dt| d}t|W dS  t	j
yO } zdt| d}t||d}~ww )	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)rA   rN   r9   Zcrc1Zcrc2r6   er*   r*   r+   crc   s   
zChunkStream.crcc                 C  s   | j d dS )zRead checksumr   N)r>   rG   )rA   rN   r9   r*   r*   r+   ra      s   zChunkStream.crc_skip   IENDc              
   C  sr   g }	 z	|   \}}}W n tjy  } zd}t||d }~ww ||kr(	 |S | |t| j| || q)NTztruncated PNG file)	rG   rb   rc   OSErrorre   r   
_safe_readr>   rW   )rA   ZendchunkZcidsrN   rO   rP   rd   r6   r*   r*   r+   verify   s   

zChunkStream.verifyN)rf   )r$   r%   r&   rB   rG   rR   rV   rT   rY   r_   re   ra   ri   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textrm   rn   rA   r*   r*   r+   rl      s   	ziTXt.__new__)NN)r$   r%   r&   __doc__staticmethodrl   r*   r*   r*   r+   rj      s    rj   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+   rB     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)rW   rt   tuple)rA   rN   r9   
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s!|dd}t |ts,|dd}|rE| d|d | d | d t|  dS | 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encoderx   r/   compress)rA   keyvaluerm   rn   zipr*   r*   r+   add_itxt  s   



 (zPngInfo.add_itxtc                 C  s   t |tr| j|||j|j|dS t |ts0z|dd}W n ty/   | j|||d Y S w t |ts;|dd}|rL| d|d t	
|  dS | 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   rz   r{      zTXt        tEXtr~   N)r   rj   r   rm   rn   r   r   UnicodeErrorrx   r/   r   )rA   r   r   r   r*   r*   r+   add_text:  s   
	

zPngInfo.add_textNF)ry   ry   F)r$   r%   r&   rq   rB   rx   r   r   r*   r*   r*   r+   rs     s    

rs   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   )superrB   im_infoim_textim_sizeim_modeim_tile
im_paletteim_custom_mimetypeim_n_frames_seq_numrewind_statetext_memoryr@   	__class__r*   r+   rB   [  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   )rA   Zchunklenr6   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r0d| d}t|zt||d d  }W n tyL   t j	rId }n Y n t
jyW   d }Y nw || jd	< |S )
Nr~   ziCCP profile name %rr   zCompression method %sr   Unknown compression method z in iCCP chunkr   icc_profile)r   rh   r>   findr[   r\   rM   r7   r4   rK   r/   rc   r   )rA   rO   rP   r5   icomp_methodr6   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
y:   Y nw |d rDd| jd	< |d
 rNd}t||S )N   zTruncated IHDR chunkr   r   r   	      r   	interlace   zunknown filter category)r   rh   r>   rK   r4   rI   r   _MODESr   
im_rawmode	Exceptionr   rM   rA   rO   rP   r5   r6   r*   r*   r+   
chunk_IHDR  s$    
zPngStream.chunk_IHDRc                 C  sd   d| j v rd| j d || jfg}n| jd urd| j d< dd| j || jfg}|| _|| _d}t|)Nbboxr   Tdefault_imager   zimage data found)r   r   r   r   r   Zim_idatEOFError)rA   rO   rP   r   r6   r*   r*   r+   
chunk_IDAT  s   


zPngStream.chunk_IDATc                 C  s   d}t |)Nzend of PNG image)r   )rA   rO   rP   r6   r*   r*   r+   
chunk_IEND  s   zPngStream.chunk_IENDc                 C  s&   t | j|}| jdkrd|f| _|S )Nr   r   )r   rh   r>   r   r   rA   rO   rP   r5   r*   r*   r+   
chunk_PLTE  s   

zPngStream.chunk_PLTEc                 C  s   t | j|}| jdkr(t|r!|d}|dkr|| jd< |S || jd< |S | jdv r6t|| jd< |S | jdkrKt|t|dt|df| jd< |S )	Nr   r~   r   transparency)r   r   r   r   r   r   )	r   rh   r>   r   _simple_palettematchr   r   i16)rA   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@Zgamma)r   rh   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>      z'PngStream.chunk_cHRM.<locals>.<genexpr>Zchromaticity)r   rh   r>   rb   unpacklenru   r   )rA   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   rh   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r8|d |d f}|| jd< |S |dkrC||f| jd	< |S )
Nr   zTruncated pHYs chunkr   r   r   r   
F%u?dpiZaspect)r   rh   r>   rK   r4   rI   r   )	rA   rO   rP   r5   r6   pxpyZunitr   r*   r*   r+   
chunk_pHYs  s   
zPngStream.chunk_pHYsc                 C  s   t | j|}z
|dd\}}W n ty   |}d}Y nw |rD|dd}|dd}|dkr3|n|| j|< || j|< | t	| |S )Nr~   r       rz   r{   replaceexif)
r   rh   r>   splitr4   r^   r   r   r   r   )rA   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y   |}d}Y nw |r&|d }nd}|dkr6d| d}t|z
t|dd  }W n tyP   t jrMd}n Y n tj	y[   d}Y nw |r{|
dd}|
dd	}| | j|< | j|< | t| |S )
Nr~   r   r   r   r   z in zTXt chunkrz   r{   r   )r   rh   r>   r   r4   rM   r7   rK   r/   rc   r^   r   r   r   r   )rA   rO   rP   r5   r   r   r   r6   r*   r*   r+   
chunk_zTXt  s:   
zPngStream.chunk_zTXtc                 C  sl  t | j| }}z
|dd\}}W n ty   | Y S w t|dk r'|S |d |d |dd  }}}z|dd\}}	}
W n tyM   | Y S w |dkry|dkrwzt|
}
W n tyk   t jrj| Y S   tj	yv   | Y S w |S z|
dd}|
dd}|	
dd}	|

dd}
W n ty   | Y S w t|
||	 | j|< | j|< | t|
 |S )Nr~   r   r   r   rz   r{   r|   )r   rh   r>   r   r4   r   r7   rK   r/   rc   r^   r   rj   r   r   r   )rA   rO   rP   rr5   r   Zcfcmrm   Ztkr   r*   r*   r+   
chunk_iTXtA  sJ    zPngStream.chunk_iTXtc                 C  s    t | j|}d| | jd< |S )N   Exif  r   )r   rh   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 ur%d | _td |S t|}|dks1|dkr8t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   rh   r>   rK   r4   r   warningswarnrI   r   r   )rA   rO   rP   r5   r6   n_framesr*   r*   r+   
chunk_acTLo  s$   


zPngStream.chunk_acTLc                 C  s@  t | j|}|dk rt jr|S d}t|t|}| jd u r#|dks/| jd ur5| j|d kr5d}t||| _t|dt|d}}t|dt|d	}}	| j\}
}|| |
ks_|	| |kred
}t|||	|| |	| f| j	d< t
|dt
|d}}|dkrd}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   rh   r>   rK   r4   rI   r   rM   r   r   r   float)rA   rO   rP   r5   r6   seqwidthZheightr   r   Zim_wZim_hZ	delay_numZ	delay_denr*   r*   r+   
chunk_fcTL  s4   
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   rh   r>   r4   rI   r   rM   r   )rA   rO   rP   r5   r6   r   r*   r*   r+   
chunk_fdAT  s   zPngStream.chunk_fdAT)r$   r%   r&   rB   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  r;   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 n0 t
y:   Y n0 tya   td||| t| j|}|dd  r_| j||f Y nw | j|| q| jj| _| jj| _| jj| _d | _| jj| _| jj| _| jjpd| _| j dd	| _!| jj"r| jj"\}}t#$||| _%|d
kr|d | _&n|| _&| jjd urd	| _'| j(  | j&| _)| j* | _+| j!r|  jd7  _| ,d | jdk| _-d S )Nr   znot a PNG filer   T%r %s %s (unknown)r   r   r   F   fdATr   ).r   r>   rG   rM   _fp_PngImageFile__frameprivate_chunksr   pngr_   r   AttributeErrorr[   r\   r   rh   islowerrW   re   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)rA   r6   rN   rO   rP   r5   rawmoder9   r*   r*   r+   _open  sZ   






zPngImageFile._openc                 C  sD   | j d u r| jr| j}| | jd  |   | jr| | | j S )Nr   )r  r	  r   rF   r   load)rA   framer*   r*   r+   rp     s   

zPngImageFile.textc                 C  s^   | j du rd}t|| j | jd d d  | j  | j  | jr*| j   d| _ dS )zVerify PNG fileNz)verify must be called directly after openr   r   r   )r>   RuntimeErrorrF   r   r   ri   rT   Z_exclusive_fp)rA   r6   r*   r*   r+   ri     s   




zPngImageFile.verifyc                 C  s   |  |sd S || jk r| dd | j}t| jd |d D ]!}z| | W q ty@ } z| | d}t||d }~ww d S )Nr   Tr   zno more images in APNG file)Z_seek_checkr   r  ranger   rF   )rA   r  Z
last_framefrd   r6   r*   r*   r+   rF   #  s   



zPngImageFile.seekFc              	   C  s   |dkrT|r-| 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rdd| }t||   | jrt| j| j| j | j | _| j | _| jrt| j| j d| _d}	 | jd
 z
| j \}}}W n tjtfy   Y ndw |dkrd}t ||dkr|rd}t|d	}z
| j!||| W n? t"y   Y n8 t y   |dkr|d
8 }|r|| _Y n#t| j| Y n t#y   t$%d||| t| j| Y nw q|| _| jj| _| j
d| _| j
d| _| j
d| _| js6d}t || jd u rG| jt&j'krGt&j(| _| jt&j'kr_| j | _| )| j| j| _d S | jt&j(kr{t*j+,| j-| j.| _| )| j| j| _d S d | _d S )Nr   r   Fr   r   r   r   zcannot seek to frame Tr   rf   zNo more images in APNG file   fcTLzAPNG missing frame datar   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   rh   rG   rb   rc   rM   r   r_   UnicodeDecodeErrorr   r[   r\   r#   r)   r(   _cropr   corefillmodesize)rA   r  r   r6   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rG| jd | j \}}}|dvr!| j||| dS |dkr?z
| j||| W n	 ty8   Y nw |d | _ n|| _ | j dks|dkrO| j }nt|| j }| j | | _ | j|S )zinternal: read more image datar   r   )   IDATs   DDATr   r   r   )r  r>   rG   r   rY   r_   r   min)rA   Z
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y)   Y nw |dkr/n|dkrB| jrBd| _| j	||| noz
| j
||| W nc tyU   Y n\ ty   |dkrc|d8 }z	t| j| W n ty } ztjr~W Y d}~Y n3|d}~ww Y n) ty   td||| t| j|}|d	d
  r| j||df Y nw q| jj| _| js| j  d| _dS | jr| jtjkr| | j| j }| jj!dkrd| j"v r|#d| j"d }n|$d}| j%|| j | | j| _| j&r
d| _&dS dS dS dS )z%internal: finished reading image datar   Tr   rf   r  r   Nr   r   r   r   r   r   )'r  r>   rG   r   rb   rc   rM   r	  r  rY   r_   r  r   r   rh   rg   rK   r   r[   r\   r   r   rW   r   r  rT   r  r  r,   r.   r  r  r  r  r   Zconvert_transparentconvertr  r  )rA   rN   rO   rP   rd   r5   updatedmaskr*   r*   r+   load_end  sp   

#





zPngImageFile.load_endc                 C  s6   d| j vr	|   d| j vrd| j v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 vr	|   t  S )Nr   )r   r  r   r(  rQ   r   r*   r+   r(    s   

zPngImageFile.getexifc                 C  s   d| j v 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.getxmpr   )r$   r%   r&   formatZformat_descriptionr  propertyrp   ri   rF   r  rH   r   r#  r'  r)  r(  r*  r   r*   r*   r   r+   r     s     C

^	!9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   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   r9   re   r*   r*   r+   putchunk(  s
   

r4  c                   @     e Zd Zdd Zdd ZdS )_idatc                 C  s   || _ || _d S r=   )r>   rw   )rA   r>   rw   r*   r*   r+   rB   6  rC   z_idat.__init__c                 C  s   |  | jd| d S )Nr!  )rw   r>   rA   r9   r*   r*   r+   r1  :     z_idat.writeNr$   r%   r&   rB   r1  r*   r*   r*   r+   r6  3  s    r6  c                   @  r5  )_fdatc                 C  s   || _ || _|| _d S r=   )r>   rw   r   )rA   r>   rw   r   r*   r*   r+   rB   A  s   
z_fdat.__init__c                 C  s*   |  | jdt| j| |  jd7  _d S )Nr   r   )rw   r>   r2  r   r7  r*   r*   r+   r1  F  s   z_fdat.writeNr9  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}	|r:t|}
nt| g|}
g }d}|
D ]}t	
|D ]}|j|krZ| }n||}| j  }t|ttfrq|| |d< t|ttfr~|| |d< t|	ttfr|	| |d< |d7 }|r#|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}|s"||dkr"||dkr"|d d  |d|7  < qNnd }d|vr.||d< ||||d qNqGt|dkrI|sI|d d
 S ||dtt|t| |rv| j|krd| |} t | t!||dd| j d|fg d}t"|D ]\}}|d
 }|d sd|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|st |t!||dd|j d|fg q|t'|||}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   listru   r)   r   r(   r   r  r  r  Zcropr  r   Zsubtract_moduloZgetbboxrW   r2  r   _saver6  	enumerateintroundo16r   r:  r   )r  r>   rw   r
  r   append_imagesr   r   r   r   r?  Z	im_framesZframe_countim_seqim_framer<  ZpreviousZprev_disposalZ
prev_blendZbase_imr  r   Zdeltar   r  Z
frame_datar  Zframe_durationZframe_disposalZframe_blendZfdat_chunksr*   r*   r+   _write_multiple_framesK  s   







5

$






rJ  c                 C  s   t | ||dd d S )NT)save_all)rB  )r  r>   filenamer*   r*   r+   	_save_all  r8  rM  Fc           $   
     s&  |rU| j d| jd}t }t  | j dg }t| g|D ]}t|D ]}	||	j	  |	j
 q(q!dD ]}
|
|v rB nq:| }
t fddtdD }n| j
}| j	}
|
dkrd| j v rotd	| j d > d
}n| jrttt| j d	 d d
d	}nd
}|dkr|dkrd	}n	|dkrd}nd}|
 d| }
| j dd| j dd| j dd| j ddf| _zt|
 \}}
W n ty } zd|
 d}t||d }~ww |t ||dt|d t|d	 |
ddd g d}| j d| jd}|rd}|d t| }||d| |d  | j d!}|rog d"}|jD ]B}|d d \}}||v rH|| |||| q,||v rU|||| q,|d	d  rm|dd }|sm|||| q,| j	dkr|d }| j d#d | }t||k r|d7 }t||k s||d$| | j d%| jd%d }|s|dkr!| j	dkr|}t!|t"r||d&|d |  nztdtd'|}d(| d }||d&|d |  na| j	d)v rtdtd*|}||d&t#| nJ| j	d#kr|\}} }!||d&t#|t#|  t#|!  n.d%| j v r d+}t|n!| j	dkrB| j$ d,krB| j d,d-}|}||d&|d |  | j d.}"|"rg||d/tt%|"d d0 d1 tt%|"d	 d0 d1 d2 |rd3d4g}|jD ]}|d d \}}||v r|| |||| qq| j d5}#|#rt!|#t&j'r|#(d6}#|#)d7r|#d8d  }#||d9|# |rt*| |||||} | rt+,| t-||d:d;| j
 d|fg |r|jD ]#}|d d \}}|d	d  r|dd }|r|||| q||d<d t.|d=r|/  d S d S )>Nr   rG  )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   Z
frame_sizer   r*   r+   r     r   z"_save.<locals>.<genexpr>.<genexpr>N)max)r   ZsizesrN  r+   r     s   $ z_save.<locals>.<genexpr>r   r   bitsr      r    r   r   ;optimizeFZcompress_levelr;  Zcompress_typeZ
dictionaryr   zcannot write mode z as PNGs   IHDRr   r~   )s   cHRMs   gAMAs   sBIT   sRGBs   tIMEr   s   ICC Profiler   s   iCCPrU  Zpnginfo)s   sPLTr}   r   r   r   s   PLTEr   s   tRNS      )r   r   r/  r   i  z%cannot use transparency for this moder   Ar   s   pHYsr   g      ?   s   bKGDs   hISTr   r   r   r!   s   eXIfr   r   rf   flush)0r<  r  r   setr>  r?  r	   r@  rx   r  r  rE   ru   r  r"  r  rO  r   ZgetdataZencoderconfig	_OUTMODESKeyErrorrg   r1  r   r2  r/   r   removert   r   r  Z
getpaletter   r   rF  ZgetpalettemoderD  r   ZExiftobytes
startswithrJ  r   rB  r6  hasattrrZ  )$r  r>   rL  rw   rK  r   ZmodesrG  rH  rI  r  r  ZcolorsrQ  r
  rd   r6   rt   Ziccnamer9   r   Zchunks_multiple_allowedZ
info_chunkrN   rv   Zpalette_byte_numberZpalette_bytesr   Zalpha_bytesZalphaZredZgreenZbluer   r   r*   rP  r+   rB    s,  
$









"



$
rB  c                 K  sD   G dd d}dd }| }z|| _ t| |d| W | ` |jS | ` w )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*   r7  r*   r*   r+   r1    rS   z"getchunks.<locals>.collector.writec                 S  s   | j | d S r=   )r9   rW   )rA   rw   r*   r*   r+   rW     r;   z#getchunks.<locals>.collector.appendN)r$   r%   r&   r9   r1  rW   r*   r*   r*   r+   	collector  s    rc  c                 W  s0   d |}tt|t|}| |||f d S )Nr   )r0  r2  r:   rW   r3  r*   r*   r+   rW     s   
zgetchunks.<locals>.appendN)r<  rB  r9   )r  paramsrc  rW   r>   r*   r*   r+   	getchunks  s   	re  z.pngz.apngz	image/png)r   )?Z
__future__r   r>  Zloggingrerb   r   r/   enumr   ry   r   r   r   r   r	   Z_binaryr
   r   r   rI   r   r   rF  r   r2  Z	getLoggerr$   r[   compiler   rJ   r   r   r   Z	SAFEBLOCKr2   r   r#   r,   r7   r:   r<   rk   rj   rs   r   r   r   r\  r4  r6  r:  rJ  rM  rB  re  Zregister_openr+  Zregister_saveZregister_save_allZregister_extensionsZregister_mimer*   r*   r*   r+   <module>   s    


	YT  \  \  I