a
    ]j<                     @   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   K/var/www/html/assistant/venv/lib/python3.9/site-packages/docx/image/jpeg.pycontent_type   s    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                   @   s   e Zd ZdZedd ZdS )Exifz*Image header parser for Exif image format.c                 C   s8   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      s   r   c                   @   s   e Zd ZdZedd ZdS )Jfifz*Image header parser for JFIF image format.c                 C   s8   t |}|jj}|jj}|jj}|jj}| ||||S )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#   /   s   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   s>   t |}g }| D ]}|| |jtjkr q6q| |S )zrReturn a |_JfifMarkers| instance containing a |_JfifMarker| subclass instance
        for each marker in `stream`.)_MarkerParserr   iter_markersr-   r1   r   ZSOS)r   r   Zmarker_parserr    r7   r   r   r   r   [   s    

z_JfifMarkers.from_streamc                 C   s,   | j D ]}|jtjkr|  S qtddS )z#First APP0 marker in image markers.zno APP0 marker in imageN)r)   r1   r   APP0KeyErrorr
   mr   r   r   r$   g   s    

z_JfifMarkers.app0c                 C   s,   | j D ]}|jtjkr|  S qtddS )z#First APP1 marker in image markers.zno APP1 marker in imageN)r)   r1   r   APP1r=   r>   r   r   r   r   o   s    

z_JfifMarkers.app1c                 C   s,   | j D ]}|jtjv r|  S qtddS )z4First start of frame (SOFn) marker in this sequence.z(no start of frame (SOFn) marker in imageN)r)   r1   r   SOF_MARKER_CODESr=   r>   r   r   r   r   w   s    

z_JfifMarkers.sof)r   r   r   r   r'   r9   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                    s   t t|   || _d S r%   )r&   r:   r'   _stream)r
   stream_readerr*   r   r   r'      s    z_MarkerParser.__init__c                 C   s   t |t}| |S )zFReturn a |_MarkerParser| instance to parse JFIF markers from `stream`.)r   r   )r   r   rD   r   r   r   r      s    
z_MarkerParser.from_streamc                 c   sP   t | j}d}d}|tjkrL||\}}t|| j|}|V  ||j }q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   rC   r   ZEOInext_MarkerFactoryr/   )r
   Zmarker_finderstartr1   segment_offsetr7   r   r   r   r;      s    
z_MarkerParser.iter_markers)	r   r   r   r   r'   r"   r   r;   rB   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 )rE   zFService class that knows how to find the next JFIF marker in a stream.c                    s   t t|   || _d S r%   )r&   rE   r'   rC   )r
   r   r*   r   r   r'      s    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  }}q@q||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.
        )rH          )_offset_of_next_ff_byte_next_non_ff_byte)r
   rH   positionbyte_r1   rI   r   r   r   rF      s    z_MarkerFinder.nextc                 C   s<   | j | |  }|dkr&|  }q| 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.
           rJ   rC   seek
_read_bytetell)r
   rH   rO   Zoffset_of_non_ff_byter   r   r   rM      s    
z_MarkerFinder._next_non_ff_bytec                 C   s8   | j | |  }|dkr&|  }q| 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.
        rP   rJ   rQ   )r
   rH   rO   Zoffset_of_ff_byter   r   r   rL      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.
        rJ   zunexpected end of file)rC   read	Exception)r
   rO   r   r   r   rS      s    z_MarkerFinder._read_byte)r   r   r   r   r'   r"   r   rF   rM   rL   rS   rB   r   r   r*   r   rE      s   
rE   c                 C   sB   | t jkrt}n$| t jkr t}n| t jv r0t}nt}||| |S )znReturn |_Marker| or subclass instance appropriate for marker at `offset` in
    `stream` having `marker_code`.)	r   r<   _App0Markerr@   _App1MarkerrA   
_SofMarker_Markerr   )r1   r   r.   Z
marker_clsr   r   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 )rZ   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&   rZ   r'   _marker_code_offset_segment_length)r
   r1   r.   r/   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   r1   r.   r/   r   r   r   r      s    

z_Marker.from_streamc                 C   s   | j S )um   The single-byte code that identifies the type of this marker, e.g. ``'à'``
        for start of image (SOI).)r[   r	   r   r   r   r1     s    z_Marker.marker_codec                 C   s   t j| j S r%   )r   Zmarker_namesr[   r	   r   r   r   r2     s    z_Marker.namec                 C   s   | j S r%   )r\   r	   r   r   r   r.     s    z_Marker.offsetc                 C   s   | j S )z-The length in bytes of this marker's segment.)r]   r	   r   r   r   r/     s    z_Marker.segment_length)r   r   r   r   r'   r"   r   r   r1   r2   r.   r/   rB   r   r   r*   r   rZ      s   
	


rZ   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 )rW   z&Represents a JFIF APP0 marker segment.c                    s*   t t| ||| || _|| _|| _d S r%   )r&   rW   r'   _density_units
_x_density
_y_density)r
   r1   r.   lengthdensity_units	x_density	y_densityr*   r   r   r'     s    z_App0Marker.__init__c                 C   s   |  | jS z[Horizontal dots per inch specified in this marker, defaults to 72 if not
        specified.)_dpir`   r	   r   r   r   r   %  s    z_App0Marker.horz_dpic                 C   s   |  | jS zYVertical dots per inch specified in this marker, defaults to 72 if not
        specified.)rg   ra   r	   r   r   r   r   +  s    z_App0Marker.vert_dpic                 C   s4   | j dkr|}n | j dkr,tt|d }nd}|S )z6Return dots per inch corresponding to `density` value.rJ      gRQ@H   )r_   intround)r
   ZdensityZdpir   r   r   rg   1  s    

z_App0Marker._dpic                 C   s@   | |}||d}| |d}| |d}| ||||||S )zUReturn an |_App0Marker| instance for the APP0 marker at `offset` in
        `stream`.	   
      )r^   	read_byte)r   r   r1   r.   r/   rc   rd   re   r   r   r   r   ;  s
    
z_App0Marker.from_stream)r   r   r   r   r'   r   r   r   rg   r"   r   rB   r   r   r*   r   rW     s   


rW   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 )rX   z-Represents a JFIF APP1 (Exif) marker segment.c                    s$   t t| ||| || _|| _d S r%   )r&   rX   r'   	_horz_dpi	_vert_dpi)r
   r1   r.   rb   r   r   r*   r   r   r'   S  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`.rj   )r^   _is_non_Exif_APP1_segment_tiff_from_exif_segmentr   r   )r   r   r1   r.   r/   Ztiffr   r   r   r   X  s
    
z_App1Marker.from_streamc                 C   s   | j S rf   )rq   r	   r   r   r   r   j  s    z_App1Marker.horz_dpic                 C   s   | j S rh   )rr   r	   r   r   r   r   p  s    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.ri      s   Exif  )rR   rU   )r   r   r.   Zexif_signaturer   r   r   rs   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`.   )rR   rU   ioBytesIOr   r   )r   r   r.   r/   Zsegment_bytesZ	substreamr   r   r   rt     s    
z#_App1Marker._tiff_from_exif_segment)r   r   r   r   r'   r"   r   r   r   r   rs   rt   rB   r   r   r*   r   rX   P  s   



rX   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 )
rY   z7Represents a JFIF start of frame (SOFx) marker segment.c                    s$   t t| ||| || _|| _d S r%   )r&   rY   r'   	_px_width
_px_height)r
   r1   r.   r/   r   r   r*   r   r   r'     s    z_SofMarker.__init__c                 C   s2   | |}| |d}| |d}| |||||S )zJReturn an |_SofMarker| instance for the SOFn marker at `offset` in stream.      )r^   )r   r   r1   r.   r/   r   r   r   r   r   r     s    

z_SofMarker.from_streamc                 C   s   | j S )zImage height in pixels.)rz   r	   r   r   r   r     s    z_SofMarker.px_heightc                 C   s   | j S )zImage width in pixels.)ry   r	   r   r   r   r     s    z_SofMarker.px_width)r   r   r   r   r'   r"   r   r   r   r   rB   r   r   r*   r   rY     s   

rY   )r   rw   Zdocx.image.constantsr   r   Zdocx.image.helpersr   r   Zdocx.image.imager   Zdocx.image.tiffr   r   r   r#   r   r:   rE   rG   rZ   rW   rX   rY   r   r   r   r   <module>   s    @I*4: