o
    ýÞh<  ã                   @   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   úO/var/www/html/premium_crap/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 )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   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}   1  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-   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`.r�   )rp   Ú_is_non_Exif_APP1_segmentÚ_tiff_from_exif_segmentr    r!   )r#   r$   r7   r4   r5   Útiffr   r   r   r   X  s
   
z_App1Marker.from_streamc                 C   rq   r|   )r‹   r
   r   r   r   r    j  r   z_App1Marker.horz_dpic                 C   rq   r   )rŒ   r
   r   r   r   r!   p  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`   re   )r#   r$   r4   Ú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`.é   )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   P  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*4: