o
    W_>                     @   s  d Z ddlmZmZmZ ddlmZ ddlmZm	Z	 ddl
mZmZ ddl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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d S )!z[
Objects related to parsing headers of JPEG image streams, both JFIF and Exif
sub-formats.
    )absolute_importdivisionprint_function   )BytesIO   )JPEG_MARKER_CODE	MIME_TYPE)
BIG_ENDIANStreamReader)BaseImageHeader)Tiffc                   @   s(   e Zd ZdZedd Zedd ZdS )Jpegz2
    Base class for JFIF and EXIF subclasses.
    c                 C   s   t jS )zi
        MIME content type for this image, unconditionally `image/jpeg` for
        JPEG images.
        )r	   ZJPEGself r   ?D:\Projects\ConvertPro\env\Lib\site-packages\docx\image\jpeg.pycontent_type      zJpeg.content_typec                 C   s   dS )zJ
        Default filename extension, always 'jpg' for JPG images.
        Zjpgr   r   r   r   r   default_ext   s   zJpeg.default_extN)__name__
__module____qualname____doc__propertyr   r   r   r   r   r   r      s    
r   c                   @      e Zd ZdZedd ZdS )Exifz3
    Image header parser for Exif image format
    c                 C   8   t |}|jj}|jj}|jj}|jj}| ||||S )zm
        Return |Exif| instance having header properties parsed from Exif
        image in *stream*.
        )_JfifMarkersfrom_streamsofpx_width	px_heightapp1horz_dpivert_dpiclsstreammarkersr!   r"   r$   r%   r   r   r   r   )   s   
zExif.from_streamNr   r   r   r   classmethodr   r   r   r   r   r   %       r   c                   @   r   )Jfifz3
    Image header parser for JFIF image format
    c                 C   r   )zj
        Return a |Jfif| instance having header properties parsed from image
        in *stream*.
        )r   r   r    r!   r"   app0r$   r%   r&   r   r   r   r   >   s   
zJfif.from_streamNr*   r   r   r   r   r-   :   r,   r-   c                       sX   e Zd ZdZ fddZdd Zedd Zedd	 Z	ed
d Z
edd Z  ZS )r   zp
    Sequence of markers in a JPEG file, perhaps truncated at first SOS marker
    for performance reasons.
    c                    s   t t|   t|| _d S N)superr   __init__list_markers)r   r)   	__class__r   r   r1   S   s   z_JfifMarkers.__init__c                 C   sN   d}d}g }| j D ]}|||j|jt|j|jf  q	|g| }d|S )z
        Returns a tabular listing of the markers in this instance, which can
        be handy for debugging and perhaps other uses.
        z4 offset  seglen  mc  name
=======  ======  ==  =====z%7d  %6d  %02X  %s
)r3   appendoffsetsegment_lengthordmarker_codenamejoin)r   headertmplZrowsmarkerlinesr   r   r   __str__W   s   



z_JfifMarkers.__str__c                 C   sD   t |}g }| D ]}|| |jtjkr | |S q| |S )z
        Return a |_JfifMarkers| instance containing a |_JfifMarker| subclass
        instance for each marker in *stream*.
        )_MarkerParserr   iter_markersr7   r;   r   ZSOS)r'   r(   Zmarker_parserr)   r@   r   r   r   r   g   s   

z_JfifMarkers.from_streamc                 C   (   | j D ]}|jtjkr|  S qtd)z5
        First APP0 marker in image markers.
        zno APP0 marker in image)r3   r;   r   APP0KeyErrorr   mr   r   r   r.   u   
   
z_JfifMarkers.app0c                 C   rE   )z5
        First APP1 marker in image markers.
        zno APP1 marker in image)r3   r;   r   APP1rG   rH   r   r   r   r#      rJ   z_JfifMarkers.app1c                 C   s(   | j D ]}|jtjv r|  S qtd)zF
        First start of frame (SOFn) marker in this sequence.
        z(no start of frame (SOFn) marker in image)r3   r;   r   SOF_MARKER_CODESrG   rH   r   r   r   r       rJ   z_JfifMarkers.sof)r   r   r   r   r1   rB   r+   r   r   r.   r#   r    __classcell__r   r   r4   r   r   N   s    

	
	r   c                       s4   e Zd ZdZ fddZedd Zdd Z  ZS )rC   z_
    Service class that knows how to parse a JFIF stream and iterate over its
    markers.
    c                       t t|   || _d S r/   )r0   rC   r1   _stream)r   stream_readerr4   r   r   r1         
z_MarkerParser.__init__c                 C   s   t |t}| |S )z`
        Return a |_MarkerParser| instance to parse JFIF markers from
        *stream*.
        )r   r
   )r'   r(   rP   r   r   r   r      s   
z_MarkerParser.from_streamc                 c   s^    t | j}d}d}|tjkr-||\}}t|| j|}|V  ||j }|tjksdS dS )z
        Generate a (marker_code, segment_offset) 2-tuple for each marker in
        the JPEG *stream*, in the order they occur in the stream.
        r   N)_MarkerFinderr   rO   r   ZEOInext_MarkerFactoryr9   )r   Zmarker_finderstartr;   segment_offsetr@   r   r   r   rD      s   

z_MarkerParser.iter_markers)	r   r   r   r   r1   r+   r   rD   rM   r   r   r4   r   rC      s    
rC   c                       sL   e Zd ZdZ fddZedd Zdd Zdd	 Zd
d Z	dd Z
  ZS )rR   zP
    Service class that knows how to find the next JFIF marker in a stream.
    c                    rN   r/   )r0   rR   r1   rO   )r   r(   r4   r   r   r1      rQ   z_MarkerFinder.__init__c                 C   s   | |S )zU
        Return a |_MarkerFinder| instance to find JFIF markers in *stream*.
        r   )r'   r(   r   r   r   r      s   z_MarkerFinder.from_streamc                 C   sH   |}	 | j |d}| j|d d\}}|dkrq||d }}	 ||fS )a`  
        Return a (marker_code, segment_offset) 2-tuple identifying and
        locating the first marker in *stream* occuring after offset *start*.
        The returned *segment_offset* points to the position immediately
        following the 2-byte marker code, the start of the marker segment,
        for those markers that have a segment.
        T)rU   r       )_offset_of_next_ff_byte_next_non_ff_byte)r   rU   positionbyte_r;   rV   r   r   r   rS      s   z_MarkerFinder.nextc                 C   sB   | j | |  }|dkr|  }|dks| j  d }||fS )u  
        Return an offset, byte 2-tuple for the next byte in *stream* that is
        not 'ÿ', starting with the byte at offset *start*. If the byte at
        offset *start* is not 'ÿ', *start* and the returned *offset* will
        be the same.
           r   rO   seek
_read_bytetell)r   rU   r[   Zoffset_of_non_ff_byter   r   r   rY      s   z_MarkerFinder._next_non_ff_bytec                 C   s>   | j | |  }|dkr|  }|dks| j  d }|S )u   
        Return the offset of the next 'ÿ' byte in *stream* starting with
        the byte at offset *start*. Returns *start* if the byte at that
        offset is a hex 255; it does not necessarily advance in the stream.
        r\   r   r]   )r   rU   r[   Zoffset_of_ff_byter   r   r   rX      s   z%_MarkerFinder._offset_of_next_ff_bytec                 C   s   | j d}|std|S )zm
        Return the next byte read from stream. Raise Exception if stream is
        at end of file.
        r   zunexpected end of file)rO   read	Exception)r   r[   r   r   r   r_      s   z_MarkerFinder._read_byte)r   r   r   r   r1   r+   r   rS   rY   rX   r_   rM   r   r   r4   r   rR      s    
rR   c                 C   sB   | t jkrt}n| t jkrt}n
| t jv rt}nt}||| |S )zx
    Return |_Marker| or subclass instance appropriate for marker at *offset*
    in *stream* having *marker_code*.
    )	r   rF   _App0MarkerrK   _App1MarkerrL   
_SofMarker_Markerr   )r;   r(   r8   Z
marker_clsr   r   r   rT     s   


rT   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  ZS )rf   zu
    Base class for JFIF marker classes. Represents a marker and its segment
    occuring in a JPEG byte stream.
    c                    s$   t t|   || _|| _|| _d S r/   )r0   rf   r1   _marker_code_offset_segment_length)r   r;   r8   r9   r4   r   r   r1     s   
z_Marker.__init__c                 C   s&   t |rd}n||}| |||S )zz
        Return a generic |_Marker| instance for the marker at *offset* in
        *stream* having *marker_code*.
        r   )r   Zis_standalone
read_short)r'   r(   r;   r8   r9   r   r   r   r     s   

z_Marker.from_streamc                 C      | j S )u   
        The single-byte code that identifies the type of this marker, e.g.
        ``'à'`` for start of image (SOI).
        )rg   r   r   r   r   r;   )  r   z_Marker.marker_codec                 C   s   t j| j S r/   )r   Zmarker_namesrg   r   r   r   r   r<   1  s   z_Marker.namec                 C   rk   r/   )rh   r   r   r   r   r8   5  s   z_Marker.offsetc                 C   rk   )z>
        The length in bytes of this marker's segment
        )ri   r   r   r   r   r9   9     z_Marker.segment_length)r   r   r   r   r1   r+   r   r   r;   r<   r8   r9   rM   r   r   r4   r   rf     s    



rf   c                       sL   e Zd ZdZ fddZedd Zedd Zdd	 Ze	d
d Z
  ZS )rc   z0
    Represents a JFIF APP0 marker segment.
    c                    s*   t t| ||| || _|| _|| _d S r/   )r0   rc   r1   _density_units
_x_density
_y_density)r   r;   r8   lengthdensity_units	x_density	y_densityr4   r   r   r1   E  s   
z_App0Marker.__init__c                 C      |  | jS zm
        Horizontal dots per inch specified in this marker, defaults to 72 if
        not specified.
        )_dpirn   r   r   r   r   r$   M     z_App0Marker.horz_dpic                 C   rt   zk
        Vertical dots per inch specified in this marker, defaults to 72 if
        not specified.
        )rv   ro   r   r   r   r   r%   U  rw   z_App0Marker.vert_dpic                 C   s8   | j dkr	|}|S | j dkrtt|d }|S d}|S )zH
        Return dots per inch corresponding to *density* value.
        r   r   gRQ@H   )rm   intround)r   ZdensityZdpir   r   r   rv   ]  s   

z_App0Marker._dpic                 C   s@   | |}||d}| |d}| |d}| ||||||S )zg
        Return an |_App0Marker| instance for the APP0 marker at *offset* in
        *stream*.
        	   
      )rj   Z	read_byte)r'   r(   r;   r8   r9   rq   rr   rs   r   r   r   r   i  s   

z_App0Marker.from_stream)r   r   r   r   r1   r   r$   r%   rv   r+   r   rM   r   r   r4   r   rc   A  s    

rc   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  ZS )rd   z7
    Represents a JFIF APP1 (Exif) marker segment.
    c                    $   t t| ||| || _|| _d S r/   )r0   rd   r1   	_horz_dpi	_vert_dpi)r   r;   r8   rp   r$   r%   r4   r   r   r1     s   
z_App1Marker.__init__c                 C   sH   | |}| ||r| |||ddS | |||}| ||||j|jS )z
        Extract the horizontal and vertical dots-per-inch value from the APP1
        header at *offset* in *stream*.
        ry   )rj   _is_non_Exif_APP1_segment_tiff_from_exif_segmentr$   r%   )r'   r(   r;   r8   r9   tiffr   r   r   r     s   
z_App1Marker.from_streamc                 C   rk   ru   )r   r   r   r   r   r$     r   z_App1Marker.horz_dpic                 C   rk   rx   )r   r   r   r   r   r%     r   z_App1Marker.vert_dpic                 C   s    | |d  |d}|dkS )z
        Return True if the APP1 segment at *offset* in *stream* is NOT an
        Exif segment, as determined by the ``'Exif  '`` signature at
        offset 2 in the segment.
        r      s   Exif  )r^   ra   )r'   r(   r8   Zexif_signaturer   r   r   r     s   
z%_App1Marker._is_non_Exif_APP1_segmentc                 C   s.   | |d  ||d }t|}t|S )z
        Return a |Tiff| instance parsed from the Exif APP1 segment of
        *segment_length* at *offset* in *stream*.
           )r^   ra   r   r   r   )r'   r(   r8   r9   Zsegment_bytesZ	substreamr   r   r   r     s   
z#_App1Marker._tiff_from_exif_segment)r   r   r   r   r1   r+   r   r   r$   r%   r   r   rM   r   r   r4   r   rd     s    




rd   c                       sD   e Zd ZdZ fddZedd Zedd Zedd	 Z	  Z
S )
re   zA
    Represents a JFIF start of frame (SOFx) marker segment.
    c                    r   r/   )r0   re   r1   	_px_width
_px_height)r   r;   r8   r9   r!   r"   r4   r   r   r1     s   
z_SofMarker.__init__c                 C   s2   | |}| |d}| |d}| |||||S )zd
        Return an |_SofMarker| instance for the SOFn marker at *offset* in
        stream.
              )rj   )r'   r(   r;   r8   r9   r"   r!   r   r   r   r     s   
z_SofMarker.from_streamc                 C   rk   )z(
        Image height in pixels
        )r   r   r   r   r   r"     rl   z_SofMarker.px_heightc                 C   rk   )z'
        Image width in pixels
        )r   r   r   r   r   r!     rl   z_SofMarker.px_width)r   r   r   r   r1   r+   r   r   r"   r!   rM   r   r   r4   r   re     s    

re   N)r   Z
__future__r   r   r   compatr   	constantsr   r	   helpersr
   r   imager   r   r   r   r   r-   objectr   rC   rR   rT   rf   rc   rd   re   r   r   r   r   <module>   s$   F#K/BG