B ]Q@sddlZddlZddlZddlmZddlmZdZdZdZ dd d d d d Z ddZ ddZ GdddejZ Gddde ZGdddeZd ddZddZGdddeZGdddeZdS)!N)Image)isPathiiFzimage buffer overrun errorzdecoding errorz unknown errorzbad configurationzout of memory error)iicCsLytj|}Wntk r.t|}YnX|sr^Zn_framesr'tell)r-framerrr _seek_check(s  zImageFile._seek_check)NN) __name__ __module__ __qualname____doc__rr/r2r3r<rIrRrarrrrrMs *  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 r0r<AssertionError __class____dict__)r-loaderimagerrrr<Bs  zStubImageFile.loadcCs tddS)z (Hook) Find actual image loader.z+StubImageFile subclass must implement _loadN)rg)r-rrrrhLszStubImageFile._loadN)rbrcrdrer#r<rhrrrrrf7s 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-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. NrrrBr@)finishedrorWrTminr=rOrmrioBytesIOrrr r>rrIrKr+rrLrD) r-roskipr[er rDflagdoarrrfeedfsR      z Parser.feedcCs|S)Nr)r-rrr __enter__szParser.__enter__cGs |dS)N)r))r-rUrrr__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) rWr{rorqr rmrsrtrrr<)r-r rrrr)s   z Parser.close)rbrcrdre incrementalrmrorWrTrqrpr{r|r}r)rrrrrnQsPrnc 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>rrJrmaxrr,r?stdoutrrFr rsUnsupportedOperationrZ _getencoderr+rCrLrDZ pushes_fdrNZencode_to_pyfdencodewriter rQZencode_to_file) rDr rbufsizefhrvrYryrzlrZrxrrr_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;) SAFEBLOCKrArrappendr=join)r r,roblockrrr _safe_reads    rc@seZdZddZddZdS) PyCodecStatecCsd|_d|_d|_d|_dS)Nr)xsizeysizexoffyoff)r-rrrr3szPyCodecState.__init__cCs |j|j|j|j|j|jfS)N)rrrr)r-rrrrS9szPyCodecState.extentsN)rbrcrdrrSrrrrr2src@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)rDrstatefdr+init)r-r+rUrrrrGs 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-rUrrrrNszPyDecoder.initcCs|jS)N) _pulls_fd)r-rrrrMWszPyDecoder.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-bufferrrrrO[s zPyDecoder.decodecCsdS)zV Override to perform decoder specific cleanup :returns: None Nr)r-rrrrQfszPyDecoder.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-rrrrrNnszPyDecoder.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)rDr,rrrrr ValueError)r-rDrSZx0Zy0Zx1y1rrrrLws    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 r5rznot enough image datarzcannot decode image dataN) r+rrKrLrDrrSrOr)r-rorawmoderxrZrrr set_as_raws    zPyDecoder.set_as_raw)N)N)rbrcrdrerrrpropertyrMrOrQrNrLrrrrrr=s   #r)r)rsr(r?rZ_utilrrrrPr rrrrfobjectrnrrrrrrrrs.   k >