o
    	'f><                     @   s   d Z ddl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ZG dd dZG dd dZdd ZG dd dZG dd deZG dd deZG dd deZdS )zdObjects related to parsing headers of JPEG image streams.

Includes both JFIF and Exif sub-formats.
    N)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 )Jpegz(Base class for JFIF and EXIF subclasses.c                 C   s   t jS )zWMIME content type for this image, unconditionally `image/jpeg` for JPEG
        images.)r   JPEGself r   G/home/ubuntu/flask/venv/lib/python3.10/site-packages/docx/image/jpeg.pycontent_type      zJpeg.content_typec                 C   s   dS )z8Default filename extension, always 'jpg' for JPG images.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 )Exifz*Image header parser for Exif image format.c                 C   8   t |}|jj}|jj}|jj}|jj}| ||||S )z[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   )Jfifz*Image header parser for JFIF image format.c                 C   r   )zXReturn a |Jfif| instance having header properties parsed from image in
        `stream`.)r   r   r   r   r   app0r    r!   r"   r   r   r   r   2   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   zfSequence 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   r-   D   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
)r/   appendoffsetsegment_lengthordmarker_codenamejoin)r   headertmplrowsmarkerlinesr   r   r   __str__H   s   

	
z_JfifMarkers.__str__c                 C   sD   t |}g }| D ]}|| |jtjkr | |S q| |S )zrReturn a |_JfifMarkers| instance containing a |_JfifMarker| subclass instance
        for each marker in `stream`.)_MarkerParserr   iter_markersr3   r7   r   SOS)r#   r$   marker_parserr%   r=   r   r   r   r   [   s   

z_JfifMarkers.from_streamc                 C   (   | j D ]}|jtjkr|  S qtd)z#First APP0 marker in image markers.zno APP0 marker in image)r/   r7   r   APP0KeyErrorr   mr   r   r   r*   g   
   
z_JfifMarkers.app0c                 C   rD   )z#First APP1 marker in image markers.zno APP1 marker in image)r/   r7   r   APP1rF   rG   r   r   r   r   o   rI   z_JfifMarkers.app1c                 C   s(   | j D ]}|jtjv r|  S qtd)z4First start of frame (SOFn) marker in this sequence.z(no start of frame (SOFn) marker in image)r/   r7   r   SOF_MARKER_CODESrF   rG   r   r   r   r   w   rI   z_JfifMarkers.sof)r   r   r   r   r-   r?   r'   r   r   r*   r   r   __classcell__r   r   r0   r   r   @   s    


r   c                       s4   e Zd ZdZ fddZedd Zdd Z  ZS )r@   zUService class that knows how to parse a JFIF stream and iterate over its
    markers.c                       t t|   || _d S r+   )r,   r@   r-   _stream)r   stream_readerr0   r   r   r-         
z_MarkerParser.__init__c                 C   s   t |t}| |S )zFReturn a |_MarkerParser| instance to parse JFIF markers from `stream`.)r   r   )r#   r$   rO   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 )zGenerate 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   rN   r   EOInext_MarkerFactoryr5   )r   marker_finderstartr7   segment_offsetr=   r   r   r   rA      s   

z_MarkerParser.iter_markers)	r   r   r   r   r-   r'   r   rA   rL   r   r   r0   r   r@      s    
r@   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 )rQ   zFService class that knows how to find the next JFIF marker in a stream.c                    rM   r+   )r,   rQ   r-   rN   )r   r$   r0   r   r   r-      rP   z_MarkerFinder.__init__c                 C   s   | |S )zCReturn 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 )aX  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)rV          )_offset_of_next_ff_byte_next_non_ff_byte)r   rV   positionbyte_r7   rW   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.
           rX   rN   seek
_read_bytetell)r   rV   r]   offset_of_non_ff_byter   r   r   r[      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^   rX   r_   )r   rV   r]   offset_of_ff_byter   r   r   rZ      s   z%_MarkerFinder._offset_of_next_ff_bytec                 C   s   | j d}|std|S )zeReturn the next byte read from stream.

        Raise Exception if stream is at end of file.
        rX   zunexpected end of file)rN   read	Exception)r   r]   r   r   r   ra      s   z_MarkerFinder._read_byte)r   r   r   r   r-   r'   r   rS   r[   rZ   ra   rL   r   r   r0   r   rQ      s    
rQ   c                 C   sB   | t jkrt}n| t jkrt}n
| t jv rt}nt}||| |S )znReturn |_Marker| or subclass instance appropriate for marker at `offset` in
    `stream` having `marker_code`.)	r   rE   _App0MarkerrJ   _App1MarkerrK   
_SofMarker_Markerr   )r7   r$   r4   
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 )rj   zqBase class for JFIF marker classes.

    Represents a marker and its segment occuring in a JPEG byte stream.
    c                    s$   t t|   || _|| _|| _d S r+   )r,   rj   r-   _marker_code_offset_segment_length)r   r7   r4   r5   r0   r   r   r-      s   
z_Marker.__init__c                 C   s&   t |rd}n||}| |||S )zhReturn a generic |_Marker| instance for the marker at `offset` in `stream`
        having `marker_code`.r   )r   is_standalone
read_short)r#   r$   r7   r4   r5   r   r   r   r      s   

z_Marker.from_streamc                 C      | j S )um   The single-byte code that identifies the type of this marker, e.g. ``'à'``
        for start of image (SOI).)rl   r
   r   r   r   r7     r   z_Marker.marker_codec                 C   s   t j| j S r+   )r   marker_namesrl   r
   r   r   r   r8     s   z_Marker.namec                 C   rq   r+   )rm   r
   r   r   r   r4     s   z_Marker.offsetc                 C   rq   )z-The length in bytes of this marker's segment.)rn   r
   r   r   r   r5        z_Marker.segment_length)r   r   r   r   r-   r'   r   r   r7   r8   r4   r5   rL   r   r   r0   r   rj      s    
	


rj   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 )rg   z&Represents a JFIF APP0 marker segment.c                    s*   t t| ||| || _|| _|| _d S r+   )r,   rg   r-   _density_units
_x_density
_y_density)r   r7   r4   lengthdensity_units	x_density	y_densityr0   r   r   r-     s   
z_App0Marker.__init__c                 C      |  | jS z[Horizontal dots per inch specified in this marker, defaults to 72 if not
        specified.)_dpiru   r
   r   r   r   r    '     z_App0Marker.horz_dpic                 C   r{   zYVertical dots per inch specified in this marker, defaults to 72 if not
        specified.)r}   rv   r
   r   r   r   r!   -  r~   z_App0Marker.vert_dpic                 C   s8   | j dkr	|}|S | j dkrtt|d }|S d}|S )z6Return dots per inch corresponding to `density` value.rX      gRQ@H   )rt   intround)r   densitydpir   r   r   r}   3  s   

z_App0Marker._dpic                 C   s@   | |}||d}| |d}| |d}| ||||||S )zUReturn an |_App0Marker| instance for the APP0 marker at `offset` in
        `stream`.	   
      )rp   	read_byte)r#   r$   r7   r4   r5   rx   ry   rz   r   r   r   r   =  s   
z_App0Marker.from_stream)r   r   r   r   r-   r   r    r!   r}   r'   r   rL   r   r   r0   r   rg     s    


rg   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 )rh   z-Represents a JFIF APP1 (Exif) marker segment.c                    $   t t| ||| || _|| _d S r+   )r,   rh   r-   	_horz_dpi	_vert_dpi)r   r7   r4   rw   r    r!   r0   r   r   r-   W     
z_App1Marker.__init__c                 C   sH   | |}| ||r| |||ddS | |||}| ||||j|jS )zmExtract the horizontal and vertical dots-per-inch value from the APP1 header
        at `offset` in `stream`.r   )rp   _is_non_Exif_APP1_segment_tiff_from_exif_segmentr    r!   )r#   r$   r7   r4   r5   tiffr   r   r   r   \  s
   
z_App1Marker.from_streamc                 C   rq   r|   )r   r
   r   r   r   r    n  r   z_App1Marker.horz_dpic                 C   rq   r   )r   r
   r   r   r   r!   t  r   z_App1Marker.vert_dpic                 C   s    | |d  |d}|dkS )zReturn 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`   re   )r#   r$   r4   exif_signaturer   r   r   r   z  s   
z%_App1Marker._is_non_Exif_APP1_segmentc                 C   s0   | |d  ||d }t|}t|S )zoReturn a |Tiff| instance parsed from the Exif APP1 segment of
        `segment_length` at `offset` in `stream`.   )r`   re   ioBytesIOr   r   )r#   r$   r4   r5   segment_bytes	substreamr   r   r   r     s   

z#_App1Marker._tiff_from_exif_segment)r   r   r   r   r-   r'   r   r   r    r!   r   r   rL   r   r   r0   r   rh   T  s    



rh   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 )
ri   z7Represents a JFIF start of frame (SOFx) marker segment.c                    r   r+   )r,   ri   r-   	_px_width
_px_height)r   r7   r4   r5   r   r   r0   r   r   r-     r   z_SofMarker.__init__c                 C   s2   | |}| |d}| |d}| |||||S )zJReturn an |_SofMarker| instance for the SOFn marker at `offset` in stream.      )rp   )r#   r$   r7   r4   r5   r   r   r   r   r   r     s   

z_SofMarker.from_streamc                 C   rq   )zImage height in pixels.)r   r
   r   r   r   r     rs   z_SofMarker.px_heightc                 C   rq   )zImage width in pixels.)r   r
   r   r   r   r     rs   z_SofMarker.px_width)r   r   r   r   r-   r'   r   r   r   r   rL   r   r   r0   r   ri     s    

ri   )r   r   docx.image.constantsr   r   docx.image.helpersr   r   docx.image.imager   docx.image.tiffr   r   r   r)   r   r@   rQ   rT   rj   rg   rh   ri   r   r   r   r   <module>   s"    @I*8: