a
    CgP                  .   @  s  d Z ddlm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 d
dlmZ d
dl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 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(dddddZ)dd dd!d"Z*dd#dd$d%Z+dZdd d'd d(d)d*Z,d[dd'd d+d,d-Z-d.d/d0d1Z.d\d2d/d3d4Z/d5d6d7d8d9Z0d5d6d7d:d;Z1d<d6d=d>d?Z2d<d6d=d@dAZ3d<d<d=dBdCZ4G dDdE dEeZ5d<d#d<dFdGdHZ6d d#dIdJdKZ7dLdMdNdOZ8dd/dPdQZ9G dRdS dSZ:eG dTdU dUZ;dVddWdXdYZ<dS )]zoDifferent miscellaneous helper functions.

Mostly for internal use, so prototypes can change between versions.
    )annotationsN)	dataclass)IntEnum)ceil)Path)packunpack)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   dictNone)inforeturnc                 C  s"   t | jd}|du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&   O/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/pillow_heif/misc.pysave_colorspace_chromaY   s    r(   z
int | Nonec                 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_orientationa   s    r+   intc                 C  s   t | d}|d u rdS |S )NFr
   r)   )r    image_orientationr&   r&   r'   _get_orientation_for_encoders   s    
r.   Fbool)r    exif_orientationresetr!   c              	   C  s   d}|  dr| d dd}|d rd }dD ]0}z|d |}W  q`W q. ty\   Y q.0 q.|rtd|}|rt|d }|rtdd	|}td
d	|}|dks|dkrd|	dt
|dkrdndg| d< |d u 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>r4       )r$   rsplitdecode	Exceptionresearchr,   subjoinencodelen)r    r0   r1   xmp_orientationZxmp_dataZdecoded_xmp_dataencodingmatchr&   r&   r'   _get_orientation_xmpx   s*    

(rD   )r    r1   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rq||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<  qlqW n ty   Y n0 t| ||d}|p|S )NexifF   Exif  T   r   r   s   II<>r   r   r   Hr   i  r
   )r1   )r$   
startswithr   ranger   r:   rD   )r    r1   Zoriginal_orientationZtif_tagZskipped_exif00Zendian_markpointerZ	tag_countoffsetZtag_nvalueZt_original_orientationZp_valueZnew_orientationrA   r&   r&   r'   r*      s@    
",r*   strr!   c                 C  sb   t | ddd }|r^|dkr"dS |dkr.dS |dv r:d	S |d
v 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-sequencer6   )
_get_bytes)fpZ
heif_brandr&   r&   r'   get_file_mimetype   s    	rT   bytesc                 C  s   t | ttfrHt| d}||p&dW  d    S 1 s>0    Y  t| drt| drd|  nd }| |prd}|d urt| dr| | |S t	| d | S )Nrbreadtellseek)

isinstancerP   r   builtinsopenrX   hasattrrY   rZ   rU   )rS   lengthfilerN   resultr&   r&   r'   rR      s    ,

rR   z
list[dict]zbytes | None)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signedrG   rF   )	enumerateappendr,   
from_bytesr@   reversed)rb   ra   purgeimd_blockZ	skip_sizere   r&   r&   r'   _retrieve_exif   s"    
 rp   c                 C  sT   d }g }t | D ]*\}}|d dkr|| |s|d }qt|D ]
}| |= qD|S )Nrc   mimere   )ri   rj   rl   )rb   ra   rm   rn   ro   r&   r&   r'   _retrieve_xmp   s    

rr   Image.Imageimgr!   c                 C  s6   d| j v r| j d S t| dr2|  }|r2| S d S )NrE   getexif)r    r^   rv   tobytes)ru   rE   r&   r&   r'   _exif_from_pillow   s    


rx   c                 C  s   d }d| j v r| j d }nxd| j v r0| j d }nbt| drPd| jv r| jd }nBt| dr| jD ]0\}}|dkr`|dd\}}|d	kr`|} qq`t|tr|d
}|S )Nr2   zXML:com.adobe.xmptag_v2i  applistZAPP1r3   r
   s   http://ns.adobe.com/xap/1.0/r4   )r    r^   ry   rz   r8   r[   rP   r?   )ru   Zim_xmpsegmentcontentmarkerZxmp_tagsr&   r&   r'   _xmp_from_pillow  s$    






r~   c                 C  s   | j dkr2| jdd d u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      rG   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 ur:| 	|S | S )N)r   r   r   r   rG      r   )
r   r   r   r   r   r   r   r   r$   Z	transpose)ru   r   methodr&   r&   r'   _rotate_pil7  s    	
r   )primary_indexr!   c                 C  sZ   dd | D }|d u 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>I  r7   z&_get_primary_index.<locals>.<listcomp>r   rW   r
   )ri   r@   )Zsome_iteratorr   Zprimary_attrsrn   vr&   r&   r'   _get_primary_indexH  s    r   ztuple | None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_matrixT  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%   rr   r   r&   r&   r'   _get_heif_metab  s    
r   c                   @  s\   e Zd ZdZddddZdddd	d
dZdddddZddddZddddZdS )	CtxEncodez0Encoder bindings from python to python C module.r   )compression_formatc                 K  s   | dtj}t||d u r dn|tj |tjkr6dndd| _| di }d }d|v rjt	 |d d }|d u r|| d}|r||d< |
 D ](\}}| j|t|tr|nt| qd S )	NqualityZHEIFZAVIFr6   
enc_paramsZsubsamplingr"   )r$   r   ZQUALITY_pillow_heifZCtxWriteZPREFERRED_ENCODERr   ZHEVC	ctx_writeSUBSAMPLING_CHROMA_MAPitemsZset_parameterr[   rP   )selfr   kwargsr   r   r"   keyrO   r&   r&   r'   __init__p  s     
zCtxEncode.__init__tuple[int, int]rP   r   )sizer   r!   c           	      K  s2  |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i | dS )zAdds image to the encoder.r   r
   zEmpty images are not supported.r   	bit_depthr   r   r   ;)seprW   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   re   r   Zbit_depth_inZbit_depth_outZpremultiplied_alphaim_outr&   r&   r'   	add_image  s    " &zCtxEncode.add_imagers   rt   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i | 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   rU   Zgetdatar$   r   )r   ru   r   r   rn   r&   r&   r'   add_image_ycbcr  s    (*zCtxEncode.add_image_ycbcr)r   c           
        sn    d}|d ur&|  dd|   drH|j fdddD     dd	}|| j  d
d  dtj  dd  dd  dd  dd|   d}|d urt|tj	r|
 }|| j|   d}|d ur|| j|   dg D ]$}|| j|d |d |d  q   dg D ]6}	t||	  krRdkr2n n|| j|	| q2d S )N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   rW   r   r   r   rE   r2   rb   rc   content_typere   
thumbnailsr   )r$   Zset_icc_profileZset_nclx_profiler?   r   r   ZSAVE_NCLX_PROFILEr[   r	   rd   rw   Zset_exifZset_xmpZset_metadatamaxZencode_thumbnail)
r   r   r   r   r   r-   rE   r2   rb   Z	thumb_boxr&   r   r'   r     sB    









" zCtxEncode._finish_add_imagerQ   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   finalizer[   rP   r   write_bytesr^   r   	TypeError)r   rS   re   r&   r&   r'   save  s    

zCtxEncode.saveN)	r   r   r   r   r   r   r   r   r   r&   r&   r&   r'   r   m  s   	)r   c                   @  s@   e Zd ZdZddddddZedd	 Zed
dddZdS )	MimCImagezMimicry of the HeifImage class.rP   r   rU   )r   r   re   c                 K  s   || _ || _|d|d t| d  tt| d d  | _|| _g | _d | _g | _	g | _
g | _d| _tjj| _tjj| _d | _d | _d S )Nr   r   r
   r   F)r   r   r$   r   r   r   re   rb   Zcolor_profiler   Zdepth_image_listZaux_image_idsr   r   	UNDEFINEDrO   r"   r   Z
colorspacer   r   )r   r   r   re   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_moder,   rQ   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   r   propertyr   r   r&   r&   r&   r'   r     s   
r   z
str | Path)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)=r   
__future__r   r\   r;   Zdataclassesr   enumr   mathr   pathlibr   structr   r   ZPILr	   r6   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#   r(   r+   r.   rD   r*   rT   rR   rp   rr   rx   r~   r   r   r   r   r   r   r   r   r   r&   r&   r&   r'   <module>   s   0#
f