o
    jqi<                     @   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   ZJPEGself r   V/home/app/PaddleOCR-VL/.venv_paddleocr/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.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 )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_markersr1   r5   r   ZSOS)r!   r"   Z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-   r5   r   APP0KeyErrorr
   mr   r   r   r(   g   
   
z_JfifMarkers.app0c                 C   r@   )z#First APP1 marker in image markers.zno APP1 marker in image)r-   r5   r   APP1rB   rC   r   r   r   r   o   rE   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-   r5   r   SOF_MARKER_CODESrB   rC   r   r   r   r   w   rE   z_JfifMarkers.sof)r   r   r   r   r+   r=   r%   r   r   r(   r   r   __classcell__r   r   r.   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_readerr.   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"   rK   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   rJ   r   ZEOInext_MarkerFactoryr3   )r
   Zmarker_finderstartr5   segment_offsetr;   r   r   r   r?      s   

z_MarkerParser.iter_markers)	r   r   r   r   r+   r%   r   r?   rH   r   r   r.   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 )rM   zFService class that knows how to find the next JFIF marker in a stream.c                    rI   r)   )r*   rM   r+   rJ   )r
   r"   r.   r   r   r+      rL   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)rP          )_offset_of_next_ff_byte_next_non_ff_byte)r
   rP   positionbyte_r5   rQ   r   r   r   rN      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.
           rR   rJ   seek
_read_bytetell)r
   rP   rW   Zoffset_of_non_ff_byter   r   r   rU      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.
        rX   rR   rY   )r
   rP   rW   Zoffset_of_ff_byter   r   r   rT      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.
        rR   zunexpected end of file)rJ   read	Exception)r
   rW   r   r   r   r[      s   z_MarkerFinder._read_byte)r   r   r   r   r+   r%   r   rN   rU   rT   r[   rH   r   r   r.   r   rM      s    
rM   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   rA   _App0MarkerrF   _App1MarkerrG   
_SofMarker_Markerr   )r5   r"   r2   Z
marker_clsr   r   r   rO      s   


rO   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 )rb   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*   rb   r+   _marker_code_offset_segment_length)r
   r5   r2   r3   r.   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   Zis_standalone
read_short)r!   r"   r5   r2   r3   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).)rc   r	   r   r   r   r5     r   z_Marker.marker_codec                 C   s   t j| j S r)   )r   Zmarker_namesrc   r	   r   r   r   r6     s   z_Marker.namec                 C   rg   r)   )rd   r	   r   r   r   r2     s   z_Marker.offsetc                 C   rg   )z-The length in bytes of this marker's segment.)re   r	   r   r   r   r3        z_Marker.segment_length)r   r   r   r   r+   r%   r   r   r5   r6   r2   r3   rH   r   r   r.   r   rb      s    
	


rb   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 )r_   z&Represents a JFIF APP0 marker segment.c                    s*   t t| ||| || _|| _|| _d S r)   )r*   r_   r+   _density_units
_x_density
_y_density)r
   r5   r2   lengthdensity_units	x_density	y_densityr.   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.)_dpirj   r	   r   r   r   r   %     z_App0Marker.horz_dpic                 C   rp   zYVertical dots per inch specified in this marker, defaults to 72 if not
        specified.)rr   rk   r	   r   r   r   r   +  rs   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.rR      gRQ@H   )ri   intround)r
   ZdensityZdpir   r   r   rr   1  s   

z_App0Marker._dpic                 C   s@   | |}||d}| |d}| |d}| ||||||S )zUReturn an |_App0Marker| instance for the APP0 marker at `offset` in
        `stream`.	   
      )rf   	read_byte)r!   r"   r5   r2   r3   rm   rn   ro   r   r   r   r   ;  s
   
z_App0Marker.from_stream)r   r   r   r   r+   r   r   r   rr   r%   r   rH   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  ZS )r`   z-Represents a JFIF APP1 (Exif) marker segment.c                    $   t t| ||| || _|| _d S r)   )r*   r`   r+   	_horz_dpi	_vert_dpi)r
   r5   r2   rl   r   r   r.   r   r   r+   S     
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`.rv   )rf   _is_non_Exif_APP1_segment_tiff_from_exif_segmentr   r   )r!   r"   r5   r2   r3   Ztiffr   r   r   r   X  s
   
z_App1Marker.from_streamc                 C   rg   rq   )r~   r	   r   r   r   r   j  r   z_App1Marker.horz_dpic                 C   rg   rt   )r   r	   r   r   r   r   p  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.ru      s   Exif  )rZ   r]   )r!   r"   r2   Zexif_signaturer   r   r   r   v  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`.   )rZ   r]   ioBytesIOr   r   )r!   r"   r2   r3   Zsegment_bytesZ	substreamr   r   r   r     s   

z#_App1Marker._tiff_from_exif_segment)r   r   r   r   r+   r%   r   r   r   r   r   r   rH   r   r   r.   r   r`   P  s    



r`   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 )
ra   z7Represents a JFIF start of frame (SOFx) marker segment.c                    r}   r)   )r*   ra   r+   	_px_width
_px_height)r
   r5   r2   r3   r   r   r.   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.      )rf   )r!   r"   r5   r2   r3   r   r   r   r   r   r     s   

z_SofMarker.from_streamc                 C   rg   )zImage height in pixels.)r   r	   r   r   r   r     rh   z_SofMarker.px_heightc                 C   rg   )zImage width in pixels.)r   r	   r   r   r   r     rh   z_SofMarker.px_width)r   r   r   r   r+   r%   r   r   r   r   rH   r   r   r.   r   ra     s    

ra   )r   r   Zdocx.image.constantsr   r   Zdocx.image.helpersr   r   Zdocx.image.imager   Zdocx.image.tiffr   r   r   r'   r   r>   rM   rO   rb   r_   r`   ra   r   r   r   r   <module>   s"    @I*4: