3
	jQcQ              
   @   s   d dl mZ d dlmZ ddl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d'dd(di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 error   zdecoding error   zunknown error   zbad configuration	   zout of memory errorc             C   sL   yt jj| }W n tk
r.   tj| }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   //usr/lib/python3/dist-packages/PIL/ImageFile.pyraise_ioerror4   s    r   c             C   s   | d S )Nr   r   )tr   r   r   	_tilesortB   s    r   c               @   sJ   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S )	ImageFilez*Base class for image file format handlers.Nc             C   s   t j j|  d| _d | _d| _f | _t| _t|rLt	|d| _
|| _d| _n|| _
|| _d | _y| j  W nF tttttjfk
r } z| jr| j
j  t|W Y d d }~X nX | j s| jd dkrtdd S )Nr   r   rbTznot identified by this driver)r   __init__
_min_frame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   N   s2    
zImageFile.__init__c             C   s   dS )zSet draft modeNr   )r,   r*   r+   r   r   r   draftt   s    zImageFile.draftc             C   s   | j r| jj  d| _dS )zCheck file integrityN)r!   r   r(   )r,   r   r   r   verifyy   s    
zImageFile.verifyc          3   C   s  t j 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ot|	dko|	d | jko|	d t jkrytt jd	rFt jj| j| _| jj| | jj| j| j|	d |	d
 | _nVddl}
t| jd}tjj| j}|
j|j ||
jd| _t jj| j| j||||	| _d}| jrd| j_W n" t
tt fk
r   d| _Y nX | j!  d}| js8| jj"t#d y
| j$}W n t
k
r   d}Y nX x| jD ]
\}}}}	t j%| j||	| j&}z|| |j'| j| |j(r|j)| j |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| || }|j*|\}}|dk rP ||d }qW W d|j0  X q(W g | _|| _1| j2  | j3rf| j4rf| jj5  d| _| j rt/ r|dk rt6| t j j| S )z"Load image data based on tile listNzcannot load this imager   Zpypy_version_infor   Frawr   mapr   r)access)key    zimage file is truncatedz0image file is truncated (%d bytes not processed))7r   loadr   r   r1   r    lenhasattrsys	load_readr
   r   read	load_seekseekr*   Z	_MAPMODESr	   Z	readimager+   immmapr   ospathgetsize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<   r>   Zdecoder_nameextentsoffsetargsr@   r   r+   Zerr_codeprefixdecoderZstatusbsnr   r   r   r7      s    
"





zImageFile.loadc             C   sR   | j  s$| j j| jks$| j j| jkr8tjj| j| j| _ | jdkrNtjj|  d S )NP)r?   r*   r+   r   r	   newr7   )r,   r   r   r   rG      s
    
zImageFile.load_preparec             C   s   d S )Nr   )r,   r   r   r   rP     s    zImageFile.load_endc             C   sD   || j k s0t| do| jd k r8|| j| j  kr8td| j |kS )N	_n_framesz attempt to seek outside sequence)r   r9   r[   Zn_framesr&   tell)r,   framer   r   r   _seek_check  s
    
zImageFile._seek_check)NN)__name__
__module____qualname____doc__r   r.   r/   r7   rG   rP   r^   r   r   r   r   r   K   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"   &  s    zStubImageFile._openc             C   sH   | j  }|d krtd| j |j| }|d k	s4t|j| _|j| _d S )Nz#cannot find loader for this %s file)_loadr   formatr7   AssertionError	__class____dict__)r,   loaderimager   r   r   r7   +  s    
zStubImageFile.loadc             C   s   t ddS )z (Hook) Find actual image loader.z+StubImageFile subclass must implement _loadN)rd   )r,   r   r   r   re   5  s    zStubImageFile._loadN)r_   r`   ra   rb   r"   r7   re   r   r   r   r   rc     s   
rc   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   resetH  s    zParser.resetc             C   s  | j r
dS | jdkr|| _n| j| | _| jr| jdkr|tt| j| j}| j|d | _| j| | _| jdksx| j r|dS | jj| j\}}|dk rd| _d| _ |dk rd| _t| ndS | j|d | _n| jrny&t	j
| j}tj|}W dQ R X W n tk
r   Y nX t|dp*t|d}|sBt|jdkrJd| _nv|j  |jd \}}}	}
g |_tj|j||
|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   r=   r;   )finishedrm   rU   rR   minr8   rM   rk   r   ioBytesIOr   r   r   r9   r   rG   rI   r*   r   rJ   r?   )r,   rm   skiprX   er   r?   flagdoar   r   r   feedP  sT    	


zParser.feedc             C   s   | S )Nr   )r,   r   r   r   	__enter__  s    zParser.__enter__c             G   s   | j   d S )N)r(   )r,   rS   r   r   r   __exit__  s    zParser.__exit__c             C   sz   | j r*| jd d | _| _ | js*td| js8td| jrttj| j$}ztj	|| _W d| j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.
        r5   Nzimage was incompletezcannot parse this image)rU   ry   rm   ro   r   rk   rq   rr   r   r   r7   )r,   r   r   r   r   r(     s    

zParser.close)r_   r`   ra   rb   Zincrementalrk   rm   rU   rR   ro   rn   ry   rz   r{   r(   r   r   r   r   rl   <  s   Rrl   c             C   s  | j   t| dsf | _|jtd tt|| jd d }|tj	krP|j
  dS y|j }|j
  W n ttjfk
r.   x|D ]\}}}}tj| j||| j}|dkr|j|d |j| j| |jr|j| |j \}	}
n&x$|j|\}	}
}|j| |
rP qW |
dk rtd|
 |j  qW Y nX x|D ]\}}}}tj| j||| j}|dkrl|j|d |j| j| |jr|j| |j \}	}
n|j||}
|
dk rtd|
 |j  q6W t|dr|j
  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
    encoderconfig)r4   r      Nz(encoder error %d when writing image fileflush)r7   r9   r|   rH   r   maxr   r+   r:   stdoutr~   rD   r
   rq   UnsupportedOperationr   Z_getencoderr*   r>   rJ   r?   Z	pushes_fdrL   Zencode_to_pyfdencodewriter   rO   Zencode_to_file)r?   r   r   bufsizeZfhrt   rV   rw   rx   lrW   rv   r   r   r   _save  sT    	







r   c             C   s   |dkrdS |t kr6| j|}t||k r2td|S g }x8|dkrr| jt|t }|sZP |j| |t|8 }q<W tdd |D |k rtddj|S )a  
    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 <i>size</i> bytes of data.

    Raises an OSError if the file is truncated and the read can not be completed

    r   r5   zTruncated File Readc             s   s   | ]}t |V  qd S )N)r8   ).0rv   r   r   r   	<genexpr>   s    z_safe_read.<locals>.<genexpr>)	SAFEBLOCKr<   r8   OSErrorrp   appendsum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   rQ   ,  s    zPyCodecState.extentsN)r_   r`   ra   r   rQ   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 | _|| _| j| d S )N)r?   r   statefdr*   init)r,   r*   rS   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)rS   )r,   rS   r   r   r   r   B  s    zPyDecoder.initc             C   s   | j S )N)	_pulls_fd)r,   r   r   r   rK   K  s    zPyDecoder.pulls_fdc             C   s
   t  dS )az  
        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)rd   )r,   bufferr   r   r   rM   O  s    	zPyDecoder.decodec             C   s   dS )zV
        Override to perform decoder specific cleanup

        :returns: None
        Nr   )r,   r   r   r   rO   Z  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   rL   b  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   zSize cannot be negativer   z Tile cannot extend outside imageN)r   r   r   r   )r?   r+   r   r   r   r   r   
ValueError)r,   r?   rQ   Zx0Zy0Zx1Zy1r   r   r   rJ   k  s    zPyDecoder.setimagec             C   sd   |s
| j }tj| j d|}|j| j| j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
        r0   r   znot enough image datar   zcannot decode image dataN)	r*   r   rI   rJ   r?   r   rQ   rM   r   )r,   rm   Zrawmoderv   rW   r   r   r   
set_as_raw  s    

zPyDecoder.set_as_raw)N)N)r_   r`   ra   rb   r   r   r   propertyrK   rM   rO   rL   rJ   r   r   r   r   r   r   1  s   		
!r   i   r6   ii)r   ) r   Z_utilr   rq   rA   r:   r'   r   r   rN   r   r   r   r   rc   objectrl   r   r   r   r   r   r   r   r   <module>   s0   	 T 
> 