B
    -¦aÀt  ã               @   sn  d dl Z 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 ddl
mZ ddl
mZ dd„ ZG d	d
„ d
ejƒZddddœZd6dd„Zdd„ Zdd„ Zdd„ Zdd„ Zd7d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#d8d/d0„Z$d9d2d3„Z%e &ej'ee¡ e (ej'e¡ e )ej'e¡ e *ej'd4¡ e +ej'd5¡ dS ):é    Né   )ÚImageÚ
ImageChopsÚ	ImageFileÚImagePaletteÚImageSequence)Úi16le)Úo8)Úo16lec             C   s   | d d… dkS )Né   )s   GIF87as   GIF89a© )Úprefixr   r   ú6/tmp/pip-unpacked-wheel-rysjrues/PIL/GifImagePlugin.pyÚ_accept)   s    r   c                   st   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‡ f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   Údata:   s    zGifImageFile.datac             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|> ¡}xjtdt	|ƒdƒD ]V}|d ||   krÐ||d    krÐ||d  ks–n t
 d|¡}| | _| _P q–W | j | _| j  ¡ | _d | _d | _|  d¡ d S )Né   znot a GIF filer   Úversioné   é
   é   r   é€   é   Ú
backgroundé   r   é   ÚRGB)r   r   r   ÚSyntaxErrorÚinfoÚi16Ú_sizeÚtileÚ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*    8zGifImageFile._openc             C   sb   | j d kr\|  ¡ }yx|  |  ¡ d ¡ qW W n" tk
rP   |  ¡ d | _ Y nX |  |¡ | j S )Nr   )r.   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|  ¡ }y|  d¡ d| _ W n tk
rX   d| _ Y nX |  |¡ | j S )Nr   TF)r/   r.   r,   r6   r7   )r   r8   r   r   r   Úis_animatedj   s    




zGifImageFile.is_animatedc             C   sž   |   |¡sd S || jk r0|dkr&d | _|  d¡ | j}xbt| jd |d ƒD ]J}y|  |¡ W qL tk
r” } z|  |¡ tdƒ|‚W d d }~X Y qLX qLW d S )Nr   r   zno more images in GIF file)Z_seek_checkÚ_GifImageFile__frameÚimr0   r&   r7   r6   )r   ÚframeZ
last_frameÚfÚer   r   r   r6   {   s    



zGifImageFile.seekc             C   sÞ  |dkr>d| _ d | _ddddg| _d| _| j | j¡ d| _n| jrL|  	¡  || jd krht
d|› ƒ‚|| _g | _| j| _| j r¤| j | j ¡ x|  ¡ rœq’W d| _ | jr¼| j | j| j¡ ddlm} || jƒ| _i }d }d }xX| j d¡}|rþ|dkrP qä|dkr<| j d¡}|  ¡ }|d dkrx|d }|d@ rH|d	 }t|dƒd
 |d< d|@ }	|	d? }	|	r(|	| _n°|d dkrÄx8|r¾d|krª|d  |7  < n||d< |  ¡ }qˆW qänd|d dkr(|| j ¡ f|d< |d d… dkr(|  ¡ }t|ƒd	kr(|d dkr(t|dƒ|d< x|  ¡ r8q*W qä|dkrä| j d¡}t|dƒt|dƒ }
}|
t|dƒ |t|dƒ  }}|| jd ks¤|| jd krÆt|| jd ƒt|| jd ƒf| _|
|||f| _|d }|d@ dk}|d@ r|d@ d }t d| j d	|> ¡¡| _| j d¡d }| j ¡ | _ P qäqäW yÜ| jdk rRd | _nÄ| jdkr¶| j\}
}}}||
 || f}t |¡ |d k	r”|n| j dd¡}tj  d||¡| _n`| jrÒ|  !| j| j¡| _nD|d k	r| j\}
}}}||
 || f}t |¡ tj  d||¡| _W n t"k
r.   Y nX |d k	r„d}|d k	rb|dkr^|| jd < n|}d!|
|||f| j |||ffg| _nt#‚x<d"D ]4}||kr¬|| | j|< n|| jkrŽ| j|= qŽW d#| _$| jrÚd| _$d S )$Nr   éÿÿÿÿr   zcannot seek to frame )Úcopyó   ;ó   !éù   r   r   Údurationé   r   éþ   Úcommentéÿ   Ú	extensionr   s   NETSCAPE2.0Úloopó   ,é	   é   r   r   é@   r   r   r    r   ÚPÚtransparencyÚgif)rE   rH   rJ   rK   ÚL)%Z_GifImageFile__offsetZdisposeZdispose_extentr;   r+   r6   r-   Zdisposal_methodr%   ÚloadÚ
ValueErrorr   r   r<   ZpasterA   r)   r*   r   r#   r,   r'   ÚsizeÚmaxr$   r   r(   r   Z_decompression_bomb_checkr"   ÚgetÚcoreÚfillZ_cropÚAttributeErrorr7   Úmode)r   r=   rA   r"   Zframe_transparencyÚ	interlacer   Úblockr1   Zdispose_bitsZx0Zy0Úx1Úy1r2   Zdispose_sizeÚcolorrQ   Úkr   r   r   r0   ‹   sà    



 "









zGifImageFile._seekc                s>   | j s,d| jkr,tj | j| j| jd ¡| _ tt| ƒ 	¡  d S )NrQ   )
r<   r"   r   rY   rZ   r\   rV   Úsuperr   Úload_prepare)r   )Ú	__class__r   r   rd   E  s    zGifImageFile.load_preparec             C   s   | j S )N)r;   )r   r   r   r   r,   K  s    zGifImageFile.tellc             C   sB   z4y| j | jkr| j  ¡  W n tk
r0   Y nX W d d | _ X d S )N)r+   r   Úcloser[   )r   r   r   r   Ú
_close__fpN  s    
zGifImageFile._close__fp)Ú__name__Ú
__module__Ú__qualname__ÚformatÚformat_descriptionZ!_close_exclusive_fp_after_loadingr)   r   r5   Úpropertyr9   r:   r6   r0   rd   r,   rg   Ú__classcell__r   r   )re   r   r   2   s    ;r   rS   rP   )Ú1rS   rP   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   rP   )r*   ÚcolorsrS   )
r\   ÚRAWMODErT   r   Zgetmodebaser*   r'   ÚgetdataÚconvertZADAPTIVE)r<   Zinitial_callZpalette_sizer   r   r   Ú_normalize_mode_  s    

ru   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*|s¨t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   rp   i   rP   r    c             s   s   | ]}|d  V  qdS )r   Nr   )Ú.0r4   r   r   r   ú	<genexpr>ž  s    z%_normalize_palette.<locals>.<genexpr>)r*   )Ú
isinstanceÚbytesÚ	bytearrayÚlistr   Ú	itertoolsÚchainÚfrom_iterableÚzipr*   r\   r<   Z
getpaletter&   Ú_get_optimizeZremap_palette)r<   r*   r"   Zsource_paletteÚused_palette_colorsr   r   r   Ú_normalize_palette}  s,    

r‚   c          	   C   sÀ   t | dƒ}x$|j ¡ D ]\}}| j ||¡ qW t||| jƒ}xt|| jƒD ]}| |¡ qLW d}t| ƒrr|dB }t	|| d|ƒ dt| ƒf|_
t ||dd| j dt|j fg¡ | d¡ d S )NTr   rO   )r   r   r   rR   ó    )ru   r"   ÚitemsÚencoderinfoÚ
setdefaultr‚   Ú_get_global_headerÚwriteÚget_interlaceÚ_write_local_headerZencoderconfigr   Ú_saverV   rr   r\   )r<   r   r*   Zim_outrb   Úvr   r1   r   r   r   Ú_write_single_frame©  s    
$r   c          	   C   sÐ  | j  d| j d¡¡}| j  d| j d¡¡}g }d}d }xÀt | g| j  dg ¡¡D ]¢}xšt |¡D ]Š}	t|	 ¡ ƒ}	|dkr¨x$|	j 	¡ D ]\}
}| j  
|
|¡ qŽW t|	|| j ƒ}	| j  ¡ }t|ttfƒrÚ|| |d< t|ttfƒrô|| |d< |d7 }|rÞ|d }| d¡dkrp|d krj| j  d| j dd	¡¡}t|	|ƒ}t d
|	j|¡}| |d d j¡ |}n|d }t|	ƒt|ƒkr˜t |	|¡}nt |	 d¡| d¡¡}| ¡ }|sâ|rh|d d  |d 7  < qhnd }| |	||dœ¡ qhW qTW t|ƒdkr–x†|D ]~}|d }	|d sPx"t|	|d ƒD ]}| |¡ q6W d}n*d|d d< |	 |d ¡}	|d d d… }t||	||d ƒ qW dS d| j krÌt| j d ttfƒrÌt | j d ƒ| j d< d S )NrE   Údisposalr   Zappend_imagesr   r@   r   rQ   )r   r   r   rP   r<   r    r…   )r<   Úbboxr…   r   )r   r   TÚinclude_color_table)!r…   rX   r"   r|   r}   r   ÚIteratorru   rA   r„   r†   r‚   rx   r{   ÚtupleÚ_get_backgroundr   ÚnewrV   Z
putpaletter*   Ú_get_palette_bytesr   Zsubtract_modulort   ZgetbboxÚappendr'   r‡   rˆ   ZcropÚ_write_frame_dataÚsum)r<   r   r*   rE   rŽ   Z	im_framesZframe_countZbackground_imZ
imSequenceÚim_framerb   rŒ   r…   Úpreviousra   r   Zbase_imÚdeltar   Z
frame_datar   Úoffsetr   r   r   Ú_write_multiple_frames¾  sn    "




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*   ÚoptimizeTrB   Úflush)r…   r"   rX   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 )Nr]   r   é   r   )r…   rX   ÚminrV   )r<   r]   r   r   r   r‰      s    r‰   c             C   s®  d}y|j d }W n tk
r&   Y nJX t|ƒ}d}t||j ƒ}|d k	rpy| |¡}W n tk
rn   d}Y nX d|j krŽt|j d d ƒ}nd}t|j  dd¡ƒ}|s¶|dks¶|r|r¾dnd}	|	|d	> O }	|sÖd}|  d
tdƒ tdƒ t|	ƒ t	|ƒ t|ƒ tdƒ ¡ d|j kr°dt
|j d ƒkr°|  d
tdƒ ¡ |j d }
t|
tƒr`|
 ¡ }
x@tdt
|
ƒdƒD ],}|
||d … }|  tt
|ƒƒ| ¡ qrW |  tdƒ¡ d|j kr|j d }|  d
tdƒ tdƒ d tdƒ tdƒ t	|ƒ tdƒ ¡ |j  d¡}|r<t|ƒ}t|ƒ}|r<|dB }||B }|  dt	|d ƒ t	|d ƒ t	|jd ƒ t	|jd ƒ t|ƒ ¡ |rœ|rœ|  t|ƒ¡ |  tdƒ¡ d S )NFrQ   TrE   r   r   rŽ   r   r   rC   rD   rN   rH   rG   rI   rK   r   s   NETSCAPE2.0r   r   r   rL   r   )r…   ÚKeyErrorÚintr€   ÚindexrU   rX   rˆ   r	   Úo16r'   rx   ÚstrÚencoder&   r•   Ú_get_color_table_sizerV   Ú_get_header_palette)r   r<   rœ   r1   Ztransparent_color_existsrQ   r   rE   rŽ   Zpacked_flagrH   r4   ZsubblockZnumber_of_loopsr   Úpalette_bytesÚcolor_table_sizer   r   r   rŠ   *  sb    

6 

:BrŠ   c       
      C   sä   |   ¡ }z°t|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 	¡  | 
¡ }	|	r”t |	|¡‚| 
¡ }	|	r¬t |	|¡‚W d Q R X W d yt |¡ W n tk
rÜ   Y nX X d S )NÚwbr    Zppmtogif)ÚstdoutÚstderrZppmquantZ256)Ústdinr±   r²   )Ú_dumpÚopenr\   Ú
subprocessÚ
check_callÚDEVNULLÚPopenÚPIPEr±   rf   ÚwaitÚCalledProcessErrorÚosÚunlinkÚOSError)
r<   r   rŸ   Útempfiler>   Z	quant_cmdZ	togif_cmdZ
quant_procZ
togif_procÚretcoder   r   r   Ú_save_netpbm~  s4    



rÂ   c             C   s   | j dkrŒ|rŒ| dd¡rŒtp&| j dk}|s<| j| j dk rŒg }x&t|  ¡ ƒD ]\}}|rN| |¡ qNW |sˆt|ƒdkrŒt	|ƒ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
    )rP   rS   r¡   r   rS   i   r   N)
r\   rX   Ú_FORCE_OPTIMIZEÚwidthÚheightÚ	enumerateZ	histogramr–   r'   rW   )r<   r"   Zoptimiser   r4   Ú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   rM   r   r   r   )r'   ÚmathÚceilÚlog)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   sb   d}|r^|}t |tƒr^y| j || ¡}W n4 tk
r\ } zt|ƒdkrJdS ‚ W d d }~X Y nX |S )Nr   z$cannot allocate more than 256 colors)rx   r’   r*   ZgetcolorrU   rª   )r<   ZinfoBackgroundr   r?   r   r   r   r“   þ  s    
r“   c             C   sØ   d}xndD ]R}|r
||kr
|dkr.|| dks
|dkrVdt || ƒ  krRdksVq
 q
d}P q
W | j d	¡dkrtd}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)rQ   rE   rK   rH   rE   r   rH   r   rI   s   89ar   r   s   GIFr   )
r'   r"   rX   r“   r•   r¬   r©   rV   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 d |` X d S )Nr   rR   )r   r   rƒ   )r…   rŠ   r   r‹   rV   rr   r\   rˆ   )r   r™   rœ   Úparamsr   r   r   r—   9  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   Ú	getheaderM  s    

rÍ   ©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 )N)r   r–   )r   r   r   r   r   rˆ   }  s    z getdata.<locals>.Collector.writeN)rh   ri   rj   r   rˆ   r   r   r   r   Ú	Collectorz  s   rÏ   )rT   r—   r   )r<   rœ   rË   rÏ   r   r   r   r   rs   k  s
    rs   z.gifz	image/gif)F)F)NN)rÎ   ),r|   rÈ   r½   r¶   Ú r   r   r   r   r   Ú_binaryr   r#   r	   r
   r©   r   r   rr   ru   r‚   r   r   r    r‹   r‰   rŠ   rÂ   rÃ   r€   r¬   r­   r•   r“   r‡   r—   rÍ   rs   Zregister_openrk   Zregister_saveZregister_save_allZregister_extensionZregister_mimer   r   r   r   Ú<module>   sH   	  ,
,M

T2%

'

!