3
	jQcoh                 @   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d2ddZdd Zdd Zdd Zdd Zd3d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!d4d,d-Z"d6d.d/Z#ej$ej%ee ej&ej%e ej'ej%e ej(ej%d0 ej)ej%d1 dS )7   )Image	ImageFileImagePalette
ImageChopsImageSequence)i8i16leo8o16le    Nz0.9c             C   s   | d d dkS )N      GIF87a   GIF89a)r   r    )prefixr   r   4/usr/lib/python3/dist-packages/PIL/GifImagePlugin.py_accept&   s    r   c               @   sd   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S )GifImageFileZGIFzCompuserve GIFFNc             C   s,   | j jd}|r(t|r(| j jt|S d S )Nr   )fpreadr   )selfsr   r   r   data6   s    zGifImageFile.datac             C   sJ  | j 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 jd|> }xxtdt	|dD ]d}|d t||   kot||d
    kot||d  kn  st
jd|}| | _| _P qW | j | _| j j | _d | _d | _| jd d S )N   r      GIF87a   GIF89aznot a GIF fileversion   
      r         
background   r      RGB)r   r   )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*    "
FzGifImageFile._openc             C   sb   | j d kr\| j }yx| j| j d  qW W n" tk
rP   | j d | _ Y nX | j| | j S )Nr   )r3   r1   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| j }y| jd d| _ W n tk
rX   d| _ Y nX | j| | j S )Nr   TF)r4   r3   r1   r;   r<   )r   r=   r   r   r   is_animatedf   s    




zGifImageFile.is_animatedc             C   s   | j |sd S || jk r"| jd | j}xRt| jd |d D ]:}y| j| W q> tk
rv   | j| tdY q>X q>W d S )Nr   r   zno more images in GIF file)Z_seek_check_GifImageFile__framer5   r+   r<   r;   )r   frameZ
last_framefr   r   r   r;   w   s    



zGifImageFile.seekc             C   s  |dkrDd| _ d | _ddddg| _d"| _| jj| j d | _d| _n| j	sR| j
  || jd krltd| || _g | _| j| _| j r| jj| j  x| j rqW d| _ | jr| j	j| j| j ddlm} || j| _xD| jjd}| s|dk rP q|dkr(| jjd}| j }t|dkrt|d }|d@ rPt|d | jd	< t|dd d
 | jd< d|@ }|d? }|r|| _nt|dkr|| jd< nrt|dkr|| jj f| jd< |d d dkr| j }t|dkrt|d dkrt|dd | jd< x| j r$qW q|dkr| j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jd| jjd|> | _t| jjd}| jj | _ d|||	|
f| j ||ffg| _P qqW yz| jdk r6d | _nH| jdkrjtj| j tjjd| j| jd  | _n| j	r~| j	j | _| jr| j | j| j| _W n t!t"fk
r   Y nX | jst#d!| _$| jrd| _$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"   L)%Z_GifImageFile__offsetZdisposedispose_extentr@   r0   r;   r2   _prev_imdisposal_methodimload
ValueErrorr*   r   r   pasterC   r.   r/   r   r   r'   r(   r1   r,   r   r-   r   Z_decompression_bomb_checkr)   ZcoreZfill_cropAttributeErrorKeyErrorr<   mode)r   rA   rC   r   blockr6   Zdispose_bitsZx0Zy0Zx1Zy1	interlacer7   r   r   r   r5      s    


 "*

zGifImageFile._seekc             C   s   | j S )N)r@   )r   r   r   r   r1     s    zGifImageFile.tellc             C   s\   t j j|  | jrL| jdkrL| j| j| j}| jj|| j|jd | j| _| jj	 | _d S )Nr   ZRGBA)
r   load_endrX   rY   r^   rZ   rW   r]   convertrC   )r   updatedr   r   r   rd     s    zGifImageFile.load_end)__name__
__module____qualname__formatZformat_descriptionZ!_close_exclusive_fp_after_loadingr.   r   r:   propertyr>   r?   r;   r5   r1   rd   r   r   r   r   r   .   s    r   rU   rT   )1rU   rT   Fc             C   sp   | j tkr| j  | S tj| j dkrf|r\d}| jrJt| jj d d }| jdtj	|dS | jdS | j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#   rT   )r/   ZcolorsrU   )
ra   RAWMODEr[   r   Zgetmodebaser/   r,   getdatare   ZADAPTIVE)rZ   Zinitial_callZpalette_sizer   r   r   _normalize_mode0  s    

rp   c             C   s   d}|rjt |tttfr(t|dd }t |tjrjttjjt|j	dd |j	dd |j	dd }| j
dkr|s| jjddd }n*|stdd tdD }tjd|d	| _	t| |}|dk	r| j||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   rm   i   rT   r%   c             s   s   | ]}|d  V  qdS )r#   Nr   ).0r9   r   r   r   	<genexpr>j  s    z%_normalize_palette.<locals>.<genexpr>)r/   )
isinstancebytes	bytearraylistr   	itertoolschainfrom_iterablezipr/   ra   rZ   Z
getpaletter+   _get_optimizeZremap_palette)rZ   r/   r'   Zsource_paletteused_palette_colorsr   r   r   _normalize_paletteN  s*    


r}   c             C   s   t | d}t||| j}xt|| jD ]}|j| q&W d}t| rL|dB }t|| d| dt| f|_tj	||dd| j
 dt|j fg |jd d S )	NTr   rR   r   rS       )r   r   )r   r   )rp   r}   encoderinfo_get_global_headerwriteget_interlace_write_local_headerZencoderconfigr   _saver)   rn   ra   )rZ   r   r/   Zim_outr   r6   r   r   r   _write_single_framev  s    
r   c             C   s  | j jdd }| j jdd }g }d}x,tj| g| j jdg D ]}xtj|D ]}t|j }t||| j }| j j }	t	|t
tfr|| |	d< t	|t
tfr|| |	d< |d7 }|r6|d }
t|t|
d krtj||
d }ntj|jd|
d jd}|j }|s:|rT|
d d  |	d 7  < qTnd }|j|||	d	 qTW q@W t|dkrx|D ]~}|d }|d
 sx"t||d D ]}|j| qW d}n*d|d d< |j|d
 }|d
 d d }t||||d  qhW dS d S )NrH   disposalr   Zappend_imagesr   rZ   r%   r   )rZ   bboxr   r   Tinclude_color_tabler$   rV   )r   r   )r   getrw   rx   r   Iteratorrp   rC   r}   rs   rv   tuple_get_palette_bytesr   Zsubtract_modulore   Zgetbboxappendr,   r   r   Zcrop_write_frame_data)rZ   r   r/   rH   r   Z	im_framesZframe_countZ
imSequenceim_framer   ZpreviousZdeltar   Z
frame_datar   offsetr   r   r   _write_multiple_frames  sX    "


r   c             C   s   t | ||dd d S )NT)save_all)r   )rZ   r   filenamer   r   r   	_save_all  s    r   c             C   s   | j j| j y| j d }W n, tk
rH   d }| j jdd| j d< Y nX | s^t| || rjt| || |jd t|dr|j	  d S )Nr/   optimizeTrD   flush)
r   updater'   r`   r   r   r   r   hasattrr   )rZ   r   r   r   r/   r   r   r   r     s    

r   c             C   s$   | j jdd}t| jdk r d}|S )Nrc   r      r   )r   r   minr)   )rZ   rc   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|j|}W n tk
rn   d}Y nX d|j krt|j d d }nd}t|j jdd}|s|dks|r|rdnd}	|	|d	> O }	|sd}| jd
td td t|	 t	| t| td  d|j krxdt
|j d   ko:dkn  rx| jd
td tt
|j d  |j d  td  d|j kr|j d }
| jd
td td d td td t	|
 td  |j jd}|r|j jdd }t|}t|}|r|dB }||B }| jdt	|d  t	|d  t	|jd  t	|jd  t|  |rr|rr| jt| | jtd d S )NFrG   TrH   r   r   r   r   r$   rE   rF   rQ   rK   rL   rJ   rN   r!   s   NETSCAPE2.0r#   r   r/   r    rO   r   )r   r`   intr{   indexr\   r   r   r	   o16r,   r   _get_color_table_sizer)   _get_header_palette)r   rZ   r   r6   Ztransparent_color_existsrG   r|   rH   r   Zpacked_flagZnumber_of_loopsr   r/   palette_bytescolor_table_sizer   r   r   r     s`    

*2&
.6r   c             C   s  dd l }ddlm}m}m}m} | j }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
j  |j }|r||||j }|r|||W d Q R X y|j| 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openra   devnullr   closewaitunlinkOSError)rZ   r   r   r   r   r   r   r   filerB   r   Z	quant_cmdZ	togif_cmdZ
quant_procZ
togif_procZretcoder   r   r   _save_netpbm4  s0    	



r   c             C   s   | j dkr|r|jddrtp&| j dk}|s<| j| j d	k rg }x&t| j D ]\}}|rN|j| qNW |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
    rT   rU   r   r   i   r    N)rT   rU   i   )
ra   r   _FORCE_OPTIMIZEwidthZheight	enumerateZ	histogramr   r,   max)rZ   r'   Zoptimiser|   r9   countr   r   r   r{   e  s    r{   c             C   s:   dd l }t|j|j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/   )rZ   r   r   r   r     s    r   c             C   s   d}xrdD ]V}|r
||kr
|dkr.|| dks
|dkrZdt ||   koPdkn   rZq
d	}P q
W | jjd
d	krxd	}t| }t|}d|kr|d nd}d| t| jd  t| jd  t|d t|td t|gS )z2Return a list of strings representing a GIF headers   87arG   rH   rN   rK   r   r   rL   s   89ar   r"   s   GIFr    )rG   rH   rN   rK   )	r,   r'   r   r   r   r   r)   r	   r   )rZ   r'   r   ZextensionKeyr   r   r"   r   r   r   r     s$    
*
r   c             C   sR   zF||_ t| ||d tj|| dd|j dt|j fg | jd W d |` X d S )Nr   rS   r~   )r   r   )r   r   r   r   r)   rn   ra   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/   rZ   r   )rZ   r/   r'   r|   Zim_modheaderr   r   r   	getheader  s    

r   c             K   s2   G dd dt }| j  | }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 j| d S )N)r   r   )r   r   r   r   r   r     s    z getdata.<locals>.Collector.writeN)rg   rh   ri   r   r   r   r   r   r   	Collector  s   r   )objectr[   r   r   )rZ   r   r   r   r   r   r   r   ro     s
    ro   z.gifz	image/gif)F)F)NNr   r   )r   )* r   r   r   r   r   Z_binaryr   r   r(   r	   r
   r   rw   __version__r   r   rn   rp   r}   r   r   r   r   r   r   r   r   r{   r   r   r   r   r   r   ro   Zregister_openrj   Zregister_saveZregister_save_allZregister_extensionZregister_mimer   r   r   r   <module>   s@    }
(>

L.#	
'

 