

import warnings
from typing import List, Optional, Union

import numpy as np
import PIL
import torch
from PIL import Image

from .configuration_utils import ConfigMixin, register_to_config
from .utils import CONFIG_NAME, PIL_INTERPOLATION, deprecate






class     __magic_name__     (							_snake_case     ):
 UpperCAmelCase				     =    CONFIG_NAME


 @register_to_config
 def __init__(    self		:			Optional[int]      ,    lowerCAmelCase__		:			bool = True      ,    lowerCAmelCase__		:			int = 8      ,    lowerCAmelCase__		:			str = "lanczos"      ,    lowerCAmelCase__		:			bool = True      ,    lowerCAmelCase__		:			bool = False      ,    )     ->   int:
   super().__init__()


 @staticmethod
 def _UpperCamelCase						(    lowerCAmelCase__		:			np.ndarray     )     ->   PIL.Image.Image:
   if images.ndim == 3:
     UpperCAmelCase          =	images[None, ...]
   UpperCAmelCase          =	(images * 2_5_5).round().astype("uint8"     )
   if images.shape[-1] == 1:
     # special case for grayscale (single channel) images
     UpperCAmelCase          =	[Image.fromarray(image.squeeze()      ,    mode="L"     ) for image in images]
   else:
     UpperCAmelCase          =	[Image.fromarray(lowerCAmelCase__     ) for image in images]

   return pil_images


 @staticmethod
 def _UpperCamelCase						(    lowerCAmelCase__		:			Union[List[PIL.Image.Image], PIL.Image.Image]     )     ->   np.ndarray:
   if not isinstance(lowerCAmelCase__      ,    lowerCAmelCase__     ):
     UpperCAmelCase          =	[images]
   UpperCAmelCase          =	[np.array(lowerCAmelCase__     ).astype(np.floataa     ) / 255.0 for image in images]
   UpperCAmelCase          =	np.stack(lowerCAmelCase__      ,    axis=0     )

   return images


 @staticmethod
 def _UpperCamelCase						(    lowerCAmelCase__		:			np.ndarray     )     ->   torch.FloatTensor:
   if images.ndim == 3:
     UpperCAmelCase          =	images[..., None]

   UpperCAmelCase          =	torch.from_numpy(images.transpose(0      ,    3      ,    1      ,    2     )     )
   return images


 @staticmethod
 def _UpperCamelCase						(    lowerCAmelCase__		:			torch.FloatTensor     )     ->   np.ndarray:
   UpperCAmelCase          =	images.cpu().permute(0      ,    2      ,    3      ,    1     ).float().numpy()
   return images


 @staticmethod
 def _UpperCamelCase						(    lowerCAmelCase__		:			Optional[int]     )     ->   Union[str, Any]:
   return 2.0 * images - 1.0


 @staticmethod
 def _UpperCamelCase						(    lowerCAmelCase__		:			Optional[int]     )     ->   Union[str, Any]:
   return (images / 2 + 0.5).clamp(0      ,    1     )


 @staticmethod
 def _UpperCamelCase						(    lowerCAmelCase__		:			PIL.Image.Image     )     ->   PIL.Image.Image:
   UpperCAmelCase          =	image.convert("RGB"     )
   return image


 def _UpperCamelCase						(    self		:			Optional[Any]      ,    lowerCAmelCase__		:			PIL.Image.Image      ,    lowerCAmelCase__		:			Optional[int] = None      ,    lowerCAmelCase__		:			Optional[int] = None      ,    )     ->   PIL.Image.Image:
   if height is None:
     UpperCAmelCase          =	image.height
   if width is None:
     UpperCAmelCase          =	image.width

   UpperCAmelCase   ,						UpperCAmelCase          =	(
       x - x % self.config.vae_scale_factor for x in (width, height)
   )  # resize to integer multiple of vae_scale_factor
   UpperCAmelCase          =	image.resize((width, height)      ,    resample=PIL_INTERPOLATION[self.config.resample]     )
   return image


 def _UpperCamelCase						(    self		:			Union[str, Any]      ,    lowerCAmelCase__		:			Union[torch.FloatTensor, PIL.Image.Image, np.ndarray]      ,    lowerCAmelCase__		:			Optional[int] = None      ,    lowerCAmelCase__		:			Optional[int] = None      ,    )     ->   torch.Tensor:
   UpperCAmelCase          =	(PIL.Image.Image, np.ndarray, torch.Tensor)
   if isinstance(lowerCAmelCase__      ,    lowerCAmelCase__     ):
     UpperCAmelCase          =	[image]
   elif not (isinstance(lowerCAmelCase__      ,    lowerCAmelCase__     ) and all(isinstance(lowerCAmelCase__      ,    lowerCAmelCase__     ) for i in image     )):
     raise ValueError(
         f"Input is in incorrect format: {[type(lowerCAmelCase__     ) for i in image]}. Currently, we only support {', '.join(lowerCAmelCase__     )}"     )

   if isinstance(image[0]      ,    PIL.Image.Image     ):
     if self.config.do_convert_rgb:
       UpperCAmelCase          =	[self.convert_to_rgb(lowerCAmelCase__     ) for i in image]
     if self.config.do_resize:
       UpperCAmelCase          =	[self.resize(lowerCAmelCase__      ,    lowerCAmelCase__      ,    lowerCAmelCase__     ) for i in image]
     UpperCAmelCase          =	self.pil_to_numpy(lowerCAmelCase__     )  # to np
     UpperCAmelCase          =	self.numpy_to_pt(lowerCAmelCase__     )  # to pt

   elif isinstance(image[0]      ,    np.ndarray     ):
     UpperCAmelCase          =	np.concatenate(lowerCAmelCase__      ,    axis=0     ) if image[0].ndim == 4 else np.stack(lowerCAmelCase__      ,    axis=0     )
     UpperCAmelCase          =	self.numpy_to_pt(lowerCAmelCase__     )
     UpperCAmelCase   ,						UpperCAmelCase   ,						UpperCAmelCase   ,						UpperCAmelCase          =	image.shape
     if self.config.do_resize and (
         height % self.config.vae_scale_factor != 0 or width % self.config.vae_scale_factor != 0
     ):
       raise ValueError(
           f"Currently we only support resizing for PIL image - please resize your numpy array to be divisible by {self.config.vae_scale_factor}"
           f"currently the sizes are {height} and {width}. You can also pass a PIL image instead to use resize option in VAEImageProcessor"     )

   elif isinstance(image[0]      ,    torch.Tensor     ):
     UpperCAmelCase          =	torch.cat(lowerCAmelCase__      ,    axis=0     ) if image[0].ndim == 4 else torch.stack(lowerCAmelCase__      ,    axis=0     )
     UpperCAmelCase   ,						UpperCAmelCase   ,						UpperCAmelCase   ,						UpperCAmelCase          =	image.shape

     # don't need any preprocess if the image is latents
     if channel == 4:
       return image

     if self.config.do_resize and (
         height % self.config.vae_scale_factor != 0 or width % self.config.vae_scale_factor != 0
     ):
       raise ValueError(
           f"Currently we only support resizing for PIL image - please resize your pytorch tensor to be divisible by {self.config.vae_scale_factor}"
           f"currently the sizes are {height} and {width}. You can also pass a PIL image instead to use resize option in VAEImageProcessor"     )

        # expected range [0,1], normalize to [-1,1]
   UpperCAmelCase          =	self.config.do_normalize
   if image.min() < 0:
     warnings.warn(
         "Passing `image` as torch tensor with value range in [-1,1] is deprecated. The expected value range for image tensor is [0,1] "
         f"when passing as pytorch tensor or numpy Array. You passed `image` with value range [{image.min()},{image.max()}]"      ,    lowerCAmelCase__      ,    )
     UpperCAmelCase          =	False

   if do_normalize:
     UpperCAmelCase          =	self.normalize(lowerCAmelCase__     )

   return image


 def _UpperCamelCase						(    self		:			List[Any]      ,    lowerCAmelCase__		:			torch.FloatTensor      ,    lowerCAmelCase__		:			str = "pil"      ,    lowerCAmelCase__		:			Optional[List[bool]] = None      ,    )     ->   Tuple:
   if not isinstance(lowerCAmelCase__      ,    torch.Tensor     ):
     raise ValueError(
         f"Input for postprocessing is in incorrect format: {type(lowerCAmelCase__     )}. We only support pytorch tensor"     )
   if output_type not in ["latent", "pt", "np", "pil"]:
     UpperCAmelCase          =	(
         f"the output_type {output_type} is outdated and has been set to `np`. Please make sure to set it to one of these instead: "
         "`pil`, `np`, `pt`, `latent`"
     )
     deprecate("Unsupported output_type"      ,    "1.0.0"      ,    lowerCAmelCase__      ,    standard_warn=lowerCAmelCase__     )
     UpperCAmelCase          =	"np"

   if output_type == "latent":
     return image

   if do_denormalize is None:
     UpperCAmelCase          =	[self.config.do_normalize] * image.shape[0]

   UpperCAmelCase          =	torch.stack(
       [self.denormalize(image[i]     ) if do_denormalize[i] else image[i] for i in range(image.shape[0]     )]     )

   if output_type == "pt":
     return image

   UpperCAmelCase          =	self.pt_to_numpy(lowerCAmelCase__     )

   if output_type == "np":
     return image

   if output_type == "pil":
     return self.numpy_to_pil(lowerCAmelCase__     )






class     __magic_name__     (							_snake_case     ):
 UpperCAmelCase				     =    CONFIG_NAME


 @register_to_config
 def __init__(    self		:			List[str]      ,    lowerCAmelCase__		:			bool = True      ,    lowerCAmelCase__		:			int = 8      ,    lowerCAmelCase__		:			str = "lanczos"      ,    lowerCAmelCase__		:			bool = True      ,    )     ->   List[Any]:
   super().__init__()


 @staticmethod
 def _UpperCamelCase						(    lowerCAmelCase__		:			Optional[Any]     )     ->   int:
   if images.ndim == 3:
     UpperCAmelCase          =	images[None, ...]
   UpperCAmelCase          =	(images * 2_5_5).round().astype("uint8"     )
   if images.shape[-1] == 1:
     # special case for grayscale (single channel) images
     UpperCAmelCase          =	[Image.fromarray(image.squeeze()      ,    mode="L"     ) for image in images]
   else:
     UpperCAmelCase          =	[Image.fromarray(image[:, :, :3]     ) for image in images]

   return pil_images


 @staticmethod
 def _UpperCamelCase						(    lowerCAmelCase__		:			Tuple     )     ->   Any:
   return image[:, :, 1] * 2**8 + image[:, :, 2]


 def _UpperCamelCase						(    self		:			Dict      ,    lowerCAmelCase__		:			List[str]     )     ->   Union[str, Any]:
   if images.ndim == 3:
     UpperCAmelCase          =	images[None, ...]
   UpperCAmelCase          =	images[:, :, :, 3:]
   if images.shape[-1] == 6:
     UpperCAmelCase          =	(images_depth * 2_5_5).round().astype("uint8"     )
     UpperCAmelCase          =	[
         Image.fromarray(self.rgblike_to_depthmap(lowerCAmelCase__     )      ,    mode="I;16"     ) for image_depth in images_depth
     ]
   elif images.shape[-1] == 4:
     UpperCAmelCase          =	(images_depth * 65_535.0).astype(np.uintaa     )
     UpperCAmelCase          =	[Image.fromarray(lowerCAmelCase__      ,    mode="I;16"     ) for image_depth in images_depth]
   else:
     raise Exception("Not supported"     )

   return pil_images


 def _UpperCamelCase						(    self		:			Tuple      ,    lowerCAmelCase__		:			torch.FloatTensor      ,    lowerCAmelCase__		:			str = "pil"      ,    lowerCAmelCase__		:			Optional[List[bool]] = None      ,    )     ->   Dict:
   if not isinstance(lowerCAmelCase__      ,    torch.Tensor     ):
     raise ValueError(
         f"Input for postprocessing is in incorrect format: {type(lowerCAmelCase__     )}. We only support pytorch tensor"     )
   if output_type not in ["latent", "pt", "np", "pil"]:
     UpperCAmelCase          =	(
         f"the output_type {output_type} is outdated and has been set to `np`. Please make sure to set it to one of these instead: "
         "`pil`, `np`, `pt`, `latent`"
     )
     deprecate("Unsupported output_type"      ,    "1.0.0"      ,    lowerCAmelCase__      ,    standard_warn=lowerCAmelCase__     )
     UpperCAmelCase          =	"np"

   if do_denormalize is None:
     UpperCAmelCase          =	[self.config.do_normalize] * image.shape[0]

   UpperCAmelCase          =	torch.stack(
       [self.denormalize(image[i]     ) if do_denormalize[i] else image[i] for i in range(image.shape[0]     )]     )

   UpperCAmelCase          =	self.pt_to_numpy(lowerCAmelCase__     )

   if output_type == "np":
     if image.shape[-1] == 6:
       UpperCAmelCase          =	np.stack([self.rgblike_to_depthmap(im[:, :, 3:]     ) for im in image]      ,    axis=0     )
     else:
       UpperCAmelCase          =	image[:, :, :, 3:]
     return image[:, :, :, :3], image_depth

   if output_type == "pil":
     return self.numpy_to_pil(lowerCAmelCase__     ), self.numpy_to_depth(lowerCAmelCase__     )
   else:
     raise Exception(f"This type {output_type} is not supported"     )






import sys
from collections.abc import Mapping

import numpy as np
import pyarrow as pa

from .. import config
from ..utils.py_utils import map_nested
from .formatting import TensorFormatter






class     __magic_name__     (							TensorFormatter[Mapping, np.ndarray, Mapping]     ):


 def __init__(    self		:			Optional[int]      ,    lowerCAmelCase__		:			str=None      ,    **lowerCAmelCase__		:			int     )     ->   Optional[Any]:
   super().__init__(features=lowerCAmelCase__     )
   UpperCAmelCase          =	np_array_kwargs


 def _UpperCamelCase						(    self		:			Any      ,    lowerCAmelCase__		:			Dict     )     ->   Union[str, Any]:
   if isinstance(lowerCAmelCase__      ,    lowerCAmelCase__     ):
     if column and all(
         isinstance(lowerCAmelCase__      ,    np.ndarray     ) and x.shape == column[0].shape and x.dtype == column[0].dtype for x in column     ):
       return np.stack(lowerCAmelCase__     )
     else:
       # don't use np.array(column, dtype=object)
       # since it fails in certain cases
       # see https://stackoverflow.com/q/51005699
       UpperCAmelCase          =	np.empty(len(lowerCAmelCase__     )      ,    dtype=lowerCAmelCase__     )
       UpperCAmelCase          =	column
       return out
   return column


 def _UpperCamelCase						(    self		:			Optional[Any]      ,    lowerCAmelCase__		:			Union[str, Any]     )     ->   List[Any]:
   if isinstance(lowerCAmelCase__      ,    (str, bytes, type(lowerCAmelCase__     ))     ):
     return value
   elif isinstance(lowerCAmelCase__      ,    (np.character, np.ndarray)     ) and np.issubdtype(value.dtype      ,    np.character     ):
     return value
   elif isinstance(lowerCAmelCase__      ,    np.number     ):
     return value

   UpperCAmelCase          =	{}

   if isinstance(lowerCAmelCase__      ,    np.ndarray     ) and np.issubdtype(value.dtype      ,    np.integer     ):
     UpperCAmelCase          =	{"dtype": np.intaa}
   elif isinstance(lowerCAmelCase__      ,    np.ndarray     ) and np.issubdtype(value.dtype      ,    np.floating     ):
     UpperCAmelCase          =	{"dtype": np.floataa}
   elif config.PIL_AVAILABLE and "PIL" in sys.modules:
     import PIL.Image

     if isinstance(lowerCAmelCase__      ,    PIL.Image.Image     ):
       return np.asarray(lowerCAmelCase__      ,    **self.np_array_kwargs     )

   return np.asarray(lowerCAmelCase__      ,    **{**default_dtype, **self.np_array_kwargs}     )


 def _UpperCamelCase						(    self		:			List[Any]      ,    lowerCAmelCase__		:			str     )     ->   Optional[int]:
   # support for torch, tf, jax etc.
   if config.TORCH_AVAILABLE and "torch" in sys.modules:
     import torch

     if isinstance(lowerCAmelCase__      ,    torch.Tensor     ):
       return self._tensorize(data_struct.detach().cpu().numpy()[()]     )
   if hasattr(lowerCAmelCase__      ,    "__array__"     ) and not isinstance(lowerCAmelCase__      ,    (np.ndarray, np.character, np.number)     ):
     UpperCAmelCase          =	data_struct.__array__()
   # support for nested types like struct of list of struct
   if isinstance(lowerCAmelCase__      ,    np.ndarray     ):
     if data_struct.dtype == object:
       return self._consolidate([self.recursive_tensorize(lowerCAmelCase__     ) for substruct in data_struct]     )
   if isinstance(lowerCAmelCase__      ,    (list, tuple)     ):
     return self._consolidate([self.recursive_tensorize(lowerCAmelCase__     ) for substruct in data_struct]     )
   return self._tensorize(lowerCAmelCase__     )


 def _UpperCamelCase						(    self		:			Union[str, Any]      ,    lowerCAmelCase__		:			dict     )     ->   Union[str, Any]:
   return map_nested(self._recursive_tensorize      ,    lowerCAmelCase__      ,    map_list=lowerCAmelCase__     )


 def _UpperCamelCase						(    self		:			int      ,    lowerCAmelCase__		:			pa.Table     )     ->   Mapping:
   UpperCAmelCase          =	self.numpy_arrow_extractor().extract_row(lowerCAmelCase__     )
   UpperCAmelCase          =	self.python_features_decoder.decode_row(lowerCAmelCase__     )
   return self.recursive_tensorize(lowerCAmelCase__     )


 def _UpperCamelCase						(    self		:			List[str]      ,    lowerCAmelCase__		:			pa.Table     )     ->   np.ndarray:
   UpperCAmelCase          =	self.numpy_arrow_extractor().extract_column(lowerCAmelCase__     )
   UpperCAmelCase          =	self.python_features_decoder.decode_column(lowerCAmelCase__      ,    pa_table.column_names[0]     )
   UpperCAmelCase          =	self.recursive_tensorize(lowerCAmelCase__     )
   UpperCAmelCase          =	self._consolidate(lowerCAmelCase__     )
   return column


 def _UpperCamelCase						(    self		:			List[Any]      ,    lowerCAmelCase__		:			pa.Table     )     ->   Mapping:
   UpperCAmelCase          =	self.numpy_arrow_extractor().extract_batch(lowerCAmelCase__     )
   UpperCAmelCase          =	self.python_features_decoder.decode_batch(lowerCAmelCase__     )
   UpperCAmelCase          =	self.recursive_tensorize(lowerCAmelCase__     )
   for column_name in batch:
     UpperCAmelCase          =	self._consolidate(batch[column_name]     )
   return batch



