o
    pi7'                     @   s   d dl mZmZmZm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mZmZmZ ddlmZ dd	lmZmZ eeZd
eeejje	jf fddZdeeejje	jf fddZG dd deZdS )    )ListOptionalTupleUnionN   )UNet2DModel)RePaintScheduler)PIL_INTERPOLATION	deprecatelogging)randn_tensor   )DiffusionPipelineImagePipelineOutputimagec                    s   d}t dd|dd t| tjr| S t| tjjr| g} t| d tjjrh| d j\ dd  fD \  fd	d
| D } tj| dd} t	| 
tjd } | dddd} d|  d } t| } | S t| d tjrwtj| dd} | S )NzThe preprocess method is deprecated and will be removed in diffusers 1.0.0. Please use VaeImageProcessor.preprocess(...) instead
preprocessz1.0.0F)standard_warnr   c                 s       | ]	}||d   V  qdS )   N .0xr   r   u/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/diffusers/pipelines/deprecated/repaint/pipeline_repaint.py	<genexpr>+       z$_preprocess_image.<locals>.<genexpr>c                    s4   g | ]}t |j ftd  ddddf qS )lanczosresampleN)nparrayresizer	   )r   ihwr   r   
<listcomp>-   s   4 z%_preprocess_image.<locals>.<listcomp>axis     o@r         g       @g      ?dim)r
   
isinstancetorchTensorPILImagesizer   concatenater    astypefloat32	transpose
from_numpycat)r   deprecation_messager   r#   r   _preprocess_image!   s&   
r;   maskc                    s   t | tjr| S t | tjjr| g} t | d tjjrY| d j\ dd  fD \  fdd| D } tj| dd} | tj	d } d| | dk < d	| | dk< t
| } | S t | d tjrhtj| dd
} | S )Nr   c                 s   r   )    Nr   r   r   r   r   r   @   r   z#_preprocess_mask.<locals>.<genexpr>c                    s:   g | ]}t |d j ftd ddddf qS )Lnearestr   N)r   r    convertr!   r	   )r   mr#   r   r   r&   A   s   : z$_preprocess_mask.<locals>.<listcomp>r'   r)         ?r*   r,   )r.   r/   r0   r1   r2   r3   r   r4   r5   r6   r8   r9   )r<   r   r#   r   _preprocess_mask8   s"   
rC   c                       s   e Zd ZU dZeed< eed< dZ fddZe	
 							
	ddee	jejjf dee	jejjf dededededeee	jee	j f  dee dedeeef fddZ  ZS )RePaintPipelinea  
    Pipeline for image inpainting using RePaint.

    This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods
    implemented for all pipelines (downloading, saving, running on a particular device, etc.).

    Parameters:
        unet ([`UNet2DModel`]):
            A `UNet2DModel` to denoise the encoded image latents.
        scheduler ([`RePaintScheduler`]):
            A `RePaintScheduler` to be used in combination with `unet` to denoise the encoded image.
    unet	schedulerc                    s   t    | j||d d S )N)rE   rF   )super__init__register_modules)selfrE   rF   	__class__r   r   rH   ^   s   
zRePaintPipeline.__init__           
   NpilTr   
mask_imagenum_inference_stepsetajump_lengthjump_n_sample	generatoroutput_typereturn_dictreturnc
              	   C   s  |}
t |
}
|
j| j| jjd}
t|}|j| j| jjd}|
jd }t|tr;t	||kr;t
dt	| d| d|
j}t||| j| jjd}| j|||| j || j_| jjd d }t|trh|d n|}t| | jjD ]&\}}||k r| ||j}| j||||
||j}n| j|||}|}qs|d d	 dd}| ddd
d }|dkr| |}|	s|fS t|dS )a  
        The call function to the pipeline for generation.

        Args:
            image (`torch.Tensor` or `PIL.Image.Image`):
                The original image to inpaint on.
            mask_image (`torch.Tensor` or `PIL.Image.Image`):
                The mask_image where 0.0 define which part of the original image to inpaint.
            num_inference_steps (`int`, *optional*, defaults to 1000):
                The number of denoising steps. More denoising steps usually lead to a higher quality image at the
                expense of slower inference.
            eta (`float`):
                The weight of the added noise in a diffusion step. Its value is between 0.0 and 1.0; 0.0 corresponds to
                DDIM and 1.0 is the DDPM scheduler.
            jump_length (`int`, *optional*, defaults to 10):
                The number of steps taken forward in time before going backward in time for a single jump ("j" in
                RePaint paper). Take a look at Figure 9 and 10 in the [paper](https://arxiv.org/pdf/2201.09865.pdf).
            jump_n_sample (`int`, *optional*, defaults to 10):
                The number of times to make a forward time jump for a given chosen time sample. Take a look at Figure 9
                and 10 in the [paper](https://arxiv.org/pdf/2201.09865.pdf).
            generator (`torch.Generator`, *optional*):
                A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make
                generation deterministic.
            output_type (`str`, `optional`, defaults to `"pil"`):
                The output format of the generated image. Choose between `PIL.Image` or `np.array`.
            return_dict (`bool`, *optional*, defaults to `True`):
                Whether or not to return a [`ImagePipelineOutput`] instead of a plain tuple.

        Example:

        ```py
        >>> from io import BytesIO
        >>> import torch
        >>> import PIL
        >>> import requests
        >>> from diffusers import RePaintPipeline, RePaintScheduler


        >>> def download_image(url):
        ...     response = requests.get(url)
        ...     return PIL.Image.open(BytesIO(response.content)).convert("RGB")


        >>> img_url = "https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/repaint/celeba_hq_256.png"
        >>> mask_url = "https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/repaint/mask_256.png"

        >>> # Load the original image and the mask as PIL images
        >>> original_image = download_image(img_url).resize((256, 256))
        >>> mask_image = download_image(mask_url).resize((256, 256))

        >>> # Load the RePaint scheduler and pipeline based on a pretrained DDPM model
        >>> scheduler = RePaintScheduler.from_pretrained("google/ddpm-ema-celebahq-256")
        >>> pipe = RePaintPipeline.from_pretrained("google/ddpm-ema-celebahq-256", scheduler=scheduler)
        >>> pipe = pipe.to("cuda")

        >>> generator = torch.Generator(device="cuda").manual_seed(0)
        >>> output = pipe(
        ...     image=original_image,
        ...     mask_image=mask_image,
        ...     num_inference_steps=250,
        ...     eta=0.0,
        ...     jump_length=10,
        ...     jump_n_sample=10,
        ...     generator=generator,
        ... )
        >>> inpainted_image = output.images[0]
        ```

        Returns:
            [`~pipelines.ImagePipelineOutput`] or `tuple`:
                If `return_dict` is `True`, [`~pipelines.ImagePipelineOutput`] is returned, otherwise a `tuple` is
                returned where the first element is a list with the generated images.
        )devicedtyper   z/You have passed a list of generators of length z+, but requested an effective batch size of z@. Make sure the batch size matches the length of the generators.)rV   rZ   r[   r*   r+   rB   r   rP   )images)r;   to_execution_devicerE   r[   rC   shaper.   listlen
ValueErrorr   rF   set_timestepsrS   	timesteps	enumerateprogress_barsamplestepprev_sample	undo_stepclampcpupermutenumpynumpy_to_pilr   )rJ   r   rQ   rR   rS   rT   rU   rV   rW   rX   original_image
batch_sizeimage_shapet_lastr"   tmodel_outputr   r   r   __call__b   s>   W


zRePaintPipeline.__call__)rM   rN   rO   rO   NrP   T)__name__
__module____qualname____doc__r   __annotations__r   model_cpu_offload_seqrH   r/   no_gradr   r0   r1   r2   intfloatr   	Generatorr   strboolr   r   rv   __classcell__r   r   rK   r   rD   L   sF   
 	

rD   )typingr   r   r   r   rn   r   	PIL.Imager1   r/   modelsr   
schedulersr   utilsr	   r
   r   utils.torch_utilsr   pipeline_utilsr   r   
get_loggerrw   loggerr2   r0   r;   rC   rD   r   r   r   r   <module>   s   
