o
    e.K                     @  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Zd dlZd dlZd dl	Z	d dl
mZ d dlmZ d dlZd dlmZ d dlmZmZmZ d dlmZ ejsYd dlmZmZmZ e	  e	d	 d d
l m!Z! W d   n1 ssw   Y  e"e#Z$d:ddZ%d;ddZ&d<ddZ'dd Z(dd Z)d=ddZ*dd  Z+d!d" Z,d>d$d%Z-d?d'd(Z.d@d*d+Z/d,d- Z0dAd/d0Z1dBd2d3Z2dCd5d6Z3dDd8d9Z4dS )E    )annotationsN)BytesIO)Path)utils)ImageImageOpsPngImagePlugin)
wasm_utils)FFmpegFFprobeFFRuntimeErrorignore)AudioSegmentx
str | dictreturnbytesc                 C  s@   t | tr| dr| d }n
t| d }n| }tt|S )zUConverts a base64 string or dictionary to a binary string that can be sent in a POST.dataname)
isinstancedictgetclient_utilsZencode_url_or_file_to_base64base64	b64decodeextract_base64_data)r   Z	base64str r   GD:\Projects\ConvertPro\env\Lib\site-packages\gradio/processing_utils.py	to_binary#   s   


r   strc                 C  s   |  ddd S )z;Just extracts the base64 data from a general base64 string.,   )rsplit)r   r   r   r   r   /   s   r   encodingImage.Imagec                 C  sb   t | }ttt|}zttdrt|}W |S W |S  t	y0   t
jd|dd Y |S w )Nexif_transposez0Failed to transpose image %s based on EXIF data.T)exc_info)r   r   openr   r   r   hasattrr   r&   	Exceptionlogwarning)r$   Zimage_encodedimgr   r   r   decode_base64_to_image9   s    
r.   c                 C  sT   t  }| j|dd | }W d    n1 sw   Y  tt|d}d| S )Npngformatutf-8data:image/png;base64,)r   Zsavefiggetvaluer   r   	b64encode)Zpltoutput_bytes
bytes_data
base64_strr   r   r   encode_plot_to_base64H   s   
r9   c                 C  s@   t  }| j D ]\}}t|trt|tr||| q	|S N)r   ZPngInfoinfoitemsr   r   Zadd_text)	pil_imagemetadatakeyvaluer   r   r   get_pil_metadataP   s   rA   r/   c                 C  sF   t  }| j||t| d | W  d    S 1 sw   Y  d S )N)Zpnginfo)r   saverA   r4   )r=   r1   r6   r   r   r   encode_pil_to_bytesZ   s   $rC   c                 C  s    t | }tt|d}d| S )Nr2   r3   )rC   r   r   r5   )r=   r7   r8   r   r   r   encode_pil_to_base64`   s   rD   c                 C  sh   t  }tt| tjdd}||d | }W d    n1 s#w   Y  tt	
|d}d| S )NF)
force_copyZPNGr2   r3   )r   r   Z	fromarray_convertnpuint8rB   r4   r   r   r5   )Zimage_arrayr6   r=   r7   r8   r   r   r   encode_array_to_base64f   s   
rI   centerc                 C  sl   |dkrd}n	|dkrd}nt t|}|d du r!| jd |d< |d du r.| jd |d< tj| ||dS )	a  
    Resize and crop an image to fit the specified size.
    args:
        size: `(width, height)` tuple. Pass `None` for either width or height
        to only crop and resize the other.
        crop_type: can be 'top', 'middle' or 'bottom', depending on this
            value, the image will cropped getting the 'top/left', 'middle' or
            'bottom/right' of the image to fit the size.
    raises:
        ValueError: if an invalid `crop_type` is provided.
    top)r   r   rJ   )      ?rL   r   Nr!   )Z	centering)
ValueErrorlistsizer   fit)r-   rO   Z	crop_typerJ   resizer   r   r   resize_and_cropo   s   rR   d   c           
   
   C  s   zt | }W n' ty. } zt|  }|r#d|rdn|  dd nd}t||d }~ww |dks7|dkrMt|| d }t|| d }||| }t|	 }	|j
dkr`|	d	|j
}	|j|	fS )
NzCannot load audio from file: `Zffprobez` not found.zr Please install `ffmpeg` in your system to use non-WAV audio file formats and make sure `ffprobe` is in your PATH. r   rS   r!   r"   )r   	from_fileFileNotFoundErrorr   is_fileRuntimeErrorlenrG   arrayZget_array_of_sampleschannelsZreshape
frame_rate)
filenameZcrop_minZcrop_maxaudioeisfilemsgZaudio_startZ	audio_endr   r   r   r   audio_from_file   s*   



rb   wavc                 C  sZ   |dkrt |}t| | |jjt|jdkrdn|jd d}|j||d}|  d S )Nrc   r!   )r\   Zsample_widthr[   r0   )	convert_to_16_bit_wavr   tobytesdtypeitemsizerY   shapeZexportclose)Zsample_rater   r]   r1   r^   filer   r   r   audio_to_file   s   rk   c                 C  s   d}| j tjtjtjfv r+t|| j  | t| 	  } | d } | 
tj} | S | j tjkrFt|| j  | d } | 
tj} | S | j tjkrO	 | S | j tjkrjt|| j  | d } | 
tj} | S | j tjkrt|| j  | d d } | 
tj} | S td| j  d)NzCTrying to convert audio automatically from {} to 16-bit int format.i  i  i   i  z2Audio data cannot be converted automatically from z to 16-bit int format.)rf   rG   float64float32float16warningswarnr1   absmaxastypeZint16Zint32Zuint16rH   rM   )r   r,   r   r   r   rd      s<   
rd   Fc                   s  t dtjdtjdtdtjdtjdtjdtjdi}dd }d dd d! fd	d
	}t	| } | j
}|tju r:t
dnt
|}|j}	|j}
|j}|j}|j}|j}t|	t|rb|r`|  } | S |dv rrt|	j}t|	j}|dv rt|
j}t|
j}|dkr| |	||	 d d kS |dkr| |
}|dkr||
||
 d 9 }|S |dkrA|dkr| |
S t| dk st| dkrtd|||	tjtj}|s|dkrtj| ||d}ntj| || d |d}|d8 }tj||d tj||||d n7|dkrtj| |d |d}tj|d||d ntj| || d d |d}tj||d tj||||d ||
S |dkru|||
tjtj}|dkr_tj| d| |d} ntj| d|d} | d||  9 } t	| |
S |dkr|dkr|| d| d| d } | |
S || d| d| S |dkr|| d| d d| } t| j|
}tj| d|| j
dd |S ||kr|| d| d d| d S |  d|d } | |8 } || d| d| dd} | |7 } | |
S )"a  
    Adapted from: https://github.com/scikit-image/scikit-image/blob/main/skimage/util/dtype.py#L510-L531

    Convert an image to the requested data-type.
    Warnings are issued in case of precision loss, or when negative values
    are clipped during conversion to unsigned integer types (sign loss).
    Floating point values are expected to be normalized and will be clipped
    to the range [0.0, 1.0] or [-1.0, 1.0] when converting to unsigned or
    signed integers respectively.
    Numbers are not shifted to the negative side when converting from
    unsigned to signed integer types. Negative values will be clipped when
    converting to unsigned integers.
    Parameters
    ----------
    image : ndarray
        Input image.
    dtype : dtype
        Target data-type.
    force_copy : bool, optional
        Force a copy of the data, irrespective of its current dtype.
    uniform : bool, optional
        Uniformly quantize the floating point range to the integer range.
        By default (uniform=False) floating point values are scaled and
        rounded to the nearest integers, which minimizes back and forth
        conversion errors.
    .. versionchanged :: 0.15
        ``_convert`` no longer warns about possible precision or sign
        information loss. See discussions on these warnings at:
        https://github.com/scikit-image/scikit-image/issues/2602
        https://github.com/scikit-image/scikit-image/issues/543#issuecomment-208202228
        https://github.com/scikit-image/scikit-image/pull/3575
    References
    ----------
    .. [1] DirectX data conversion rules.
           https://msdn.microsoft.com/en-us/library/windows/desktop/dd607323%28v=vs.85%29.aspx
    .. [2] Data Conversions. In "OpenGL ES 2.0 Specification v2.0.25",
           pp 7-8. Khronos Group, 2010.
    .. [3] Proper treatment of pixels as integers. A.W. Paeth.
           In "Graphics Gems I", pp 249-256. Morgan Kaufmann, 1990.
    .. [4] Dirty Pixels. J. Blinn. In "Jim Blinn's corner: Dirty Pixels",
           pp 47-57. Morgan Kaufmann, 1998.
    )FT)r"   r!   c                   s   t  fdd|D S )a  Return first of `dtypes` with itemsize greater than `itemsize`
        Parameters
        ----------
        itemsize: int
            The data type object element size.
        Other Parameters
        ----------------
        *dtypes:
            Any Object accepted by `np.dtype` to be converted to a data
            type object
        Returns
        -------
        dtype: data type object
            First of `dtypes` with itemsize greater than `itemsize`.
        c                 3  s$    | ]}t |j kr|V  qd S r:   )rG   rf   rg   ).0dtrg   r   r   	<genexpr>  s   " z4_convert.<locals>._dtype_itemsize.<locals>.<genexpr>)next)rg   Zdtypesr   rv   r   _dtype_itemsize  s   z!_convert.<locals>._dtype_itemsizer!   c                   s0   t  fdd|fd D }tt| S )a  Return dtype of `kind` that can store a `bits` wide unsigned int
        Parameters:
        kind: str
            Data type kind.
        bits: int
            Desired number of bits.
        itemsize: int
            The data type object element size.
        Returns
        -------
        dtype: data type object
            Data type of `kind` that can store a `bits` wide unsigned int
        c                 3  s4    | ]} |d  k s |d  krdkr|V  qdS )   uNr   )rt   ibitskindr   r   rw   -  s     z0_convert.<locals>._dtype_bits.<locals>.<genexpr>)      rz   )rx   rG   rf   r   )r   r~   rg   sr   r}   r   _dtype_bits  s   z_convert.<locals>._dtype_bitsTc                   s  | j j}||kr|  d| k r|  ||S ||kr$|r"|  S | S ||krO|rEt| j ||}tj| d||  || j dd |S | d||   } | S || dkr|rwt| j ||}tj	| d| d d| d  ||j d |S | j ||| j j
dd} | d| d d| d  9 } | S || d | }|rt| j ||}tj	| d| d d| d  ||j d |d||   }|S | j ||| j j
dd} | d| d d| d  9 } | d||   } | S )	a  Scale an array of unsigned/positive integers from `n` to `m` bits.
        Numbers can be represented exactly only if `m` is a multiple of `n`.
        Parameters
        ----------
        a : ndarray
            Input image array.
        n : int
            Number of bits currently used to encode the values in `a`.
        m : int
            Desired number of bits to encode the values in `out`.
        copy : bool, optional
            If True, allocates and returns new array. Otherwise, modifies
            `a` in place.
        Returns
        -------
        out : array
            Output image array. Has the same kind as `a`.
        r   unsafeoutrf   Zcastingr   r!   )r   rf   Fcopy)rf   r   rr   rs   r   rG   emptyrh   Zfloor_dividemultiplyrg   )anmr   r   bor   r   r   _scale5  s<   ((z_convert.<locals>._scalerl   Zuir   r   fg      g      ?z.Images of type float must be between -1 and 1.r{   )rf   rL   )r   r   g       @r|   rz   r   r   Fr   N)r!   )T) boolrG   Zbool_Zbool8floatZfloat_rn   rm   rl   Zasarrayrf   Zfloatingtyper   rg   Z
issubdtypeZ
obj2sctyper   Ziinfominrr   rs   rM   r   ZrintZclipflooraddviewr   rh   maximum)imagerf   rE   uniformZdtype_rangery   r   Zdtypeobj_inZdtypeobj_outZdtype_inZ	dtype_outZkind_inZkind_outZitemsize_inZitemsize_outZimin_inZimax_inZimin_outZimax_outresultZcomputation_typeZ	image_outr   r   r   rF      s   ,

:












rF   r   c                   C  s   t jrdS tdd uS )NFZffmpeg)r	   IS_WASMshutilwhichr   r   r   r   ffmpeg_installed  s   r   video_filepathc              
   C  sx   z.t | j }td| did}|jtjtjd}t|d }|d d d }||fdv W S  t	t
tfy;   Y d	S w )
zDetermines if a video is playable in the browser.

    A video is playable if it has a playable container and codec.
        .mp4 -> h264
        .webm -> vp9
        .ogg -> theora
    z?-show_format -show_streams -select_streams v -print_format jsonN)global_optionsinputs)stderrstdoutr   streamsZ
codec_name)).mp4Zh264)z.oggZtheora)z.webmZvp9T)r   suffixlowerr   run
subprocessPIPEjsonloadsr   
IndexErrorKeyError)r   	containerZprobeoutputZvideo_codecr   r   r   video_is_playable  s   r   
video_pathc              
   C  s   znz:t jdd*}t| d}t| |j tt|jdit|didd}|	  W d   n1 s5w   Y  W n t
yX } ztdt|  | }W Y d}~nd}~ww W t|j t|S W t|j t|S t|j w )zLConvert the video to mp4. If something goes wrong return the original video.F)deleter   Nz-y -loglevel quiet)r   Zoutputsr   z2Error converting video to browser-playable format )tempfileNamedTemporaryFiler   with_suffixr   copy2r   r
   r   r   r   printosremove)r   Ztmp_fileZoutput_pathffr_   r   r   r   convert_video_to_playable_mp4  s0   


r   )r   r   r   r   )r   r   r   r   )r$   r   r   r%   )r/   )rJ   )r   rS   )rc   )FF)r   r   )r   r   r   r   )r   r   r   r   )5
__future__r   r   r   loggingr   r   r   r   ro   ior   pathlibr   numpyrG   Zgradio_clientr   r   ZPILr   r   r   Zgradior	   r   Zffmpyr
   r   r   catch_warningssimplefilterZpydubr   	getLogger__name__r+   r   r   r.   r9   rA   rC   rD   rI   rR   rb   rk   rd   rF   r   r   r   r   r   r   r   <module>   sP    









	
 

#  

