
    hi<                     `   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e	          Z G d	 d
e          Z G d de          Z G d d          Z G d d          Z G d d          Zd Z G d d          Z G d de          Z G d de          Z G 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                   >    e Zd ZdZed             Zed             ZdS )Jpegz(Base class for JFIF and EXIF subclasses.c                     t           j        S )zWMIME content type for this image, unconditionally `image/jpeg` for JPEG
        images.)r   JPEGselfs    g/var/www/development/aibuddy-work/election-extract/venv/lib/python3.11/site-packages/docx/image/jpeg.pycontent_typezJpeg.content_type   s     ~    c                     dS )z8Default filename extension, always 'jpg' for JPG images.jpg r   s    r   default_extzJpeg.default_ext   s	     ur   N)__name__
__module____qualname____doc__propertyr   r   r   r   r   r
   r
      sN        22  X
   X  r   r
   c                   (    e Zd ZdZed             ZdS )Exifz*Image header parser for Exif image format.c                     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%   s          r   r   zExif.from_stream    sW     **622 ;'K)	<(<(s8Y(;;;r   Nr   r   r   r   classmethodr   r   r   r   r   r      s3        44< < [< < <r   r   c                   (    e Zd ZdZed             ZdS )Jfifz*Image header parser for JFIF image format.c                     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&   s          r   r   zJfif.from_stream2   sU     **622;'K)	<(<(s8Y(;;;r   Nr*   r   r   r   r-   r-   /   s3        44
< 
< [
< 
< 
<r   r-   c                        e Zd ZdZ fdZd Zed             Zed             Z	ed             Z
ed             Z xZS )r   zfSequence of markers in a JPEG file, perhaps truncated at first SOS marker for
    performance reasons.c                 ~    t          t          |                                            t          |          | _        d S N)superr   __init__list_markers)r   r)   	__class__s     r   r4   z_JfifMarkers.__init__D   s0    lD!!**,,,Wr   c           	          d}d}g }| j         D ]?}|                    ||j        |j        t	          |j                  |j        fz             @|g|z   }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
)r6   appendoffsetsegment_lengthordmarker_codenamejoin)r   headertmplrowsmarkerliness         r   __str__z_JfifMarkers.__str__H   s     I#m 		 		FKKM)*++K	    4yyr   c                     t                               |          }g }|                                D ].}|                    |           |j        t
          j        k    r n/ | |          S )zrReturn a |_JfifMarkers| instance containing a |_JfifMarker| subclass instance
        for each marker in `stream`.)_MarkerParserr   iter_markersr:   r>   r   SOS)r'   r(   marker_parserr)   rD   s        r   r   z_JfifMarkers.from_stream[   ss     &11&99#0022 	 	FNN6"""!%5%999 :s7||r   c                 f    | j         D ]}|j        t          j        k    r|c S t	          d          )z#First APP0 marker in image markers.zno APP0 marker in image)r6   r>   r   APP0KeyErrorr   ms     r   r/   z_JfifMarkers.app0g   C      	 	A} 0 555 60111r   c                 f    | j         D ]}|j        t          j        k    r|c S t	          d          )z#First APP1 marker in image markers.zno APP1 marker in image)r6   r>   r   APP1rN   rO   s     r   r#   z_JfifMarkers.app1o   rQ   r   c                 b    | j         D ]}|j        t          j        v r|c S t	          d          )z4First start of frame (SOFn) marker in this sequence.z(no start of frame (SOFn) marker in image)r6   r>   r   SOF_MARKER_CODESrN   rO   s     r   r    z_JfifMarkers.sofw   sD      	 	A} 0 AAA BABBBr   )r   r   r   r   r4   rF   r+   r   r   r/   r#   r    __classcell__r7   s   @r   r   r   @   s         & & & & &     & 	 	 [	 2 2 X2 2 2 X2 C C XC C C C Cr   r   c                   >     e Zd ZdZ fdZed             Zd Z xZS )rH   zUService class that knows how to parse a JFIF stream and iterate over its
    markers.c                 d    t          t          |                                            || _        d S r2   )r3   rH   r4   _stream)r   stream_readerr7   s     r   r4   z_MarkerParser.__init__   s*    mT""++---$r   c                 B    t          |t                    } | |          S )zFReturn a |_MarkerParser| instance to parse JFIF markers from `stream`.)r   r   )r'   r(   r[   s      r   r   z_MarkerParser.from_stream   s#     %VZ88s=!!!r   c              #     K   t                               | j                  }d}d}|t          j        k    rN|                    |          \  }}t          || j        |          }|V  ||j        z   }|t          j        k    Ld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   rZ   r   EOInext_MarkerFactoryr<   )r   marker_finderstartr>   segment_offsetrD   s         r   rI   z_MarkerParser.iter_markers   s       &11$,??-111*7*<*<U*C*C'K#K~NNFLLL"V%::E	 -1111111r   )	r   r   r   r   r4   r+   r   rI   rV   rW   s   @r   rH   rH      sl         % % % % % " " ["

; 
; 
; 
; 
; 
; 
;r   rH   c                   P     e Zd ZdZ fdZed             Zd Zd Zd Z	d Z
 xZS )r^   zFService class that knows how to find the next JFIF marker in a stream.c                 d    t          t          |                                            || _        d S r2   )r3   r^   r4   rZ   )r   r(   r7   s     r   r4   z_MarkerFinder.__init__   s*    mT""++---r   c                      | |          S )zCReturn a |_MarkerFinder| instance to find JFIF markers in `stream`.r   )r'   r(   s     r   r   z_MarkerFinder.from_stream   s     s6{{r   c                     |}	 |                      |          }|                     |dz             \  }}|dk    r:||dz   }}	 ||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)rc          )_offset_of_next_ff_byte_next_non_ff_byte)r   rc   positionbyte_r>   rd   s         r   r`   z_MarkerFinder.next   sk     
	33(3CCH"448a<4HHOHe*/AKN**r   c                     | j                             |           |                                 }|dk    r|                                 }|dk    | j                                         dz
  }||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.
           ri   rZ   seek
_read_bytetell)r   rc   rn   offset_of_non_ff_bytes       r   rl   z_MarkerFinder._next_non_ff_byte   st     	%   !!wOO%%E w $ 1 1 3 3a 7$e++r   c                     | j                             |           |                                 }|dk    r|                                 }|dk    | j                                         dz
  }|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   ri   rq   )r   rc   rn   offset_of_ff_bytes       r   rk   z%_MarkerFinder._offset_of_next_ff_byte   so     	%   !!wOO%%E w L--//!3  r   c                 \    | j                             d          }|st          d          |S )zeReturn the next byte read from stream.

        Raise Exception if stream is at end of file.
        ri   zunexpected end of file)rZ   read	Exception)r   rn   s     r   rs   z_MarkerFinder._read_byte   s5    
 !!!$$ 	64555r   )r   r   r   r   r4   r+   r   r`   rl   rk   rs   rV   rW   s   @r   r^   r^      s        PP       [+ + +,, , ,! ! !      r   r^   c                     | t           j        k    rt          }n5| 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   rM   _App0MarkerrS   _App1MarkerrU   
_SofMarker_Markerr   )r>   r(   r;   
marker_clss       r   ra   ra      sc     &+++ 

	(-	-	- 

	(9	9	9


!!&+v>>>r   c                        e Zd ZdZ fdZed             Zed             Zed             Z	ed             Z
ed             Z xZS )r   zqBase class for JFIF marker classes.

    Represents a marker and its segment occuring in a JPEG byte stream.
    c                     t          t          |                                            || _        || _        || _        d S r2   )r3   r   r4   _marker_code_offset_segment_length)r   r>   r;   r<   r7   s       r   r4   z_Marker.__init__   s<    gt%%''''-r   c                 t    t          j        |          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(   r>   r;   r<   s        r   r   z_Marker.from_stream   sE     )+66 	7NN#..v66Ns;777r   c                     | j         S )um   The single-byte code that identifies the type of this marker, e.g. ``'à'``
        for start of image (SOI).)r   r   s    r   r>   z_Marker.marker_code  s       r   c                 0    t           j        | j                 S r2   )r   marker_namesr   r   s    r   r?   z_Marker.name  s    ,T->??r   c                     | j         S r2   )r   r   s    r   r;   z_Marker.offset  s
    |r   c                     | j         S )z-The length in bytes of this marker's segment.)r   r   s    r   r<   z_Marker.segment_length  s     ##r   )r   r   r   r   r4   r+   r   r   r>   r?   r;   r<   rV   rW   s   @r   r   r      s         
. . . . . 8 8 [8 ! ! X!
 @ @ X@   X $ $ X$ $ $ $ $r   r   c                   j     e Zd ZdZ fdZed             Zed             Zd Ze	d             Z
 xZS )r|   z&Represents a JFIF APP0 marker segment.c                     t          t          |                               |||           || _        || _        || _        d S r2   )r3   r|   r4   _density_units
_x_density
_y_density)r   r>   r;   lengthdensity_units	x_density	y_densityr7   s          r   r4   z_App0Marker.__init__  s?    k4  ))+vvFFF+##r   c                 6    |                      | j                  S z[Horizontal dots per inch specified in this marker, defaults to 72 if not
        specified.)_dpir   r   s    r   r$   z_App0Marker.horz_dpi%       yy)))r   c                 6    |                      | j                  S zYVertical dots per inch specified in this marker, defaults to 72 if not
        specified.)r   r   r   s    r   r%   z_App0Marker.vert_dpi+  r   r   c                 |    | j         dk    r|}n-| j         dk    r t          t          |dz                      }nd}|S )z6Return dots per inch corresponding to `density` value.ri      gRQ@H   )r   intround)r   densitydpis      r   r   z_App0Marker._dpi1  sJ    !##CC A%%eGdN++,,CCC
r   c                     |                     |          }|                    |d          }|                     |d          }|                     |d          } | ||||||          S )zUReturn an |_App0Marker| instance for the APP0 marker at `offset` in
        `stream`.	   
      )r   	read_byte)r'   r(   r>   r;   r<   r   r   r   s           r   r   z_App0Marker.from_stream;  sq      **622((33%%fb11	%%fb11	s;yR[\\\r   )r   r   r   r   r4   r   r$   r%   r   r+   r   rV   rW   s   @r   r|   r|     s        00$ $ $ $ $ * * X*
 * * X*
   ] ] [] ] ] ] ]r   r|   c                        e Zd ZdZ fdZed             Zed             Zed             Z	ed             Z
ed             Z xZS )r}   z-Represents a JFIF APP1 (Exif) marker segment.c                 x    t          t          |                               |||           || _        || _        d S r2   )r3   r}   r4   	_horz_dpi	_vert_dpi)r   r>   r;   r   r$   r%   r7   s         r   r4   z_App1Marker.__init__S  s7    k4  ))+vvFFF!!r   c                     |                     |          }|                     ||          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   )r   _is_non_Exif_APP1_segment_tiff_from_exif_segmentr$   r%   )r'   r(   r>   r;   r<   tiffs         r   r   z_App1Marker.from_streamX  s{      **622((88 	D3{FNBCCC**66>JJs;t}UUUr   c                     | j         S r   )r   r   s    r   r$   z_App1Marker.horz_dpij       ~r   c                     | j         S r   )r   r   s    r   r%   z_App1Marker.vert_dpip  r   r   c                 h    |                     |dz              |                    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  )rr   ry   )r'   r(   r;   exif_signatures       r   r   z%_App1Marker._is_non_Exif_APP1_segmentv  s4    
 	FQJQ00r   c                     |                     |dz              |                    |dz
            }t          j        |          }t	          j        |          S )zoReturn a |Tiff| instance parsed from the Exif APP1 segment of
        `segment_length` at `offset` in `stream`.   )rr   ry   ioBytesIOr   r   )r'   r(   r;   r<   segment_bytes	substreams         r   r   z#_App1Marker._tiff_from_exif_segment  sP    
 	FQJNQ$677J}--		***r   )r   r   r   r   r4   r+   r   r   r$   r%   r   r   rV   rW   s   @r   r}   r}   P  s        77" " " " "
 V V [V"   X
   X
 1 1 [1 + + [+ + + + +r   r}   c                   d     e Zd ZdZ fdZed             Zed             Zed             Z	 xZ
S )r~   z7Represents a JFIF start of frame (SOFx) marker segment.c                 x    t          t          |                               |||           || _        || _        d S r2   )r3   r~   r4   	_px_width
_px_height)r   r>   r;   r<   r!   r"   r7   s         r   r4   z_SofMarker.__init__  s7    j$((fnMMM!#r   c                     |                     |          }|                     |d          }|                     |d          } | |||||          S )zJReturn an |_SofMarker| instance for the SOFn marker at `offset` in stream.      )r   )r'   r(   r>   r;   r<   r"   r!   s          r   r   z_SofMarker.from_stream  sY      **622%%fa00	$$VQ//s;)LLLr   c                     | j         S )zImage height in pixels.)r   r   s    r   r"   z_SofMarker.px_height  s     r   c                     | j         S )zImage width in pixels.)r   r   s    r   r!   z_SofMarker.px_width  s     ~r   )r   r   r   r   r4   r+   r   r   r"   r!   rV   rW   s   @r   r~   r~     s        AA$ $ $ $ $
 M M [M   X   X    r   r~   )r   r   docx.image.constantsr   r   docx.image.helpersr   r   docx.image.imager   docx.image.tiffr   r
   r   r-   r   rH   r^   ra   r   r|   r}   r~   r   r   r   <module>r      s@   
 
			 < < < < < < < < 7 7 7 7 7 7 7 7 , , , , , ,                ?   < < < < <4 < < <$< < < < <4 < < <"=C =C =C =C =C =C =C =C@; ; ; ; ; ; ; ;6F F F F F F F FR? ? ?'$ '$ '$ '$ '$ '$ '$ '$T1] 1] 1] 1] 1]' 1] 1] 1]h7+ 7+ 7+ 7+ 7+' 7+ 7+ 7+t         r   