a
    Cg]                  
   @  s  d Z ddlmZ ddlmZmZ ddlmZ ddl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 n8 e!y Z" z ddl#m$Z$ e$e"Z W Y dZ"["n
dZ"["0 0 G dd dZ%G dd de%Z&G dd de%Z'G dd de%Z(G dd dZ)ddddZ*d1ddddZ+d2dddd Z,d!d"d#d$d%d&Z-d'd#d(d)d*Z.d+dd,d-d.Z/d!d"dd$d/d0Z0dS )3z8Functions and classes for heif images to read and write.    )annotations)copydeepcopy)SEEK_SET)Any)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                   @  sp   e Zd ZU dZded< ded< dd Zedd	 Zed
dddZedd Z	ddddZ
ddddZdS )	BaseImagez^Base class for :py:class:`HeifImage`, :py:class:`HeifDepthImage` and :py:class:`HeifAuxImage`.tuple[int, int]sizestrmodec                 C  s   |j \| _| _|| _d | _d S N)	size_moder   r    _c_image_data)selfc_image r'   O/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/pillow_heif/heif.py__init__4   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(   data9   s    zBaseImage.dataint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   B   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*   r-   r0   r   r    r   r,   )r%   widthr5   r4   r'   r'   r(   __array_interface__M   s    zBaseImage.__array_interface__Image.Imagec                 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_pillow\   s    zBaseImage.to_pillowNonec                 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*   k   s    
zBaseImage.loadN)__name__
__module____qualname____doc____annotations__r)   propertyr,   r0   r8   r=   r*   r'   r'   r'   r(   r   (   s   



r   c                      s:   e Zd ZdZ fddZdd Zd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)   rG   infor   )r%   r&   rG   	__class__r'   r(   r)   y   s
    zHeifDepthImage.__init__c              	   C  s0   d| j j d| jd  d| jd  d| j d	S N< r   xr   >rK   r@   r   r    r+   r'   r'   r(   __repr__   s    zHeifDepthImage.__repr__r9   r.   c                   s   t   }| j |_|S )r:   )rH   r=   rI   r   r%   imagerJ   r'   r(   r=      s    
zHeifDepthImage.to_pillow)r@   rA   rB   rC   r)   rR   r=   __classcell__r'   r'   rJ   r(   rF   v   s   rF   c                   @  s   e Zd ZdZdd ZdS )HeifAuxImagezdClass representing the auxiliary image associated with the :py:class:`~pillow_heif.HeifImage` class.c              	   C  s0   d| j j d| jd  d| jd  d| j d	S rL   rQ   r+   r'   r'   r(   rR      s    zHeifAuxImage.__repr__N)r@   rA   rB   rC   rR   r'   r'   r'   r(   rV      s   rV   c                      s   e Zd ZdZ fddZdd Zedddd	Zeddd
dZej	ddddZdd fddZ
dddddZ  ZS )	HeifImagez;One image in a :py:class:`~pillow_heif.HeifFile` container.c                   s8  t  | |j}t|}t|}tjr8dd |jD ng }tjrRdd |j	D ng }t
|jt|j||||d| _tjri }|jD ],}||}	|	|vrg ||	< ||	 | q|| jd< t|}
|r|| jd< |
r|
| jd< t|| j |j}|r4|d d	v r&|d
 | jd< |d | jd< n|d
 | jd< d S )Nc                 S  s   g | ]}|d ur|qS r!   r'   .0ir'   r'   r(   
<listcomp>       z&HeifImage.__init__.<locals>.<listcomp>c                 S  s   g | ]}|d urt |qS r!   )rF   rX   r'   r'   r(   r[      r\   )primary	bit_depthexifrG   
thumbnailsdepth_imagesZauxxmpheiftype)ZrICCZprofr,   icc_profileicc_profile_typenclx_profile)rH   r)   rG   r   r   r	   Z
THUMBNAILSr`   ZDEPTH_IMAGESZdepth_image_listboolr]   r-   r^   rI   Z
AUX_IMAGESZaux_image_idsZget_aux_typeappendr   r   color_profile)r%   r&   rG   r_   rb   r`   ra   Zctx_aux_infoaux_idZaux_typeZ	heif_metarj   rJ   r'   r(   r)      sD    




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 )Nz bytesnorM   rN   r   rO   r    with z image data and r`   z thumbnails>)r$   
isinstancer#   r   lenr,   rK   r@   r   r    rI   get)r%   Zs_bytesr'   r'   r(   rR      s    &,zHeifImage.__repr__rh   r.   c                 C  s   | j jddd d dv 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.rq   rr   r   rt   rv   )rh   r    rw   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 )Nru   rv   )rx   r    replacer%   r{   r'   r'   r(   ry      s    r9   c                   s*   t   }| j |_t|j|jd< |S )r:   original_orientation)rH   r=   rI   r   r   rS   rJ   r'   r(   r=      s    
zHeifImage.to_pillowr-   rV   )rk   r/   c                 C  s   | j |}t|S )zMethod to retrieve the auxiliary image at the given ID.

        :returns: a :py:class:`~pillow_heif.HeifAuxImage` class instance.
        )r#   get_aux_imagerV   )r%   rk   Z	aux_imager'   r'   r(   r      s    zHeifImage.get_aux_image)r@   rA   rB   rC   r)   rR   rE   rx   ry   setterr=   r   rU   r'   r'   rJ   r(   rW      s   '
rW   c                   @  s&  e Zd ZdZd>ddZedd Zed	d
 Zedd Zedd Z	e	j
ddddZ	edd Zedd Zedd ZddddZddddZdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d*d+d,d-Zd.d.d/d0d1Zdd.d/d2d3Zed4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= ZeZdS )?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 u 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|tj	}|| _dd |D | _d| _t| jD ]\}	}
|
jddr|	| _qd S )Nseekr    Zavifrt   AVIFZheicrc   HEIFZremove_strideTZhdr_to_16bitreload_sizec                 S  s   g | ]}|d urt |qS r!   )rW   rX   r'   r'   r(   r[     r\   z%HeifFile.__init__.<locals>.<listcomp>r]   F)hasattrr   r   r   r   findr	   ZPREFERRED_DECODERrp   _pillow_heifZ	load_fileZDECODE_THREADSZALLOW_INCORRECT_HEADERSZDISABLE_SECURITY_LIMITSmimetype_imagesprimary_index	enumeraterI   )r%   fpconvert_hdr_to_8bitbgr_modekwargsimagesr   Zfp_bytesZpreferred_decoderindexr?   r'   r'   r(   r)      s:    


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   rx   r+   r'   r'   r(   rx   (  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   ry   r+   r'   r'   r(   ry   0  s    zHeifFile.premultiplied_alpharh   rz   c                 C  s   || j | j _d S r!   r   r}   r'   r'   r(   ry   8  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   D  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   rI   r+   r'   r'   r(   rI   L  s    zHeifFile.infor9   r.   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=   T  s    zHeifFile.to_pillowr>   c                 K  s   t | j|fi | 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(   save[  s    +zHeifFile.savec                 C  s*   d| j j dt|  ddd | D  dS )NrM   rm   z	 images: c                 S  s   g | ]}t |qS r'   )r   rX   r'   r'   r(   r[     r\   z%HeifFile.__repr__.<locals>.<listcomp>rP   )rK   r@   ro   r+   r'   r'   r(   rR     s    zHeifFile.__repr__c                 C  s
   t | jS r!   )ro   r   r+   r'   r'   r(   __len__  s    zHeifFile.__len__c                 c  s   | j E d H  d S r!   )r   r+   r'   r'   r(   __iter__  s    zHeifFile.__iter__c                 C  s.   |dk s|t | jkr$td| | j| S Nr   zinvalid image index: ro   r   
IndexError)r%   r   r'   r'   r(   __getitem__  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   )r    r   c                 K  s(   t t|||fi |}| 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.
        )rW   r   r   ri   )r%   r    r   r,   r   added_imager'   r'   r(   add_frombytes  s    zHeifFile.add_frombytesrW   )rT   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   rI   pop)r%   rT   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urx|dkrxt||}|	  | 
|j|j | }dD ]}||jv r|j| |j|< qdD ]"}||jv 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.r_   rb   N)r^   r`   re   rf   )rg   rG   )r   
ValueErrorrI   r   r   r   r   r   r   r*   r   r    tobytesr   )	r%   rT   rI   rb   r~   imgr   r   Zim_xmpr'   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   r8   r+   r'   r'   r(   r8     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,   ri   r    r   rI   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   rI   )	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.__copyc                 C  s   | j | j |S )z`get_aux_image`` method of the primary :class:`~pillow_heif.HeifImage` in the container.

        :exception IndexError: If there are no images.
        )r   r   r   )r%   rk   r'   r'   r(   r     s    zHeifFile.get_aux_image)NTF)r@   rA   rB   rC   r)   rE   r   r    rx   ry   r   r,   r0   rI   r=   r   rR   r   r   r   r   r   r   r   r8   r   r   Z_HeifFile__copyr   __copy__r'   r'   r'   r(   r      sF   
"






-$
r   rh   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f_datar'   r'   r(   is_supported  s    	
r   TFc                 K  s   t | ||fi |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   retr   r'   r'   r(   	read_heif*  s    
r   r   r   r>   )r    r   r/   c                 K  s,   t tt| ||fi |g|fi | 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   rW   r   )r    r   r,   r   r   r'   r'   r(   encodeF  s    r   zlist[HeifImage])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}t	|fi |}t
|D ]|\}}	|	  |	j }
d|
d< ||kr|
jf i | 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)rp   r
   ZAV1ZHEVCr   Zget_lib_infoRuntimeErrorr   r   r   r   r*   rI   r   updater   Z	add_imager   r    r,   r   r0   r   )r   r   r   compressionZcompression_formatZimages_to_saver   Z	ctx_writerZ   r   rI   r'   r'   r(   r   Q  s>    

r   r9   )	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_pillowp  s    
r   c                 K  s    t  }|j| ||fi | |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)1rC   
__future__r   r   r   ior   typingr   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   rF   rV   rW   r   r   r   r   r   r   r   r   r'   r'   r'   r(   <module>   s6   HNS  