U
    Žbد                     @   s6  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&d$d% Z'dTd&d'Z(G d(d) d)Z)G d*d+ d+e*Z+G d,d- d-Z,G d.d/ d/e)Z-d0d1 Z.G d2d3 d3ejZ/d4d5d6d7d8d9d:d:d;d<d=d>d?d@dAZ0dBdC Z1G dDdE dEZ2G dFdG dGZ3dHdI Z4dJdK Z5e1dLfdMdNZ6dOdP Z7e	8e/j9e/e. e	:e/j9e6 e	;e/j9e5 e	<e/j9dQdRg e	=e/j9dS dS )U    N)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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-_wxctax1/PIL/PngImagePlugin.pyr"   b   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+   w   s   r+   c                 C   s   d}t dtdi D ]j\}}| |r| t|d  } | |jkrtj||  d | d |j d |  d t	dd	 ||    S qt
d
t d|  dd S )Nz:deprecated and will be removed in Pillow 10 (2023-07-01). ZAPNG_DISPOSE_ZAPNG_BLEND_z is zUse .z	 instead.r   )
stacklevelzmodule 'z' has no attribute '')r"   r+   items
startswithlen__members__warningswarnr#   DeprecationWarningAttributeError)name
deprecatedenumprefixr)   r)   r*   __getattr__   s8    

	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	plaintextr)   r)   r*   _safe_zlib_decompress   s
    rF   c                 C   s   t | |d@ S )Nl    )r>   crc32)dataseedr)   r)   r*   _crc32   s    rJ   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selfrM   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 ))rN   poprM   seekreadtelli32is_cidr   LOAD_TRUNCATED_IMAGESSyntaxErrorrepr)rP   cidposlengthrD   r)   r)   r*   rU      s    
zChunkStream.readc                 C   s   | S rL   r)   rP   r)   r)   r*   	__enter__   s    zChunkStream.__enter__c                 G   s   |    d S rL   )close)rP   argsr)   r)   r*   __exit__   s    zChunkStream.__exit__c                 C   s   d  | _  | _| _d S rL   )rN   crcrM   r_   r)   r)   r*   ra      s    zChunkStream.closec                 C   s   | j |||f d S rL   )rN   appendrP   r\   r]   r^   r)   r)   r*   push   s    zChunkStream.pushc                 C   s*   t d||| t| d|d ||S )z"Call the appropriate chunk handlerzSTREAM %r %s %sZchunk_ascii)loggerdebuggetattrdecoderf   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rbtdt| dW n: t	j
k
r } ztdt| d|W 5 d}~X Y nX dS )	zRead and verify checksumr      r   Nr   z(broken PNG file (bad header checksum in rR   z(broken PNG file (incomplete checksum in )r   rY   crc_skiprJ   rW   rM   rU   rZ   r[   structerror)rP   r\   rH   Zcrc1Zcrc2er)   r)   r*   rd      s     zChunkStream.crcc                 C   s   | j d dS )z3Read checksum.  Used if the C module is not presentr   N)rM   rU   )rP   r\   rH   r)   r)   r*   ro      s    zChunkStream.crc_skip   IENDc              
   C   sv   g }z|   \}}}W n. tjk
rD } ztd|W 5 d }~X Y nX ||krPqr| |t| j| || q|S )Nztruncated PNG file)	rU   rp   rq   OSErrorrd   r   
_safe_readrM   re   )rP   ZendchunkZcidsr\   r]   r^   rr   r)   r)   r*   verify   s    zChunkStream.verifyN)rs   )r#   r$   r%   rQ   rU   r`   rc   ra   rg   rm   rd   ro   rv   r)   r)   r)   r*   rK      s   rK   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textrz   r{   rP   r)   r)   r*   ry     s    	ziTXt.__new__)NN)r#   r$   r%   __doc__staticmethodry   r)   r)   r)   r*   rw     s   rw   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 rL   )chunksr_   r)   r)   r*   rQ   $  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)re   r   tuple)rP   r\   rH   
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encoder   r>   compress)rP   keyvaluerz   r{   zipr)   r)   r*   add_itxt6  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   r   r      zTXt        tEXtr   N)r   rw   r   rz   r{   r   r   UnicodeErrorr   r>   r   )rP   r   r   r   r)   r)   r*   add_textR  s    	


zPngInfo.add_textN)F)r   r   F)F)r#   r$   r%   r~   rQ   r   r   r   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   )superrQ   im_infoim_textim_sizeim_modeim_tile
im_paletteim_custom_mimetypeim_n_frames_seq_numrewind_statetext_memoryrO   	__class__r)   r*   rQ   s  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_MEMORYrC   )rP   Zchunklenr)   r)   r*   check_text_memory  s
    
zPngStream.check_text_memoryc                 C   s   | j  | j| jd| _d S )N)infotileseq_num)r   copyr   r   r   r_   r)   r)   r*   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*   rewind  s    zPngStream.rewindc                 C   s   t | j|}|d}td|d |  td||  || }|dkr\td| dzt||d d  }W n: tk
r   t j	rd }n Y n t
jk
r   d }Y nX || jd< |S )	Nr   ziCCP profile name %rzCompression method %sr   Unknown compression method z in iCCP chunkr   icc_profile)r   ru   rM   findri   rj   rZ   rF   rC   rY   r>   rq   r   )rP   r]   r^   rD   icomp_methodr   r)   r)   r*   
chunk_iCCP  s"    


zPngStream.chunk_iCCPc                 C   s   t | j|}t|dt|df| _z 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   ru   rM   rW   r   _MODESr   
im_rawmode	Exceptionr   rZ   rP   r]   r^   rD   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bboxr   Tdefault_imager   )r   r   r   r   r   Zim_idatEOFError)rP   r]   r^   r   r)   r)   r*   
chunk_IDAT  s    


zPngStream.chunk_IDATc                 C   s   t d S rL   )r   )rP   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   ru   rM   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   r   r   transparencyr   r   r   r   r   r   )	r   ru   rM   r   _simple_palettematchr   r   i16)rP   r]   r^   rD   r   r)   r)   r*   
chunk_tRNS  s    




 zPngStream.chunk_tRNSc                 C   s$   t | j|}t|d | jd< |S )N     j@gammar   ru   rM   rW   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   ru   rM   rp   unpackr3   r   r   )rP   r]   r^   rD   Zraw_valsr)   r)   r*   
chunk_cHRM  s    zPngStream.chunk_cHRMc                 C   s    t | j|}|d | jd< |S )Nr   Zsrgbr   ru   rM   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   
F%u?dpiZaspectr   )rP   r]   r^   rD   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       r   r   replaceexif)
r   ru   rM   splitrC   rl   r   r   r   r3   )rP   r]   r^   rD   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rjtd| dzt|dd  }W n: tk
r   t jrd}n Y n tj	k
r   d}Y nX |r|
dd}|
dd	}| | j|< | j|< | t| |S )
Nr   r   r   r   r   z in zTXt chunkr   r   r   )r   ru   rM   r   rC   rZ   rF   rY   r>   rq   rl   r   r   r   r3   )rP   r]   r^   rD   r   r   r   r)   r)   r*   
chunk_zTXt,  s2    


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   r   r   r   )r   ru   rM   r   rC   r3   rF   rY   r>   rq   rl   r   rw   r   r   r   )rP   r]   r^   rrD   r   cfcmrz   Ztkr   r)   r)   r*   
chunk_iTXtN  sB    
 



zPngStream.chunk_iTXtc                 C   s    t | j|}d| | jd< |S )N   Exif  r   r   r   r)   r)   r*   
chunk_eXIfw  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   ru   rM   r   r5   r6   rW   r   r   )rP   r]   r^   rD   n_framesr)   r)   r*   
chunk_acTL}  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   #APNG contains frame sequence errorsr   r   r   r   zAPNG contains invalid framesr         d     duration   disposal   blend)
r   ru   rM   rW   r   rZ   r   r   r   float)rP   r]   r^   rD   seqwidthheightr   r   Zim_wZim_hZ	delay_numZ	delay_denr)   r)   r*   
chunk_fcTL  s,    
zPngStream.chunk_fcTLc                 C   sF   t | jd}t|}| j|d kr,td|| _| |d |d S )Nr   r   r   )r   ru   rM   rW   r   rZ   r   )rP   r]   r^   rD   r   r)   r)   r*   
chunk_fdAT  s    zPngStream.chunk_fdAT)r#   r$   r%   rQ   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   r  s*   	")r   c                 C   s   | d d t kS )Nr   )_MAGIC)r<   r)   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| _| j \}}}z| j	|||}W nh t
k
rt   Y qY nR tk
r   td||| t| j|}|dd  r| j||f Y nX | j|| q8| jj| _| jj| _| jj| _d | _| jj| _| jj| _| jjpd| _| j dd| _!| jj"rR| jj"\}}t#$||| _%|d	krh|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   rM   rU   rZ   _PngImageFile__fp_PngImageFile__frameprivate_chunksr   pngrm   r   r8   ri   rj   r   ru   islowerre   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_idatrV   _PngImageFile__rewind_seekis_animated)rP   r\   r]   r^   rD   rawmoderH   r)   r)   r*   _open  sP    	








zPngImageFile._openc                 C   sD   | j d kr>| jr&| j}| | jd  |   | jr>| | | j S )Nr   )r  r  r  rT   r   load)rP   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   )rM   RuntimeErrorrT   r   r  rv   ra   Z_exclusive_fpr_   r)   r)   r*   rv     s    



zPngImageFile.verifyc                 C   s   |  |sd S || jk r$| dd | j}t| jd |d D ]J}z| | W q> tk
r } z| | td|W 5 d }~X Y q>X q>d S )Nr   Tr   zno more images in APNG file)Z_seek_checkr  r  ranger   rT   )rP   r  Z
last_framefrr   r)   r)   r*   rT     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}| jd	 z| j \}}}W n" tjtfk
r^   Y q<Y nX |d
krrt d|dkr|rtdd}z| j!||| W n t"k
r   Y q<Y nz t k
r   |dkr|d	8 }|r|| _Y q<t| j| Y n4 t#k
r6   t$%d||| t| j| Y nX q|| _| jj| _| j
d| _| j
d| _| j
d| _| jst | 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   rs   zNo more images in APNG file   fcTLzAPNG missing frame dataTr  r  )/r  rT   r  r  r   r  r  impyaccessr   r   r   r   rM   _prev_imdisposer  r   Z
dispose_opblend_opdispose_extentr  rC   r  paster   r   ru   rU   rp   rq   rZ   r   rm   UnicodeDecodeErrorr8   ri   rj   r"   r(   r'   _cropr   corefillr	  size)rP   r  r   Zframe_startr\   r]   r^   r)   r)   r*   r  -  s    








zPngImageFile._seekc                 C   s   | j S rL   )r  r_   r)   r)   r*   rV     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)   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(  rM   rU   r  rg   rm   r   min)rP   
read_bytesr\   r]   r^   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 qHY nX |dkrhqHn(|dkr| jrd| _| j	||| qHz| j
||| W q tk
r   Y qHY q tk
r   |dkr|d8 }t| j| Y q tk
rD   td||| t| j|}|dd  r@| j||d	f Y qX q| jj| _| jsl| j  d
| _nT| jr| jtjkr| | j| j}| j|| j| d | j| _| j!rd
| _!d
S )z%internal: finished reading image datar   r   rs   r  r  r  r   r   TNr   )"r(  rM   rU   r  rp   rq   rZ   r  r  rg   rm   r#  r   r   ru   r8   ri   rj   r  r  re   r   r  ra   r  r   r+   r-   r$  r  r!  r"  convertr  )rP   r\   r]   r^   rD   updatedr)   r)   r*   load_end  sP    



  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_dictr_   r)   r)   r*   _getexif  s
    
zPngImageFile._getexifc                    s   d| j kr|   t  S )Nr   )r   r  r   r1  r_   r   r)   r*   r1    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_getxmpr_   r)   r)   r*   getxmp  s    	zPngImageFile.getxmpc                 C   sB   z4z| j | jkr| j   W n tk
r0   Y nX W 5 d | _ X d S rL   )r  rM   ra   r8   r_   r)   r)   r*   
_close__fp  s    
zPngImageFile._close__fp)F)r#   r$   r%   formatformat_descriptionr  propertyr}   rv   rT   r  rV   r)  r-  r0  r2  r1  r3  r4  r   r)   r)   r   r*   r    s    D

Z	!/r  )r       )L;1r8  )r   s    )r   s    )r   s    )r   s   )r   s    )r   s   )r   s   )r   s   )r   s   )r   s   )r   s   )r   r9  r   r   r   r   r   zI;16r   r   r   r   r   r   c                 G   sJ   d |}| tt||  | | t|t|}| t| dS )z'Write a PNG chunk (including CRC field)r   N)joinwriteo32r3   rJ   rM   r\   rH   rd   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 rL   )rM   r   )rP   rM   r   r)   r)   r*   rQ   +  s    z_idat.__init__c                 C   s   |  | jd| d S )Nr*  )r   rM   rP   rH   r)   r)   r*   r;  /  s    z_idat.writeNr#   r$   r%   rQ   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 rL   )rM   r   r   )rP   rM   r   r   r)   r)   r*   rQ   6  s    z_fdat.__init__c                 C   s*   |  | jdt| j| |  jd7  _d S )Nr  r   )r   rM   r<  r   r@  r)   r)   r*   r;  ;  s    z_fdat.writeNrA  r)   r)   r)   r*   rB  3  s   rB  c                 C   sN  | j d| jd}| j d| jdd}| j d| jdd}| j d| jdtj}| j d| jdtj}|rt| j dg }	nt| g| j dg }	g }
d}|	D ]}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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r2|
d d }n|d }t|d|d}| }|s||dkr||dkrt|ttfr|d d  |d 7  < qnd }|
|||d qq||dtt|
t| |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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   Zappend_imagesr   )r  r   encoderinfor   r  r   )r   r   r   r   r   r   r   )r  r   rD  s   acTLr   r  r   )*rD  r  r   r"   r&   r+   r,   	itertoolschainr   Iteratorr   r	  r.  r  r   listr   r(   r3   r'   r   r%  r&  r'  Zcropr"  r   Zsubtract_moduloZgetbboxre   r<  r   _saver?  	enumerateintroundo16r   rB  r   )r  rM   r   r  r   r   r   r   r   rG  Z	im_framesZframe_countZim_seqZim_framerD  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_frames@  s    


 
$





rQ  c                 C   s   t | ||dd d S )NT)save_all)rJ  )r  rM   filenamer)   r)   r*   	_save_all  s    rT  Fc              
   C   sx  | 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| _zt	| \}}W n6 t
k
r }	 ztd| d|	W 5 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}|r@d d!d"d#g}|jD ]}|d d \}}||
kr|
| |||| nH||kr|||| n0|dd  r|dd }|s|||| q| j dkr|d }| jd$d | }t||k r|d7 }qh||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rHt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 |rnd4d5g}
|jD ]6}|d d \}}||
kr6|
| |||| q6| jd6| jd6}|rt|tjr|d7}| d8r|d9d  }||d:| |rt!| ||| n$t"#| t$||d;d<| j d|fg |rT|jD ]F}|d d \}}|dd  r|dd }|r|||| q||d=d t%|d>rt|&  d S )?Nr   bitsr      r   r   r   r   ;optimizeFZcompress_levelrC  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   i  z%cannot use transparency for this moder   Ar   s   pHYsr   g      ?   s   bKGDs   hISTr   r   r   r    s   eXIfr   r   rs   flush)'r	  rD  r+  r  maxr3   Zgetdatar  Zencoderconfig	_OUTMODESKeyErrorrt   r;  r   r<  r'  r   r>   r   remover   r  r  Z
getpaletter   r   rN  ZgetpalettemoderL  r   ZExiftobytesr2   rQ  r   rJ  r?  hasattrr_  )r  rM   rS  r   rR  r	  colorsrU  r  rr   r   Ziccr9   rH   r   Zchunks_multiple_allowedZ
info_chunkr\   r   Zpalette_byte_numberZpalette_bytesr   Zalpha_bytesalphaZredZgreenZbluer   r   r)   r)   r*   rJ    s    
$$






"




$
rJ  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 rL   r)   r@  r)   r)   r*   r;  y  s    z"getchunks.<locals>.collector.writec                 S   s   | j | d S rL   )rH   re   )rP   r   r)   r)   r*   re   |  s    z#getchunks.<locals>.collector.appendN)r#   r$   r%   rH   r;  re   r)   r)   r)   r*   	collectorv  s   rh  c                 W   s0   d |}tt|t|}| |||f d S )Nr   )r:  r<  rJ   re   r=  r)   r)   r*   re     s    
zgetchunks.<locals>.appendN)rD  rJ  rH   )r  paramsrh  re   rM   r)   r)   r*   	getchunkss  s    	rj  z.pngz.apngz	image/png)r   )>rF  loggingrerp   r5   r>   r;   r   r   r   r   r   r   r   _binaryr	   r   r
   rW   r   r   rN  r   r<  	getLoggerr#   ri   compiler   rX   r   r   r   Z	SAFEBLOCKrA   r   r"   r+   r=   rF   rJ   rK   rx   rw   r   r   r   r  ra  r>  r?  rB  rQ  rT  rJ  rj  Zregister_openr5  Zregister_saveZregister_save_allZregister_extensionsZregister_mimer)   r)   r)   r*   <module>"   s   


\T  ?  W} 3