U
    “~Hj>P  ã                .   @   sâ  d Z ddlZddl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 ddlmZmZmZ dd	lmZ d
dlmZ d
dl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 ddej ej!fddej ej!fddej ej"fddej ej!fddej ej!fddej ej"fddej#ej#fddej#ej#fd
dej#ej#fd
dej#ej#fd
dej#ej#fddej ej!fddej ej!fddej ej"fddej ej!fddej ej!fddej ej"fddej#ej#fddej#ej#fd
dej#ej#fd
dej#ej#fd
dej#ej#fddej ej!fddej ej!fddej ej"fddej ej!fddej ej!fddej ej"fddej#ej#fddej#ej#fd
dej#ej#fd
dej#ej#fd
dej#ej#fddej ej$fddej ej$fddej ej%fddej ej$fddej ej$fddej ej%fddej#ej#fddej#ej#fd
dej#ej#fddej&ej'fdœ+Z(ddddœZ)ddddœZ*e+ddœdd„Z,e+ee- dœdd„Z.e+e-dœd d!„Z/dNe+ee- e0ee- d#œd$d%„Z1dOe+e0ee- d&œd'd(„Z2e3d)œd*d+„Z4dPe5d)œd,d-„Z6ee+ ee5 d.œd/d0„Z7ee+ ee5 d.œd1d2„Z8ejee5 d3œd4d5„Z9ejee5 d3œd6d7„Z:ejejd3œd8d9„Z;G d:d;„ d;eƒZ<eje-ejd<œd=d>„Z=ee- e-d?œd@dA„Z>ee? dBœdCdD„Z@e+d)œdEdF„ZAG dGdH„ dHƒZBeG dIdJ„ dJƒƒZCee3e
f ddKœdLdM„ZDdS )QzoDifferent miscellaneous helper functions.

Mostly for internal use, so prototypes can change between versions.
é    N)Ú	dataclass)ÚIntEnum)Úceil)ÚPath)ÚpackÚunpack)ÚListÚOptionalÚUnion)ÚImageé   )Úoptions)ÚHeifChannelÚ
HeifChromaÚHeifColorspaceÚHeifCompressionFormat)ÚDeferredErroré   é   é   é   é   é
   é   )+zBGRA;16zBGRa;16zBGR;16zRGBA;16zRGBa;16zRGB;16zLA;16zLa;16zL;16zI;16úI;16LzBGRA;12zBGRa;12zBGR;12zRGBA;12zRGBa;12zRGB;12zLA;12zLa;12zL;12zI;12zI;12LzBGRA;10zBGRa;10zBGR;10zRGBA;10zRGBa;10zRGB;10zLA;10zLa;10zL;10zI;10zI;10LÚRGBAZRGBaÚRGBZBGRAZBGRaÚBGRZLAZLaÚLÚYCbCri¼  i¦  i¤  )z4:4:4z4:2:2z4:2:0)r   r   r   )ÚinfoÚreturnc                 C   s"   t  | jd¡}|dk	r||d< dS )zYConverts `chroma` value from `c_image` to useful values and stores them in ``info`` dict.NÚchroma)ÚLIBHEIF_CHROMA_MAPÚgetr"   )Úc_imager    r"   © r&   ú4/tmp/pip-unpacked-wheel-ne56ham8/pillow_heif/misc.pyÚsave_colorspace_chromaX   s    r(   c                 C   s
   t | dƒS )a¶  Reset orientation in ``EXIF`` to ``1`` if any orientation present.

    Removes ``XMP`` orientation tag if it is present.
    In Pillow plugin mode, it is called automatically for images.
    When ``pillow_heif`` used in ``standalone`` mode, if you wish, you can call it manually.

    .. note:: If there is no orientation tag, this function will not add it and do nothing.

        If both XMP and EXIF orientation tags are present, EXIF orientation tag will be returned,
        but both tags will be removed.

    :param info: `info` dictionary from :external:py:class:`~PIL.Image.Image` or :py:class:`~pillow_heif.HeifImage`.
    :returns: Original orientation or None if it is absent.
    T©Ú_get_orientation)r    r&   r&   r'   Úset_orientation`   s    r+   c                 C   s   t | dƒ}|d krdS |S )NFr   r)   )r    Úimage_orientationr&   r&   r'   Ú_get_orientation_for_encoderr   s    
r-   F)r    Úexif_orientationÚresetr!   c              	   C   sò   d}|   d¡rÚ| d  dd¡}|d rÚd }dD ]2}z|d  |¡}W  qbW q. tk
r^   Y q.X q.|rÚt d|¡}|r¢t|d ƒ}|r¢t dd	|¡}t d
d	|¡}|dks²|dkrÚd | 	d¡t
|ƒdkrÎdndg¡| d< |d krî|dkrî|S d S )Nr   Úxmpó    r   )úutf-8Úlatin1ztiff:Orientation(="|>)([0-9])r   ztiff:Orientation="([0-9])"Ú z,<tiff:Orientation>([0-9])</tiff:Orientation>r2   ó    )r$   ÚrsplitÚdecodeÚ	ExceptionÚreÚsearchÚintÚsubÚjoinÚencodeÚlen)r    r.   r/   Úxmp_orientationZxmp_dataZdecoded_xmp_dataÚencodingÚmatchr&   r&   r'   Ú_get_orientation_xmpw   s*    

(rC   )r    r/   r!   c                 C   sž  d }|   d¡�r†�z\| d }d}| d¡r:d}|dd … }|dd… dkrNd	nd
}t|d |dd… ƒd }t|d |||d … ƒd }|d }t|ƒD ]Ð}	|d|	  }t|d |||d … ƒd dkrÎqš||d |d … }
t|d |
dd… ƒd }|dkrš|}|�s �ql|d }|�r*|d7 }t|d dƒ}| d d |… | | d |d d …  | d<  �qlqšW n tk
�r„   Y nX t| ||d�}|�pœ|S )NÚexifFó   Exif  Té   r   r   s   IIú<ú>r   r   r   ÚHr   i  r   )r/   )r$   Ú
startswithr   Úranger   r8   rC   )r    r/   Zoriginal_orientationZtif_tagZskipped_exif00Zendian_markÚpointerZ	tag_countÚoffsetZtag_nÚvalueZ_original_orientationZp_valueZnew_orientationr@   r&   r&   r'   r*   �   s@    
",r*   ©r!   c                 C   sb   t | dƒdd… }|r^|dkr"dS |dkr.dS |dkr:d	S |d
krFdS |dkrRdS |dkr^dS dS )a”  Gets the MIME type of the HEIF(or AVIF) object.

    :param fp: A filename (string), pathlib.Path object, file object or bytes.
        The file object must implement ``file.read``, ``file.seek`` and ``file.tell`` methods,
        and be opened in binary mode.
    :returns: "image/heic", "image/heif", "image/heic-sequence", "image/heif-sequence",
        "image/avif", "image/avif-sequence" or "".
    r   r   Ns   avifz
image/avifs   aviszimage/avif-sequence)s   heics   heixs   heims   heisz
image/heic)s   hevcs   hevxs   hevms   hevszimage/heic-sequences   mif1z
image/heifs   msf1zimage/heif-sequencer4   )Ú
_get_bytes)ÚfpZ
heif_brandr&   r&   r'   Úget_file_mimetype³   s    	rR   c              
   C   sš   t | ttfƒr<t | d¡�}| |p&d¡W  5 Q R £ S Q R X t| dƒrŠt| dƒrX|  ¡ nd }|  |pfd¡}|d k	r†t| dƒr†|  |¡ |S t	| ƒd |… S )NÚrbéÿÿÿÿÚreadÚtellÚseek)
Ú
isinstanceÚstrr   ÚbuiltinsÚopenrU   ÚhasattrrV   rW   Úbytes)rQ   ÚlengthÚfilerM   Úresultr&   r&   r'   rP   Í   s     

rP   )Úmetadatar!   c                 C   sÊ   d }g }t | ƒD ] \}}|d dkr| |¡ tj|d d d… ddd�}|d7 }t|d ƒ| dkrld}n(|dkr”|d |d |… d	kr”|d8 }|d |d … }|s|r|}qt|ƒD ]
}| |= qº|S )
NÚtypeÚExifÚdatar   ÚbigF)Ú	byteorderÚsignedrF   rE   )Ú	enumerateÚappendr;   Ú
from_bytesr?   Úreversed)ra   Ú_resultÚ_purgeÚiÚmd_blockZ	skip_sizeÚ_datar&   r&   r'   Ú_retrieve_exifÚ   s"    
 rq   c                 C   sT   d }g }t | ƒD ]*\}}|d dkr| |¡ |s|d }qt|ƒD ]
}| |= qD|S )Nrb   Úmimerd   )rh   ri   rk   )ra   rl   rm   rn   ro   r&   r&   r'   Ú_retrieve_xmpî   s    

rs   ©Úimgr!   c                 C   s6   d| j kr| j d S t| dƒr2|  ¡ }|r2| ¡ S d S )NrD   Úgetexif)r    r\   rv   Útobytes)ru   rD   r&   r&   r'   Ú_exif_from_pillowû   s    


rx   c                 C   sª   d }d| j kr| j d }nxd| j kr0| j d }nbt| dƒrPd| jkr’| jd }nBt| dƒr’| jD ]0\}}|dkr`| dd¡\}}|d	kr`|} q’q`t|tƒr¦| d
¡}|S )Nr0   zXML:com.adobe.xmpÚtag_v2i¼  ÚapplistZAPP1r1   r   s   http://ns.adobe.com/xap/1.0/r2   )r    r\   ry   rz   r6   rX   rY   r>   )ru   Z_xmpÚsegmentÚcontentÚmarkerZxmp_tagsr&   r&   r'   Ú_xmp_from_pillow  s$    






r~   c                 C   s”   | j dkr2| j dd ¡d k	r dnd}| j|d�} n^| j dkrJ| jdd�} nF| j dkrb| jd	d�} n.| j d
krz| jdd�} n| j dkr�| jdd�} | S )NÚPZtransparencyr   r   )ÚmodeÚIr   Ú1r   ZCMYKr   )r€   r    r$   Úconvert)ru   r€   r&   r&   r'   Ú_pil_to_supported_mode  s    




r„   c                   @   s,   e Zd ZdZdZdZdZdZdZdZ	dZ
d	S )
Ú	TransposezkTemporary workaround till we support old Pillows, remove this when a minimum Pillow version will have this.r   r   r   r   r   é   rF   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚFLIP_LEFT_RIGHTÚFLIP_TOP_BOTTOMÚ	ROTATE_90Ú
ROTATE_180Ú
ROTATE_270Ú	TRANSPOSEÚ
TRANSVERSEr&   r&   r&   r'   r…   *  s   r…   )ru   Úorientationr!   c                 C   s>   t jt jt jt jt jt jt jdœ |¡}|d k	r:|  	|¡S | S )N)r   r   r   r†   rF   é   r   )
r…   r‹   rŽ   rŒ   r�   r�   r‘   r�   r$   Z	transpose)ru   r’   Úmethodr&   r&   r'   Ú_rotate_pil6  s    ùø	
r•   )Úprimary_indexr!   c                 C   sZ   dd„ | D ƒ}|d kr6d}t |ƒD ]\}}|r"|}q"n |dksJ|t|ƒkrVt|ƒd }|S )Nc                 S   s   g | ]}|j  d d¡‘qS )ÚprimaryF)r    r$   )Ú.0Ú_r&   r&   r'   Ú
<listcomp>H  s     z&_get_primary_index.<locals>.<listcomp>r   rT   r   )rh   r?   )Zsome_iteratorr–   Zprimary_attrsrn   Úvr&   r&   r'   Ú_get_primary_indexG  s    rœ   ©Úvaluesc                 C   s,   | r(| d | d | d | d | d dœS d S )Nr   r   r   r   r   )Zfocal_length_xZfocal_length_yZprincipal_point_xZprincipal_point_yZskewr&   r�   r&   r&   r'   Ú__get_camera_intrinsic_matrixS  s    	ùû÷rŸ   c                 C   s0   i }t | jƒ}|r||d< | j}|r,||d< |S )NÚcamera_intrinsic_matrixÚcamera_extrinsic_matrix_rot)rŸ   r    r¡   )r%   ÚrZ_camera_intrinsic_matrixZ_camera_extrinsic_matrix_rotr&   r&   r'   Ú_get_heif_metaa  s    
r£   c                   @   s^   e Zd ZdZedœdd„Zeeddœdd„Ze	j	dd	œd
d„Z
edœdd„Zddœdd„ZdS )Ú	CtxEncodez0Encoder bindings from python to python C module.)Úcompression_formatc           	      K   sÄ   |  dtj¡}t ||d kr dn|tj  |tjkr6dndd¡¡| _|  di ¡}d }d|krjt	  |d d ¡}|d kr~|  dd ¡}|rŠ||d< | 
¡ D ],\}}t|tƒr¨|nt|ƒ}| j ||¡ q’d S )	NÚqualityéþÿÿÿZHEIFZAVIFr4   Ú
enc_paramsZsubsamplingr"   )r$   r   ZQUALITYÚ_pillow_heifZCtxWriteZPREFERRED_ENCODERr   ZHEVCÚ	ctx_writeÚSUBSAMPLING_CHROMA_MAPÚitemsrX   rY   Zset_parameter)	Úselfr¥   Úkwargsr¦   r¨   r"   ÚkeyrN   Ú_valuer&   r&   r'   Ú__init__o  s"    ýzCtxEncode.__init__N)Úsizer€   r!   c           	      K   s.  |d dks|d dkr t dƒ‚t| d }|dkr8dn
| dd¡}|dkrZtjrVdnd}t|jd	d
�d d dkƒ}| j |t| d t| d |¡}t| d dkrÈ| 	||||| dd¡t
j¡ nRt| d dkrô| ||||| dd¡¡ n&| ||||| d¡dk| dd¡¡ | j||f|Ž dS )zAdds image to the encoder.r   r   zEmpty images are not supported.r   Ú	bit_depthr   r   r   ú;)ÚseprT   Úar   r   Ústrider   N)Ú
ValueErrorÚ	MODE_INFOr$   r   ZSAVE_HDR_TO_12_BITr;   Úsplitrª   Úcreate_imageÚadd_plane_lr   Ú	CHANNEL_YZadd_plane_laZ	add_planeÚfindÚ_finish_add_image)	r­   r²   r€   rd   r®   Zbit_depth_inZbit_depth_outZpremultiplied_alphaÚim_outr&   r&   r'   Ú	add_image‚  s    " &zCtxEncode.add_imagert   c                 K   s|   | j  |jt|j d t|j d d¡}tjtjtjfD ],}| 	|jddt
| |¡ƒ| dd¡|¡ q8| j||jf|Ž dS )z*Adds image in `YCbCR` mode to the encoder.r   r   r   r   r·   N)rª   r»   r²   r¹   r€   r   r½   Z
CHANNEL_CBZ
CHANNEL_CRr¼   r]   Zgetdatar$   r¿   )r­   ru   r®   rÀ   rn   r&   r&   r'   Úadd_image_ycbcr–  s    (*zCtxEncode.add_image_ycbcr)r²   c           
         sv  ˆ   dd ¡}|d k	r(| ˆ   dd¡|¡ ˆ   dd ¡rL|j‡ fdd„dD ƒŽ  ˆ   dd	¡}| | jˆ   d
d¡ˆ   dtj¡ˆ   dd¡ˆ   dd¡ˆ   dd¡ˆ   dd¡|¡ ˆ   dd ¡}|d k	rÚt|tj	ƒrÌ| 
¡ }| | j|¡ ˆ   dd ¡}|d k	rü| | j|¡ ˆ   dg ¡D ]$}| | j|d |d |d ¡ �qˆ   dg ¡D ]6}	t|ƒ|	  k�rZdk�r:n n| | j|	|¡ �q:d S )NZicc_profileZicc_profile_typeZprofÚnclx_profilec                    s   g | ]}ˆ d  | ‘qS )rÃ   r&   )r˜   rn   ©r®   r&   r'   rš   §  s   ÿz/CtxEncode._finish_add_image.<locals>.<listcomp>)Úcolor_primariesÚtransfer_characteristicsÚmatrix_coefficientsÚfull_range_flagr,   r   r—   FZsave_nclx_profilerÅ   rT   rÆ   rÇ   rÈ   rD   r0   ra   rb   Úcontent_typerd   Ú
thumbnailsr   )r$   Zset_icc_profileZset_nclx_profiler>   rª   r   ZSAVE_NCLX_PROFILErX   r   rc   rw   Zset_exifZset_xmpZset_metadataÚmaxZencode_thumbnail)
r­   rÀ   r²   r®   Z_CtxEncode__icc_profiler,   rD   r0   ra   Z	thumb_boxr&   rÄ   r'   r¿   Ÿ  sB    
þÿ




ø" zCtxEncode._finish_add_imagerO   c                 C   sJ   | j  ¡ }t|ttfƒr(t|ƒ |¡ nt|dƒr>| |¡ ntdƒ‚dS )z?Ask encoder to produce output based on previously added images.Úwritez=`fp` must be a path to file or an object with `write` method.N)	rª   ÚfinalizerX   rY   r   Úwrite_bytesr\   rÌ   Ú	TypeError)r­   rQ   rd   r&   r&   r'   ÚsaveÈ  s    

zCtxEncode.save)r‡   rˆ   r‰   rŠ   r   r±   ÚtuplerY   rÁ   r   rÂ   r¿   rÐ   r&   r&   r&   r'   r¤   l  s   	)r¤   c                   @   s@   e Zd ZdZeeedœdd„Zedd„ ƒZ	ee
dœdd	„ƒZd
S )Ú	MimCImagezMimicry of the HeifImage class.)r€   r²   rd   c                 K   s†   || _ || _| d|d t| d  tt| d d ƒ ¡| _|| _g | _d | _g | _	g | _
d| _tjj| _tjj| _d | _d | _d S )Nr·   r   r   r   F)r€   r²   r$   r¹   r   r·   rd   ra   Zcolor_profilerÊ   Zdepth_image_listr—   r   Ú	UNDEFINEDrN   r"   r   Z
colorspacer    r¡   )r­   r€   r²   rd   r®   r&   r&   r'   r±   ×  s    2

zMimCImage.__init__c                 C   s   | j | jfS )zMimicry of c_image property.)r²   r€   ©r­   r&   r&   r'   Ú	size_modeæ  s    zMimCImage.size_moderO   c                 C   s   t | j d S )z%Return bit-depth based on image mode.r   )r¹   r€   rÔ   r&   r&   r'   r³   ë  s    zMimCImage.bit_depthN)r‡   rˆ   r‰   rŠ   rY   rÑ   r]   r±   ÚpropertyrÕ   r;   r³   r&   r&   r&   r'   rÒ   Ó  s   
rÒ   )Úplugin_pathr!   c                 C   s   t  | ¡ dS )zLoad specified LibHeif plugin.N)r©   Zload_plugin)r×   r&   r&   r'   Úload_libheif_pluginñ  s    rØ   )F)F)N)ErŠ   rZ   r9   Zdataclassesr   Úenumr   Úmathr   Úpathlibr   Ústructr   r   Útypingr   r	   r
   ZPILr   r4   r   Ú	constantsr   r   r   r   r©   ÚImportErrorÚexZ_deffered_errorr   r   ZINTERLEAVED_RRGGBBAA_LEZINTERLEAVED_RRGGBB_LEZ
MONOCHROMEZINTERLEAVED_RGBAZINTERLEAVED_RGBZYCBCRZ
CHROMA_444r¹   r«   r#   Údictr(   r;   r+   r-   ÚboolrC   r*   rY   rR   r]   rP   rq   rs   rx   r~   r„   r…   r•   rœ   rÑ   rŸ   r£   r¤   rÒ   rØ   r&   r&   r&   r'   Ú<module>   s²   Ô0ýý#
g