U
    wh0Y                  
   @   s  d Z ddlmZmZ ddlmZ ddlmZmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z m!Z! zdd
l"Z"W n6 e#k
r Z$ zddl%m&Z& e&e$Z"W 5 d
Z$[$X Y nX G dd dZ'G dd de'Z(G dd de'Z)G dd dZ*e+dddZ,d(e*dddZ-d)e*dddZ.e/e0d
dddZ1ee) d
d d!d"Z2eje*d#d$d%Z3e/e0e*dd&d'Z4d
S )*z8Functions and classes for heif images to read and write.    )copydeepcopy)SEEK_SET)AnyDictListOptionalTuple)Image   )options)HeifCompressionFormat)	MODE_INFO	CtxEncode	MimCImage_exif_from_pillow
_get_bytes_get_heif_meta_get_orientation_for_encoder_get_primary_index_pil_to_supported_mode_retrieve_exif_retrieve_xmp_rotate_pil_xmp_from_pillowget_file_mimetypesave_colorspace_chromaset_orientationN)DeferredErrorc                   @   sr   e Zd ZU dZeed< eed< dd Zedd Z	ee
dd	d
Zedd ZejdddZddddZdS )	BaseImagezDBase class for :py:class:`HeifImage` and :py:class:`HeifDepthImage`.sizemodec                 C   s   |j \| _| _|| _d | _d S N)	size_moder    r!   _c_image_data)selfc_image r(   X/var/www/dating/data/www/fatepal.com/env/lib/python3.8/site-packages/pillow_heif/heif.py__init__2   s    zBaseImage.__init__c                 C   s   |    | jS )zaDecodes image and returns image data.

        :returns: ``bytes`` of the decoded image.
        )loadr%   r&   r(   r(   r)   data7   s    zBaseImage.datareturnc                 C   s   |    | jjS )zStride of the image.

        .. note:: from `0.10.0` version this value always will have width * sizeof pixel in default usage mode.

        :returns: An Int value indicating the image stride after decoding.
        )r+   r$   strider,   r(   r(   r)   r0   @   s    zBaseImage.stridec                 C   s   |    t| jt| j d  }t| j d dkr8d}nt|d }d}| jd |f}t| j d dkr||t| j d f7 }||d| jdS )	zNumpy array interface support.r   r      z|u1   z<u2   )shapetypestrversionr-   )r+   intr0   r   r!   r    r-   )r&   widthr5   r4   r(   r(   r)   __array_interface__K   s    zBaseImage.__array_interface__c                 C   s&   |    t| j| j| jd| j| jS )Helper method to create :external:py:class:`~PIL.Image.Image` class.

        :returns: :external:py:class:`~PIL.Image.Image` class created from an image.
        raw)r+   r
   	frombytesr!   r    r-   r0   r,   r(   r(   r)   	to_pillowZ   s    zBaseImage.to_pillowNc                 C   s"   | j s| jj| _ | jj\| _}dS )zMethod to decode image.

        .. note:: In normal cases, you should not call this method directly,
            when reading `data` or `stride` property of image will be loaded automatically.
        N)r%   r$   r-   r#   r    )r&   _r(   r(   r)   r+   i   s    
zBaseImage.load)__name__
__module____qualname____doc__tuple__annotations__strr*   propertyr-   r7   r0   r9   r
   r=   r+   r(   r(   r(   r)   r   &   s   



r   c                       s<   e Zd ZdZ fddZdd Zejd fddZ  ZS )	HeifDepthImagez`Class representing the depth image associated with the :py:class:`~pillow_heif.HeifImage` class.c                    s,   t  | |j}d|i| _t|| j d S )Nmetadata)superr*   rH   infor   )r&   r'   	_metadata	__class__r(   r)   r*   w   s     zHeifDepthImage.__init__c              	   C   sV   | j st| jtr"t| j dnd}d| jj d| jd  d| jd  d| j	 d	S )	N bytesno< r   xr   >)
r%   
isinstancer$   r   lenr-   rM   r?   r    r!   r&   Z_bytesr(   r(   r)   __repr__   s    &zHeifDepthImage.__repr__r.   c                    s   t   }| j |_|S )r:   )rI   r=   rJ   r   r&   imagerL   r(   r)   r=      s    
zHeifDepthImage.to_pillow)	r?   r@   rA   rB   r*   rW   r
   r=   __classcell__r(   r(   rL   r)   rG   t   s   rG   c                       st   e Zd ZdZ fddZdd ZeedddZeedd	d
Z	e	j
eddd
Z	ejd fddZ  ZS )	HeifImagez;One image in a :py:class:`~pillow_heif.HeifFile` container.c           	         s   t  | |j}t|}t|}tjr8dd |jD ng }tjrRdd |j	D ng }t
|}t|jt|j||||d| _|r|| jd< |r|| jd< t|| j |j}|r|d dkr|d	 | jd
< |d | jd< n|d	 | jd< d S )Nc                 S   s   g | ]}|d k	r|qS r"   r(   .0ir(   r(   r)   
<listcomp>   s      z&HeifImage.__init__.<locals>.<listcomp>c                 S   s   g | ]}|d k	rt |qS r"   )rG   r\   r(   r(   r)   r_      s      )primary	bit_depthexifrH   
thumbnailsZdepth_imagesxmpheiftype)ZrICCZprofr-   icc_profileicc_profile_typenclx_profile)rI   r*   rH   r   r   r   Z
THUMBNAILSrc   ZDEPTH_IMAGESZdepth_image_listr   boolr`   r7   ra   rJ   r   Zcolor_profile)	r&   r'   rK   Z_exif_xmpZ_thumbnailsZ_depth_imagesZ
_heif_metaZ_color_profilerL   r(   r)   r*      s6    

zHeifImage.__init__c                 C   sp   | j st| jtr"t| j dnd}d| jj d| jd  d| jd  d| j	 d| d	t| j
d
g  dS )NrN   rO   rP   rQ   r   rR   r    with z image data and rc   z thumbnails>)r%   rT   r$   r   rU   r-   rM   r?   r    r!   rJ   getrV   r(   r(   r)   rW      s    &HzHeifImage.__repr__r.   c                 C   s   | j jddd d dkS )zD``True`` for images with the ``alpha`` channel, ``False`` otherwise.;sepr   )Aa)r!   splitr,   r(   r(   r)   	has_alpha   s    zHeifImage.has_alphac                 C   s   t | jjddd d dkS )zN``True`` for images with ``premultiplied alpha`` channel, ``False`` otherwise.rn   ro   r   rq   rs   )rj   r!   rt   r,   r(   r(   r)   premultiplied_alpha   s    zHeifImage.premultiplied_alphavaluec                 C   s*   | j r&| j|rdnd|rdnd| _d S )Nrr   rs   )ru   r!   replacer&   rx   r(   r(   r)   rv      s    c                    s*   t   }| j |_t|j|jd< |S )r:   original_orientation)rI   r=   rJ   r   r   rX   rL   r(   r)   r=      s    
zHeifImage.to_pillow)r?   r@   rA   rB   r*   rW   rF   rj   ru   rv   setterr
   r=   rZ   r(   r(   rL   r)   r[      s   !r[   c                   @   s"  e Zd ZdZd6ddZedd Zed	d
 Zedd Zedd Z	e	j
edddZ	edd Zedd Zedd ZejdddZddddZdd Zdd Zd d! Zd"d# Zd$d% Zeed&d'd(Zeed)d*d+Zejed)d,d-Zed.d/ Zd0d1 Zd2d3 Zd4d5 Z e Z!dS )7HeifFilea  Representation of the :py:class:`~pillow_heif.HeifImage` classes container.

    To create :py:class:`~pillow_heif.HeifFile` object, use the appropriate factory functions.

    * :py:func:`~pillow_heif.open_heif`
    * :py:func:`~pillow_heif.read_heif`
    * :py:func:`~pillow_heif.from_pillow`
    * :py:func:`~pillow_heif.from_bytes`

    Exceptions that can be raised when working with methods:
        `ValueError`, `EOFError`, `SyntaxError`, `RuntimeError`, `OSError`
    NTFc                 K   s  t |dr|dt |d kr(g }d}nt|}t|}|ddkrVtjdd}n0|ddksr|ddkrtjd	d}nd}t	
|tj|||d
d|dd|dtj|}|| _dd |D | _d| _t| jD ]\}	}
|
jddr|	| _qd S )Nseekr    Zavifrq   AVIFZheicre   HEIFZremove_strideTZhdr_to_16bitreload_sizec                 S   s   g | ]}|d k	rt |qS r"   )r[   r\   r(   r(   r)   r_      s      z%HeifFile.__init__.<locals>.<listcomp>r`   F)hasattrr~   r   r   r   findr   ZPREFERRED_DECODERrm   _pillow_heifZ	load_fileZDECODE_THREADSZALLOW_INCORRECT_HEADERSmimetype_imagesprimary_index	enumeraterJ   )r&   fpconvert_hdr_to_8bitbgr_modekwargsimagesr   Zfp_bytesZpreferred_decoderindexr>   r(   r(   r)   r*      s8    



zHeifFile.__init__c                 C   s   | j | j jS )z:attr:`~pillow_heif.HeifImage.size` property of the primary :class:`~pillow_heif.HeifImage`.

        :exception IndexError: If there are no images.
        )r   r   r    r,   r(   r(   r)   r      s    zHeifFile.sizec                 C   s   | j | j jS )z:attr:`~pillow_heif.HeifImage.mode` property of the primary :class:`~pillow_heif.HeifImage`.

        :exception IndexError: If there are no images.
        )r   r   r!   r,   r(   r(   r)   r!   	  s    zHeifFile.modec                 C   s   | j | j jS )z:attr:`~pillow_heif.HeifImage.has_alpha` property of the primary :class:`~pillow_heif.HeifImage`.

        :exception IndexError: If there are no images.
        )r   r   ru   r,   r(   r(   r)   ru     s    zHeifFile.has_alphac                 C   s   | j | j jS )z:attr:`~pillow_heif.HeifImage.premultiplied_alpha` property of the primary :class:`~pillow_heif.HeifImage`.

        :exception IndexError: If there are no images.
        r   r   rv   r,   r(   r(   r)   rv     s    zHeifFile.premultiplied_alpharw   c                 C   s   || j | j _d S r"   r   rz   r(   r(   r)   rv   !  s    c                 C   s   | j | j jS )z:attr:`~pillow_heif.HeifImage.data` property of the primary :class:`~pillow_heif.HeifImage`.

        :exception IndexError: If there are no images.
        )r   r   r-   r,   r(   r(   r)   r-   %  s    zHeifFile.datac                 C   s   | j | j jS )z:attr:`~pillow_heif.HeifImage.stride` property of the primary :class:`~pillow_heif.HeifImage`.

        :exception IndexError: If there are no images.
        )r   r   r0   r,   r(   r(   r)   r0   -  s    zHeifFile.stridec                 C   s   | j | j jS )z`info`` dict of the primary :class:`~pillow_heif.HeifImage` in the container.

        :exception IndexError: If there are no images.
        )r   r   rJ   r,   r(   r(   r)   rJ   5  s    zHeifFile.infor.   c                 C   s   | j | j  S )zHelper method to create Pillow :external:py:class:`~PIL.Image.Image`.

        :returns: :external:py:class:`~PIL.Image.Image` class created from the primary image.
        )r   r   r=   r,   r(   r(   r)   r=   =  s    zHeifFile.to_pillowc                 K   s   t | j|f| dS )a  Saves image(s) under the given fp.

        Keyword options can be used to provide additional instructions to the writer.
        If a writer does not recognize an option, it is silently ignored.

        Supported options:
            ``save_all`` - boolean. Should all images from ``HeiFile`` be saved?
            (default = ``True``)

            ``append_images`` - do the same as in Pillow. Accepts the list of ``HeifImage``

            .. note:: Appended images always will have ``info["primary"]=False``

            ``quality`` - see :py:attr:`~pillow_heif.options.QUALITY`

            ``enc_params`` - dictionary with key:value to pass to :ref:`x265 <hevc-encoder>` encoder.

            ``exif`` - override primary image's EXIF with specified.
            Accepts ``None``, ``bytes`` or ``PIL.Image.Exif`` class.

            ``xmp`` - override primary image's XMP with specified. Accepts ``None`` or ``bytes``.

            ``primary_index`` - ignore ``info["primary"]`` and set `PrimaryImage` by index.

            ``chroma`` - custom subsampling value. Possible values: ``444``, ``422`` or ``420`` (``x265`` default).

            ``subsampling`` - synonym for *chroma*. Format is string, compatible with Pillow: ``x:x:x``, e.g. '4:4:4'.

            ``format`` - string with encoder format name. Possible values: ``HEIF`` (default) or ``AVIF``.

            ``save_nclx_profile`` - boolean, see :py:attr:`~pillow_heif.options.SAVE_NCLX_PROFILE`

            ``matrix_coefficients`` - int, nclx profile: color conversion matrix coefficients, default=6 (see h.273)

            ``color_primaries`` - int, nclx profile: color primaries (see h.273)

            ``transfer_characteristic`` - int, nclx profile: transfer characteristics (see h.273)

            ``full_range_flag`` - nclx profile: full range flag, default: 1

        :param fp: A filename (string), pathlib.Path object or an object with `write` method.
        N)_encode_imagesr   )r&   r   r   r(   r(   r)   saveD  s    +zHeifFile.savec                 C   s*   d| j j dt|  ddd | D  dS )NrP   rl   z	 images: c                 S   s   g | ]}t |qS r(   )rE   r\   r(   r(   r)   r_   r  s     z%HeifFile.__repr__.<locals>.<listcomp>rS   )rM   r?   rU   r,   r(   r(   r)   rW   q  s    zHeifFile.__repr__c                 C   s
   t | jS r"   )rU   r   r,   r(   r(   r)   __len__t  s    zHeifFile.__len__c                 c   s   | j E d H  d S r"   )r   r,   r(   r(   r)   __iter__w  s    zHeifFile.__iter__c                 C   s.   |dk s|t | jkr$td| | j| S Nr   zinvalid image index: rU   r   
IndexError)r&   r   r(   r(   r)   __getitem__z  s    zHeifFile.__getitem__c                 C   s0   |dk s|t | jkr$td| | j|= d S r   r   )r&   keyr(   r(   r)   __delitem__  s    zHeifFile.__delitem__)r!   r    c                 K   s$   t t|||f|}| j| |S )aP  Adds image from bytes to container.

        .. note:: Supports ``stride`` value if needed.

        :param mode: see :ref:`image-modes`.
        :param size: tuple with ``width`` and ``height`` of image.
        :param data: bytes object with raw image data.

        :returns: :py:class:`~pillow_heif.HeifImage` added object.
        )r[   r   r   append)r&   r!   r    r-   r   added_imager(   r(   r)   add_frombytes  s    zHeifFile.add_frombytes)rY   r/   c                 C   s@   |   | j|j|j|j|jd}t|j|_|jdd |S )zAdd image to the container.

        :param image: :py:class:`~pillow_heif.HeifImage` class to add from.

        :returns: :py:class:`~pillow_heif.HeifImage` added object.
        )r0   r`   N)	r+   r   r!   r    r-   r0   r   rJ   pop)r&   rY   r   r(   r(   r)   add_from_heif  s    zHeifFile.add_from_heifc                 C   s  |j d dks|j d dkr$td|j }t||d< t|}|rN||d< t|}t|}|dk	rx|dkrxt||}|	  | 
|j|j | }dD ]}||jkr|j| |j|< qdD ]"}||jkrt|j| |j|< qt||jd< t|}|r||jd< |S )	zAdd image to the container.

        :param image: Pillow :external:py:class:`~PIL.Image.Image` class to add from.

        :returns: :py:class:`~pillow_heif.HeifImage` added object.
        r   r   zEmpty images are not supported.rb   rd   N)ra   rc   rg   rh   )ri   rH   )r    
ValueErrorrJ   r   r   r   r   r   r   r+   r   r!   tobytesr   )r&   rY   _infork   r{   Z_imgr   r   r(   r(   r)   add_from_pillow  s8    




zHeifFile.add_from_pillowc                 C   s   | j | j jS )z+Returns the primary image as a numpy array.)r   r   r9   r,   r(   r(   r)   r9     s    zHeifFile.__array_interface__c                 C   s@   g }| j D ]&}t|j}||j|j||jg q
| j| j|gS r"   )	r   bytesr-   r   r!   r    rJ   r   r   )r&   im_descZimim_datar(   r(   r)   __getstate__  s
    

zHeifFile.__getstate__c           	      C   sD   |    |\| _| _}|D ]$}|\}}}}| |||}||_qd S r"   )r*   r   r   r   rJ   )	r&   stater   r   Zim_modeZim_sizer   Zim_infor   r(   r(   r)   __setstate__  s    zHeifFile.__setstate__c                 C   s&   t  }t| j|_| j|_| j|_|S r"   )r}   r   r   r   r   )r&   Z_im_copyr(   r(   r)   Z__copy  s
    zHeifFile.__copy)NTF)"r?   r@   rA   rB   r*   rF   r    r!   ru   rv   r|   rj   r-   r0   rJ   r
   r=   r   rW   r   r   r   r   rE   rC   r   r[   r   r   r9   r   r   Z_HeifFile__copy__copy__r(   r(   r(   r)   r}      sD   
!






-$
r}   r.   c                 C   s*   t | d}|dd dkrdS t|dkS )aV  Checks if the given `fp` object contains a supported file type.

    :param fp: A filename (string), pathlib.Path object or a file object.
        The file object must implement ``file.read``, ``file.seek``, and ``file.tell`` methods,
        and be opened in binary mode.

    :returns: A boolean indicating if the object can be opened.
          r1   s   ftypFr   )r   r   )r   Z__datar(   r(   r)   is_supported  s    	
r   TFc                 K   s   t | ||f|S )a  Opens the given HEIF(AVIF) image file.

    :param fp: See parameter ``fp`` in :func:`is_supported`
    :param convert_hdr_to_8bit: Boolean indicating should 10 bit or 12 bit images
        be converted to 8-bit images during decoding. Otherwise, they will open in 16-bit mode.
        ``Does not affect "monochrome" or "depth images".``
    :param bgr_mode: Boolean indicating should be `RGB(A)` images be opened in `BGR(A)` mode.
    :param kwargs: **hdr_to_16bit** a boolean value indicating that 10/12-bit image data
        should be converted to 16-bit mode during decoding. `Has lower priority than convert_hdr_to_8bit`!
        Default = **True**

    :returns: :py:class:`~pillow_heif.HeifFile` object.
    :exception ValueError: invalid input data.
    :exception EOFError: corrupted image data.
    :exception SyntaxError: unsupported feature.
    :exception RuntimeError: some other error.
    :exception OSError: out of memory.
    )r}   )r   r   r   r   r(   r(   r)   	open_heif  s    r   c                 K   s.   t | ||fddi|}|D ]}|  q|S )a\  Opens the given HEIF(AVIF) image file and decodes all images.

    .. note:: In most cases it is better to call :py:meth:`~pillow_heif.open_heif`, and
        let images decoded automatically only when needed.

    :param fp: See parameter ``fp`` in :func:`is_supported`
    :param convert_hdr_to_8bit: Boolean indicating should 10 bit or 12 bit images
        be converted to 8-bit images during decoding. Otherwise, they will open in 16-bit mode.
        ``Does not affect "monochrome" or "depth images".``
    :param bgr_mode: Boolean indicating should be `RGB(A)` images be opened in `BGR(A)` mode.
    :param kwargs: **hdr_to_16bit** a boolean value indicating that 10/12-bit image data
        should be converted to 16-bit mode during decoding. `Has lower priority than convert_hdr_to_8bit`!
        Default = **True**

    :returns: :py:class:`~pillow_heif.HeifFile` object.
    :exception ValueError: invalid input data.
    :exception EOFError: corrupted image data.
    :exception SyntaxError: unsupported feature.
    :exception RuntimeError: some other error.
    :exception OSError: out of memory.
    r   T)r}   r+   )r   r   r   r   retimgr(   r(   r)   	read_heif  s    
r   )r!   r    r/   c                 K   s$   t tt| ||f|g|f| dS )aR  Encodes data in a ``fp``.

    :param mode: `BGR(A);16`, `RGB(A);16`, LA;16`, `L;16`, `I;16L`, `BGR(A)`, `RGB(A)`, `LA`, `L`
    :param size: tuple with ``width`` and ``height`` of an image.
    :param data: bytes object with raw image data.
    :param fp: A filename (string), pathlib.Path object or an object with ``write`` method.
    N)r   r[   r   )r!   r    r-   r   r   r(   r(   r)   encode(  s    r   )r   r/   c                 K   s  | dd}|dkrtjntj}t | s<td| d| | dg  }| ddsd|d d	 }|sptd
t|| dd }t	|f|}t
|D ]v\}}	|	  |	j }
d|
d< ||kr|
jf | d|
d< |
dd |j|	j|	j|	jfdt|
i|
d|	ji q|| d S )Nformatr   r   zNo z encoder found.Zappend_imagesZsave_allTr   z)Cannot write file with no images as HEIF.r   Fr`   r0   r   Zimage_orientation)rm   r   ZAV1ZHEVCr   Zget_lib_infoRuntimeErrorr   r   r   r   r+   rJ   r   updater   Z	add_imager    r!   r-   r   r0   r   )r   r   r   compressionZcompression_formatZimages_to_saver   Z	ctx_writer^   r   r   r(   r(   r)   r   3  s>    

r   )	pil_imager/   c                 C   s   t  }||  |S )zCreates :py:class:`~pillow_heif.HeifFile` from a Pillow Image.

    :param pil_image: Pillow :external:py:class:`~PIL.Image.Image` class.

    :returns: New :py:class:`~pillow_heif.HeifFile` object.
    )r}   r   )r   r>   r(   r(   r)   from_pillowR  s    
r   c                 K   s   t  }|j| ||f| |S )aJ  Creates :py:class:`~pillow_heif.HeifFile` from bytes.

    .. note:: Supports ``stride`` value if needed.

    :param mode: see :ref:`image-modes`.
    :param size: tuple with ``width`` and ``height`` of an image.
    :param data: bytes object with raw image data.

    :returns: New :py:class:`~pillow_heif.HeifFile` object.
    )r}   r   )r!   r    r-   r   r>   r(   r(   r)   
from_bytes^  s    r   )TF)TF)5rB   r   r   ior   typingr   r   r   r   r	   ZPILr
   r   r   	constantsr   miscr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ImportErrorexZ_deffered_errorr   r   rG   r[   r}   rj   r   r   r   rE   rC   r   r   r   r   r(   r(   r(   r)   <module>   s2   HNE  