o
    f4                     @   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d6d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#d7d/d0Z$d8d2d3Z%e&ej'ee e(ej'e e)ej'e e*ej'd4 e+ej'd5 dS )9    N   )Image
ImageChops	ImageFileImagePaletteImageSequence)i16le)o8)o16lec                 C   s   | d d dv S )N   )s   GIF87as   GIF89a )prefixr   r   4/usr/lib/python3/dist-packages/PIL/GifImagePlugin.py_accept)      r   c                       s|   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dd Z  ZS )GifImageFile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	@ rw|d
 | jd< | j d|> }tdt	|dD ],}|d ||   krg||d    krg||d  ksvn t
d|}| | _| _ nqJ| 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   sZ   | j d u r*|  }z	 | |  d  q ty$   |  d | _ Y nw | | | j S )NTr   )r0   r.   seekEOFErrorr   currentr   r   r   n_frames^   s   

zGifImageFile.n_framesc                 C   sl   | j d u r3| jd ur| jdk| _ | j S |  }z
| d d| _ W n ty-   d| _ Y nw | | | j S )Nr   TF)r1   r0   r.   r8   r9   r:   r   r   r   is_animatedj   s   





zGifImageFile.is_animatedc                 C   s   |  |sd S || jk rd | _| d | j}t| jd |d D ]}z| | W q! ty@ } z
| | td|d }~ww d S )Nr   r   zno more images in GIF file)_seek_check_GifImageFile__frameimr2   r(   r9   r8   )r   frame
last_framefer   r   r   r8   {   s   




zGifImageFile.seekc                    s  |dkrd| _ d | _g d| _d| _| j| j d| _n| jr$| 	  || jd kr2t
d| g | _| j| _| j rO| j| j  |  rL	 |  sGd| _ d }i }d }d }d }	 | jd}|rf|dkrhn|dkr| jd}|  }|d d	kr|d }	|	d@ r|d
 }t|dd |d< d|	@ }
|
d? }
|
r|
| _nN|d dkr|rd|v r|d  |7  < n||d< |  }|sqY|d dkr|| j f|d< |d d dkr|  }t|d
kr|d dkrt|d|d< |  r	 |  sn|dkry| jd}t|dt|d}}|t|d |t|d }}|| jd ks,|| jd krCt|| jd t|| jd f| _t| j ||||f}|d }	|	d@ dk}|	d@ rj|	d@ d }td| jd
|> }| jdd }| j | _ n	 qZ|d u rt|| _| jdkrd | _d| jv rd | _| j| jd d | jd tj| _| jd= nd| _| jdtj| _| jr| j | j| j |p| j!  fd!d"}|| _z| jdk rd | _nx| jdkr&| j\}}}}|| || f}t| | j"d|}|d urd }||d# }nd}|| j"d$d}tj#$|||| _n4| jr4| %| j| j| _n&|d urZ| j\}}}}|| || f}t| tj#$d |||d# | _W n
 t&ye   Y nw |d ur|dkrz|d urz|| jd< d%||||f| j ||ffg| _ntd&D ]}||v r|| | j|< q|| jv r| j|= q|dkrЈ rd'nd(| _| jd'kr|sdd)l'm'} || j!}|| _(d S  | _)|| _*d S )*Nr   )r   r   r   r   r   zcannot seek to frame T   ;   !   r    r   duration   r!      comment   	extensionr      NETSCAPE2.0loop   ,	      r   r   @   r   r   r"   transparencyRGBAc                    s4    rt  j| d | d d  } | S | | | f} | S )Nr    )tupler,   )colorframe_paletter   r   _rgb  s
   
z GifImageFile._seek.<locals>._rgb)r   r   gif)rI   rL   rN   rP   PL)copy)+_GifImageFile__offsetdisposedispose_extentr?   r-   r8   r/   disposal_methodr'   load
ValueErrorr   r   r   r%   r.   r)   sizemaxr&   r   _decompression_bomb_checkr   r*   r9   pyaccessr$   moder@   putpalettealphaconvertFLOYDSTEINBERGpaster+   getcorefill_cropAttributeErrorr_   r,   _frame_palette_frame_transparency)r   rA   r,   r$   frame_transparency	interlaceframe_dispose_extentr   blockr3   dispose_bitsx0y0x1y1r4   r[   dispose_sizerX   dispose_modekr_   r   rY   r   r2      s"  

 "

S













zGifImageFile._seekc                    s   | j dkrd| jv rtj| j| j| jd | _n*| j| _| j	r=d| _tjd| j| j
p-d| _| jj| j	   d | _	nd| _d | _t   d S )Nr   rU   r]   r^   )r?   r$   r   rp   rq   rj   rf   r@   _prev_imrt   ru   
putpalettegetdatasuperload_preparer   	__class__r   r   r   d  s   

zGifImageFile.load_preparec                 C   s   | j dkrd S | jd ur| j| jd | jd}n| jd}| || j}| j| _| jj| _|jdkrA| j	|| j| d S | j	|| j d S )Nr   rV   r"   )
r?   ru   r@   rk   rl   rr   rb   r   rj   rn   )r   frame_imr   r   r   load_endw  s   



zGifImageFile.load_endc                 C   s   | j S N)r?   r   r   r   r   r.     s   zGifImageFile.tellc                 C   sP   z#z| j | jkr| j   W n	 ty   Y nw W d | _ d S W d | _ d S d | _ w r   )r-   r   closers   r   r   r   r   
_close__fp  s   

zGifImageFile._close__fp)__name__
__module____qualname__formatformat_description!_close_exclusive_fp_after_loadingr+   r   r7   propertyr<   r=   r8   r2   r   r   r.   r   __classcell__r   r   r   r   r   2   s$    

 [r   r^   r]   )1r^   r]   Fc                 C   s   | j tv r|   | S t| j dkrV|rQd}| jr%t| j d d }| jdtj	|d} | jj dkrO| jj
 D ]}|d dkrN| jj
| | jd	<  | S q:| 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    r]   )r,   colorsrV   r   rU   r^   )rj   RAWMODErd   r   getmodebaser,   r)   r   rl   ADAPTIVEr   keysr$   )r@   initial_callpalette_sizergbar   r   r   _normalize_mode  s&   


r   c           	   	   C   sf  d}|rt |tttfrt|dd }t |tjrt|j}| jdkr1|s0| jddd }n|s>tdd t	dD }tjd|d| _|rg }t	dt
|d	D ]%}t|||d	  }z| jj| }W n tyq   d}Y nw || qRt|D ]\}}|du rt	t
|D ]}||vr|||<  nqq|| |} nt| |}|du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   r]   r"   c                 s   s    | ]}|d  V  qdS )r    Nr   ).0r6   r   r   r   	<genexpr>  s    z%_normalize_palette.<locals>.<genexpr>r,   r   r    )
isinstancebytes	bytearraylistr   r,   rj   r@   
getpaletter(   r)   rW   r   KeyErrorappend	enumerateremap_palette_get_optimize)	r@   r,   r$   source_paletteused_palette_colorsr6   source_colorindexjr   r   r   _normalize_palette  sJ   


r   c              	   C   s   t | d}|j D ]\}}| j|| q
t||| j}t|| jD ]}|| q#d}t| r5|dB }t	|| d| dt| f|_
t||dd| j dt|j fg |d d S )NTr   rT   r   r   r   r\       )r   r$   itemsencoderinfo
setdefaultr   _get_global_headerwriteget_interlace_write_local_headerencoderconfigr   _saverf   r   rj   )r@   r   r,   im_outr   vr   r3   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rL|	j	 D ]\}
}| j 
|
| q@t|	|| j }	| j  }t|ttfre|| |d< t|ttfrr|| |d< |d7 }|r|d }|ddkr|d u 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/q(t|dkr:|D ]?}|d }	|d st|	|d D ]}|| q
d}n|sd|d d< |	|d }	|d d d }t||	||d  qdS d| j v rWt| j d ttfrYt | j d | j d< d S d S d S )NrI   disposalr   append_imagesr   rE   r!   rU   )r   r   r   r]   r@   r"   r   )r@   bboxr   r   r   Tinclude_color_table)!r   ro   r$   	itertoolschainr   Iteratorr   r_   r   r   r   r   r   rW   _get_backgroundr   newrf   r   r,   _get_palette_bytesr   subtract_modulorl   getbboxr   r)   r   r   crop_write_frame_datasum)r@   r   r,   rI   r   	im_framesframe_countbackground_im
imSequenceim_framer   r   r   previousrX   r   base_imdeltar   
frame_datar   offsetr   r   r   _write_multiple_frames
  s|   

-
r   c                 C   s   t | ||dd d S )NT)save_all)r   )r@   r   filenamer   r   r   	_save_allX  s   r   c                 C   s   d| j v s
d| jv r| j d| jd}nd }| j dd| j d< |r*t| ||s0t| || |d t|dr@|  d S d S )Nr,   optimizeTrF   flush)r   r$   ro   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 )Nrw   r      r   )r   ro   minrf   )r@   rw   r   r   r   r   m  s   r   c                 C   s  d}z|j d }W n	 ty   Y n$w t|}d}t||j }|d ur6z||}W n ty5   d}Y nw d|j v rEt|j d d }nd}t|j dd}|sX|dksX|r|r\dnd}	|	|d	> O }	|shd}| d
td td t|	 t	| t| td  d|j v rdt
|j d kr| d
td  |j d }
t|
tr|
 }
tdt
|
dD ]}|
||d  }| tt
||  q| td d|j v 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|  |rD|rD| t| | td d S )NFrU   TrI   r   r   r   r   r!   rG   rH   rS   rL   rK   rM   rP   r   rO   r    r   r   rQ   r   )r   r   intr   r   re   ro   r   r	   o16r)   r   strencoder(   r   _get_color_table_sizerf   _get_header_palette)r   r@   r   r3   transparent_color_existsrU   r   rI   r   packed_flagrL   r6   subblocknumber_of_loopsr   palette_bytescolor_table_sizer   r   r   r   w  s   








r   c           
      C   s  |   }ztt|dS}| jdkrtjd|g|tjd n:dd|g}dg}tj|tjtjd}tj||j|tjd}|j	  |
 }	|	rJt|	||
 }	|	rVt|	|W d    n1 s`w   Y  W zt| W d S  tyx   Y d S w zt| W w  ty   Y w w )Nwbr"   ppmtogif)stdoutstderrppmquant256)stdinr   r   )_dumpopenrj   
subprocess
check_callDEVNULLPopenPIPEr   r   waitCalledProcessErrorosunlinkOSError)
r@   r   r   tempfilerC   	quant_cmd	togif_cmd
quant_proc
togif_procretcoder   r   r   _save_netpbm  sL   



r
  c                 C   s   | j dv rD|rF|ddrHtp| j dk}|s| j| j dk rJg }t|  D ]\}}|r1|| q&|sBt|dkrLt	|t|krN|S dS dS dS dS d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)
rj   ro   _FORCE_OPTIMIZEwidthheightr   	histogramr   r)   rg   )r@   r$   optimiser   r6   countr   r   r   r      s    
r   c                 C   s6   | sdS t | dk rdS ttt | d dd S )Nr   rR   r   r    r!   )r)   mathceillog)r   r   r   r   r   %  s
   r   c                 C   s<   t | }d|> t| d  }|dkr| 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   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   A  s   r   c              
   C   sd   d}|r0|}t |tr0z
| j|| }W |S  ty/ } zt|dkr*W Y d }~dS  d }~ww |S )Nr   z$cannot allocate more than 256 colors)r   rW   r,   getcolorre   r   )r@   infoBackgroundr   rD   r   r   r   r   K  s   
r   c                 C   s   d}dD ]*}|r.||v r.|dkr|| dks)|dkr*dt ||   kr(dks*n qd} nq| jd	dkr9d}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)rU   rI   rP   rL   rI   r   rL   r   rM   s   89ar   r   s   GIFr   )
r)   r$   ro   r   r   r   r   rf   r	   r   )r@   r$   r   extensionKeyr   r   r   r   r   r   r   _  s2   &
r   c              	   C   sT   z&||_ t| ||d t|| dd|j dt|j fg | d W |` d S |` w )Nr   r\   r   r   )r   r   r   r   rf   r   rj   r   )r   r   r   paramsr   r   r   r     s   r   c                 C   sd   t | |}|du ri }d|vrd| jv r| 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   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     r   z getdata.<locals>.Collector.writeN)r   r   r   r   r   r   r   r   r   	Collector  s    r  )rd   r   r   )r@   r   r  r  r   r   r   r   r     s
   r   z.gifz	image/gif)F)NN)r   ),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   register_openr   register_saveregister_save_allregister_extensionregister_mimer   r   r   r   <module>   sJ   	  i
$5N

T2%

'

!