B
    ‚Þ1\¡m  ã               @   sF  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lZdZdd„ ZG dd	„ d	ejƒZd
d
ddœZd3dd„Zdd„ Zdd„ Zdd„ Zdd„ Zd4d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!d5d,d-„Z"d6d/d0„Z#e $ej%ee¡ e &ej%e¡ e 'ej%e¡ e (ej%d1¡ e )ej%d2¡ dS )7é   )ÚImageÚ	ImageFileÚImagePaletteÚ
ImageChopsÚImageSequence)Úi8Úi16leÚo8Úo16leé    Nz0.9c             C   s   | d d… dkS )Né   )s   GIF87as   GIF89a© )Úprefixr   r   ú1lib/python3.7/site-packages/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   Údata6   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|> ¡}xvtdt	|ƒdƒD ]b}|d t|| ƒ  krút||d	  ƒ  krút||d  ƒks´n t
 d|¡}| | _| _P q´W | j | _| j  ¡ | _d | _d | _|  d¡ d S )Né   r   )s   GIF87as   GIF89aznot a GIF fileÚversioné   é
   é   r   é€   é   Ú
backgroundé   r   é   ÚRGB)r   r   ÚSyntaxErrorÚinfoÚi16Z_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   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_framesZ   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_animatedf   s    




zGifImageFile.is_animatedc          	   C   s€   |   |¡sd S || jk r"|  d¡ | j}xRt| jd |d ƒD ]:}y|  |¡ W q> tk
rv   |  |¡ tdƒ‚Y q>X q>W d S )Nr   r   zno more images in GIF file)Z_seek_checkÚ_GifImageFile__framer0   r&   r7   r6   )r   ÚframeZ
last_frameÚfr   r   r   r6   w   s    



zGifImageFile.seekc          	   C   s6  |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 ¡ x|  ¡ r q–W d| _ | jrÀ| j	 | j| j¡ ddlm} || jƒ| _i }xj| j d¡}|rø|dkrüP qà|dkrR| j d¡}|  ¡ }t|ƒdkr„t|d ƒ}|d@ rNt|d	 ƒ|d
< t|dd	… ƒd |d< d|@ }|d? }|r>|| _nºt|ƒdkrÐx8|rÊd|kr¶|d  |7  < n||d< |  ¡ }q”W qànnt|ƒdkr>|| j ¡ f|d< |d d… dkr>|  ¡ }t|ƒd	kr>t|d ƒdkr>t|dd	… ƒ|d< x|  ¡ rNq@W qà|dkrà| j d¡}t|dd … ƒt|dd … ƒ }}	|t|dd … ƒ |	t|dd … ƒ  }
}||	|
|f| _t|d ƒ}|d@ dk}|d@ r|d@ d }t d| j d	|> ¡¡| _t| j d¡ƒ}| j ¡ | _ d||	|
|f| j ||ffg| _P qàqàW yn| jdk r`d | _n<| jdkrˆ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"‚x<d"D ]4}||kr|| | j|< n|| jkræ| j|= qæW d#| _#| jr2d | _#d S )$Nr   éÿÿÿÿr   zcannot seek to frame %d)Úcopyó   ;ó   !éù   r   Útransparencyr   Údurationé   r    éþ   Úcommentéÿ   Ú	extensionr   s   NETSCAPE2.0Úloopó   ,é	   é   r   r   é@   r   r   r!   ÚgifÚPr   )rC   rD   rG   rI   rJ   ÚL)$Z_GifImageFile__offsetZdisposeÚdispose_extentr;   r+   r6   r-   Ú_prev_imÚdisposal_methodÚimÚloadÚ
ValueErrorr%   r   r   Úpaster?   r)   r*   r   r   r$   r,   r'   r   r(   r   ZcoreZfillÚsizer#   Ú_cropÚAttributeErrorÚKeyErrorr7   Úmode)r   r<   r?   r#   r   Úblockr1   Zdispose_bitsZx0Zy0Zx1Zy1Ú	interlacer2   Úkr   r   r   r0   …   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_endrS   rT   rZ   rU   rR   rX   Úconvertr?   )r   Úupdatedr   r   r   ra   #  s    zGifImageFile.load_endc             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__fp1  s    
zGifImageFile._close__fp)Ú__name__Ú
__module__Ú__qualname__ÚformatZformat_descriptionZ!_close_exclusive_fp_after_loadingr)   r   r5   Úpropertyr9   r:   r6   r0   r,   ra   re   r   r   r   r   r   .   s    r   rQ   rP   )Ú1rQ   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*   ZcolorsrQ   )
r]   ÚRAWMODErV   r   Zgetmodebaser*   r'   Úgetdatarb   ZADAPTIVE)rU   Zinitial_callZpalette_sizer   r   r   Ú_normalize_modeE  s    

ro   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   rl   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]   rU   Z
getpaletter&   Ú_get_optimizeZremap_palette)rU   r*   r#   Zsource_paletteÚused_palette_colorsr   r   r   Ú_normalize_palettec  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   rN   )r   r   r   rO   ó    )ro   r#   ÚitemsÚencoderinfoÚ
setdefaultr|   Ú_get_global_headerÚwriteÚget_interlaceÚ_write_local_headerZencoderconfigr   Ú_saverY   rm   r]   )rU   r   r*   Zim_outr`   Úvr   r1   r   r   r   Ú_write_single_frame‹  s    
r‡   c             C   s4  | j  d| j d¡¡}| j  d| j d¡¡}g }d}x^t | g| j  dg ¡¡D ]@}x8t |¡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 }|rx|d }t|ƒt|d ƒkr.t ||d ¡}nt | d¡|d  d¡¡}| ¡ }|s||rd|d	 d  |d 7  < qdnd }| |||d
œ¡ qdW qPW t|ƒdkr0x†|D ]~}|d }|d sêx"t||d	 ƒD ]}| |¡ qÐW d}n*d|d	 d< | |d ¡}|d d d… }t||||d	 ƒ qªW dS d S )NrD   Údisposalr   Zappend_imagesr   r>   rU   r!   r   )rU   Úbboxr   r‰   )r   r   TÚinclude_color_tabler    )r   Úgetr#   rv   rw   r   ÚIteratorro   r?   r~   r€   r|   rr   ru   ÚtupleÚ_get_palette_bytesr   Zsubtract_modulorb   ZgetbboxÚappendr'   r   r‚   ZcropÚ_write_frame_data)rU   r   r*   rD   rˆ   Z	im_framesZframe_countZ
imSequenceÚim_framer`   r†   r   ZpreviousZdeltar‰   Z
frame_datar   Úoffsetr   r   r   Ú_write_multiple_frames¡  sd    


r“   c             C   s   t | ||dd d S )NT)Úsave_all)r…   )rU   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*   ÚoptimizeTr@   Úflush)r   r#   r‹   r“   r‡   r‚   Úhasattrr˜   )rU   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   r‹   ÚminrY   )rU   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ƒ ¡ xLtdt
|j d ƒdƒD ]2}
|j d |
|
d … }|  tt
|ƒƒ| ¡ qZW |  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 )NFrC   TrD   r   r   rˆ   r   r    rA   rB   rM   rG   rF   rH   rJ   r   s   NETSCAPE2.0r   rŠ   r   rK   r   )r   r\   Úintrz   ÚindexrW   r‹   r‚   r	   Úo16r'   r&   rŽ   Ú_get_color_table_sizerY   Ú_get_header_palette)r   rU   r’   r1   Ztransparent_color_existsrC   r{   rD   rˆ   Zpacked_flagr4   ZsubblockZnumber_of_loopsrŠ   Úpalette_bytesÚcolor_table_sizer   r   r   r„     sh    

*
.6r„   c          
   C   s  dd l }ddlm}m}m}m} |  ¡ }t|dƒº}	| jdkrjt|j	dƒ}
|d|g|	|
d W d Q R X n~dd|g}dg}t|j	dƒ&}
||||
d}|||j
|	|
d	}W d Q R X |j
 ¡  | ¡ }|rÒ|||ƒ‚| ¡ }|rè|||ƒ‚W d Q R X y| |¡ W n tk
r   Y nX d S )
Nr   )ÚPopenÚ
check_callÚPIPEÚCalledProcessErrorÚwbr!   Zppmtogif)ÚstdoutÚstderrZppmquantZ256)Ústdinr¨   r©   )ÚosÚ
subprocessr£   r¤   r¥   r¦   Z_dumpÚopenr]   Údevnullr¨   rd   ÚwaitÚunlinkÚOSError)rU   r   r•   r«   r£   r¤   r¥   r¦   Úfiler=   r®   Z	quant_cmdZ	togif_cmdZ
quant_procZ
togif_procZretcoder   r   r   Ú_save_netpbmR  s0    	



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   rQ   r—   r   rQ   i   r   N)
r]   r‹   Ú_FORCE_OPTIMIZEÚwidthZheightÚ	enumerateZ	histogramr   r'   Úmax)rU   r#   Zoptimiser{   r4   Úcountr   r   r   rz   ƒ  s    rz   c             C   s:   dd l }t| | t| ƒd d¡¡ƒd }|dk r6d}|S )Nr   r   r    r   )Úmathrœ   ZceilÚlogr'   )r¡   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*   )rU   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}d}d
|krž|d
 }t|tƒrž| j |¡}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)rC   rD   rJ   rG   rD   r   rG   r   rH   s   89ar   r   s   GIFr   )r'   r#   r‹   rr   r   r*   ZgetcolorrŽ   rŸ   rž   rY   r	   r    )rU   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   rO   )r   r   r}   )r   r„   r   r…   rY   rm   r]   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   )rz   r#   r|   r*   rU   r   )rU   r*   r#   r{   Zim_modÚheaderr   r   r   Ú	getheader  s    

r½   ©r   r   c             K   s2   G dd„ dt ƒ}|  ¡  |ƒ }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)rf   rg   rh   r   r‚   r   r   r   r   Ú	Collector8  s   r¿   )ÚobjectrV   r   r   )rU   r’   r»   r¿   r   r   r   r   rn   *  s
    rn   z.gifz	image/gif)F)F)NN)r¾   )*Ú r   r   r   r   r   Z_binaryr   r   r$   r	   r
   rž   rv   Ú__version__r   r   rm   ro   r|   r‡   r“   r–   r…   rƒ   r„   r³   r´   rz   rŸ   r    rŽ   r   r   r½   rn   Zregister_openri   Zregister_saveZregister_save_allZregister_extensionZregister_mimer   r   r   r   Ú<module>   sB     
(D

N.#	
/

 