


'''simple docstring'''





import os
import sys
import warnings
from dataclasses import dataclass, field
from io import BytesIO
from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Union

import numpy as np
import pyarrow as pa

from .. import config
from ..download.streaming_download_manager import xopen
from ..table import array_cast
from ..utils.file_utils import is_local_path
from ..utils.py_utils import first_non_null_value, no_op_if_value_is_null, string_to_dict


if TYPE_CHECKING:
							import PIL.Image

							from .features import FeatureType


a					  =     None
a					  =     '<' if sys.byteorder == 'little' else '>'
# Origin: https://github.com/python-pillow/Pillow/blob/698951e19e19972aeed56df686868f1329981c12/src/PIL/Image.py#L3126 minus "|i1" which values are not preserved correctly when saving and loading an image
a					  =     [
    np.dtype('|b1'),
    np.dtype('|u1'),
    np.dtype('<u2'),
    np.dtype('>u2'),
    np.dtype('<i2'),
    np.dtype('>i2'),
    np.dtype('<u4'),
    np.dtype('>u4'),
    np.dtype('<i4'),
    np.dtype('>i4'),
    np.dtype('<f4'),
    np.dtype('>f4'),
    np.dtype('<f8'),
    np.dtype('>f8'),
]







@dataclass
class        UpperCamelCase__   :
					__SCREAMING_SNAKE_CASE       :  bool						=   True
					__SCREAMING_SNAKE_CASE       :  Optional[str]						=   None
					# Automatically constructed
					__SCREAMING_SNAKE_CASE       :  ClassVar[str]						=   "PIL.Image.Image"
					__SCREAMING_SNAKE_CASE       :  ClassVar[Any]						=   pa.struct({'bytes': pa.binary(), 'path': pa.string()}   )
					__SCREAMING_SNAKE_CASE       :  str						=   field(default='Image'							,				init=UpperCAmelCase__							,				repr=UpperCAmelCase__   )

					def __call__(     self       :   List[str]       ):






										'''simple docstring'''






										return self.pa_type

					def   UpperCAmelCase__       (     self       :   List[str]							,					UpperCamelCase__       :   Union[str, bytes, dict, np.ndarray, "PIL.Image.Image"]       ):






										'''simple docstring'''






										if config.PIL_AVAILABLE:
															import PIL.Image
										else:
															raise ImportError("""To support encoding images, please install 'Pillow'."""       )

										if isinstance(UpperCamelCase__							,					UpperCamelCase__       ):
															lowercase_  							=			np.array(UpperCamelCase__       )

										if isinstance(UpperCamelCase__							,					UpperCamelCase__       ):
															return {"path": value, "bytes": None}
										elif isinstance(UpperCamelCase__							,					UpperCamelCase__       ):
															return {"path": None, "bytes": value}
										elif isinstance(UpperCamelCase__							,					np.ndarray       ):
															# convert the image array to PNG/TIFF bytes
															return encode_np_array(UpperCamelCase__       )
										elif isinstance(UpperCamelCase__							,					PIL.Image.Image       ):
															# convert the PIL image to bytes (default format is PNG/TIFF)
															return encode_pil_image(UpperCamelCase__       )
										elif value.get("""path"""       ) is not None and os.path.isfile(value["""path"""]       ):
															# we set "bytes": None to not duplicate the data if they're already available locally
															return {"bytes": None, "path": value.get("""path"""       )}
										elif value.get("""bytes"""       ) is not None or value.get("""path"""       ) is not None:
															# store the image bytes, and path is used to infer the image format using the file extension
															return {"bytes": value.get("""bytes"""       ), "path": value.get("""path"""       )}
										else:
															raise ValueError(
															    F'''An image sample should have one of \'path\' or \'bytes\' but they are missing or None in {value}.'''       )

					def   UpperCAmelCase__       (     self       :   Optional[Any]							,					UpperCamelCase__       :   dict							,					UpperCamelCase__       :   Tuple=None       ):






										'''simple docstring'''






										if not self.decode:
															raise RuntimeError("""Decoding is disabled for this feature. Please use Image(decode=True) instead."""       )

										if config.PIL_AVAILABLE:
															import PIL.Image
										else:
															raise ImportError("""To support decoding images, please install 'Pillow'."""       )

										if token_per_repo_id is None:
															lowercase_  							=			{}

										lowercase_  							=			value["""path"""], value["""bytes"""]
										if bytes_ is None:
															if path is None:
																				raise ValueError(F'''An image should have one of \'path\' or \'bytes\' but both are None in {value}.'''       )
															else:
																				if is_local_path(UpperCamelCase__       ):
																									lowercase_  							=			PIL.Image.open(UpperCamelCase__       )
																				else:
																									lowercase_  							=			path.split("""::"""       )[-1]
																									try:
																														lowercase_  							=			string_to_dict(UpperCamelCase__							,					config.HUB_DATASETS_URL       )["""repo_id"""]
																														lowercase_  							=			token_per_repo_id.get(UpperCamelCase__       )
																									except ValueError:
																														lowercase_  							=			None
																									with xopen(UpperCamelCase__							,					"""rb"""							,					use_auth_token=UpperCamelCase__       ) as f:
																														lowercase_  							=			BytesIO(f.read()       )
																									lowercase_  							=			PIL.Image.open(bytes_       )
										else:
															lowercase_  							=			PIL.Image.open(BytesIO(bytes_       )       )
										image.load()  # to avoid "Too many open files" errors
										return image

					def   UpperCAmelCase__       (     self       :   Tuple       ):






										'''simple docstring'''






										from .features import Value

										return (
										    self
										    if self.decode
										    else {
										        "bytes": Value("""binary"""       ),
										        "path": Value("""string"""       ),
										    }
										)

					def   UpperCAmelCase__       (     self       :   Optional[int]							,					UpperCamelCase__       :   Union[pa.StringArray, pa.StructArray, pa.ListArray]       ):






										'''simple docstring'''






										if pa.types.is_string(storage.type       ):
															lowercase_  							=			pa.array([None] * len(UpperCamelCase__       )							,					type=pa.binary()       )
															lowercase_  							=			pa.StructArray.from_arrays([bytes_array, storage]							,					["""bytes""", """path"""]							,					mask=storage.is_null()       )
										elif pa.types.is_binary(storage.type       ):
															lowercase_  							=			pa.array([None] * len(UpperCamelCase__       )							,					type=pa.string()       )
															lowercase_  							=			pa.StructArray.from_arrays([storage, path_array]							,					["""bytes""", """path"""]							,					mask=storage.is_null()       )
										elif pa.types.is_struct(storage.type       ):
															if storage.type.get_field_index("""bytes"""       ) >= 0:
																				lowercase_  							=			storage.field("""bytes"""       )
															else:
																				lowercase_  							=			pa.array([None] * len(UpperCamelCase__       )							,					type=pa.binary()       )
															if storage.type.get_field_index("""path"""       ) >= 0:
																				lowercase_  							=			storage.field("""path"""       )
															else:
																				lowercase_  							=			pa.array([None] * len(UpperCamelCase__       )							,					type=pa.string()       )
															lowercase_  							=			pa.StructArray.from_arrays([bytes_array, path_array]							,					["""bytes""", """path"""]							,					mask=storage.is_null()       )
										elif pa.types.is_list(storage.type       ):
															lowercase_  							=			pa.array(
															    [encode_np_array(np.array(UpperCamelCase__       )       )["""bytes"""] if arr is not None else None for arr in storage.to_pylist()]							,					type=pa.binary()							,					)
															lowercase_  							=			pa.array([None] * len(UpperCamelCase__       )							,					type=pa.string()       )
															lowercase_  							=			pa.StructArray.from_arrays(
															    [bytes_array, path_array]							,					["""bytes""", """path"""]							,					mask=bytes_array.is_null()       )
										return array_cast(UpperCamelCase__							,					self.pa_type       )







					def   UpperCAmelCase__       (     self       :   List[str]							,					UpperCamelCase__       :   pa.StructArray       ):






										'''simple docstring'''






										@no_op_if_value_is_null
										def path_to_bytes(UpperCamelCase__       :   List[str]       ):
															with xopen(UpperCamelCase__							,					"""rb"""       ) as f:
																				lowercase_  							=			f.read()
															return bytes_

										lowercase_  							=			pa.array(
										    [
										        (path_to_bytes(x["""path"""]       ) if x["""bytes"""] is None else x["""bytes"""]) if x is not None else None
										        for x in storage.to_pylist()
										    ]							,					type=pa.binary()							,					)
										lowercase_  							=			pa.array(
										    [os.path.basename(UpperCamelCase__       ) if path is not None else None for path in storage.field("""path"""       ).to_pylist()]							,					type=pa.string()							,					)
										lowercase_  							=			pa.StructArray.from_arrays([bytes_array, path_array]							,					["""bytes""", """path"""]							,					mask=bytes_array.is_null()       )
										return array_cast(UpperCamelCase__							,					self.pa_type       )



def 			UpperCAmelCase_				(      ):
					if config.PIL_AVAILABLE:
										import PIL.Image
					else:
										raise ImportError("""To support encoding images, please install 'Pillow'."""  )

					global _IMAGE_COMPRESSION_FORMATS
					if _IMAGE_COMPRESSION_FORMATS is None:
										PIL.Image.init()
										lowercase_  							=			list(set(PIL.Image.OPEN.keys()  ) & set(PIL.Image.SAVE.keys()  )  )
					return _IMAGE_COMPRESSION_FORMATS


def 			UpperCAmelCase_				(      UpperCAmelCase__  ):
					lowercase_  							=			BytesIO()
					if image.format in list_image_compression_formats():
										lowercase_  							=			image.format
					else:
										lowercase_  							=			"""PNG""" if image.mode in ["""1""", """L""", """LA""", """RGB""", """RGBA"""] else """TIFF"""
					image.save(UpperCAmelCase__						,							format=UpperCAmelCase__  )
					return buffer.getvalue()


def 			UpperCAmelCase_				(      UpperCAmelCase__  ):
					if hasattr(UpperCAmelCase__						,							"""filename"""  ) and image.filename != "":
										return {"path": image.filename, "bytes": None}
					else:
										return {"path": None, "bytes": image_to_bytes(UpperCAmelCase__  )}


def 			UpperCAmelCase_				(      UpperCAmelCase__  ):
					if config.PIL_AVAILABLE:
										import PIL.Image
					else:
										raise ImportError("""To support encoding images, please install 'Pillow'."""  )

					lowercase_  							=			array.dtype
					lowercase_  							=			dtype.byteorder if dtype.byteorder != """=""" else _NATIVE_BYTEORDER
					lowercase_  							=			dtype.kind
					lowercase_  							=			dtype.itemsize

					lowercase_  							=			None

					# Multi-channel array case (only np.dtype("|u1") is allowed)
					if array.shape[2:]:
										lowercase_  							=			np.dtype("""|u1"""  )
										if dtype_kind not in ["u", "i"]:
															raise TypeError(
															    F'''Unsupported array dtype {dtype} for image encoding. Only {dest_dtype} is supported for multi-channel arrays.'''  )
										if dtype is not dest_dtype:
															warnings.warn(F'''Downcasting array dtype {dtype} to {dest_dtype} to be compatible with \'Pillow\''''  )
    # Exact match
					elif dtype in _VALID_IMAGE_ARRAY_DTPYES:
										lowercase_  							=			dtype
					else:  # Downcast the type within the kind (np.can_cast(from_type, to_type, casting="same_kind") doesn't behave as expected, so do it manually)
										while dtype_itemsize >= 1:
															lowercase_  							=			dtype_byteorder + dtype_kind + str(UpperCAmelCase__  )
															lowercase_  							=			np.dtype(UpperCAmelCase__  )
															if dest_dtype in _VALID_IMAGE_ARRAY_DTPYES:
																				warnings.warn(F'''Downcasting array dtype {dtype} to {dest_dtype} to be compatible with \'Pillow\''''  )
																				break
															else:
																				dtype_itemsize //= 2

					if dest_dtype is None:
										raise TypeError(
										    F'''Cannot convert dtype {dtype} to a valid image dtype. Valid image dtypes: {_VALID_IMAGE_ARRAY_DTPYES}'''  )
					lowercase_  							=			PIL.Image.fromarray(array.astype(UpperCAmelCase__  )  )
					return {"path": None, "bytes": image_to_bytes(UpperCAmelCase__  )}



def 			UpperCAmelCase_				(      UpperCAmelCase__  ):
					if config.PIL_AVAILABLE:
										import PIL.Image
					else:
										raise ImportError("""To support encoding images, please install 'Pillow'."""  )

					if objs:
										lowercase_  							=			first_non_null_value(UpperCAmelCase__  )
										if isinstance(UpperCAmelCase__						,							UpperCAmelCase__  ):
															return [{"path": obj, "bytes": None} if obj is not None else None for obj in objs]
										if isinstance(UpperCAmelCase__						,							np.ndarray  ):
															lowercase_  							=			no_op_if_value_is_null(UpperCAmelCase__  )
															return [obj_to_image_dict_func(UpperCAmelCase__  ) for obj in objs]
										elif isinstance(UpperCAmelCase__						,							PIL.Image.Image  ):
															lowercase_  							=			no_op_if_value_is_null(UpperCAmelCase__  )
															return [obj_to_image_dict_func(UpperCAmelCase__  ) for obj in objs]
										else:
															return objs
					else:
										return objs






from typing import TYPE_CHECKING

from ...utils import (
    OptionalDependencyNotAvailable,
    _LazyModule,
    is_sentencepiece_available,
    is_speech_available,
    is_torch_available,
)


a					  =     {
    'configuration_trocr': ['TROCR_PRETRAINED_CONFIG_ARCHIVE_MAP', 'TrOCRConfig'],
    'processing_trocr': ['TrOCRProcessor'],
}


try:
							if not is_torch_available():
														raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
							pass
else:
							a					  =     [
							    'TROCR_PRETRAINED_MODEL_ARCHIVE_LIST',
							    'TrOCRForCausalLM',
							    'TrOCRPreTrainedModel',
							]


if TYPE_CHECKING:
							from .configuration_trocr import TROCR_PRETRAINED_CONFIG_ARCHIVE_MAP, TrOCRConfig
							from .processing_trocr import TrOCRProcessor

							try:
														if not is_torch_available():
																					raise OptionalDependencyNotAvailable()
							except OptionalDependencyNotAvailable:
														pass
							else:
														from .modeling_trocr import TROCR_PRETRAINED_MODEL_ARCHIVE_LIST, TrOCRForCausalLM, TrOCRPreTrainedModel

else:
							import sys

							a					  =     _LazyModule(__name__, globals()['__file__'], _import_structure, module_spec=__spec__)


