3 }\Q @sddlmZddlmZddlZddlZddlZdZd#ZdZ d$dd%d d&d d'dd(diZ ddZ ddZ GdddejZ Gddde ZGdddeZd)ddZddZGdd d eZGd!d"d"eZdS)*)Image)isPathNiiFzimage buffer overrun errorzdecoding errorz unknown errorzbad configuration zout of memory errorc CsLytjj|}Wntk r.tj|}YnX|sr^Zn_framesr'tell)r-framerrr _seek_checks  zImageFile._seek_check)NN) __name__ __module__ __qualname____doc__rr/r2r3r<rIrRrarrrrrJs (   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#1szStubImageFile._opencCsH|j}|dkrtd|j|j|}|dk s4t|j|_|j|_dS)Nz#cannot find loader for this %s file)_loadr r0r<AssertionError __class____dict__)r-loaderimagerrrr<6s  zStubImageFile.loadcCs tddS)z (Hook) Find actual image loader.z+StubImageFile subclass must implement _loadN)rg)r-rrrrh@szStubImageFile._loadN)rbrcrdrer#r<rhrrrrrf)s rfc@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)datari)r-rrrresetSsz Parser.resetc Cs|jr dS|jdkr||_n |j||_|jr|jdkr|tt|j|j}|j|d|_|j||_|jdksx|j r|dS|jj|j\}}|dkrd|_d|_|dkrd|_t|ndS|j|d|_n|jrny&t j |j}t j |}WdQRXWnt k rYnXt|dp*t|d}|sBt|jdkrJd|_nv|j|jd\}}} } g|_t j|j|| |j|_|jj|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. NrrrBr@)finishedrorWrTminr=rOrmrioBytesIOrrr r>rrIrKr+rrLrD) r-roskipr[er rDflagdoarrrfeed[sT      z Parser.feedcCs|S)Nr)r-rrr __enter__szParser.__enter__cGs |jdS)N)r))r-rUrrr__exit__szParser.__exit__cCsz|jr*|jdd|_|_|js*td|js8td|jrttj|j$}ztj ||_Wd|jj 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) rWr{rorqr rmrsrtrrr<)r-r rrrr)s   z Parser.close)rbrcrdre incrementalrmrorWrTrqrpr{r|r}r)rrrrrnGsRrnc Cs|jt|dsf|_|jtdtt||jdd}|tj krP|j dSy|j }|j Wnt t jfk r,x|D]\}}}}tj|j|||j}|dkr|j||j|j||jr|j||j\} } n&x$|j|\} } } |j| | rPqW| dkrtd| |jqWYnXx|D]\}}}}tj|j|||j}|dkrh|j||j|j||jr|j||j\} } n |j||} | dkrtd| |jq4Wt|dr|j 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 encoderconfig)r9rNz(encoder error %d when writing image fileflush)r<r>rrJrmaxrr,r?stdoutrrFr rsUnsupportedOperationrZ _getencoderr+rCrLrDZ pushes_fdrNZencode_to_pyfdencodewriter rQZencode_to_file) rDr rbufsizefhrvrYryrzlrZrxrrr_savesT                 rcCsf|dkr dS|tkr|j|Sg}x8|dkrZ|jt|t}|sBP|j||t|8}q$Wdj|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:) SAFEBLOCKrArrappendr=join)r r,roblockrrr _safe_reads    rc@seZdZddZddZdS) PyCodecStatecCsd|_d|_d|_d|_dS)Nr)xsizeysizexoffyoff)r-rrrr)szPyCodecState.__init__cCs |j|j|j|j|j|jfS)N)rrrr)r-rrrrS/szPyCodecState.extentsN)rbrcrdrrSrrrrr(src@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|_||_|j|dS)N)rDrstatefdr+init)r-r+rUrrrr>s zPyDecoder.__init__cCs ||_dS)z Override to perform decoder specific initialization :param args: Array of args items from the tile entry :returns: None N)rU)r-rUrrrrEszPyDecoder.initcCs|jS)N) _pulls_fd)r-rrrrMNszPyDecoder.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)rg)r-bufferrrrrORs zPyDecoder.decodecCsdS)zV Override to perform decoder specific cleanup :returns: None Nr)r-rrrrQ]szPyDecoder.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-rrrrrNeszPyDecoder.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 rzSize cannot be negativerz Tile cannot extend outside imageN)rrrr)rDr,rrrrr ValueError)r-rDrSZx0Zy0x1y1rrrrLns    zPyDecoder.setimagecCsd|s |j}tj|jd|}|j|j|jj|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 r5rznot enough image datarzcannot decode image dataN) r+rrKrLrDrrSrOr)r-rorawmoderxrZrrr set_as_raws    zPyDecoder.set_as_raw)N)N)rbrcrdrerrrpropertyrMrOrQrNrLrrrrrr4s   !rir;ii)r)rZ_utilrrsr?r(rrrPr rrrrfobjectrnrrrrrrrrs.   ` >