o
    W_+                     @   s   d dl mZmZmZ ddlmZmZmZ ddlm	Z	m
Z
mZ ddlmZ G dd deZG dd	 d	eZG d
d deZG dd deZ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eZG dd deZdS )    )absolute_importdivisionprint_function   )	MIME_TYPETIFF_FLDTIFF_TAG)
BIG_ENDIANLITTLE_ENDIANStreamReader)BaseImageHeaderc                   @   s4   e Zd ZdZedd Zedd Zedd ZdS )	Tiffzd
    Image header parser for TIFF images. Handles both big and little endian
    byte ordering.
    c                 C   s   t jS )zm
        Return the MIME type of this TIFF image, unconditionally the string
        ``image/tiff``.
        )r   ZTIFFself r   ?D:\Projects\ConvertPro\env\Lib\site-packages\docx\image\tiff.pycontent_type   s   zTiff.content_typec                 C      dS )zL
        Default filename extension, always 'tiff' for TIFF images.
        Ztiffr   r   r   r   r   default_ext   s   zTiff.default_extc                 C   s0   t |}|j}|j}|j}|j}| ||||S )zk
        Return a |Tiff| instance containing the properties of the TIFF image
        in *stream*.
        )_TiffParserparsepx_width	px_heighthorz_dpivert_dpi)clsstreamparserr   r   r   r   r   r   r   from_stream   s   
zTiff.from_streamN)	__name__
__module____qualname____doc__propertyr   r   classmethodr   r   r   r   r   r   
   s    

r   c                       s|   e Zd ZdZ fddZedd Zedd Zedd	 Z	ed
d Z
edd Zedd Zdd Zedd Z  ZS )r   zu
    Parses a TIFF image stream to extract the image properties found in its
    main image file directory (IFD)
    c                       t t|   || _d S N)superr   __init___ifd_entries)r   ifd_entries	__class__r   r   r(   3      
z_TiffParser.__init__c                 C   s(   |  |}|d}t||}| |S )z
        Return an instance of |_TiffParser| containing the properties parsed
        from the TIFF image in *stream*.
           )_make_stream_reader	read_long_IfdEntriesr   )r   r   
stream_rdrZifd0_offsetr*   r   r   r   r   7   s   

z_TiffParser.parsec                 C      |  tjS )z
        The horizontal dots per inch value calculated from the XResolution
        and ResolutionUnit tags of the IFD; defaults to 72 if those tags are
        not present.
        )_dpir   ZX_RESOLUTIONr   r   r   r   r   B      z_TiffParser.horz_dpic                 C   r3   )z
        The vertical dots per inch value calculated from the XResolution and
        ResolutionUnit tags of the IFD; defaults to 72 if those tags are not
        present.
        )r4   r   ZY_RESOLUTIONr   r   r   r   r   K   r5   z_TiffParser.vert_dpic                 C      | j tjS )z
        The number of stacked rows of pixels in the image, |None| if the IFD
        contains no ``ImageLength`` tag, the expected case when the TIFF is
        embeded in an Exif image.
        )r)   getr   ZIMAGE_LENGTHr   r   r   r   r   T      z_TiffParser.px_heightc                 C   r6   )z
        The number of pixels in each row in the image, |None| if the IFD
        contains no ``ImageWidth`` tag, the expected case when the TIFF is
        embeded in an Exif image.
        )r)   r7   r   ZIMAGE_WIDTHr   r   r   r   r   ]   r8   z_TiffParser.px_widthc                 C   s$   | d |d}|dkrtS tS )z
        Return either BIG_ENDIAN or LITTLE_ENDIAN depending on the endian
        indicator found in the TIFF *stream* header, either 'MM' or 'II'.
        r      s   MM)seekreadr	   r
   )r   r   Z
endian_strr   r   r   _detect_endianf   s   

z_TiffParser._detect_endianc                 C   s^   | j }||vr	dS tj|v r|tj nd}|dkrdS |dkr!dnd}|| }tt|| S )a)  
        Return the dpi value calculated for *resolution_tag*, which can be
        either TIFF_TAG.X_RESOLUTION or TIFF_TAG.Y_RESOLUTION. The
        calculation is based on the values of both that tag and the
        TIFF_TAG.RESOLUTION_UNIT tag in this parser's |_IfdEntries| instance.
        H   r9   r   gRQ@)r)   r   ZRESOLUTION_UNITintround)r   Zresolution_tagr*   Zresolution_unitZunits_per_inchZdots_per_unitr   r   r   r4   p   s   

z_TiffParser._dpic                 C   s   |  |}t||S )z
        Return a |StreamReader| instance with wrapping *stream* and having
        "endian-ness" determined by the 'MM' or 'II' indicator in the TIFF
        stream header.
        )r<   r   )r   r   Zendianr   r   r   r/      s   

z_TiffParser._make_stream_reader)r   r    r!   r"   r(   r$   r   r#   r   r   r   r   r<   r4   r/   __classcell__r   r   r+   r   r   .   s$    






	r   c                       sF   e Zd ZdZ fddZdd Zdd Zedd	 ZdddZ	  Z
S )r1   z
    Image File Directory for a TIFF image, having mapping (dict) semantics
    allowing "tag" values to be retrieved by tag code.
    c                    r%   r&   )r'   r1   r(   _entries)r   entriesr+   r   r   r(      r-   z_IfdEntries.__init__c                 C      | j |S )zG
        Provides ``in`` operator, e.g. ``tag in ifd_entries``
        )rA   __contains__r   keyr   r   r   rD         z_IfdEntries.__contains__c                 C   rC   )zU
        Provides indexed access, e.g. ``tag_value = ifd_entries[tag_code]``
        )rA   __getitem__rE   r   r   r   rH      rG   z_IfdEntries.__getitem__c                 C   s(   t ||}tdd | D }| |S )zh
        Return a new |_IfdEntries| instance parsed from *stream* starting at
        *offset*.
        c                 s   s    | ]	}|j |jfV  qd S r&   )tagvalue).0er   r   r   	<genexpr>   s    z*_IfdEntries.from_stream.<locals>.<genexpr>)
_IfdParserdictiter_entries)r   r   offsetZ
ifd_parserrB   r   r   r   r      s   
z_IfdEntries.from_streamNc                 C   s   | j ||S )zz
        Return value of IFD entry having tag matching *tag_code*, or
        *default* if no matching tag found.
        )rA   r7   )r   tag_codedefaultr   r   r   r7         z_IfdEntries.getr&   )r   r    r!   r"   r(   rD   rH   r$   r   r7   r@   r   r   r+   r   r1      s    
	r1   c                       s4   e Zd ZdZ fddZdd Zedd Z  ZS )rN   zk
    Service object that knows how to extract directory entries from an Image
    File Directory (IFD)
    c                       t t|   || _|| _d S r&   )r'   rN   r(   _stream_rdr_offset)r   r2   rQ   r+   r   r   r(         
z_IfdParser.__init__c                 c   s:    t | jD ]}| jd |d  }t| j|}|V  qdS )zh
        Generate an |_IfdEntry| instance corresponding to each entry in the
        directory.
        r9      N)range_entry_countrW   _IfdEntryFactoryrV   )r   idxZdir_entry_offsetZ	ifd_entryr   r   r   rP      s   z_IfdParser.iter_entriesc                 C   s   | j | jS )zU
        The count of directory entries, read from the top of the IFD header
        )rV   
read_shortrW   r   r   r   r   r[      rT   z_IfdParser._entry_count)	r   r    r!   r"   r(   rP   r#   r[   r@   r   r   r+   r   rN      s    
rN   c                 C   sJ   t jtt jtt jtt jti}| 	|d}||v r|| }nt
}|| |S )z~
    Return an |_IfdEntry| subclass instance containing the value of the
    directory entry at *offset* in *stream_rdr*.
    r9   )r   ASCII_AsciiIfdEntryZSHORT_ShortIfdEntryZLONG_LongIfdEntryZRATIONAL_RationalIfdEntryr^   	_IfdEntryr   )r2   rQ   Zifd_entry_classesZ
field_typeZ	entry_clsr   r   r   r\      s   
r\   c                       sP   e Zd ZdZ fddZedd Zedd Zedd	 Z	ed
d Z
  ZS )rd   zw
    Base class for IFD entry classes. Subclasses are differentiated by value
    type, e.g. ASCII, long int, etc.
    c                    rU   r&   )r'   rd   r(   	_tag_code_value)r   rR   rJ   r+   r   r   r(      rX   z_IfdEntry.__init__c                 C   s>   | |d}||d}||d}| ||||}| ||S )a)  
        Return an |_IfdEntry| subclass instance containing the tag and value
        of the tag parsed from *stream_rdr* at *offset*. Note this method is
        common to all subclasses. Override the ``_parse_value()`` method to
        provide distinctive behavior based on field type.
        r   r.      )r^   r0   _parse_value)r   r2   rQ   rR   value_countvalue_offsetrJ   r   r   r   r      s   
z_IfdEntry.from_streamc                 C   r   )z
        Return the value of this field parsed from *stream_rdr* at *offset*.
        Intended to be overridden by subclasses.
        zUNIMPLEMENTED FIELD TYPEr   r   r2   rQ   ri   rj   r   r   r   rh     s   z_IfdEntry._parse_valuec                 C      | j S )z?
        Short int code that identifies this IFD entry
        )re   r   r   r   r   rI        z_IfdEntry.tagc                 C   rl   )zI
        Value of this tag, its type being dependent on the tag.
        )rf   r   r   r   r   rJ     rm   z_IfdEntry.value)r   r    r!   r"   r(   r$   r   rh   r#   rI   rJ   r@   r   r   r+   r   rd      s    


rd   c                   @      e Zd ZdZedd ZdS )r`   zE
    IFD entry having the form of a NULL-terminated ASCII string
    c                 C   s   | |d |S )z
        Return the ASCII string parsed from *stream_rdr* at *value_offset*.
        The length of the string, including a terminating ' ' (NUL)
        character, is in *value_count*.
        r   )Zread_strrk   r   r   r   rh     s   z_AsciiIfdEntry._parse_valueNr   r    r!   r"   r$   rh   r   r   r   r   r`         r`   c                   @   rn   )ra   z9
    IFD entry expressed as a short (2-byte) integer
    c                 C      |dkr
| |dS dS )z
        Return the short int value contained in the *value_offset* field of
        this entry. Only supports single values at present.
        r   rg   z)Multi-value short integer NOT IMPLEMENTED)r^   rk   r   r   r   rh   -     z_ShortIfdEntry._parse_valueNro   r   r   r   r   ra   )  rp   ra   c                   @   rn   )rb   z8
    IFD entry expressed as a long (4-byte) integer
    c                 C   rq   )z
        Return the long int value contained in the *value_offset* field of
        this entry. Only supports single values at present.
        r   rg   z(Multi-value long integer NOT IMPLEMENTEDr0   rk   r   r   r   rh   =  rr   z_LongIfdEntry._parse_valueNro   r   r   r   r   rb   9  rp   rb   c                   @   rn   )rc   z>
    IFD entry expressed as a numerator, denominator pair
    c                 C   s*   |dkr| |}| |d}|| S dS )z
        Return the rational (numerator / denominator) value at *value_offset*
        in *stream_rdr* as a floating-point number. Only supports single
        values at present.
        r   r.   z$Multi-value Rational NOT IMPLEMENTEDrs   )r   r2   rQ   ri   rj   	numeratordenominatorr   r   r   rh   M  s
   
z_RationalIfdEntry._parse_valueNro   r   r   r   r   rc   I  rp   rc   N)Z
__future__r   r   r   	constantsr   r   r   helpersr	   r
   r   imager   r   objectr   r1   rN   r\   rd   r`   ra   rb   rc   r   r   r   r   <module>   s   $f'1