B
    0\WQ                 @   s   d dl mZ d dlmZ ddlZddlZddlZdZdZdZ	dd	d
dddZ
dd Zdd ZG dd dejZG dd deZG dd deZd ddZdd ZG dd deZG dd deZdS )!   )Image)isPath    Ni   i   Fzimage buffer overrun errorzdecoding errorzunknown errorzbad configurationzout of memory error)iic             C   sL   yt j| }W n tk
r.   t| }Y nX |s<d|  }t|d d S )Nzdecoder error %dz when reading image file)r   coreZgetcodecstatusAttributeErrorERRORSgetIOError)errormessage r   ,lib/python3.7/site-packages/PIL/ImageFile.pyraise_ioerror3   s    r   c             C   s   | d S )N   r   )tr   r   r   	_tilesortA   s    r   c               @   sR   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd ZdS )	ImageFilez*Base class for image file format handlers.Nc             C   s   t j |  d| _d | _d | _d| _d| _t| _t	|rRt
|d| _|| _d| _n|| _|| _d | _y|   W nF tttttjfk
r } z| jr| j  t|W d d }~X Y nX | jr| jd dkrtdd S )Nr   r   r   rbTznot identified by this driver)r   __init__
_min_framecustom_mimetypetilereadonlydecoderconfigMAXBLOCKdecodermaxblockr   openfpfilename_exclusive_fp_open
IndexError	TypeErrorKeyErrorEOFErrorstructr   closeSyntaxErrormodesize)selfr    r!   vr   r   r   r   M   s4    
zImageFile.__init__c             C   s   dS )zSet draft modeNr   )r-   r+   r,   r   r   r   draftu   s    zImageFile.draftc             C   s&   | j d krd S | jp$tj| j  S )N)formatr   r   ZMIMEr   upper)r-   r   r   r   get_format_mimetypez   s    
zImageFile.get_format_mimetypec             C   s   | j r| j  d| _dS )zCheck file integrityN)r"   r    r)   )r-   r   r   r   verify   s    
zImageFile.verifyc          
   C   s  t j | }| jdkrtd| js(|S d| _| jo@t| jdk}|oPttd }d}y| j	}d}W n t
k
r   | jj}Y nX y| j}d}W n t
k
r   | jj}Y nX |r| jd \}}}}	|dkrt|	dkr|	d | jkr|	d t jkrytt jd	rLt j| j| _| j| | j| j| j|	d |	d
 | _nTddl}
t| jd}|
j| d|
jd| _W dQ R X t j| j| j||||	| _d}| jrd| j_W n" t
ttfk
r   d| _Y nX |   d}| js<| jjt d y
| j!}W n t
k
r    d}Y nX x| jD ]
\}}}}	t "| j||	| j#}z|| |$| j| |j%r|&| j |'d\}}n|}xy|| j(}W n. t)t*j+fk
r   t,rP ntdY nX |st,rP ng | _tdt| || }|'|\}}|dk rP ||d }qW W d|-  X q,W g | _|| _.| /  | j0rj| j1rj| j2  d| _| jst,s|dk rt3| t j | S )z"Load image data based on tile listNzcannot load this imager   Zpypy_version_infor   Fraw   mapr   r)accessr   )key    zimage file is truncatedz0image file is truncated (%d bytes not processed))4r   loadr   r   r6   r!   lenhasattrsys	load_readr	   r    read	load_seekseekr+   Z	_MAPMODESr   Z	readimager,   immmapr   filenoZACCESS_READZ
map_bufferZpaletteZdirtyEnvironmentErrorImportErrorload_preparesortr   Ztile_prefix_getdecoderr   setimagepulls_fdsetfddecoder   r$   r(   r   LOAD_TRUNCATED_IMAGEScleanupr   load_endr"   Z!_close_exclusive_fp_after_loadingr)   r   )r-   ZpixelZuse_mmapr   r@   rB   Zdecoder_nameextentsoffsetargsrD   r    Zerr_codeprefixdecoderZstatusbsnr   r   r   r;      s    







zImageFile.loadc             C   sP   | j r"| j j| jks"| j j| jkr6tj| j| j| _ | jdkrLtj|  d S )NP)rC   r+   r,   r   r   newr;   )r-   r   r   r   rH     s
    
zImageFile.load_preparec             C   s   d S )Nr   )r-   r   r   r   rQ     s    zImageFile.load_endc             C   sB   || j k s.t| dr| jd ks6|| j| j  kr6td|  |kS )N	_n_framesz attempt to seek outside sequence)r   r=   r\   Zn_framesr'   tell)r-   framer   r   r   _seek_check  s
    
zImageFile._seek_check)NN)__name__
__module____qualname____doc__r   r/   r2   r3   r;   rH   rQ   r_   r   r   r   r   r   J   s   
(	 	r   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	StubImageFilez
    Base class for stub image loaders.

    A stub loader is an image loader that can identify files of a
    certain format, but relies on external code to load the file.
    c             C   s   t dd S )Nz+StubImageFile subclass must implement _open)NotImplementedError)r-   r   r   r   r#   0  s    zStubImageFile._openc             C   sH   |   }|d krtd| j || }|d k	s4t|j| _|j| _d S )Nz#cannot find loader for this %s file)_loadr   r0   r;   AssertionError	__class____dict__)r-   loaderimager   r   r   r;   5  s    
zStubImageFile.loadc             C   s   t ddS )z (Hook) Find actual image loader.z+StubImageFile subclass must implement _loadN)re   )r-   r   r   r   rf   ?  s    zStubImageFile._loadN)r`   ra   rb   rc   r#   r;   rf   r   r   r   r   rd   (  s   
rd   c               @   sP   e Zd ZdZdZdZdZdZdZdZ	dd Z
dd Zdd	 Zd
d Zdd ZdS )Parserzj
    Incremental image parser.  This class implements the standard
    feed/close consumer interface.
    Nr   c             C   s   | j dkstddS )z
        (Consumer) Reset the parser.  Note that you can only call this
        method immediately after you've created a parser; parser
        instances cannot be reused.
        Nzcannot reuse parsers)datarg   )r-   r   r   r   resetR  s    zParser.resetc          	   C   s  | j r
dS | jdkr|| _n| j| | _| jr| jdkrztt| j| j}| j|d | _| j| | _| jdksv| jszdS | j| j\}}|dk rd| _d| _ |dk rd| _t| ndS | j|d | _n| jrny&t	
| j}t|}W dQ R X W n tk
r   Y nX t|dp(t|d}|s@t|jdkrHd| _nv|  |jd \}}}	}
g |_t|j||
|j| _| j|j| |	| _| jt| jkr| j| jd | _d| _|| _dS )z
        (Consumer) Feed data to the parser.

        :param data: A string buffer.
        :exception IOError: If the parser failed to parse the image file.
        Nr   r   rA   r?   )finishedrm   rV   rS   minr<   rN   rk   r   ioBytesIOr   r   r   r=   r   rH   rJ   r+   r   rK   rC   )r-   rm   skiprY   er    rC   flagdoar   r   r   feedZ  sT    	


zParser.feedc             C   s   | S )Nr   )r-   r   r   r   	__enter__  s    zParser.__enter__c             G   s   |    d S )N)r)   )r-   rT   r   r   r   __exit__  s    zParser.__exit__c          	   C   sz   | j r*| d d | _| _ | js*td| js8td| jrtt| j$}zt	|| _W d| j
  X W dQ R X | jS )a  
        (Consumer) Close the stream.

        :returns: An image object.
        :exception IOError: If the parser failed to parse the image file either
                            because it cannot be identified or cannot be
                            decoded.
        r:   Nzimage was incompletezcannot parse this image)rV   ry   rm   ro   r   rk   rq   rr   r   r   r;   )r-   r    r   r   r   r)     s    

zParser.close)r`   ra   rb   rc   Zincrementalrk   rm   rV   rS   ro   rn   ry   rz   r{   r)   r   r   r   r   rl   F  s   Rrl   c          
   C   s  |    t| dsd| _|jtd tt|| jd d }|tj	krP|
  dS y| }|
  W n ttjfk
r.   x|D ]\}}}}t| j||| j}|dkr||d || j| |jr|| | \}	}
n&x$||\}	}
}|| |
rP qW |
dk rtd|
 |  qW Y nX x|D ]\}}}}t| j||| j}|dkrl||d || j| |jr|| | \}	}
n|||}
|
dk rtd|
 |  q6W t|dr|
  dS )	zHelper to save image based on tile list

    :param im: Image object.
    :param fp: File object.
    :param tile: Tile list.
    :param bufsize: Optional buffer size
    encoderconfigr   )r9   r      Nz(encoder error %d when writing image fileflush)r;   r=   r|   rI   r   maxr   r,   r>   stdoutr~   rE   r	   rq   UnsupportedOperationr   Z_getencoderr+   rB   rK   rC   Z	pushes_fdrM   Zencode_to_pyfdencodewriter   rP   Zencode_to_file)rC   r    r   bufsizeZfhrt   rW   rw   rx   lrX   rv   r   r   r   _save  sT    	







r   c             C   sf   |dkrdS |t kr| |S g }x8|dkrZ| t|t }|sBP || |t|8 }q$W d|S )ao  
    Reads large blocks in a safe way.  Unlike fp.read(n), this function
    doesn't trust the user.  If the requested size is larger than
    SAFEBLOCK, the file is read block by block.

    :param fp: File handle.  Must implement a <b>read</b> method.
    :param size: Number of bytes to read.
    :returns: A string containing up to <i>size</i> bytes of data.
    r   r:   )	SAFEBLOCKr@   rp   appendr<   join)r    r,   rm   blockr   r   r   
_safe_read  s    



r   c               @   s   e Zd Zdd Zdd ZdS )PyCodecStatec             C   s   d| _ d| _d| _d| _d S )Nr   )xsizeysizexoffyoff)r-   r   r   r   r   (  s    zPyCodecState.__init__c             C   s    | j | j| j | j | j| j fS )N)r   r   r   r   )r-   r   r   r   rR   .  s    zPyCodecState.extentsN)r`   ra   rb   r   rR   r   r   r   r   r   '  s   r   c               @   s\   e Zd ZdZdZdd Zdd Zedd Zd	d
 Z	dd Z
dd ZdddZdddZdS )	PyDecoderz
    Python implementation of a format decoder. Override this class and
    add the decoding logic in the `decode` method.

    See :ref:`Writing Your Own File Decoder in Python<file-decoders-py>`
    Fc             G   s(   d | _ t | _d | _|| _| | d S )N)rC   r   statefdr+   init)r-   r+   rT   r   r   r   r   =  s
    zPyDecoder.__init__c             C   s
   || _ dS )z
        Override to perform decoder specific initialization

        :param args: Array of args items from the tile entry
        :returns: None
        N)rT   )r-   rT   r   r   r   r   D  s    zPyDecoder.initc             C   s   | j S )N)	_pulls_fd)r-   r   r   r   rL   M  s    zPyDecoder.pulls_fdc             C   s
   t  dS )a  
        Override to perform the decoding process.

        :param buffer: A bytes object with the data to be decoded.
            If `handles_eof` is set, then `buffer` will be empty and `self.fd`
            will be set.
        :returns: A tuple of (bytes consumed, errcode).
            If finished with decoding return <0 for the bytes consumed.
            Err codes are from `ERRORS`
        N)re   )r-   bufferr   r   r   rN   Q  s    zPyDecoder.decodec             C   s   dS )zV
        Override to perform decoder specific cleanup

        :returns: None
        Nr   )r-   r   r   r   rP   ^  s    zPyDecoder.cleanupc             C   s
   || _ dS )z
        Called from ImageFile to set the python file-like object

        :param fd: A python file-like object
        :returns: None
        N)r   )r-   r   r   r   r   rM   f  s    zPyDecoder.setfdNc             C   s   || _ |r|\}}}}nd\}}}}|dkrJ|dkrJ| j j\| j_| j_n(|| j_|| j_|| | j_|| | j_| jjdks| jjdkrtd| jj| jj | j jd ks| jj| jj | j jd krtddS )z
        Called from ImageFile to set the core output image for the decoder

        :param im: A core image object
        :param extents: a 4 tuple of (x0, y0, x1, y1) defining the rectangle
            for this tile
        :returns: None
        )r   r   r   r   r   zSize cannot be negativer   z Tile cannot extend outside imageN)rC   r,   r   r   r   r   r   
ValueError)r-   rC   rR   Zx0Zy0Zx1Zy1r   r   r   rK   o  s    zPyDecoder.setimagec             C   sd   |s
| j }t| j d|}|| j| j  ||}|d dkrLtd|d dkr`tddS )a  
        Convenience method to set the internal image from a stream of raw data

        :param data: Bytes to be set
        :param rawmode: The rawmode to be used for the decoder.
            If not specified, it will default to the mode of the image
        :returns: None
        r4   r   znot enough image datar   zcannot decode image dataN)	r+   r   rJ   rK   rC   r   rR   rN   r   )r-   rm   Zrawmoderv   rX   r   r   r   
set_as_raw  s    

zPyDecoder.set_as_raw)N)N)r`   ra   rb   rc   r   r   r   propertyrL   rN   rP   rM   rK   r   r   r   r   r   r   3  s   		
!r   )r   ) r   Z_utilr   rq   r>   r(   r   r   rO   r
   r   r   r   rd   objectrl   r   r   r   r   r   r   r   r   <module>   s.   	 _ 
>