U
    &^p                     @   sZ  d dl Z d dlZd dlZddlmZmZmZmZmZ ddl	m
Z
mZmZmZ dd ZG dd dejZd	d	d
dZd4ddZdd Zdd Zdd Zdd Zd5d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"d+d, Z#d6d-d.Z$d7d0d1Z%e&ej'ee e(ej'e e)ej'e e*ej'd2 e+ej'd3 dS )8    N   )Image
ImageChops	ImageFileImagePaletteImageSequence)i8i16leo8o16lec                 C   s   | d d dkS )N   s   GIF87as   GIF89a )prefixr   r   6/tmp/pip-install-a1j0c_p1/Pillow/PIL/GifImagePlugin.py_accept&   s    r   c                   @   sl   e Zd ZdZdZdZdZdd Zdd Ze	d	d
 Z
e	dd Zdd Zdd Zdd Zdd Zdd ZdS )GifImageFileZGIFzCompuserve GIFFNc                 C   s,   | j d}|r(t|r(| j t|S d S Nr   )fpreadr   )selfsr   r   r   data7   s    zGifImageFile.datac                 C   sH  | j d}|d d dkr$td|d d | jd< t|dd  t|dd  f| _g | _t|d }|d@ d	 }|d
@ rt|d | jd< | j d|> }tdt	|dD ]f}|d t||   krt||d	    krt||d  ksn t
d|}| | _| _ qq| j | _| j  | _d | _d | _| d d S )N   r   r   znot a GIF fileversion   
      r         
background   r      RGB)r   r   SyntaxErrorinfoi16_sizetiler   rangelenr   rawglobal_palettepalette_GifImageFile__fptell_GifImageFile__rewind	_n_frames_is_animated_seek)r   r   flagsbitspir   r   r   _open=   s*    "
DzGifImageFile._openc                 C   s^   | j d krX|  }z| |  d  qW n" tk
rL   |  d | _ Y nX | | | j S r   )r1   r/   seekEOFErrorr   currentr   r   r   n_frames[   s    

zGifImageFile.n_framesc                 C   sj   | j d krd| jd k	r"| jdk| _ nB|  }z| d d| _ W n tk
rX   d| _ Y nX | | | j S )Nr   TF)r2   r1   r/   r9   r:   r;   r   r   r   is_animatedg   s    




zGifImageFile.is_animatedc              	   C   s   |  |sd S || jk r0|dkr&d | _| d | j}t| jd |d D ]:}z| | W qJ tk
r   | | tdY qJX qJd S )Nr   r   zno more images in GIF file)Z_seek_check_GifImageFile__frameimr3   r)   r:   r9   )r   frameZ
last_framefr   r   r   r9   x   s    



zGifImageFile.seekc              	   C   sp  |dkrDd| _ d | _ddddg| _d| _| j| j d | _d| _n| j	sR| 
  || jd krltd| || _g | _| j| _| j r| j| j  |  rqd| _ | jr| j	| j| j ddlm} || j| _i }| jd}|r|dkrq|q|dkrB| jd}|  }t|dkr~t|d }|d@ rHt|d	 |d
< t|dd	 d |d< d|@ }|d? }|r2|| _nt|dkr|rd|kr|d  |7  < n||d< |  }qqnnt|dkr2|| j f|d< |d d dkr2|  }t|d	kr2t|d dkr2t|dd	 |d< |  rzq2q|dkr| jd}t|dd  t|dd   }}	|t|dd   |	t|dd    }
}|
| jd ks|| jd krt|
| jd t|| jd f| _||	|
|f| _t|d }|d@ dk}|d@ r:|d@ d }td| jd	|> | _t| jd}| j | _ d||	|
|f| j ||ffg| _q|qqzz| jdk rd | _nH| jdkrt| j tj d | j| j!d! | _n| j	r| j	 | _| jr| "| j| j| _W n t#t$fk
r   Y nX | jst%d"D ]4}||kr@|| | j!|< n|| j!kr"| j!|= q"d#| _&| jrld | _&d S )$Nr   r   zcannot seek to frame %d)copy   ;   !   r!   transparencyr   duration   r"      comment   	extensionr      NETSCAPE2.0loop   ,	      r   r   @   r   r   r#   gifPr    )rH   rI   rL   rN   rP   L)'Z_GifImageFile__offsetZdisposedispose_extentr?   r.   r9   r0   _prev_imdisposal_methodr@   load
ValueErrorr(   r   r   pasterD   r,   r-   r   r   r&   r/   r*   sizemaxr'   r   r+   r   Z_decompression_bomb_checkcorefillr%   _cropAttributeErrorKeyErrorr:   mode)r   rA   rD   r%   r   blockr4   Zdispose_bitsZx0Zy0x1y1	interlacer5   kr   r   r   r3      s    


 
"* "

zGifImageFile._seekc                 C   s   | j S N)r?   r   r   r   r   r/   $  s    zGifImageFile.tellc                 C   s\   t j |  | jrL| jdkrL| | j| j}| j|| j|d | j| _| j	 | _d S )Nr   ZRGBA)
r   load_endrY   rZ   rb   r@   rX   r]   convertrD   )r   updatedr   r   r   rm   '  s    zGifImageFile.load_endc                 C   sB   z4z| j | jkr| j   W n tk
r0   Y nX W 5 d | _ X d S rk   )r.   r   closerc   rl   r   r   r   
_close__fp4  s    
zGifImageFile._close__fp)__name__
__module____qualname__formatformat_descriptionZ!_close_exclusive_fp_after_loadingr,   r   r8   propertyr=   r>   r9   r3   r/   rm   rq   r   r   r   r   r   /   s    

 r   rW   rV   )1rW   rV   Fc                 C   sp   | j tkr|   | S t| j dkrf|r\d}| jrJt| j d d }| jdtj	|dS | d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.

    UNDONE: What is the point of mucking with the initial call palette, for
    an image that shouldn't have a palette, or it would be a mode 'P' and
    get returned in the RAWMODE clause.

    :param im: Image object
    :param initial_call: Default false, set to true for a single frame.
    :returns: Image object
    r#      r   r!   rV   )r-   colorsrW   )
re   RAWMODEr[   r   Zgetmodebaser-   r*   getdatarn   ZADAPTIVE)r@   Zinitial_callZpalette_sizer   r   r   _normalize_modeE  s    

r}   c              	   C   s   d}|rjt |tttfr(t|dd }t |tjrjttjt|j	dd |j	dd |j	dd }| j
dkr|s| jddd }n*|stdd tdD }tjd|d	| _	t| |}|dk	r| ||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   ry   i   rV   r#   c                 s   s   | ]}|d  V  qdS )r!   Nr   ).0r7   r   r   r   	<genexpr>  s     z%_normalize_palette.<locals>.<genexpr>r-   )
isinstancebytes	bytearraylistr   	itertoolschainfrom_iterablezipr-   re   r@   Z
getpaletter)   _get_optimizeZremap_palette)r@   r-   r%   Zsource_paletteused_palette_colorsr   r   r   _normalize_palettec  s2    


r   c              	   C   s   t | d}|j D ]\}}| j|| qt||| j}t|| jD ]}|| qFd}t| rj|dB }t	|| d| dt| f|_
t||dd| j dt|j fg |d d S )NTr   rT   r   r   r   rU       )r}   r%   itemsencoderinfo
setdefaultr   _get_global_headerwriteget_interlace_write_local_headerZencoderconfigr   _saver^   r{   re   )r@   r   r-   Zim_outrj   vr   r4   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r^|d krXt| | j d| jd}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rx|D ]z}|d
 }	|d s4t|	|d D ]}|| qd}n*d|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 )NrI   disposalr   Zappend_imagesr   rC   r"   r    rV   r@   r#   r   )r@   bboxr   r   r   Tinclude_color_table)!r   getr%   r   r   r   Iteratorr}   rD   r   r   r   r   r   tuple_get_backgroundr   newr^   Z
putpaletter-   _get_palette_bytesr   Zsubtract_modulorn   Zgetbboxappendr*   r   r   Zcrop_write_frame_datasum)r@   r   r-   rI   r   Z	im_framesZframe_countZbackground_imZ
imSequenceim_framerj   r   r   previousr    Zbase_imdeltar   Z
frame_datar   offsetr   r   r   _write_multiple_frames  sx    

 
 r   c                 C   s   t | ||dd d S )NT)save_all)r   )r@   r   filenamer   r   r   	_save_all  s    r   c                 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 )Nr-   optimizeTrE   flush)r   r%   r   r   r   r   hasattrr   )r@   r   r   r   r-   r   r   r   r     s    

r   c                 C   s$   | j dd}t| jdk r d}|S )Nri   r      r   )r   r   minr^   )r@   ri   r   r   r   r     s    r   c                 C   s  d}z|j d }W n tk
r&   Y nJX t|}d}t||j }|d k	rpz||}W n tk
rn   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r`|
 }
tdt
|
dD ],}|
||d  }| tt
||  qp| td d|j kr |j d }| d
td td d td td t	| td  |j d}|r8t|}t|}|r8|dB }||B }| dt	|d  t	|d  t	|jd  t	|jd  t|  |r|r| t| | td d S )NFrH   TrI   r   r   r   r   r"   rF   rG   rS   rL   rK   rM   rP   r   rO   r!   r   r   rQ   r   )r   rd   intr   indexr\   r   r   r
   o16r*   r   strencoder)   r   _get_color_table_sizer^   _get_header_palette)r   r@   r   r4   Ztransparent_color_existsrH   r   rI   r   Zpacked_flagrL   r7   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openre   
subprocess
check_callDEVNULLPopenPIPEr   rp   waitCalledProcessError)
r@   r   r   tempfilerB   Z	quant_cmdZ	togif_cmdZ
quant_procZ
togif_procretcoder   r   r   _save_netpbmd  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
    )rV   rW   r   r   rW   i   r   N)
re   r   _FORCE_OPTIMIZEwidthheight	enumerateZ	histogramr   r*   r_   )r@   r%   Zoptimiser   r7   countr   r   r   r     s    
r   c                 C   sF   dd l }| sdS t| dk r dS t||t| d dd S d S )Nr   rR   r   r!   r"   )mathr*   r   ceillog)r   r   r   r   r   r     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     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   )r@   r   r   r   r     s    r   c                 C   s&   d}|r"|}t |tr"| j|}|S )Nr   )r   r   r-   Zgetcolor)r@   ZinfoBackgroundr    r   r   r   r     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)rH   rI   rP   rL   rI   r   rL   r   rM   s   89ar   r    s   GIFr   )
r*   r%   r   r   r   r   r   r^   r
   r   )r@   r%   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   rU   r   r   )r   r   r   r   r^   r{   re   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   r%   r   r-   r@   r   )r@   r-   r%   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 rk   )r   r   )r   r   r   r   r   r   ]  s    z getdata.<locals>.Collector.writeN)rr   rs   rt   r   r   r   r   r   r   	CollectorZ  s   r   )r[   r   r   )r@   r   r   r   r   r   r   r   r|   K  s
    r|   z.gifz	image/gif)F)F)NN)r   ),r   r   r    r   r   r   r   r   _binaryr   r	   r&   r
   r   r   r   r   r{   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r|   Zregister_openru   Zregister_saveZregister_save_allZregister_extensionZregister_mimer   r   r   r   <module>   sB   	  
,M

T2%
'

!