





"""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


lowerCamelCase_       =		None
lowerCamelCase_       =		"<" 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
lowerCamelCase_       =		[
    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  _SCREAMING_SNAKE_CASE:
       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=A   ,     repr=A  )




       def __call__(						self							)      ->				Union[str, Any]:





             """simple docstring"""






             return self.pa_type




       def    _UpperCamelCase					(						self		,SCREAMING_SNAKE_CASE__							)      ->				dict:





             """simple docstring"""






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

             if isinstance(SCREAMING_SNAKE_CASE__		,SCREAMING_SNAKE_CASE__							):
                   __SCREAMING_SNAKE_CASE       :Dict		    =  np.array(SCREAMING_SNAKE_CASE__							)

             if isinstance(SCREAMING_SNAKE_CASE__		,SCREAMING_SNAKE_CASE__							):
                   return {"path": value, "bytes": None}
             elif isinstance(SCREAMING_SNAKE_CASE__		,SCREAMING_SNAKE_CASE__							):
                   return {"path": None, "bytes": value}
             elif isinstance(SCREAMING_SNAKE_CASE__		,np.ndarray							):
                   # convert the image array to PNG/TIFF bytes
                   return encode_np_array(SCREAMING_SNAKE_CASE__							)
             elif isinstance(SCREAMING_SNAKE_CASE__		,PIL.Image.Image							):
                   # convert the PIL image to bytes (default format is PNG/TIFF)
                   return encode_pil_image(SCREAMING_SNAKE_CASE__							)
             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		,SCREAMING_SNAKE_CASE__		,SCREAMING_SNAKE_CASE__=None							)      ->				"PIL.Image.Image":





             """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:
                   __SCREAMING_SNAKE_CASE       :List[str]		    =  {}

             __SCREAMING_SNAKE_CASE    ,__SCREAMING_SNAKE_CASE       :int		    =  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(SCREAMING_SNAKE_CASE__							):
                               __SCREAMING_SNAKE_CASE       :List[str]		    =  PIL.Image.open(SCREAMING_SNAKE_CASE__							)
                         else:
                               __SCREAMING_SNAKE_CASE       :int		    =  path.split('''::'''							)[-1]
                               try:
                                     __SCREAMING_SNAKE_CASE       :str		    =  string_to_dict(SCREAMING_SNAKE_CASE__		,config.HUB_DATASETS_URL							)['''repo_id''']
                                     __SCREAMING_SNAKE_CASE       :Tuple		    =  token_per_repo_id.get(SCREAMING_SNAKE_CASE__							)
                               except ValueError:
                                     __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  None
                               with xopen(SCREAMING_SNAKE_CASE__		,'''rb'''		,use_auth_token=SCREAMING_SNAKE_CASE__							) as f:
                                     __SCREAMING_SNAKE_CASE       :List[str]		    =  BytesIO(f.read()							)
                               __SCREAMING_SNAKE_CASE       :Tuple		    =  PIL.Image.open(bytes_							)
             else:
                   __SCREAMING_SNAKE_CASE       :Dict		    =  PIL.Image.open(BytesIO(bytes_							)							)
             image.load()  # to avoid "Too many open files" errors
             return image




       def    _UpperCamelCase					(						self							)      ->				Union["FeatureType", Dict[str, "FeatureType"]]:





             """simple docstring"""






             from .features import Value

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




       def    _UpperCamelCase					(						self		,SCREAMING_SNAKE_CASE__							)      ->				pa.StructArray:





             """simple docstring"""






             if pa.types.is_string(storage.type							):
                   __SCREAMING_SNAKE_CASE       :int		    =  pa.array([None] * len(SCREAMING_SNAKE_CASE__							)		,type=pa.binary()							)
                   __SCREAMING_SNAKE_CASE       :List[Any]		    =  pa.StructArray.from_arrays([bytes_array, storage]		,['''bytes''', '''path''']		,mask=storage.is_null()							)
             elif pa.types.is_binary(storage.type							):
                   __SCREAMING_SNAKE_CASE       :Union[str, Any]		    =  pa.array([None] * len(SCREAMING_SNAKE_CASE__							)		,type=pa.string()							)
                   __SCREAMING_SNAKE_CASE       :str		    =  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:
                         __SCREAMING_SNAKE_CASE       :Optional[int]		    =  storage.field('''bytes'''							)
                   else:
                         __SCREAMING_SNAKE_CASE       :Any		    =  pa.array([None] * len(SCREAMING_SNAKE_CASE__							)		,type=pa.binary()							)
                   if storage.type.get_field_index('''path'''							) >= 0:
                         __SCREAMING_SNAKE_CASE       :Tuple		    =  storage.field('''path'''							)
                   else:
                         __SCREAMING_SNAKE_CASE       :Any		    =  pa.array([None] * len(SCREAMING_SNAKE_CASE__							)		,type=pa.string()							)
                   __SCREAMING_SNAKE_CASE       :str		    =  pa.StructArray.from_arrays([bytes_array, path_array]		,['''bytes''', '''path''']		,mask=storage.is_null()							)
             elif pa.types.is_list(storage.type							):
                   __SCREAMING_SNAKE_CASE       :List[Any]		    =  pa.array(
                       [encode_np_array(np.array(SCREAMING_SNAKE_CASE__							)							)['''bytes'''] if arr is not None else None for arr in storage.to_pylist()]		,type=pa.binary()		,)
                   __SCREAMING_SNAKE_CASE       :Any		    =  pa.array([None] * len(SCREAMING_SNAKE_CASE__							)		,type=pa.string()							)
                   __SCREAMING_SNAKE_CASE       :Optional[int]		    =  pa.StructArray.from_arrays(
                       [bytes_array, path_array]		,['''bytes''', '''path''']		,mask=bytes_array.is_null()							)
             return array_cast(SCREAMING_SNAKE_CASE__		,self.pa_type							)




       def    _UpperCamelCase					(						self		,SCREAMING_SNAKE_CASE__							)      ->				pa.StructArray:





             """simple docstring"""






             @no_op_if_value_is_null
             def path_to_bytes(SCREAMING_SNAKE_CASE__							):
                   with xopen(SCREAMING_SNAKE_CASE__		,'''rb'''							) as f:
                         __SCREAMING_SNAKE_CASE       :Any		    =  f.read()
                   return bytes_

             __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  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()		,)
             __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  pa.array(
                 [os.path.basename(SCREAMING_SNAKE_CASE__							) if path is not None else None for path in storage.field('''path'''							).to_pylist()]		,type=pa.string()		,)
             __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  pa.StructArray.from_arrays([bytes_array, path_array]		,['''bytes''', '''path''']		,mask=bytes_array.is_null()							)
             return array_cast(SCREAMING_SNAKE_CASE__		,self.pa_type							)




def 					__lowerCamelCase       (							)      ->				List[str]:
      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()
            __SCREAMING_SNAKE_CASE       :int		    =  list(set(PIL.Image.OPEN.keys()							) & set(PIL.Image.SAVE.keys()							)							)
      return _IMAGE_COMPRESSION_FORMATS



def 					__lowerCamelCase       (							a_					:		"PIL.Image.Image"							)      ->				bytes:
      __SCREAMING_SNAKE_CASE       :Optional[int]		    =  BytesIO()
      if image.format in list_image_compression_formats():
            __SCREAMING_SNAKE_CASE       :Union[str, Any]		    =  image.format
      else:
            __SCREAMING_SNAKE_CASE       :Dict		    =  '''PNG''' if image.mode in ['''1''', '''L''', '''LA''', '''RGB''', '''RGBA'''] else '''TIFF'''
      image.save(a_			,       format=a_							)
      return buffer.getvalue()



def 					__lowerCamelCase       (							a_					:		"PIL.Image.Image"							)      ->				dict:
      if hasattr(a_			,       '''filename'''							) and image.filename != "":
            return {"path": image.filename, "bytes": None}
      else:
            return {"path": None, "bytes": image_to_bytes(a_							)}



def 					__lowerCamelCase       (							a_					:		np.ndarray							)      ->				dict:
      if config.PIL_AVAILABLE:
            import PIL.Image
      else:
            raise ImportError('''To support encoding images, please install \'Pillow\'.'''							)

      __SCREAMING_SNAKE_CASE       :Dict		    =  array.dtype
      __SCREAMING_SNAKE_CASE       :Union[str, Any]		    =  dtype.byteorder if dtype.byteorder != '''=''' else _NATIVE_BYTEORDER
      __SCREAMING_SNAKE_CASE       :List[str]		    =  dtype.kind
      __SCREAMING_SNAKE_CASE       :int		    =  dtype.itemsize

      __SCREAMING_SNAKE_CASE       :Dict		    =  None

      # Multi-channel array case (only np.dtype("|u1") is allowed)
      if array.shape[2:]:
            __SCREAMING_SNAKE_CASE       :List[Any]		    =  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:
            __SCREAMING_SNAKE_CASE       :Any		    =  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:
                  __SCREAMING_SNAKE_CASE       :List[Any]		    =  dtype_byteorder + dtype_kind + str(a_							)
                  __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  np.dtype(a_							)
                  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}'''							)
      __SCREAMING_SNAKE_CASE       :Any		    =  PIL.Image.fromarray(array.astype(a_							)							)
      return {"path": None, "bytes": image_to_bytes(a_							)}







def 					__lowerCamelCase       (							a_					:		Union[List[str], List[dict], List[np.ndarray], List["PIL.Image.Image"]]							)      ->				List[dict]:
      if config.PIL_AVAILABLE:
            import PIL.Image
      else:
            raise ImportError('''To support encoding images, please install \'Pillow\'.'''							)

      if objs:
            __SCREAMING_SNAKE_CASE    ,__SCREAMING_SNAKE_CASE       :Tuple		    =  first_non_null_value(a_							)
            if isinstance(a_			,       a_							):
                  return [{"path": obj, "bytes": None} if obj is not None else None for obj in objs]
            if isinstance(a_			,       np.ndarray							):
                  __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  no_op_if_value_is_null(a_							)
                  return [obj_to_image_dict_func(a_							) for obj in objs]
            elif isinstance(a_			,       PIL.Image.Image							):
                  __SCREAMING_SNAKE_CASE       :List[str]		    =  no_op_if_value_is_null(a_							)
                  return [obj_to_image_dict_func(a_							) for obj in objs]
            else:
                  return objs
      else:
            return objs






"""simple docstring"""
import math
import unittest



def 					__lowerCamelCase       (							a_					:		int							)      ->				bool:
      assert isinstance(a_			,       a_							) and (
          number >= 0
      ), "'number' must been an int and positive"

      if 1 < number < 4:
            # 2 and 3 are primes
            return True
      elif number < 2 or number % 2 == 0 or number % 3 == 0:
            # Negatives, 0, 1, all even numbers, all multiples of 3 are not primes
            return False

      # All primes number are in format of 6k +/- 1
      for i in range(5			,       int(math.sqrt(a_							) + 1							)			,       6							):
            if number % i == 0 or number % (i + 2) == 0:
                  return False
      return True






class  _SCREAMING_SNAKE_CASE(       unittest.TestCase  ):




       def    _UpperCamelCase					(						self							)      ->				Union[str, Any]:





             """simple docstring"""






             self.assertTrue(is_prime(2							)							)
             self.assertTrue(is_prime(3							)							)
             self.assertTrue(is_prime(5							)							)
             self.assertTrue(is_prime(7							)							)
             self.assertTrue(is_prime(11							)							)
             self.assertTrue(is_prime(13							)							)
             self.assertTrue(is_prime(17							)							)
             self.assertTrue(is_prime(19							)							)
             self.assertTrue(is_prime(23							)							)
             self.assertTrue(is_prime(29							)							)




       def    _UpperCamelCase					(						self							)      ->				Tuple:





             """simple docstring"""






             with self.assertRaises(SCREAMING_SNAKE_CASE__							):
                   is_prime(-19							)
             self.assertFalse(
                 is_prime(0							)		,'''Zero doesn\'t have any positive factors, primes must have exactly two.'''		,)
             self.assertFalse(
                 is_prime(1							)		,'''One only has 1 positive factor, primes must have exactly two.'''		,)
             self.assertFalse(is_prime(2 * 2							)							)
             self.assertFalse(is_prime(2 * 3							)							)
             self.assertFalse(is_prime(3 * 3							)							)
             self.assertFalse(is_prime(3 * 5							)							)
             self.assertFalse(is_prime(3 * 5 * 7							)							)


if __name__ == "__main__":
  unittest.main()