U
    Žb                     @   s  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 G dd	 d	eZejZd
d ZG dd de	j	ZddddZdd Zdd Zdd Zdd Zdd Zd9ddZdd Zd d! Zd"d# Z dZ!d$d% Z"d&d' Z#d(d) Z$d*d+ Z%d,d- Z&d.d/ Z'd0d1 Z(d:d2d3Z)d;d5d6Z*e+ej,ee e-ej,e e.ej,e e/ej,d7 e0ej,d8 dS )<    N)IntEnum   )Image
ImageChops	ImageFileImagePaletteImageSequence)i16le)o8)o16lec                   @   s   e Zd ZdZdZdZdZdS )LoadingStrategyz.. versionadded:: 9.1.0r   r      N)__name__
__module____qualname____doc__RGB_AFTER_FIRST RGB_AFTER_DIFFERENT_PALETTE_ONLY
RGB_ALWAYS r   r   6/tmp/pip-unpacked-wheel-_wxctax1/PIL/GifImagePlugin.pyr   '   s   r   c                 C   s   | d d dkS )N   )s   GIF87as   GIF89ar   )prefixr   r   r   _accept6   s    r   c                       s   e Zd ZdZdZdZdZdd Zdd Zd	d
 Z	e
dd Ze
dd Zdd ZdddZ fddZdd Zdd Zdd Z  ZS )GifImageFileZGIFzCompuserve GIFFNc                 C   s,   | j d}|r(|d r(| j |d S d S )Nr   r   )fpread)selfsr   r   r   dataG   s    zGifImageFile.datac                 C   sX   t dt|dD ]B}|d ||   krJ||d    krJ||d  ksn  dS qdS )Nr      r   r   TF)rangelen)r   pir   r   r   _is_palette_neededM   s    8zGifImageFile._is_palette_neededc                 C   s   | j d}t|std|d d | jd< t|dt|df| _g | _|d }|d@ d }|d	@ r|d
 | jd< | j d|> }| |rt	
d|}| | _| _| j | _| j  | _d | _d | _| d d S )N   znot a GIF filer   version   
      r         
backgroundr    RGBr   )r   r   r   SyntaxErrorinfoi16_sizetiler%   r   rawglobal_palettepalette_GifImageFile__fptell_GifImageFile__rewind	_n_frames_is_animated_seek)r   r   flagsbitsr#   r   r   r   _openS   s&    
zGifImageFile._openc                 C   s`   | j d krZ|  }z| |  d d qW n" tk
rN   |  d | _ Y nX | | | j S )Nr   F)r:   r8   r<   EOFErrorseekr   currentr   r   r   n_frameso   s    

zGifImageFile.n_framesc                 C   sx   | j d krr| jd k	r"| jdk| _ nP|  }|r6d| _ n<z| dd d| _ W n tk
rf   d| _ Y nX | | | j S )Nr   TF)r;   r:   r8   r<   r@   rA   rB   r   r   r   is_animated{   s    



zGifImageFile.is_animatedc                 C   s   |  |sd S || jk r(d | _| d | j}t| jd |d D ]J}z| | W qB tk
r } z| | td|W 5 d }~X Y qBX qBd S )Nr   r   zno more images in GIF file)Z_seek_check_GifImageFile__frameimr<   r!   r@   rA   )r   frameZ
last_framefer   r   r   rA      s    



zGifImageFile.seekTc                    sp  |dkr0d _ d  _d _ j j d _n jrB|rB   | jd kr^t	d|  j _
 j r j
 j    rqzd _  j
d}|r|dkrt| _g  _d }i }d }d }d }|sֈ j
d}|r|dkrq:nJ|dkr" j
d}  }	|d dkr`|	d }
|
d@ r0|	d }t|	dd	 |d
< d|
@ }|d? }|r| _n|d dkr|	rd|kr|d  |	7  < n|	|d<   }	qnd }qnd|d dkr|	 j
 f|d< |	d d dkr  }	t|	dkr|	d dkrt|	d|d<   r4qn|dkr4 j
d}t|dt|d }}|t|d |t|d  }}| jd ks| jd kr|rt| jd t| jd f _||||f}|d }
|
d@ dk}|
d@ r|
d@ d } j
d|> } |rtd|} j
dd } j
  _ q:n d }q|d krHt|sRd S  jrl j j j |pv j _|dkrֈ jrttjkrdnd _nd _|sΈ jrddl m } | j}| _!n| _" jdkr^ttj#ks|r^d  _$d  j%krD j& j%d  d  j'd!t(j)j* _d! _ j%d = nd _ j'dt(j)j* _ fd"d#}| _zJ jdk rd  _n0 jdkr2 j\}}}}|| || f}t(+| d} j%,d |}|d k	r jd$krd!}||d% }n& j%,d&d} jd$krd}||}t(j-.||| _n jd k	rR / j j _nh|d k	r j\}}}}|| || f}t(+| d}|} jd$krd!}||d% }t(j-.||| _W n t0k
r   Y nX |d k	r2d}|d k	r|dkr| j%d < n jd$kr|}d'||||f j |||ffg _d(D ]4}||krT||  j%|< n| j%kr6 j%|= q6d S ))Nr   r   zcannot seek to frame    ;   !   r    r)   duration   r      comment   	extensionr,      NETSCAPE2.0loop   ,	      r   r(   @   r+   r*   r.   PL)copytransparencyRGBAc                    s6    j r(t j j| d | d d  } n
| | | f} | S )Nr    )_frame_palettetupler6   )colorr   r   r   _rgbC  s    "
z GifImageFile._seek.<locals>._rgbr.   r_   )r   r-   gif)rO   rR   rT   rV   )1Z_GifImageFile__offsetZdisposerF   r7   rA   r9   Zdisposal_methodr3   load
ValueErrorr   r   r   r@   r1   r8   r"   sizemaxr2   r%   r   r4   rG   pastedispose_extentr5   r`   LOADING_STRATEGYr   r   moder]   r6   _frame_transparencyr   Zpyaccessr0   putpalettealphaconvertr   DitherFLOYDSTEINBERGZ_decompression_bomb_checkgetcorefill_cropAttributeError)r   rH   Zupdate_imager   r6   r0   Zframe_transparency	interlaceZframe_dispose_extentblockr=   Zdispose_bitsZx0Zy0x1y1r>   r#   r]   rd   Zdispose_sizeZdispose_moderb   r^   kr   rc   r   r<      s<   





&"













	
zGifImageFile._seekc                    s   | j r
dnd}d | _| jdkrDd| jkrtj|| j| jd | _nL| j	dkr| j| _| j rtjd| j| j
ppd| _| jj| j    nd | _|| _	d | _ t   d S )Nr[   r\   r   r^   re   )r`   _prev_imrF   r0   r   ru   rv   ri   rG   rn   ro   
putpalettegetdatasuperload_prepare)r   Z	temp_mode	__class__r   r   r     s$    

  
zGifImageFile.load_preparec                 C   s   | j dkr<| jdkr8ttjkr8d| _| jdtjj	| _d S | jdkr| j
r| jd k	rt| j| jd | jd}q| jd}n| j
sd S | j}| || j}| j
| _| jj| _|jdkr| j|| j| n| j|| j d S )Nr   r[   r.   r_   )rF   rn   rm   r   r   rG   rq   r   rr   rs   r~   ro   rp   rw   rl   rk   )r   Zframe_imr   r   r   load_end  s&    



zGifImageFile.load_endc                 C   s   | j S N)rF   rc   r   r   r   r8     s    zGifImageFile.tellc                 C   sB   z4z| j | jkr| j   W n tk
r0   Y nX W 5 d | _ X d S r   )r7   r   closerx   rc   r   r   r   
_close__fp  s    
zGifImageFile._close__fp)T)r   r   r   formatformat_descriptionZ!_close_exclusive_fp_after_loadingr5   r   r%   r?   propertyrD   rE   rA   r<   r   r   r8   r   __classcell__r   r   r   r   r   ?   s$   


 rr   r\   r[   )1r\   r[   c                 C   s   | j tkr|   | S t| j dkr|| jdtjjd} | jj dkrx| jj	
 D ]&}|d dkrP| jj	| | jd<  qxqP| S | dS )	a  
    Takes an image (or frame), returns an image in a mode that is appropriate
    for saving in a Gif.

    It may return the original image, or it may return an image converted to
    palette or 'L' mode.

    :param im: Image object
    :returns: Image object
    r.   r[   r6   r_   r    r   r^   r\   )rn   RAWMODErg   r   Zgetmodebaserq   ZPaletteZADAPTIVEr6   colorskeysr0   )rG   Zrgbar   r   r   _normalize_mode  s    
r   c           	   	   C   sp  d}|r>t |tttfr(t|dd }t |tjr>t|j}| jdkrb|s| jddd }n*|s|tdd t	dD }tjd|d| _|rDg }t	dt
|d	D ]L}t|||d	  }z| jj| }W n tk
r   d}Y nX || qt|D ]:\}}|dkrt	t
|D ]}||kr|||<  qqq| |} n t| |}|dk	rd| ||S || j_| S )
at  
    Normalizes the palette for image.
      - Sets the palette to the incoming palette, if provided.
      - Ensures that there's a palette for L mode images
      - Optimizes the palette if necessary/desired.

    :param im: Image object
    :param palette: bytes object containing the source palette, or ....
    :param info: encoderinfo
    :returns: Image object
    Ni   r[   r.   c                 s   s   | ]}|d  V  qdS )r    Nr   ).0r$   r   r   r   	<genexpr>  s     z%_normalize_palette.<locals>.<genexpr>r   r   r    )
isinstancebytes	bytearraylistr   r6   rn   rG   Z
getpaletter!   r"   ra   r   KeyErrorappend	enumerateZremap_palette_get_optimize)	rG   r6   r0   Zsource_paletteused_palette_colorsr$   Zsource_colorindexjr   r   r   _normalize_palette  sB    






r   c              	   C   s   t | }|j D ]\}}| j|| qt||| j}t|| jD ]}|| qDd}t| rh|dB }t	|| d| dt| f|_
t||dd| j dt|j fg |d d S )Nr   rZ   r   r   r(   rf       )r   r0   itemsencoderinfo
setdefaultr   _get_global_headerwriteget_interlace_write_local_headerZencoderconfigr   _saveri   r   rn   )rG   r   r6   Zim_outr}   vr   r=   r   r   r   _write_single_frame  s    $r   c              	   C   s  | j d| jd}| j d| jd}g }d}d }t| g| j dg D ]}t|D ]}	t|	 }	|dkr|	j	 D ]\}
}| j 
|
| qt|	|| j }	| j  }t|ttfr|| |d< t|ttfr|| |d< |d7 }|r|d }|ddkrd|d kr^| j d| jdd	}t|	|}td
|	j|}||d d j |}n|d }t|	t|krt|	|}nt|	d|d}| }|s|r`|d d  |d 7  < q`nd }||	||d q`qPt|dkr|D ]}|d }	|d s:t|	|d D ]}|| q"d}n0|sLd|d d< |	|d }	|d d d }t||	||d  qdS d| j krt| j d ttfrt | j d | j d< d S )NrO   disposalr   Zappend_imagesr   rK   r   r^   )r   r   r   r[   rG   r.   r   )rG   bboxr   r   r   Tinclude_color_table)!r   rt   r0   	itertoolschainr   Iteratorr   r]   r   r   r   r   r   ra   _get_backgroundr   newri   r   r6   _get_palette_bytesr   Zsubtract_modulorq   Zgetbboxr   r"   r   r   Zcrop_write_frame_datasum)rG   r   r6   rO   r   Z	im_framesZframe_countZbackground_imZ
imSequenceim_framer}   r   r   previousrb   r-   Zbase_imdeltar   Z
frame_datar   offsetr   r   r   _write_multiple_frames2  s|    

 
 
 r   c                 C   s   t | ||dd d S )NT)save_all)r   )rG   r   filenamer   r   r   	_save_all  s    r   Fc                 C   s   d| j ksd| jkr,| j d| jd}nd }| j dd| j d< |rTt| ||s`t| || |d t|dr||  d S )Nr6   optimizeTrL   flush)r   r0   rt   r   r   r   hasattrr   )rG   r   r   r   r6   r   r   r   r     s    

r   c                 C   s$   | j dd}t| jdk r d}|S )Nry   r      r   )r   rt   minri   )rG   ry   r   r   r   r     s    r   c              	   C   s  d}z,d|j kr|j d }n
|jd }t|}W n ttfk
rH   Y nBX d}t||j }|d k	rz||}W n tk
r   d}Y nX d|j krt|j d d }nd}t|j dd}|s|dks|r*|rdnd}	|	|d	> O }	|sd}| d
t	d t	d t	|	 t
| t	| t	d  d|j krdt|j d kr| d
t	d  |j d }
t|
trz|
 }
tdt|
dD ],}|
||d  }| t	t||  q| t	d d|j kr|j d }| d
t	d t	d d t	d t	d t
| t	d  |j d}|rRt|}t|}|rR|dB }||B }| dt
|d  t
|d  t
|jd  t
|jd  t	|  |r|r| t| | t	d d S )NFr^   TrO   r)   r   r   r   r   rM   rN   rY   rR   rQ   rS   rV   r,   rU   r    r   r+   rW   r(   )r   r0   intr   rh   r   r   rt   r   r
   o16r"   r   strencoder!   r   _get_color_table_sizeri   _get_header_palette)r   rG   r   r=   Ztransparent_color_existsr^   r   rO   r   Zpacked_flagrR   r$   ZsubblockZnumber_of_loopsr   palette_bytescolor_table_sizer   r   r   r     s    




 




r   c           
      C   s   |   }zt|d}| jdkr8tjd|g|tjd ntdd|g}dg}tj	|tj
tjd}tj	||j|tjd}|j  | }	|	rt|	|| }	|	rt|	|W 5 Q R X W 5 zt| W n tk
r   Y nX X d S )Nwbr.   Zppmtogif)stdoutstderrZppmquantZ256)stdinr   r   )_dumposunlinkOSErroropenrn   
subprocess
check_callDEVNULLPopenPIPEr   r   waitCalledProcessError)
rG   r   r   tempfilerI   Z	quant_cmdZ	togif_cmdZ
quant_procZ
togif_procretcoder   r   r   _save_netpbm  sB    
  
  
r   c                 C   s   | j dkr|r|ddrtp&| j dk}|s<| j| j dk rg }t|  D ]\}}|rL|| qL|st|dkrt	|t|kr|S dS )aL  
    Palette optimization is a potentially expensive operation.

    This function determines if the palette should be optimized using
    some heuristics, then returns the list of palette entries in use.

    :param im: Image object
    :param info: encoderinfo
    :returns: list of indexes of palette entries in use, or None
    )r[   r\   r   r   r\   i   r+   N)
rn   rt   _FORCE_OPTIMIZEwidthheightr   Z	histogramr   r"   rj   )rG   r0   Zoptimiser   r$   countr   r   r   r   +  s    
r   c                 C   s:   | sdS t | dk rdS ttt | d dd S d S )Nr   rX   r   r    r   )r"   mathceillog)r   r   r   r   r   P  s
    r   c                 C   s<   t | }d|> t| d  }|dkr8| tdd | 7 } | S )z
    Returns the palette, null padded to the next power of 2 (*3) bytes
    suitable for direct inclusion in the GIF header

    :param palette_bytes: Unpadded palette bytes, in RGBRGB form
    :returns: Null padded palette
    r   r    r   )r   r"   r
   )r   r   Zactual_target_size_diffr   r   r   r   Z  s
    r   c                 C   s   | j j S )z
    Gets the palette for inclusion in the gif header

    :param im: Image object
    :returns: Bytes, len<=768 suitable for inclusion in gif header
    r   )rG   r   r   r   r   l  s    r   c              
   C   sh   d}|rd|}t |trdz| j|| }W n: tk
rb } zt|dkrPW Y 
dS  W 5 d }~X Y nX |S )Nr   z$cannot allocate more than 256 colors)r   ra   r6   Zgetcolorrh   r   )rG   ZinfoBackgroundr-   rJ   r   r   r   r   v  s    

r   c                 C   s   d}dD ]T}|r||kr|dkr,|| dks|dkrTdt ||   krPdksTq qd} qrq| jd	dkrrd}t| |d
}t| }t|}d| t| jd  t| jd  t|d t|td t	|gS )z2Return a list of strings representing a GIF headers   87a)r^   rO   rV   rR   rO   r   rR   r   rS   s   89ar'   r-   s   GIFr+   )
r"   r0   rt   r   r   r   r   ri   r
   r   )rG   r0   r'   ZextensionKeyr-   r   r   r   r   r   r     s<     

r   c              	   C   sR   zF||_ t| ||d t|| dd|j dt|j fg | d W 5 |` X d S )Nr   rf   r   r   )r   r   r   r   ri   r   rn   r   )r   r   r   paramsr   r   r   r     s      r   c                 C   sd   t | |}|dkri }d|kr6d| jkr6| jd |d< t| ||}|j| _|j| _t| |}||fS )a  
    Legacy Method to get Gif data from image.

    Warning:: May modify image data.

    :param im: Image object
    :param palette: bytes object containing the source palette, or ....
    :param info: encoderinfo
    :returns: tuple of(list of header items, optimized palette)

    Nr-   )r   r0   r   r6   rG   r   )rG   r6   r0   r   Zim_modheaderr   r   r   	getheader  s    

r   r   c                 K   s0   G dd d}|    | }t|| || |jS )a  
    Legacy Method

    Return a list of strings representing this image.
    The first string is a local image header, the rest contains
    encoded image data.

    :param im: Image object
    :param offset: Tuple of (x, y) pixels. Defaults to (0,0)
    :param \**params: E.g. duration or other encoder info parameters
    :returns: List of Bytes containing gif encoded frame data

    c                   @   s   e Zd Zg Zdd ZdS )zgetdata.<locals>.Collectorc                 S   s   | j | d S r   )r   r   )r   r   r   r   r   r     s    z getdata.<locals>.Collector.writeN)r   r   r   r   r   r   r   r   r   	Collector  s   r   )rg   r   r   )rG   r   r   r   r   r   r   r   r     s
    r   z.gifz	image/gif)F)NN)r   )1r   r   r   r   enumr    r   r   r   r   r   _binaryr	   r1   r
   r   r   r   r   rm   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zregister_openr   Zregister_saveZregister_save_allZregister_extensionZregister_mimer   r   r   r   <module>   sP   		   5N

W2%

'

!