o
    Si&                     @   sj  d dl Z d dlZd dlmZmZ d dlmZ d dlmZm	Z	m
Z
mZ d dlZd dlmZ d dlmZ d dlmZmZ G dd	 d	ed
ZG dd ded
Zi Zi Zde	e fddZdd Zdd Zdede
e fddZdede
e fddZdede
e fddZdede fddZ!eG dd deZ"eG d d! d!eZ#eG d"d# d#eZ$eG d$d% d%eZ%dS )&    N)ABCMetaabstractmethod)Path)DictListTypeUnion)FileIO)Image)Pathlikeis_module_availablec                   @   s>   e Zd ZdZeedefddZededej	fddZ
dS )	ImageReadera  
    ``ImageReader`` defines the interface of how to load images from a particular storage backend.
    This backend could either be:

    - files on a local filesystem;
    - in-memory storage;
    - cloud storage;
    - etc.

    Each class inheriting from ``ImageReader`` must define:

    - the ``read()`` method, which defines the loading operation
      (accepts the ``key`` to locate the image in the storage and return it).
    - the ``name()`` property that is unique to this particular storage mechanism.
    returnc                 C      d S N selfr   r   C/home/ubuntu/.local/lib/python3.10/site-packages/lhotse/image/io.pyname      zImageReader.namekeyc                 C   r   r   r   )r   r   r   r   r   read$   s   zImageReader.readN)__name__
__module____qualname____doc__propertyr   strr   npndarrayr   r   r   r   r   r      s    r   )	metaclassc                   @   s   e Zd ZdZeedefddZeedefddZedede	j
defd	d
Zdedeee	j
ef defddZdd Zdd ZdS )ImageWritera  
    ``ImageWriter`` defines the interface of how to store images in a particular storage backend.
    This backend could either be:

    - files on a local filesystem;
    - in-memory storage;
    - cloud storage;
    - etc.

    Each class inheriting from ``ImageWriter`` must define:

    - the ``write()`` method, which defines the storing operation
      (accepts a ``key`` used to place the ``value`` image in the storage);
    - the ``storage_path()`` property, which is either a directory for the files,
      or empty string for in-memory storage.
    - the ``name()`` property that is unique to this particular storage mechanism.
    r   c                 C   r   r   r   r   r   r   r   r   ?   r   zImageWriter.namec                 C   r   r   r   r   r   r   r   storage_pathD   r   zImageWriter.storage_pathr   valuec                 C   r   r   r   r   r   r$   r   r   r   writeI      zImageWriter.writec                 C   s   t dsJ dddl}t||jjrt|}n3t|tr(t|j|}n$t|tjr1|}nt|t	rCt|jt
|}n	tdt| |jdd \}}| ||}t| j| j|||dS )a  
        Store an image in the underlying storage and return a manifest
        describing how to retrieve it.

        :param key: An ID that uniquely identifies the image.
        :param value: The image to be stored. Can be:
            - A path to an image file
            - A numpy array with shape (height, width, channels)
            - Raw bytes of an image file
        :return: A manifest of type :class:`~lhotse.image.Image`
        PIL9In order to store images, please run 'pip install pillow'r   NzUnsupported image value type:    )storage_typer#   storage_keywidthheight)r   	PIL.Image
isinstancer
   r   arrayr   openr    bytesioBytesIO
ValueErrortypeshaper&   r   r#   )r   r   r$   r(   imgr.   r-   r,   r   r   r   store_imageM   s0   

zImageWriter.store_imagec                 C      | S r   r   r   r   r   r   	__enter__|      zImageWriter.__enter__c                 O   r   r   r   r   argskwargsr   r   r   __exit__   r=   zImageWriter.__exit__N)r   r   r   r   r   r   r   r   r#   r   r    r&   r   r3   r
   r:   r<   rA   r   r   r   r   r"   ,   s&    
/r"   r   c                   C   s   t tttS r   )sortedsetREADER_BACKENDSintersectionWRITER_BACKENDSr   r   r   r   available_storage_backends   s   rG   c                 C      | t | j< | S )zK
    Decorator used to add a new ``ImageReader`` to Lhotse's registry.
    )rD   r   clsr   r   r   register_reader      
rK   c                 C   rH   )zK
    Decorator used to add a new ``ImageWriter`` to Lhotse's registry.
    )rF   r   rI   r   r   r   register_writer   rL   rM   r   c                 C   ,   | t vrtd|  dtt   t |  S )z
    Find the available ``ImageReader`` implementation with the provided name.
    The name is the value of the ``name`` property in a concrete ``ImageReader`` implementation.
    z#No image reader backend with name '$' is available. Available backends: )rD   r6   listkeysr   r   r   r   
get_reader      
rS   c                 C   rN   )z
    Find the available ``ImageWriter`` implementation with the provided name.
    The name is the value of the ``name`` property in a concrete ``ImageWriter`` implementation.
    z#No image writer backend with name 'rO   )rF   r6   rP   rQ   rR   r   r   r   
get_writer   rT   rU   c                 C   s$   t | }t| sJ d|  d|S )z]
    Find the available in-memory ``ImageWriter`` implementation with the provided name.
    zStorage type 'z' is not an in-memory storage.)rU   is_in_memory)r   writerr   r   r   get_memory_writer   s   rX   r+   c                 C   s   | dkS )zR
    Determines whether a given storage_type represents an in-memory storage.
    pillow_memoryr   )r+   r   r   r   rV      s   rV   c                       sP   e Zd ZdZdZdef fddZedefddZ	dd
ede
fddZ  ZS )PillowReaderz
    Reads image files using Pillow from a directory on the local filesystem.
    ``storage_path`` corresponds to the directory path;
    ``storage_key`` for each image is the name of the file in that directory.
    pillow_filesr#   c                       t    t|| _d S r   super__init__r	   r4   r   r#   r?   r@   	__class__r   r   r_         
zPillowReader.__init__r   c                 C      | j jS r   r4   r#   r   r   r   r   r#         zPillowReader.storage_pathFr   as_pil_imagec                 C   sp   t dsJ dddl}| j|d\}}|j|}|  W d   n1 s*w   Y  |r3|S t|S )z3Read the image file and return it as a numpy array.r(   8In order to load images, please run 'pip install pillow'r   Nr)	r   r/   r4   open_fileobjr
   r2   loadr   r1   )r   r   rg   r(   f
input_pathr9   r   r   r   r      s   

zPillowReader.readF)r   r   r   r   r   r   r_   r   r   r#   boolr   __classcell__r   r   ra   r   rZ      s    rZ   c                       sT   e Zd ZdZdZdef fddZedefddZ	d	ed
e
jdefddZ  ZS )PillowWriterz
    Writes image files using Pillow to a directory on the local filesystem.
    ``storage_path`` corresponds to the directory path;
    ``storage_key`` for each image is the name of the file in that directory.
    r[   r#   c                    r\   r   r]   r`   ra   r   r   r_      rc   zPillowWriter.__init__r   c                 C   rd   r   re   r   r   r   r   r#      rf   zPillowWriter.storage_pathr   r$   c                 C   s   t dsJ dddl}t|js|d }|j|}| jj|ddd\}}|| W d   n1 s6w   Y  | jj	sKd	
t|jd
d S |S )z%Write a numpy array as an image file.r(   r)   r   Nz.pngwT)
add_subdir/)r   r/   r   suffixr
   	fromarrayr4   rj   saveis_urljoinparts)r   r   r$   r(   r9   rl   output_pathr   r   r   r&      s   
zPillowWriter.write)r   r   r   r   r   r   r_   r   r   r#   r   r    r&   rp   r   r   ra   r   rq      s     rq   c                   @   s6   e Zd ZdZdZdd Zddededej	fd	d
Z
dS )PillowInMemoryReaderz8
    Reads images from memory storage using Pillow.
    rY   c                 O   r   r   r   r>   r   r   r   r_     r=   zPillowInMemoryReader.__init__Fraw_datarg   r   c                 C   s   t dsJ dddl}t|}t|tr(|jt	|}|r#|S t
|S t|t
jr8|r6|j|S |S t||jjrH|rC|S t
|S tdt| )z(Read the image from the bytes in memory.r(   rh   r   NzUnsupported data type: )r   r/   pickleloadsr0   r3   r
   r2   r4   r5   r   r1   r    rw   r6   r7   )r   r~   rg   r(   datar9   r   r   r   r     s*   



zPillowInMemoryReader.readNrn   )r   r   r   r   r   r_   r3   ro   r   r    r   r   r   r   r   r}     s
    r}   c                   @   s\   e Zd ZdZdZdd ZedddZd	ed
e	j
defddZdddZdd Zdd ZdS )PillowInMemoryWriterz7
    Writes images to memory storage using Pillow.
    rY   c                 O   r   r   r   r>   r   r   r   r_   @  r=   zPillowInMemoryWriter.__init__r   Nc                 C   r   r   r   r   r   r   r   r#   C  r'   z!PillowInMemoryWriter.storage_pathr   r$   c                 C   s
   t |S )zU
        Store the image in memory. We're simply pickle-ing the numpy array.
        )r   dumpsr%   r   r   r   r&   G  s   
zPillowInMemoryWriter.writec                 C   r   r   r   r   r   r   r   closeM  r=   zPillowInMemoryWriter.closec                 C   r;   r   r   r   r   r   r   r<   P  r=   zPillowInMemoryWriter.__enter__c                 C   r   r   r   )r   exc_typeexc_valexc_tbr   r   r   rA   S  r=   zPillowInMemoryWriter.__exit__)r   N)r   r   r   r   r   r_   r   r#   r   r   r    r3   r&   r   r<   rA   r   r   r   r   r   8  s    
r   )&r4   r   abcr   r   pathlibr   typingr   r   r   r   numpyr   lhotse.features.ior	   lhotse.image.imager
   lhotse.utilsr   r   r   r"   rD   rF   r   rG   rK   rM   rS   rU   rX   ro   rV   rZ   rq   r}   r   r   r   r   r   <module>   s8    W	!('