B ]l@sddlZddlZddlZddlZddlmZmZmZddlm Z m Z m Z mZmZddlmZdZeeZedjZdZd d d d d dddddddddddZedZejZdeZ ddZ!dDddZ"Gdd d e#Z$Gd!d"d"e%Z&Gd#d$d$e#Z'Gd%d&d&e$Z(d'd(Z)Gd)d*d*ejZ*d+d,d-d.d/d0d1d1d2d3d4d5d6d7d8Z+d9d:Z,Gd;d<dZ.d?d@Z/e0e*j1e*e)e2e*j1e.e3e*j1dAdBge4e*j1dCdS)EN)Image ImageFile ImagePalette)i8i16bei32beo16beo32be)py3z0.9s\w\w\w\wsPNG  )1r )LzL;2)r zL;4)r r )IzI;16B)RGBr)rzRGB;16B)PzP;1)rzP;2)rzP;4)rr)LAr)RGBAzLA;16B)rr)rzRGBA;16B))rr)r)r)r)r)rr)rr)r)rr)rr)rr)rr)rr)r)rrs^**$@cCs&t}||t}|jr"td|S)NzDecompressed Data Too Large)zlib decompressobj decompressMAX_TEXT_CHUNKunconsumed_tail ValueError)sZdobj plaintextr"4/tmp/pip-build-ktz6qwqq/Pillow/PIL/PngImagePlugin.py_safe_zlib_decompressYs  r$cCst||d@S)Nl)rcrc32)dataseedr"r"r#_crc32asr(c@s^eZdZddZddZddZddZd d Zd d Zd dZ ddZ ddZ dddZ dS) ChunkStreamcCs||_g|_dS)N)fpqueue)selfr*r"r"r#__init__jszChunkStream.__init__cCszd}|jr(|j\}}}|j|n*|jd}|dd}|j}t|}t|sptj spt dt ||||fS)z.Fetch a new chunk. Returns header information.Nrrzbroken PNG file (chunk %s)) r+popr*seekreadtelli32is_cidrLOAD_TRUNCATED_IMAGES SyntaxErrorrepr)r,cidposlengthr r"r"r#r0os   zChunkStream.readcCs|S)Nr")r,r"r"r# __enter__szChunkStream.__enter__cGs |dS)N)close)r,argsr"r"r#__exit__szChunkStream.__exit__cCsd|_|_|_dS)N)r+crcr*)r,r"r"r#r;szChunkStream.closecCs|j|||fdS)N)r+append)r,r7r8r9r"r"r#pushszChunkStream.pushcCs*td|||t|d|d||S)z"Call the appropriate chunk handlerzSTREAM %r %s %sZchunk_ascii)loggerdebuggetattrdecode)r,r7r8r9r"r"r#callszChunkStream.callcCstjr*t|dd?d@r*|||dSy6t|t|}t|jd}||kr^td|Wn"t j k rtd|YnXdS)zRead and verify checksumrrNrz+broken PNG file (bad header checksum in %r)z+broken PNG file (incomplete checksum in %r)) rr4rcrc_skipr(r2r*r0r5structerror)r,r7r&Zcrc1Zcrc2r"r"r#r>s zChunkStream.crccCs|jddS)z3Read checksum. Used if the C module is not presentrN)r*r0)r,r7r&r"r"r#rHszChunkStream.crc_skipIENDcCsjg}x`y|\}}}Wntjk r6tdYnX||krBP||t|j|||qW|S)Nztruncated PNG file) r0rIrJIOErrorr>r _safe_readr*r?)r,ZendchunkZcidsr7r8r9r"r"r#verifyszChunkStream.verifyN)rK) __name__ __module__ __qualname__r-r0r:r=r;r@rFr>rHrNr"r"r"r#r)isr)c@seZdZdZedddZdS)iTXtzq Subclass of string to allow iTXt chunks to look like strings while keeping their extra information NcCst||}||_||_|S)z :param cls: the class to use when creating the instance :param text: value for this key :param lang: language code :param tkey: UTF-8 version of the key name )str__new__langtkey)clstextrUrVr,r"r"r#rTs z iTXt.__new__)NN)rOrPrQ__doc__ staticmethodrTr"r"r"r#rRsrRc@s4eZdZdZddZddZd dd Zdd d Zd S)PngInfoz< PNG chunk container (for use with save(pnginfo=)) cCs g|_dS)N)chunks)r,r"r"r#r-szPngInfo.__init__cCs|j||fdS)zAppends an arbitrary chunk. Use with caution. :param cid: a byte string, 4 bytes long. :param data: a byte string of the encoded data N)r\r?)r,r7r&r"r"r#addsz PngInfo.addFcCst|ts|dd}t|ts,|dd}t|tsB|dd}t|tsX|dd}|r|d|d|d|dt|n$|d|d|d|d|dS) zAppends an iTXt chunk. :param key: latin-1 encodable text key name :param value: value for this key :param lang: language code :param tkey: UTF-8 version of the key name :param zip: compression flag zlatin-1strictzutf-8siTXtssN) isinstancebytesencoder]rcompress)r,keyvaluerUrVzipr"r"r#add_itxts        &zPngInfo.add_itxtcCst|tr"|j|||j|j|dSt|ts^y|dd}Wn tk r\|j|||dSXt|tst|dd}|r|d|dt |n|d|d|dS) zAppends a text chunk. :param key: latin-1 encodable text key name :param value: value for this key, text or an :py:class:`PIL.PngImagePlugin.iTXt` instance :param zip: compression flag )rgzlatin-1r_szTXtsstEXtr`N) rarRrhrUrVrbrc UnicodeErrorr]rrd)r,rerfrgr"r"r#add_texts    zPngInfo.add_textN)r^r^F)F)rOrPrQrYr-r]rhrjr"r"r"r#r[s  r[c@seZdZddZddZddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZddZddZddZdd Zd!d"Zd#S)$ PngStreamcCs@t||i|_i|_d|_d|_d|_d|_d|_d|_ dS)N)rrr) r)r-im_infoim_textim_sizeim_modeim_tile im_paletteim_custom_mimetype text_memory)r,r*r"r"r#r-'s zPngStream.__init__cCs*|j|7_|jtkr&td|jdS)Nz7Too much memory used in text chunks: %s>MAX_TEXT_MEMORY)rsMAX_TEXT_MEMORYr)r,Zchunklenr"r"r#check_text_memory6s  zPngStream.check_text_memorycCst|j|}|d}td|d|tdt||t||}|dkr`td|yt||dd}Wn:t k rtj rd}nYnt j k rd}YnX||j d<|S)Nr`ziCCP profile name %rzCompression method %srz+Unknown compression method %s in iCCP chunkr icc_profile)rrMr*findrBrCrr5r$rr4rrJrl)r,r8r9r i comp_methodrvr"r"r# chunk_iCCP>s$     zPngStream.chunk_iCCPcCst|j|}t|t|ddf|_y(tt|dt|df\|_|_Wnt k rdYnXt|dr|d|j d<t|drt d|S) Nrr r interlace zunknown filter category) rrMr*r2rn_MODESrro im_rawmode Exceptionrlr5)r,r8r9r r"r"r# chunk_IHDR[s(   zPngStream.chunk_IHDRcCs&dd|j||jfg|_||_tdS)Nrg)rr)rnrrpZim_idatEOFError)r,r8r9r"r"r# chunk_IDATjszPngStream.chunk_IDATcCstdS)N)r)r,r8r9r"r"r# chunk_IENDqszPngStream.chunk_IENDcCs&t|j|}|jdkr"d|f|_|S)Nrr)rrMr*rorq)r,r8r9r r"r"r# chunk_PLTEvs  zPngStream.chunk_PLTEcCst|j|}|jdkrLt|r@|d}|dkrJ||jd<q||jd<nP|jdkrft||jd<n6|jdkrt|t|ddt|ddf|jd<|S) Nrr`r transparency)r r rrrr) rrMr*ro_simple_palettematchrwrli16)r,r8r9r rxr"r"r# chunk_tRNS~s       ,zPngStream.chunk_tRNScCs$t|j|}t|d|jd<|S)Ngj@gamma)rrMr*r2rl)r,r8r9r r"r"r# chunk_gAMAszPngStream.chunk_gAMAcCsBt|j|}tdt|d|}tdd|D|jd<|S)Nz>%dIrcss|]}|dVqdS)gj@Nr").0eltr"r"r# sz'PngStream.chunk_cHRM..Z chromaticity)rrMr*rIunpacklentuplerl)r,r8r9r Zraw_valsr"r"r# chunk_cHRMszPngStream.chunk_cHRMcCs t|j|}t||jd<|S)NZsrgb)rrMr*rrl)r,r8r9r r"r"r# chunk_sRGBszPngStream.chunk_sRGBcCst|j|}t|t|dd}}t|d}|dkrht|ddt|ddf}||jd<n|dkr~||f|jd<|S) Nrrrg F%u?g?dpirZaspect)rrMr*r2rintrl)r,r8r9r Zpxpyunitrr"r"r# chunk_pHYss   zPngStream.chunk_pHYscCst|j|}y|dd\}}Wntk r>|}d}YnX|rtr`|dd}|dd}||j|<|j|<| t ||S)Nr`rzlatin-1r_replace) rrMr*splitrr rErlrmrur)r,r8r9r kvr"r"r# chunk_tEXts   zPngStream.chunk_tEXtcCst|j|}y|dd\}}Wntk r>|}d}YnX|rRt|d}nd}|dkrjtd|yt|dd}Wn:tk rtjrd}nYnt j k rd}YnX|rt r| dd}| dd}||j |<|j|<|t||S) Nr`rrrz+Unknown compression method %s in zTXt chunkzlatin-1r_r)rrMr*rrrr5r$r4rrJr rErlrmrur)r,r8r9r rrryr"r"r# chunk_zTXts6     zPngStream.chunk_zTXtc Cs~t|j|}}y|dd\}}Wntk r:|SXt|dkrL|St|dt|d|dd}}}y|dd\}} } Wntk r|SX|dkr|dkry t| } Wn6tk rtjr|SYnt j k r|SXn|St rPy4| dd}| dd}| dd} | dd} Wnt k rN|SXt| || |j|<|j|<|t| |S)Nr`rrrzlatin-1r_zutf-8)rrMr*rrrrr$r4rrJr rErirRrlrmru) r,r8r9rr rZcfcmrUZtkrr"r"r# chunk_iTXtsD (      zPngStream.chunk_iTXtcCs t|j|}d||jd<|S)NsExifexif)rrMr*rl)r,r8r9r r"r"r# chunk_eXIfszPngStream.chunk_eXIfcCst|j|}d|_|S)Nz image/apng)rrMr*rr)r,r8r9r r"r"r# chunk_acTL#szPngStream.chunk_acTLN)rOrPrQr-rurzrrrrrrrrrrrrrrr"r"r"r#rk&s"   %*rkcCs|ddtkS)Nr)_MAGIC)prefixr"r"r#_accept-src@sXeZdZdZdZddZeddZddZd d Z d d Z d dZ ddZ ddZ dS) PngImageFileZPNGzPortable network graphicsc Cs|jdtkrtdt|j|_x~|j\}}}y|j|||}WnFtk r`PYn2tk rt d|||t |j|}YnX|j ||q&W|jj|_|jj|_|jj|_d|_|jj|_|jj|_|jjr|jj\}}t|||_||_dS)Nrznot a PNG filez%r %s %s (unknown))r*r0rr5rkpngrFrAttributeErrorrBrCrrMr>romodern_sizerlinfo_textrptilerrZcustom_mimetyperqrrawpalette_PngImageFile__prepare_idat)r,r7r8r9r rawmoder&r"r"r#_open:s.       zPngImageFile._opencCs|jdkr||jS)N)rload)r,r"r"r#rXis zPngImageFile.textcCsZ|jdkrtd|j|jddd|j|j|jrP|jd|_dS)zVerify PNG fileNz)verify must be called directly after openrrr)r* RuntimeErrorr/rrrNr;Z _exclusive_fp)r,r"r"r#rNrs    zPngImageFile.verifycCs0|jdr|jd|_|j|_tj|dS)z"internal: prepare to read PNG filer})rN)rgetZ decoderconfigr_PngImageFile__idatr load_prepare)r,r"r"r#rs  zPngImageFile.load_preparecCsxL|jdkrL|jd|j\}}}|dkrD|j|||dS||_qW|dkr^|j}n t||j}|j||_|j|S)zinternal: read more image datarr)sIDATsDDATr)rr*r0rr@min)r,Z read_bytesr7r8r9r"r"r# load_reads     zPngImageFile.load_readc Csx|jdy|j\}}}Wntjtfk r>PYnX|dkrJPy|j|||Wqtk rtPYqtk rt |j|Yqt k rt d|||t |j|YqXqW|jj|_|jd|_dS)z%internal: finished reading image datarsIENDz%r %s %s (unknown)N)r*r0rrIrJr5rFUnicodeDecodeErrorrrrMrrBrCrmrr;)r,r7r8r9r"r"r#load_ends(   zPngImageFile.load_endcCs,d|jkr|d|jkr dSt|S)Nr)rrdictgetexif)r,r"r"r#_getexifs   zPngImageFile._getexifcCsd|jkr|tj|S)Nr)rrrr)r,r"r"r#rs zPngImageFile.getexifN)rOrPrQformatformat_descriptionrpropertyrXrNrrrrrr"r"r"r#r5s/  r)r s)zL;1s)zL;2s)zL;4s)r s)rs)zI;16Bs)zP;1s)zP;2s)zP;4s)rs)rs)rs)r zL;1zL;2zL;4r rrzI;16zP;1zP;2zP;4rrrcGsJd|}|tt||||t|t|}|t|dS)z'Write a PNG chunk (including CRC field)rN)joinwriteo32rr()r*r7r&r>r"r"r#putchunks   rc@seZdZddZddZdS)_idatcCs||_||_dS)N)r*chunk)r,r*rr"r"r#r-sz_idat.__init__cCs||jd|dS)NsIDAT)rr*)r,r&r"r"r#rsz _idat.writeN)rOrPrQr-rr"r"r"r#rsrc Cs|j}|dkrd|jkr(d|jd>}n.|jrRttt|jdddd}nd}|dkrdd}n |dkrrd}n|dkrd}nd }|d krd ||f}|jd d |jd d|jdd|jddf|_yt |\}}Wn t k rt d|YnX| t ||dt|jdt|jd|ddddddddg}|jd|jd} | rd} | dt| } ||d| |d|jd} | rd d!d"d#g} xL| jD]B\}} ||kr|||||| n|| kr|||| qW|jdkrLd|d}|jd$d|}xt||kr>|d7}q$W||d%||jd&|jd&d}|st|dkrX|jdkrd|}t|tr||d'|d|n0tdtd(|}d)|d}||d'|d|nz|jd*kr tdtd+|}||d't|nL|jd$krB|\}}}||d't|t|t|nd&|jkrt d,nF|jdkr|jd-kr|jd-d.}d|}||d'|d||jd/}|r||d0tt|dd1d2tt|dd1d2d3|jd} | r8d4d5g}x4| jD]*\}} ||kr |||||| q W|jd6|jd6}|rt|tjrl|d }|d7r|d8d}||d9|t !|t"||d:d;|jd|fg||dNrbitsrrrrrrz%s;%doptimizeFZcompress_level compress_type dictionaryrzcannot write mode %s as PNGsIHDRrr`scHRMsgAMAssBITssRGBstIMErvs ICC ProfilessiCCPZpnginfossPLTsiTXtstEXtszTXtrsPLTErstRNS)r r riz%cannot use transparency for this moderArspHYsg F%u?g?sbKGDshISTrsExifrseXIfrg)rrsIENDflush)%r encoderinformaxrrZgetdatarZ encoderconfig _OUTMODESKeyErrorrLrrrsizerrrdremover\imZ getpaletterarbo16ZgetpalettemoderrZExiftobytes startswithr_saverhasattrr)rr*filenamerrcolorsrrr\Ziccnamer&rZchunks_multiple_allowedr7Zpalette_byte_numberZ palette_bytesrZ alpha_bytesalphaZredZgreenZbluerrr"r"r#rs $                       "          $  rcKsDGdddt}dd}|}z||_t||d|Wd|`X|jS)z4Return a list of PNG chunks representing this image.c@s eZdZgZddZddZdS)zgetchunks..collectorcSsdS)Nr")r,r&r"r"r#rsz"getchunks..collector.writecSs|j|dS)N)r&r?)r,rr"r"r#r?sz#getchunks..collector.appendN)rOrPrQr&rr?r"r"r"r# collectorsrcWs0d|}tt|t|}||||fdS)Nr)rrr(r?)r*r7r&r>r"r"r#r?s zgetchunks..appendN)objectrrr&)rparamsrr?r*r"r"r# getchunkss rz.pngz.apngz image/png)r)5loggingrerIrr^rrr_binaryrrrrr2r rr rZ_utilr __version__ getLoggerrOrBcompilerr3rrrZ SAFEBLOCKrrtr$r(rr)rSrRr[rkrrrrrrrZ register_openrZ register_saveZregister_extensionsZ register_mimer"r"r"r#"s|     XO   #