Spaces:
Runtime error
Runtime error
| # Copyright (c) 2024 Jaerin Lee | |
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |
| # of this software and associated documentation files (the "Software"), to deal | |
| # in the Software without restriction, including without limitation the rights | |
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| # copies of the Software, and to permit persons to whom the Software is | |
| # furnished to do so, subject to the following conditions: | |
| # The above copyright notice and this permission notice shall be included in all | |
| # copies or substantial portions of the Software. | |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| # SOFTWARE. | |
| import copy | |
| from typing import Optional, Union | |
| from PIL import Image | |
| import torch | |
| class BackgroundObject: | |
| def __init__( | |
| self, | |
| image: Optional[Image.Image] = None, | |
| prompt: Optional[str] = None, | |
| negative_prompt: Optional[str] = None, | |
| ) -> None: | |
| self.image = image | |
| self.prompt = prompt | |
| self.negative_prompt = negative_prompt | |
| def is_empty(self) -> bool: | |
| return ( | |
| self.image is None and | |
| self.prompt is None and | |
| self.negative_prompt is None | |
| ) | |
| def extra_repr(self) -> str: | |
| return '' | |
| def __repr__(self) -> str: | |
| strings = [] | |
| if self.image is not None: | |
| if isinstance(self.image, Image.Image): | |
| image_str = f'Image(size={str(self.image.size)})' | |
| else: | |
| image_str = f'Tensor(shape={str(self.image.shape)})' | |
| strings.append(f'image={image_str}') | |
| if self.prompt is not None: | |
| strings.append(f'prompt="{self.prompt}"') | |
| if self.negative_prompt is not None: | |
| strings.append(f'negative_prompt="{self.negative_prompt}"') | |
| extra_repr = self.extra_repr() | |
| if extra_repr != '': | |
| strings.append(extra_repr) | |
| return f'{type(self).__name__}({", ".join(strings)})' | |
| class LayerObject: | |
| def __init__( | |
| self, | |
| idx: Optional[int] = None, | |
| prompt: Optional[str] = None, | |
| negative_prompt: Optional[str] = None, | |
| suffix: Optional[str] = None, | |
| prompt_strength: Optional[float] = None, | |
| mask: Optional[Union[torch.Tensor, Image.Image]] = None, | |
| mask_std: Optional[float] = None, | |
| mask_strength: Optional[float] = None, | |
| ) -> None: | |
| self.idx = idx | |
| self.prompt = prompt | |
| self.negative_prompt = negative_prompt | |
| self.suffix = suffix | |
| self.prompt_strength = prompt_strength | |
| self.mask = mask | |
| self.mask_std = mask_std | |
| self.mask_strength = mask_strength | |
| def is_empty(self) -> bool: | |
| return ( | |
| self.prompt is None and | |
| self.negative_prompt is None and | |
| self.prompt_strength is None and | |
| self.mask is None and | |
| self.mask_strength is None and | |
| self.mask_std is None | |
| ) | |
| def merge(self, other: 'LayerObject') -> bool: # Overriden or not. | |
| if self.idx != other.idx: | |
| # Merge only the modification requests for the same layer. | |
| return False | |
| if self.prompt is None and other.prompt is not None: | |
| self.prompt = copy.deepcopy(other.prompt) | |
| if self.negative_prompt is None and other.negative_prompt is not None: | |
| self.negative_prompt = copy.deepcopy(other.negative_prompt) | |
| if self.suffix is None and other.suffix is not None: | |
| self.suffix = copy.deepcopy(other.suffix) | |
| if self.prompt_strength is None and other.prompt_strength is not None: | |
| self.prompt_strength = copy.deepcopy(other.prompt_strength) | |
| if self.mask is None and other.mask is not None: | |
| self.mask = copy.deepcopy(other.mask) | |
| if self.mask_strength is None and other.mask_strength is not None: | |
| self.mask_strength = copy.deepcopy(other.mask_strength) | |
| if self.mask_std is None and other.mask_std is not None: | |
| self.mask_std = copy.deepcopy(other.mask_std) | |
| return True | |
| def extra_repr(self) -> str: | |
| return '' | |
| def __repr__(self) -> str: | |
| strings = [] | |
| if self.idx is not None: | |
| strings.append(f'idx={self.idx}') | |
| if self.prompt is not None: | |
| strings.append(f'prompt="{self.prompt}"') | |
| if self.negative_prompt is not None: | |
| strings.append(f'negative_prompt="{self.negative_prompt}"') | |
| if self.suffix is not None: | |
| strings.append(f'suffix="{self.suffix}"') | |
| if self.prompt_strength is not None: | |
| strings.append(f'prompt_strength={self.prompt_strength}') | |
| if self.mask is not None: | |
| if isinstance(self.mask, Image.Image): | |
| mask_str = f'Image(size={str(self.mask.size)})' | |
| else: | |
| mask_str = f'Tensor(shape={str(self.mask.shape)})' | |
| strings.append(f'mask={mask_str}') | |
| if self.mask_std is not None: | |
| strings.append(f'mask_std={self.mask_std}') | |
| if self.mask_strength is not None: | |
| strings.append(f'mask_strength={self.mask_strength}') | |
| extra_repr = self.extra_repr() | |
| if extra_repr != '': | |
| strings.append(extra_repr) | |
| return f'{type(self).__name__}({", ".join(strings)})' | |
| class BackgroundState(BackgroundObject): | |
| def __init__( | |
| self, | |
| image: Optional[Image.Image] = None, | |
| prompt: Optional[str] = None, | |
| negative_prompt: Optional[str] = None, | |
| latent: Optional[torch.Tensor] = None, | |
| embed: Optional[torch.Tensor] = None, | |
| ) -> None: | |
| super().__init__(image, prompt, negative_prompt) | |
| self.latent = latent | |
| self.embed = embed | |
| def is_incomplete(self) -> bool: | |
| return ( | |
| self.image is None or | |
| self.prompt is None or | |
| self.negative_prompt is None or | |
| self.latent is None or | |
| self.embed is None | |
| ) | |
| def extra_repr(self) -> str: | |
| strings = [] | |
| if self.latent is not None: | |
| strings.append(f'latent=Tensor(shape={str(self.latent.shape)})') | |
| if self.embed is not None: | |
| strings.append(f'embed=Tuple[Tensor(shape={str(self.embed[0].shape)})]') | |
| return ', '.join(strings) | |
| # TODO | |
| # class LayerState: | |
| # def __init__( | |
| # self, | |
| # prompst: List[str] = [], | |
| # negative_prompts: List[str] = [], | |
| # suffix: List[str] = [], | |
| # masks: Optional[torch.Tensor] = None, | |
| # mask_std: Optional[torch.Tensor] = None, | |
| # mask_strength: Optional[torch.Tensor] = None, | |
| # original_masks: Optional[Union[torch.Tensor, List[Image.Image]]] = None, | |
| # ) -> None: | |
| # self.prompts = prompts | |
| # self.negative_prompts = negative_prompts | |
| # self.suffix = suffix | |
| # self.masks = masks | |
| # self.mask_std = mask_std | |
| # self.mask_strength = mask_strength | |
| # self.original_masks = original_masks | |
| # def __len__(self) -> int: | |
| # self.check_integrity(True) | |
| # return len(self.prompts) | |
| # @property | |
| # def is_empty(self) -> bool: | |
| # self.check_integrity(True) | |
| # return len(self.prompt) == 0 | |
| # def check_integrity(self, throw_error: bool = True) -> bool: | |
| # p = len(self.prompts) | |
| # flag = ( | |
| # p != len(self.negative_prompts) or | |
| # p != len(self.suffix) or | |
| # p != len(self.masks) or | |
| # p != len(self.mask_std) or | |
| # p != len(self.mask_strength) or | |
| # p != len(self.original_masks) | |
| # ) | |
| # if flag and throw_error: | |
| # print( | |
| # f'LayerState(\n\tlen(prompts): {p},\n\tlen(negative_prompts): {len(self.negative_prompts)},\n\t' | |
| # f'len(suffix): {len(self.suffix)},\n\tlen(masks): {len(self.masks)},\n\t' | |
| # f'len(mask_std): {len(self.mask_std)},\n\tlen(mask_strength): {len(self.mask_strength)},\n\t' | |
| # f'len(original_masks): {len(self.original_masks)}\n)' | |
| # ) | |
| # raise ValueError('LayerState is corrupted!') | |
| # return not flag | |
| # def extra_repr(self) -> str: | |
| # strings = [] | |
| # if self.idx is not None: | |
| # strings.append(f'idx={self.idx}') | |
| # if self.prompt is not None: | |
| # strings.append(f'prompt="{self.prompt}"') | |
| # if self.negative_prompt is not None: | |
| # strings.append(f'negative_prompt="{self.negative_prompt}"') | |
| # if self.suffix is not None: | |
| # strings.append(f'suffix="{self.suffix}"') | |
| # if self.mask is not None: | |
| # if isinstance(self.mask, Image.Image): | |
| # mask_str = f'PIL.Image.Image(size={str(self.mask.size)})' | |
| # else: | |
| # mask_str = f'torch.Tensor(shape={str(self.mask.shape)})' | |
| # strings.append(f'mask={mask_str}') | |
| # if self.mask_std is not None: | |
| # strings.append(f'mask_std={self.mask_std}') | |
| # if self.mask_strength is not None: | |
| # strings.append(f'mask_strength={self.mask_strength}') | |
| # return f'{type(self).__name__}({", ".join(strings)})' |