o
    eS                     @  s  d dl mZ d dlZd dlZd dlZd dlZd dlmZ ddlm	Z	m
Z
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 G d	d
 d
eZejZdd ZG dd dejZddddZdd Zdd Zdd Zdd Zdd Z dd Z!d<d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/d0 Z+d1d2 Z,d3d4 Z-d=d5d6Z.d>d8d9Z/e	0ej1ee e	2ej1e" e	3ej1e! e	4ej1d: e	5ej1d; dS )?    )annotationsN)IntEnum   )Image
ImageChops	ImageFile	ImageMathImageOpsImagePaletteImageSequence)i16le)o8)o16lec                   @  s   e Zd ZdZdZdZdZdS )LoadingStrategyz.. versionadded:: 9.1.0r   r      N)__name__
__module____qualname____doc__RGB_AFTER_FIRST RGB_AFTER_DIFFERENT_PALETTE_ONLY
RGB_ALWAYS r   r   E/var/www/html/venv/lib/python3.10/site-packages/PIL/GifImagePlugin.pyr   0   s
    r   c                 C  s   | d d dv S )N   )s   GIF87as   GIF89ar   )prefixr   r   r   _accept?      r   c                      s~   e Zd ZdZdZdZdZdd Zdd Zd	d
 Z	e
dd Ze
dd Zdd ZdddZ f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   dataO   s   zGifImageFile.datac                 C  s\   t dt|dD ]#}|d ||   kr'||d    kr'||d  ks+ dS   dS qdS )Nr      r   r   TF)rangelen)r"   pir   r   r   _is_palette_neededU   s   4zGifImageFile._is_palette_neededc                 C  s   | j d}t|sd}t||d d | jd< t|dt|df| _g | _|d }|d@ d }|d	@ rU|d
 | jd< | j d|> }| |rUt	
d|}| | _| _| j | _| j  | _d | _d | _| d d S )N   znot a GIF filer   version   
      r         
backgroundr%   RGBr   )r    r!   r   SyntaxErrorinfoi16_sizetiler*   r
   rawglobal_palettepalette_fptell_GifImageFile__rewind	_n_frames_is_animated_seek)r"   r#   msgflagsbitsr(   r   r   r   _open[   s(   
zGifImageFile._openc                 C  s\   | j d u r+|  }z	 | |  d d q ty%   |  d | _ Y nw | | | j S )NTr   F)r?   r=   rA   EOFErrorseekr"   currentr   r   r   n_framesw   s   

zGifImageFile.n_framesc                 C  s~   | j d u r<| jd ur| jdk| _ | j S |  }|rd| _ | j S z| dd d| _ W n ty6   d| _ Y nw | | | j S )Nr   TF)r@   r?   r=   rA   rF   rG   rH   r   r   r   is_animated   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yB } z| | d}t||d }~ww d S )Nr   r   no more images in GIF file)_seek_check_GifImageFile__frameimrA   r&   rF   rG   )r"   frame
last_frameferB   r   r   r   rG      s    




zGifImageFile.seekTc                   s  |dkr!d _ d  _d _ j j d _d jv r  jd= n	 jr*|r* 	  | jd kr:d| }t
| j _ j rT j j    rQ	   sLd _  jd}|r`|dkrfd}t|d }i }d }d }d }		 |sy jd}|r|dkrn9|d	kr' jd}  }
|d d
kr|
d }|d@ r|
d }t|
dd |d< d|@ }|d? }|r| _nb|d dkrd}|
r||
7 }  }
|
sd|v r|d  d| 7  < n||d< d }qp|d dkr|dkr|
 j f|d< |
d d dkr  }
t|
dkr|
d dkrt|
d jd<   r&	   s n|dkr jd}t|dt|d}}|t|d |t|d }}| jd ks\| jd krv|rvt| jd t| jd f _t j ||||f}	|d }|d@ dk}|d@ r|d@ d } jd|> } |rtd |}nd!} jdd } j  _ nd }qq|d u rd"}t|| _|sd S g  _ jr݈ j j j |d ur|n j _| _|dkr" jr	t t!j"kr|d urd#nd  _#nd$ _#nd% _#|s jrdd&l$m$} | j}| _%nA j&d$krct t!j'ks1|rcd  _(d' jv rV j) jd' d  j*d#tj+j, _d# _# jd'= nd  _# j*d tj+j, _ fd(d)}|	 _z jdk rwd  _n jdkrˈ j\}}}}|| || f}t| d$} j-d'|}|d ur j&d*v rd#}||d+ }n j-d,d} j&d*v rd }||}tj./||| _nD jd urۈ 0 j j _n4|d ur j\}}}}|| || f}t| d$}|} j&d*v rd#}||d+ }tj./||| _W n
 t1y   Y nw |d urPd}|d ur@|dkr8t t!j"kr7| jd'< n j&d*vr@|}d-||||f j |||ffg _|-dr]|d  jd< d.D ]}||v ro||  j|< q_| jv ry j|= q_d S )/Nr   commentr   zcannot seek to frame    ;rL   T   !   r%   r.   duration   r             
   	extensionr1      NETSCAPE2.0loop   ,	      r   r-   @   r0   r/   r3   Fzimage not found in GIF frameRGBAPL)copytransparencyc                   sT    j r#| d d t j jkrd} t j j| d | d d  } | S | | | f} | S )Nr%   r   )_frame_paletter'   r;   tuple)colorr"   r   r   _rgbT  s    
z GifImageFile._seek.<locals>._rgbr3   rf   )r   r2   gif)rY   r_   )2_GifImageFile__offsetdisposerN   r<   rG   r>   disposal_methodr5   r8   load
ValueErrorr    r$   r!   rF   r6   r=   r'   sizemaxr7   r   _decompression_bomb_checkr*   r
   r9   rO   pastedispose_extentr:   rk   _frame_transparencyLOADING_STRATEGYr   r   _moderi   r;   moder   pyaccessputpalettealphaconvertDitherFLOYDSTEINBERGgetcorefill_cropAttributeError)r"   rP   update_imagerB   r#   r;   r5   frame_transparency	interlaceframe_dispose_extentblockrC   dispose_bitsrU   x0y0x1y1rD   r(   ri   ro   dispose_sizedispose_moderm   rj   kr   rn   r   rA      sp  






&"

[


	








	
zGifImageFile._seekc                   s   | j rdnd}d | _| jdkr | jd urtj|| j| j| _n&| j	dv rF| j| _| j rCtjd| j| jp6d| _| jj
| j    nd | _|| _d | _ t   d S )Nrg   rh   r   rp   )rk   _prev_imrN   r|   r   r   r   rw   rO   r   
putpalettegetdatar~   superload_prepare)r"   	temp_mode	__class__r   r   r     s"   



zGifImageFile.load_preparec                 C  s   | j dkr0| jdkr.ttjkr.| jd ur | j| jd d| _nd| _| j	| jt
jj| _d S | js5d S | jd urI| j| jd | j	d}n| j	d}| || j}| j| _| jj| _|jdkro| j|| j| d S | j|| j d S )Nr   rg   rf   r3   )rN   r   r}   r   r   r|   rO   r   r~   r   r   r   r   r   r   r{   rz   )r"   frame_imr   r   r   load_end  s(   




zGifImageFile.load_endc                 C  s   | j S N)rN   rn   r   r   r   r=     s   zGifImageFile.tell)T)r   r   r   formatformat_description!_close_exclusive_fp_after_loadingr:   r$   r*   rE   propertyrJ   rK   rG   rA   r   r   r=   __classcell__r   r   r   r   r   H   s$    


 r   rh   rg   )1rh   rg   c                 C  s   | j tv r|   | S t| j dkr=| jdtjjd} | jj dkr;| jj	D ]}|d dkr:| jj	| | j
d<  | S q&| 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.

    :param im: Image object
    :returns: Image object
    r3   rg   r;   rf   r%   r   rj   rh   )r   RAWMODEru   r   getmodebaser   PaletteADAPTIVEr;   colorsr5   )rO   rgbar   r   r   _normalize_mode  s   

r   c           	      C  s  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	  }| jj|}||v rkd}|| qRt|D ]\}}|du rt	t
|D ]}||vr|||<  nqqu| |} n/t| |}|dur| ||} d
|v rz||d
 |d
< W | S  ty   |d
= Y | S w | 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   rg   r3   c                 s  s    | ]}|d  V  qdS )r%   Nr   ).0r)   r   r   r   	<genexpr>  s    z%_normalize_palette.<locals>.<genexpr>r   r   r%   rj   )
isinstancebytes	bytearraylistr
   r;   r   rO   
getpaletter&   r'   rl   r   r   append	enumerateremap_palette_get_optimizeindexrv   )	rO   r;   r5   source_paletteused_palette_colorsr)   source_colorr   jr   r   r   _normalize_palette  s\   



r   c              	   C  s   t | }|j D ]\}}| j|| q	t||| j}t|| jD ]}|| q"d}t| r4|dB }t	|| d| dt| f|_
t||dd| j dt|j fg |d d S )Nr   re   r   r   r-   rq       )r   r5   itemsencoderinfo
setdefaultr   _get_global_headerwriteget_interlace_write_local_headerencoderconfigr   _saverw   r   r   )rO   r    r;   im_outr   vr#   rC   r   r   r   _write_single_frame2  s   $r   c                 C  s@   t |t | kr|d}| d} t|| }||jddfS )Nrf   F)
alpha_only)_get_palette_bytesr   r   subtract_modulogetbbox)base_imim_framedeltar   r   r   _getbboxG  s
   

r   c              
   C  s  | j d}| j d| jd}g }d }d}d }t| g| j dg D ]T}	t|	D ]K}
t|
 }
|dkrP|
j	 D ]\}}|dkrHq?| j 
|| q?| j  }d|
jv rc|
d|
jd  t|
||}
t|ttfrw|| |d< n|d u rd|
jv r|
jd |d< t|ttfr|| |d< |d7 }d }|rit||
\}}|s|dr|d d d  |d 7  < q-|dd	kr|d u r| j d| jdd
}t|
|}td|
j|}||d d j t||
\}}|drh|
jdkrhd|vrz
|
j|
|d< W n
 ty   Y nw d|v rh|
 }td|j|d }|jdkrA| \}}}}tjd||||d}n|jdkrWtd|j}||  |}tjd|d}|j|t |d nd }|
}|!|ps|
||d q-q%t"|dkrd| j v r|d d d | j d< d S |D ]@}|d }
|d st#|
|d D ]}|$| qd}n|sd|d d< |
%|d }
|d d d	 }t&||
||d  qdS )NrY   disposalr   append_imagesrj   r   rT   r   r   )r   r   r   rg   rO   optimizer   rf   z-convert(max(max(max(r, g), b), a) * 255, '1'))rgbarh   zconvert(im * 255, '1')rO   )mask)rO   bboxr   r   r   Tinclude_color_table)'r   r   r5   	itertoolschainr   Iteratorr   ri   r   r   r   r   r   rl   r   _get_backgroundr   newrw   r   r;   r   _new_color_indexrv   splitr   evalputdatar   rz   r	   invertr   r'   r   r   crop_write_frame_data)rO   r    r;   rY   r   	im_framesprevious_imframe_countbackground_im
imSequencer   r   r   r   
diff_framer   r   rm   r2   r   r   r   r   r   r   delta_l
frame_datar#   offsetr   r   r   _write_multiple_framesO  s   






O
r   c                 C  s   t | ||dd d S )NT)save_all)r   )rO   r    filenamer   r   r   	_save_all  s   r   Fc                 C  s~   d| j v s
d| jv r| j d| jd}n	d }| j dd |r't| ||s-t| || |d t|dr=|  d S d S )Nr;   r   TrV   flush)	r   r5   r   r   r   r   r   hasattrr   )rO   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   minrw   )rO   r   r   r   r   r     s   r   c                 C  sj  z|j d }W n ty   d }Y nw d|j v r"t|j d d }nd}t|j dd}|d us7|dks7|rd|d ur=dnd}||d> O }| dtd	 td
 t| t| t|p\d 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 )Nrj   rY   r.   r   r   r   r   rW   rX   rd   r   r0   rb   r-   )r   KeyErrorintr   r   r   o16r   _get_color_table_sizerw   _get_header_palette)r    rO   r   rC   rj   rY   r   packed_flagr   palette_bytescolor_table_sizer   r   r   r     sd   




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wbr3   ppmtogif)stdoutstderrppmquant256)stdinr	  r
  )_dumpopenr   
subprocess
check_callDEVNULLPopenPIPEr	  closewaitCalledProcessErrorosunlinkOSError)
rO   r    r   tempfilerR   	quant_cmd	togif_cmd
quant_proc
togif_procretcoder   r   r   _save_netpbm  sL   



r!  c                 C  s   | j dv r`|rb|drdtp| j dk}|s| j| j dk rfg }t|  D ]\}}|r0|| q%|s;t|t	|kr=|S t	| j
j
t| j
j  }d|d  > }t	||d krh|dkrj|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
    )rg   rh   r   rh   i   r   r   N)r   r   _FORCE_OPTIMIZEwidthheightr   	histogramr   rx   r'   r;   r   getmodebands
bit_length)rO   r5   optimiser   r)   countnum_palette_colorscurrent_palette_sizer   r   r   r   B  s*   
r   c                 C  s6   | sdS t | dk rdS ttt | d dd S )Nr   rc   r   r%   r   )r'   mathceillog)r  r   r   r   r  p  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  z  s
   r  c                 C  s   | j r| j j S d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   r     s   r   c              
   C  sd   d}|r0t |tr.z
| j|| }W |S  ty- } zt|dvr" W Y d }~|S d }~ww |}|S )Nr   )z$cannot allocate more than 256 colorsz/cannot add non-opaque RGBA color to RGB palette)r   rl   r;   getcolorrv   str)rO   info_backgroundr2   rS   r   r   r   r     s   



r   c                 C  s~  d}| j ddks!|r#d|v s!|ddus!|ds!|dr#d}t| |d	}t| }t|}d
| t| jd  t| jd  t|d t|td t|g}|ddur}|	dtd td d td td t|d  td  |drdtd }|d }t
|tr| }tdt|dD ]}	||	|	d  }
|tt|
|
 7 }q|td7 }|	| |S )z2Return a list of strings representing a GIF headers   87ar,   s   89arj   ra   NrY   rU   r2   s   GIFr   r   r0   rW   r^   r1   r`   r%   r[   )r5   r   r   r   r  r  rw   r   r  r   r   r1  encoder&   r'   )rO   r5   r,   r2   r  r  headercomment_blockrU   r)   subblockr   r   r   r     sl   





r   c              	   C  sT   z&||_ t| ||d t|| dd|j dt|j fg | d W |` d S |` w )Nr   rq   r   r   )r   r   r   r   rw   r   r   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)

    Nr2   )r   r5   r   r;   rO   r   )rO   r;   r5   r   im_modr4  r   r   r   	getheader  s   

r9  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.

    To specify duration, add the time in milliseconds,
    e.g. ``getdata(im_frame, duration=1000)``

    :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   0  r   z getdata.<locals>.Collector.writeN)r   r   r   r$   r   r   r   r   r   	Collector-  s    r:  )ru   r   r$   )rO   r   r7  r:  r    r   r   r   r     s
   r   z.gifz	image/gif)F)NN)r   )6
__future__r   r   r,  r  r  enumr    r   r   r   r   r	   r
   r   _binaryr   r6   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   r9  r   register_openr   register_saveregister_save_allregister_extensionregister_mimer   r   r   r   <module>   sV   $			   <p

01.

>

$