B
    W_>                 @   s  d Z ddlmZmZmZ ddlm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eZG dd deZG dd deZdd ZG dd deZG dd deZG dd deZG dd deZd S )!z[
Objects related to parsing headers of JPEG image streams, both JFIF and Exif
sub-formats.
    )absolute_importdivisionprint_function   )BytesIO   )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 )Jpegz2
    Base class for JFIF and EXIF subclasses.
    c             C   s   t jS )zi
        MIME content type for this image, unconditionally `image/jpeg` for
        JPEG images.
        )r	   ZJPEG)self r   A/var/www/html/venv/lib/python3.7/site-packages/docx/image/jpeg.pycontent_type   s    zJpeg.content_typec             C   s   dS )zJ
        Default 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 )Exifz3
    Image header parser for Exif image format
    c             C   s8   t |}|jj}|jj}|jj}|jj}| ||||S )zm
        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 )Jfifz3
    Image header parser for JFIF image format
    c             C   s8   t |}|jj}|jj}|jj}|jj}| ||||S )zj
        Return a |Jfif| instance having header properties parsed from image
        in *stream*.
        )r   r   r   r   r   app0r    r!   )r"   r#   r$   r   r   r    r!   r   r   r   r   >   s    
zJfif.from_streamN)r   r   r   r   r%   r   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   zp
    Sequence 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)   S   s    z_JfifMarkers.__init__c             C   sR   d}d}g }x0| j D ]&}|||j|jt|j|jf  qW |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tmplZrowsmarkerlinesr   r   r   __str__W   s    
z_JfifMarkers.__str__c             C   s@   t |}g }x(| D ]}|| |jtjkrP qW | |S )z
        Return a |_JfifMarkers| instance containing a |_JfifMarker| subclass
        instance for each marker in *stream*.
        )_MarkerParserr   iter_markersr.   r2   r   ZSOS)r"   r#   Zmarker_parserr$   r7   r   r   r   r   g   s    

z_JfifMarkers.from_streamc             C   s,   x| j D ]}|jtjkr|S qW tddS )z5
        First APP0 marker in image markers.
        zno APP0 marker in imageN)r+   r2   r   APP0KeyError)r   mr   r   r   r'   u   s    z_JfifMarkers.app0c             C   s,   x| j D ]}|jtjkr|S qW tddS )z5
        First APP1 marker in image markers.
        zno APP1 marker in imageN)r+   r2   r   APP1r=   )r   r>   r   r   r   r      s    z_JfifMarkers.app1c             C   s,   x| j D ]}|jtjkr|S qW tddS )zF
        First start of frame (SOFn) marker in this sequence.
        z(no start of frame (SOFn) marker in imageN)r+   r2   r   SOF_MARKER_CODESr=   )r   r>   r   r   r   r      s    z_JfifMarkers.sof)r   r   r   r   r)   r9   r%   r   r   r'   r   r   __classcell__r   r   )r,   r   r   N   s   

r   c                   s4   e Zd ZdZ fddZedd Zdd Z  ZS )r:   z_
    Service class that knows how to parse a JFIF stream and iterate over its
    markers.
    c                s   t t|   || _d S )N)r(   r:   r)   _stream)r   stream_reader)r,   r   r   r)      s    z_MarkerParser.__init__c             C   s   t |t}| |S )z`
        Return a |_MarkerParser| instance to parse JFIF markers from
        *stream*.
        )r   r
   )r"   r#   rC   r   r   r   r      s    
z_MarkerParser.from_streamc             c   sT   t | j}d}d}x:|tjkrN||\}}t|| j|}|V  ||j }qW 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   rB   r   ZEOInext_MarkerFactoryr0   )r   Zmarker_finderstartr2   segment_offsetr7   r   r   r   r;      s    z_MarkerParser.iter_markers)	r   r   r   r   r)   r%   r   r;   rA   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 )rD   zP
    Service class that knows how to find the next JFIF marker in a stream.
    c                s   t t|   || _d S )N)r(   rD   r)   rB   )r   r#   )r,   r   r   r)      s    z_MarkerFinder.__init__c             C   s   | |S )zU
        Return a |_MarkerFinder| instance to find JFIF markers in *stream*.
        r   )r"   r#   r   r   r   r      s    z_MarkerFinder.from_streamc             C   sL   |}x>| j |d}| j|d d\}}|dkr0q||d  }}P qW ||fS )a`  
        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.
        )rG   r       )_offset_of_next_ff_byte_next_non_ff_byte)r   rG   positionbyte_r2   rH   r   r   r   rE      s    z_MarkerFinder.nextc             C   s@   | j | |  }x|dkr(|  }qW | 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.
           r   )rB   seek
_read_bytetell)r   rG   rM   Zoffset_of_non_ff_byter   r   r   rK      s    
z_MarkerFinder._next_non_ff_bytec             C   s<   | j | |  }x|dkr(|  }qW | 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.
        rN   r   )rB   rO   rP   rQ   )r   rG   rM   Zoffset_of_ff_byter   r   r   rJ      s    
z%_MarkerFinder._offset_of_next_ff_bytec             C   s   | j d}|std|S )zm
        Return the next byte read from stream. Raise Exception if stream is
        at end of file.
        r   zunexpected end of file)rB   read	Exception)r   rM   r   r   r   rP      s    z_MarkerFinder._read_byte)r   r   r   r   r)   r%   r   rE   rK   rJ   rP   rA   r   r   )r,   r   rD      s   rD   c             C   sB   | t jkrt}n$| t jkr t}n| t jkr0t}nt}||| |S )zx
    Return |_Marker| or subclass instance appropriate for marker at *offset*
    in *stream* having *marker_code*.
    )	r   r<   _App0Markerr?   _App1Markerr@   
_SofMarker_Markerr   )r2   r#   r/   Z
marker_clsr   r   r   rF     s    


rF   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 )rW   zu
    Base class for JFIF marker classes. Represents a marker and its segment
    occuring in a JPEG byte stream.
    c                s$   t t|   || _|| _|| _d S )N)r(   rW   r)   _marker_code_offset_segment_length)r   r2   r/   r0   )r,   r   r   r)     s    z_Marker.__init__c             C   s&   t |rd}n
||}| |||S )zz
        Return a generic |_Marker| instance for the marker at *offset* in
        *stream* having *marker_code*.
        r   )r   Zis_standalone
read_short)r"   r#   r2   r/   r0   r   r   r   r     s    

z_Marker.from_streamc             C   s   | j S )u   
        The single-byte code that identifies the type of this marker, e.g.
        ``'à'`` for start of image (SOI).
        )rX   )r   r   r   r   r2   )  s    z_Marker.marker_codec             C   s   t j| j S )N)r   Zmarker_namesrX   )r   r   r   r   r3   1  s    z_Marker.namec             C   s   | j S )N)rY   )r   r   r   r   r/   5  s    z_Marker.offsetc             C   s   | j S )z>
        The length in bytes of this marker's segment
        )rZ   )r   r   r   r   r0   9  s    z_Marker.segment_length)r   r   r   r   r)   r%   r   r   r2   r3   r/   r0   rA   r   r   )r,   r   rW     s   rW   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 )rT   z0
    Represents a JFIF APP0 marker segment.
    c                s*   t t| ||| || _|| _|| _d S )N)r(   rT   r)   _density_units
_x_density
_y_density)r   r2   r/   lengthdensity_units	x_density	y_density)r,   r   r   r)   E  s    z_App0Marker.__init__c             C   s   |  | jS )zm
        Horizontal dots per inch specified in this marker, defaults to 72 if
        not specified.
        )_dpir]   )r   r   r   r   r    M  s    z_App0Marker.horz_dpic             C   s   |  | jS )zk
        Vertical dots per inch specified in this marker, defaults to 72 if
        not specified.
        )rc   r^   )r   r   r   r   r!   U  s    z_App0Marker.vert_dpic             C   s4   | j dkr|}n | j dkr,tt|d }nd}|S )zH
        Return dots per inch corresponding to *density* value.
        r   r   gRQ@H   )r\   intround)r   ZdensityZdpir   r   r   rc   ]  s    

z_App0Marker._dpic             C   s@   | |}||d}| |d}| |d}| ||||||S )zg
        Return an |_App0Marker| instance for the APP0 marker at *offset* in
        *stream*.
        	   
      )r[   Z	read_byte)r"   r#   r2   r/   r0   r`   ra   rb   r   r   r   r   i  s    

z_App0Marker.from_stream)r   r   r   r   r)   r   r    r!   rc   r%   r   rA   r   r   )r,   r   rT   A  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 )rU   z7
    Represents a JFIF APP1 (Exif) marker segment.
    c                s$   t t| ||| || _|| _d S )N)r(   rU   r)   	_horz_dpi	_vert_dpi)r   r2   r/   r_   r    r!   )r,   r   r   r)     s    z_App1Marker.__init__c             C   sH   | |}| ||r&| |||ddS | |||}| ||||j|jS )z
        Extract the horizontal and vertical dots-per-inch value from the APP1
        header at *offset* in *stream*.
        rd   )r[   _is_non_Exif_APP1_segment_tiff_from_exif_segmentr    r!   )r"   r#   r2   r/   r0   tiffr   r   r   r     s    
z_App1Marker.from_streamc             C   s   | j S )zm
        Horizontal dots per inch specified in this marker, defaults to 72 if
        not specified.
        )rj   )r   r   r   r   r      s    z_App1Marker.horz_dpic             C   s   | j S )zk
        Vertical dots per inch specified in this marker, defaults to 72 if
        not specified.
        )rk   )r   r   r   r   r!     s    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  )rO   rR   )r"   r#   r/   Zexif_signaturer   r   r   rl     s    
z%_App1Marker._is_non_Exif_APP1_segmentc             C   s.   | |d  ||d }t|}t|S )z
        Return a |Tiff| instance parsed from the Exif APP1 segment of
        *segment_length* at *offset* in *stream*.
           )rO   rR   r   r   r   )r"   r#   r/   r0   Zsegment_bytesZ	substreamr   r   r   rm     s    z#_App1Marker._tiff_from_exif_segment)r   r   r   r   r)   r%   r   r   r    r!   rl   rm   rA   r   r   )r,   r   rU     s   rU   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 )
rV   zA
    Represents a JFIF start of frame (SOFx) marker segment.
    c                s$   t t| ||| || _|| _d S )N)r(   rV   r)   	_px_width
_px_height)r   r2   r/   r0   r   r   )r,   r   r   r)     s    z_SofMarker.__init__c             C   s2   | |}| |d}| |d}| |||||S )zd
        Return an |_SofMarker| instance for the SOFn marker at *offset* in
        stream.
              )r[   )r"   r#   r2   r/   r0   r   r   r   r   r   r     s    
z_SofMarker.from_streamc             C   s   | j S )z(
        Image height in pixels
        )rr   )r   r   r   r   r     s    z_SofMarker.px_heightc             C   s   | j S )z'
        Image width in pixels
        )rq   )r   r   r   r   r     s    z_SofMarker.px_width)r   r   r   r   r)   r%   r   r   r   r   rA   r   r   )r,   r   rV     s
   rV   N)r   
__future__r   r   r   compatr   	constantsr   r	   Zhelpersr
   r   imager   rn   r   r   r   r&   objectr   r:   rD   rF   rW   rT   rU   rV   r   r   r   r   <module>   s"   F#K/BG