B .^P@sddlZddlZddlZddlmZddlmZdZdZdZ dd d d d d Z ddZ ddZ GdddejZ Gddde ZGdddZd ddZddZGdddZGdddZdS)!N)Image)isPathiiFzimage buffer overrun errorzdecoding errorz unknown errorzbad configurationzout of memory error)iicCsLytj|}Wntk r.t|}YnX|ss            zImageFile.loadcCsP|jr"|jj|jks"|jj|jkr6tj|j|j|_|jdkrLtj|dS)NP)rFr+r,rrnewr>)r/rrrrJs" zImageFile.load_preparecCsdS)Nr)r/rrrrSszImageFile.load_endcCsB||jks.t|dr|jdks6||j|jkr6td||kS)N _n_framesz attempt to seek outside sequence)rr@r_Zn_framesr(tell)r/framerrr _seek_check&s  zImageFile._seek_check)NN) __name__ __module__ __qualname____doc__rr4r5r>rJrSrb __classcell__rr)r1rrMs-  rc@s(eZdZdZddZddZddZdS) 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. cCs tddS)Nz+StubImageFile subclass must implement _open)NotImplementedError)r/rrrr$=szStubImageFile._opencCsH|}|dkrtd|j||}|dk s4t|j|_|j|_dS)Nz#cannot find loader for this %s file)_loadr r2r>AssertionErrorr1__dict__)r/loaderimagerrrr>@s  zStubImageFile.loadcCs tddS)z (Hook) Find actual image loader.z+StubImageFile subclass must implement _loadN)ri)r/rrrrjJszStubImageFile._loadN)rcrdrerfr$r>rjrrrrrh5s rhc@sPeZdZdZdZdZdZdZdZdZ ddZ ddZ dd Z d d Z d d ZdS)Parserzj Incremental image parser. This class implements the standard feed/close consumer interface. NrcCs|jdkstddS)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. Nzcannot reuse parsers)datark)r/rrrreset\sz Parser.resetc Cs|jr dS|jdkr||_n |j||_|jr|jdkrztt|j|j}|j|d|_|j||_|jdksv|jszdS|j|j\}}|dkrd|_d|_|dkrd|_t|ndS|j|d|_n|jrny&t |j}t |}WdQRXWnt k rYnXt|dp(t|d}|s@t|jdkrHd|_nv||jd\}}} } g|_t |j|| |j|_|j|j|| |_|jt|jkr|j|jd|_d|_||_dS)z (Consumer) Feed data to the parser. :param data: A string buffer. :exception IOError: If the parser failed to parse the image file. NrrrDrB)finishedrprXrUminr?rPrnrioBytesIOrr r r@rrJrLr+rrMrF) r/rpskipr\er!rFflagdoarrrfeeddsR      z Parser.feedcCs|S)Nr)r/rrr __enter__szParser.__enter__cGs |dS)N)r.)r/rVrrr__exit__szParser.__exit__c Csz|jr*|dd|_|_|js*td|js8td|jrtt|j$}zt ||_Wd|j XWdQRX|jS)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=Nzimage was incompletezcannot parse this image) rXr|rprrr rnrtrurr r>)r/r!rrrr.s   z Parser.close)rcrdrerf incrementalrnrprXrUrrrqr|r}r~r.rrrrroOsProc Cs|t|dsd|_|jtdtt||jdd}|tj krP| dSy| }| Wnt t jfk r,x|D]\}}}}t|j|||j}|dkr||||j||jr|||\} } n&x$||\} } } || | rPqW| dkrtd| |qWYnXx|D]\}}}}t|j|||j}|dkrh||||j||jr|||\} } n |||} | dkrtd| |q4Wt|dr| dS) 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)r<rNz(encoder error %d when writing image fileflush)r>r@rrKrmaxrr,rAstdoutrrHr rtUnsupportedOperationrZ _getencoderr+rErMrFZ pushes_fdrOZencode_to_pyfdencodewriter rRZencode_to_file) rFr!rbufsizefhrwrZrzr{lr[ryrrr_savesT                 rcCsf|dkr dS|tkr||Sg}x8|dkrZ|t|t}|sBP|||t|8}q$Wd|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 read method. :param size: Number of bytes to read. :returns: A string containing up to size bytes of data. rr=) SAFEBLOCKrCrsappendr?join)r!r,rpblockrrr _safe_reads    rc@seZdZddZddZdS) PyCodecStatecCsd|_d|_d|_d|_dS)Nr)xsizeysizexoffyoff)r/rrrr1szPyCodecState.__init__cCs |j|j|j|j|j|jfS)N)rrrr)r/rrrrT7szPyCodecState.extentsN)rcrdrerrTrrrrr0src@s\eZdZdZdZddZddZeddZd d Z d d Z d dZ dddZ dddZ dS) 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` FcGs(d|_t|_d|_||_||dS)N)rFrstatefdr+init)r/r+rVrrrrEs zPyDecoder.__init__cCs ||_dS)z Override to perform decoder specific initialization :param args: Array of args items from the tile entry :returns: None N)rV)r/rVrrrrLszPyDecoder.initcCs|jS)N) _pulls_fd)r/rrrrNUszPyDecoder.pulls_fdcCs tdS)a' Override to perform the decoding process. :param buffer: A bytes object with the data to be decoded. :returns: A tuple of (bytes consumed, errcode). If finished with decoding return <0 for the bytes consumed. Err codes are from `ERRORS` N)ri)r/bufferrrrrPYs zPyDecoder.decodecCsdS)zV Override to perform decoder specific cleanup :returns: None Nr)r/rrrrRdszPyDecoder.cleanupcCs ||_dS)z Called from ImageFile to set the python file-like object :param fd: A python file-like object :returns: None N)r)r/rrrrrOlszPyDecoder.setfdNcCs||_|r|\}}}}n d\}}}}|dkrJ|dkrJ|jj\|j_|j_n(||j_||j_|||j_|||j_|jjdks|jjdkrtd|jj|jj|jjdks|jj|jj|jjdkrtddS)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 )rrrrrzSize cannot be negativerz Tile cannot extend outside imageN)rFr,rrrrr ValueError)r/rFrTZx0Zy0x1y1rrrrMus    zPyDecoder.setimagecCsd|s |j}t|jd|}||j|j||}|ddkrLtd|ddkr`tddS)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 r7rznot enough image datarzcannot decode image dataN) r+rrLrMrFrrTrPr)r/rprawmoderyr[rrr set_as_raws    zPyDecoder.set_as_raw)N)N)rcrdrerfrrrpropertyrNrPrRrOrMrrrrrr;s   #r)r)rtr)rArZ_utilrrrrQr rrrrhrorrrrrrrrs.   i >