a :jg@sddlmZddlZddlZddlZddlZddlZddlZddlm Z ddl m Z ddl m Z mZmZmZmZmZddlmZmZmZmZmZddlmZdd lmZdd lmZdd lmZ dd lm!Z"erdd lm#Z#e$e%Z&e'dj(Z)dZ*ddddddddddddddddZ+e'd Z,ej-Z.d!e.Z/Gd"d#d#e Z0Gd$d%d%e Z1d&d&d'd(d)Z2dod&d*d*d+d,d-Z3Gd.d/d/Z4Gd0d1d1e5Z6Gd2d3d3Z7Gd4d5d5eZ8Gd6d7d7e4Z9d&d8d9d:d;Z:Gdd?d@dAdBdCdDdDdDdEdFdGdHdIdJdKZGdSdTdTZ?GdUdVdVeZ@dWdLdXdYdYdZd[dZd\d]d^ZAdWdLd_dMd`dadbZBe=dcfdWdLd_dXd8dMdddedfZCdWdgdhdidjdkZDeEe;jFe;e:eGe;jFeCeHe;jFeBeIe;jFdldmgeJe;jFdndS)p) annotationsN)Callable)IntEnum)IO TYPE_CHECKINGAny NamedTupleNoReturncast)Image ImageChops ImageFile ImagePalette ImageSequence)i16be)i32be)o8)o16be)o32be)_imagings\w\w\w\wsPNG  )1r)LL;2)rL;4)rr)I;16I;16B)RGBr)rzRGB;16B)PP;1)rP;2)rP;4)rr)LAr")RGBAzLA;16B)r#r#)r#zRGBA;16B))r r)r)r)r)r)r&r$)r'r$)r )r$r()r%r()r&r()r&r%)r'r%)r&)r'r)s^**$@c@seZdZdZdZdZdS)Disposalrr r$N)__name__ __module__ __qualname__OP_NONE OP_BACKGROUND OP_PREVIOUSr2r2|j|||jdur"|jnd|jdur4|jnd|dSt|ts|z|dd}Wn"tyz|j|||dYS0t|ts|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 N)rrrzTXttEXtr) rryrrzr{r7r UnicodeErrorrr:r)rOrrrr2r2r3add_textMs$     zPngInfo.add_textN)F)rrF)F)r,r-r.rrPrrrr2r2r2r3rs$rc@s&eZdZUded<ded<ded<dS) _RewindStatez dict[str | tuple[int, int], Any]infozlist[ImageFile._Tile]tilez int | Noneseq_numNr,r-r.rr2r2r2r3rus rcseZdZdddfdd Zddddd Zdd d d Zdd d dZddddddZddddddZddddddZ ddddddZ ddddddZ ddddddZ ddddddZ ddddd d!Zddddd"d#Zddddd$d%Zddddd&d'Zddddd(d)Zddddd*d+Zddddd,d-Zddddd.d/Zddddd0d1Zddddd2d3ZZS)4 PngStreamrHrIrJcsZt|i|_i|_d|_d|_g|_d|_d|_d|_ d|_ t igd|_ d|_ dS)Nrrrr)superrPim_infoim_textim_sizeim_modeim_tile im_paletteim_custom_mimetype im_n_frames_seq_numr rewind_state text_memoryrN __class__r2r3rP|s zPngStream.__init__rB)chunklenr9cCs2|j|7_|jtkr.d|jd}t|dS)Nz%Too much memory used in text chunks: z>MAX_TEXT_MEMORY)rMAX_TEXT_MEMORYr?)rOrr@r2r2r3check_text_memorys zPngStream.check_text_memoryrQcCst|j|j|j|_dSrL)rrcopyrrrr_r2r2r3 save_rewinds zPngStream.save_rewindcCs&|jj|_|jj|_|jj|_dSrL)rrrrrrrrr_r2r2r3rewinds zPngStream.rewindr7)r]r^r9cCs|jdusJt|j|}|d}td|d|||d}td||dkrnd|d}t|zt||dd}Wn6tytj rd}nYnt j yd}Yn0||j d <|S) NrziCCP profile name %rr zCompression method %srUnknown compression method z in iCCP chunkr$ icc_profile) rKrrwfindrirjr[rAr?rYr:rqr)rOr]r^r8i comp_methodr@rr2r2r3 chunk_iCCPs&       zPngStream.chunk_iCCPcCs|jdusJt|j|}|dkr:tjr.|Sd}t|t|dt|df|_z t|d|df\|_|_ Wnt yYn0|drd|j d <|d rd }t ||S) N zTruncated IHDR chunkrr%r& r interlace zunknown filter category) rKrrwrYr?rWr_MODESr im_rawmode Exceptionrr[rOr]r^r8r@r2r2r3 chunk_IHDRs$   zPngStream.chunk_IHDRr cCspd|jvr&td|jd||jg}n.|jdur:d|jd<tdd|j||jg}||_||_d}t|dS)NbboxrT default_imagerzimage data found) rr_TilerrrrZim_idatEOFError)rOr]r^rr@r2r2r3 chunk_IDATs   zPngStream.chunk_IDATcCsd}t|dS)Nzend of PNG image)r)rOr]r^r@r2r2r3 chunk_IENDszPngStream.chunk_IENDcCs4|jdusJt|j|}|jdkr0d|f|_|S)Nrr)rKrrwrrrOr]r^r8r2r2r3 chunk_PLTEs   zPngStream.chunk_PLTEcCs|jdusJt|j|}|jdkrZt|rN|d}|dkrX||jd<q||jd<nD|jdvrtt||jd<n*|jdkrt|t|dt|df|jd<|S) Nrrr transparency)rrrrr$r%) rKrrwr_simple_palettematchrri16)rOr]r^r8rr2r2r3 chunk_tRNSs        zPngStream.chunk_tRNScCs2|jdusJt|j|}t|d|jd<|S)Nj@gamma)rKrrwrWrrr2r2r3 chunk_gAMAszPngStream.chunk_gAMAcCsP|jdusJt|j|}tdt|d|}tdd|D|jd<|S)Nz>%dIr%css|]}|dVqdS)rNr2).0eltr2r2r3 rz'PngStream.chunk_cHRM..Z chromaticity)rKrrwrpunpacklentupler)rOr]r^r8Zraw_valsr2r2r3 chunk_cHRMs zPngStream.chunk_cHRMcCsL|jdusJt|j|}|dkr:tjr.|Sd}t||d|jd<|S)Nr zTruncated sRGB chunkrZsrgb)rKrrwrYr?rrr2r2r3 chunk_sRGBszPngStream.chunk_sRGBc Cs|jdusJt|j|}|dkr:tjr.|Sd}t|t|dt|d}}|d}|dkr||d|df}||jd<n|dkr||f|jd <|S) NrzTruncated pHYs chunkrr%r&r F%u?dpiZaspect)rKrrwrYr?rWr) rOr]r^r8r@pxpyunitrr2r2r3 chunk_pHYs#s zPngStream.chunk_pHYscCs|jdusJt|j|}z|dd\}}WntyJ|}d}Yn0|r|dd}|dd}|dkrt|n||j|<||j|<|t ||S)Nrr rrrreplacesexif) rKrrwsplitr?rlrrrr)rOr]r^r8kvk_strv_strr2r2r3 chunk_tEXt5s     zPngStream.chunk_tEXtc Cs |jdusJt|j|}z|dd\}}WntyJ|}d}Yn0|rZ|d}nd}|dkrzd|d}t|zt|dd}Wn6tytjrd}nYntj yd}Yn0|r| dd}| dd } | |j |<|j |<| t| |S) Nrr rrrz in zTXt chunkrrr)rKrrwrr?r[rArYr:rqrlrrrr) rOr]r^r8rrrr@rrr2r2r3 chunk_zTXtIs6        zPngStream.chunk_zTXtcCs|jdusJt|j|}}z|dd\}}WntyJ|YS0t|dkr\|S|d|d|dd}}}z|dd\}} } Wnty|YS0|dkr |dkrz t| } Wn:tytjr|YSYntj y|YS0n|S|dkr | |j d<z4| dd} | d d} | d d} | d d}Wnt yl|YS0t || | |j | <|j| <|t||S) Nrr r$rsXML:com.adobe.xmpZxmprrr)rKrrwrr?rrArYr:rqrrlrryrr)rOr]r^rr8rcfcmrzZtkrrZlang_strZtk_strrr2r2r3 chunk_iTXtlsH                 zPngStream.chunk_iTXtcCs.|jdusJt|j|}d||jd<|S)NExifexif)rKrrwrrr2r2r3 chunk_eXIfszPngStream.chunk_eXIfcCs|jdusJt|j|}|dkr:tjr.|Sd}t||jdurXd|_td|St|}|dksp|dkr~td|S||_t|d|j d<d|_ |S) Nr&z"APNG contains truncated acTL chunkz4Invalid APNG, will use default PNG image if possiblerlr%loopz image/apng) rKrrwrYr?rwarningswarnrWrr)rOr]r^r8r@n_framesr2r2r3 chunk_acTLs&   zPngStream.chunk_acTLcCsP|jdusJt|j|}|dkr:tjr.|Sd}t|t|}|jdurT|dksl|jdurx|j|dkrxd}t|||_t|dt|d}}t|dt|d }} |j\} } ||| ks| || krd }t||| ||| |f|j d <t |d t |d } } | dkrd} t | t | d|j d<|d|j d<|d|j d<|S)Nz"APNG contains truncated fcTL chunkrr #APNG contains frame sequence errorsr%r&rr'zAPNG contains invalid framesrddurationdisposalblend) rKrrwrYr?rWrr[rrrfloat)rOr]r^r8r@seqwidthheightrrZim_wZim_hZ delay_numZ delay_denr2r2r3 chunk_fcTLs<   zPngStream.chunk_fcTLcCs|jdusJ|dkr:tjr.t|j|}|Sd}t|t|jd}t|}|j|dkrjd}t|||_||d|dS)Nr%z"APNG contains truncated fDAT chunkr r) rKrrYrwr?rWrr[r)rOr]r^r8r@rr2r2r3 chunk_fdATszPngStream.chunk_fdAT)r,r-r.rPrrrrrrrrrrrrrrrrrrr r  __classcell__r2r2rr3r{s*   #+rr)prefixr9cCs|ddtkS)Nr&)_MAGIC)r r2r2r3_acceptsrcseZdZdZdZddddZedddd Zddd d Zd dd ddZ d%d dddddZ d dddZ ddddZ d ddddZ ddddZddd d!Zd"dfd#d$ ZZS)& PngImageFileZPNGzPortable network graphicsrIrQc Cst|jdsd}t||j|_d|_g|_t|j|_|j\}}}z|j |||}Wndt yvYqYnPt yt d|||t|j|}|ddr|j||fYn0|j||q<|jj|_|jj|_|jj|_d|_|jj|_|jj|_|jjpd|_|j dd|_!|jj"rR|jj"\}}t#$|||_%|d krh|d |_&n||_&|jjdurd|_'|j(|j&|_)|j*|_+|j!r|jd7_|,d|jdk|_-dS) Nr&znot a PNG filer%r %s %s (unknown)r r$rFfdATr%).rrKrUr[_fp_PngImageFile__frameprivate_chunksrpngrmrAttributeErrorrirjrrwislowerrersr_moder_sizerr_textrrrZcustom_mimetyperrgetrrrrawpalette_PngImageFile__prepare_idatZ!_close_exclusive_fp_after_loadingr_PngImageFile__rewind_idatrV_PngImageFile__rewind_seek is_animated)rOr@r\r]r^r8rawmoderCr2r2r3_opensR               zPngImageFile._openzdict[str, str | iTXt]cCsR|jdur>|jr&|j}||jd||jr>|||jdusLJ|jS)Nr )rr"rrTrload)rOframer2r2r3r}5s  zPngImageFile.textcCsl|jdurd}t||j|jddd|jdus>J|j|j|jrb|jd|_dS)zVerify PNG fileNz)verify must be called directly after openrr$r&)rK RuntimeErrorrTrrrxrcZ _exclusive_fp)rOr@r2r2r3rxEs    zPngImageFile.verifyrB)r&r9c Cs||sdS||jkr$|dd|j}t|jd|dD]P}z||Wq>ty}z$||d}t||WYd}~q>d}~00q>dS)NrTr zno more images in APNG file)Z _seek_checkrr!rangerrT)rOr&Z last_framefrrr@r2r2r3rTWs    zPngImageFile.seekFr)r&rr9c Cs6|jdusJ|d}|dkr|rd|j|j|j|j|_d|_|jj|_ |jj |_ |j|_ d|_ d|_|j dd|_|j d|_|j d|_|j d}d|_n||jdkrd|}t|||jr|j|j|j|j|_ |j|_ |jr$t|j |jd|_d}|j d z|j\}}}Wn tjtfyhYqHYn0|d krd }t ||d kr|rd }t|d}z|j!|||Wnt"yYqHYnvt y|dkr|d 8}|r||_YqHt|j |Yn2t#yBt$%d|||t|j |Yn0q(||_|jj |_ |j d|_|j d|_|j d}|j sd}t ||r||_|j dur|jt&j'krt&j(|_d|_|jt&j'kr|j r2|j |_|)|j|j|_n4|jt&j(kr2t*j+,|j-|j.|_|)|j|j|_dS)NrrFrrrr zcannot seek to frame r%rtzNo more images in APNG filefcTLzAPNG missing frame dataTrrzimage not found in APNG frame)/rrrTr rrrZ_imrrrrrK_prev_imdisposerrZ dispose_opblend_oprr?r%impastedispose_extentrrrwrUrprqr[rrmUnicodeDecodeErrorrrirjr+r1r0_cropr corefillmodesize) rOr&rr0r@Z frame_startr\r]r^r2r2r3r!fs                zPngImageFile._seekcCs|jSrL)rr_r2r2r3rVszPngImageFile.tellcCs0|jdr|jd|_|j|_tj|dS)z"internal: prepare to read PNG filer)r N)rrZ decoderconfigr_PngImageFile__idatr load_preparer_r2r2r3r8s  zPngImageFile.load_preparer7) read_bytesr9cCs|jdusJ|jdkr|jd|j\}}}|dvrP|j|||dS|dkrz|j|||Wnty~Yn0|d|_q||_q|dkr|j}n t||j}|j||_|j|S)zinternal: read more image dataNrr%)IDATsDDATrrr)rr7rKrUrgrmrmin)rOr9r\r]r^r2r2r3 load_reads&      zPngImageFile.load_readc Cs|jdusJ|jdkr&|j|j|jdz|j\}}}WntjtfydYqYn0|dkrtqn(|dkr|jrd|_|j |||qz|j |||Wq&t yYqYq&t yB|dkr|d8}zt |j|WnDty<}z*t jr$WYd}~Yqn|WYd}~n d}~00Yq&tytd|||t |j|}|dd r|j||d fYq&0q&|jj|_|js|jd|_n|jr|jtjkr||j|j }|jj!d krd |j"vr|#d |j"d }n\|jj!dkrdd |j"vrd|j"d }t$|t%rN|&|nt$|t'rd|(||)d }|j*||j ||j|_dS)z%internal: finished reading image dataNrr%rtr*rrr r$Trrr#r)+rr7rKrUrprqr[r"rrgrmr1rrrwrvrYrrirjrrrerrrcr+r-r4r6r2r.r0r5rZconvert_transparentrr7ZputpalettealphasrBZputpalettealphaconvertr/) rOr\r]r^rrr8updatedmasktr2r2r3load_endsf              zPngImageFile.load_endzdict[int, Any] | NonecCs6d|jvr|d|jvr*d|jvr*dS|S)NrzRaw profile type exif)rr%getexifZ_get_merged_dictr_r2r2r3_getexif4s  zPngImageFile._getexifz Image.Exifcsd|jvr|tS)Nr)rr%rrBr_rr2r3rB;s zPngImageFile.getexif)F)r,r-r.formatformat_descriptionr$propertyr}rxrTr!rVr8r<rArCrBr r2r2rr3rsCb ">r)rr)L;1rGr)rr)rr)rr)r"rKrJ)rr)rrG)r rIrM)r!rJrM)rrKrM)rrKrI)r#rK)rrHrrrr"Irrrr r!rrr#rHrIrKr\rCr9cGsJd|}|tt||||t|t|}|t|dS)z'Write a PNG chunk (including CRC field)rN)joinwriteo32rrFrKr\rCZ byte_datarsr2r2r3putchunkYs   rUc@s.eZdZddddddZdddd d Zd S) _idatrHCallable[..., None]rI)rKchunkr9cCs||_||_dSrL)rKrX)rOrKrXr2r2r3rPgsz_idat.__init__r7rCr9cCs||jd|dS)Nr:)rXrKrOrCr2r2r3rRksz _idat.writeNr,r-r.rPrRr2r2r2r3rVdsrVc@s0eZdZdddddddZddd d d Zd S) _fdatrHrWrBrI)rKrXrr9cCs||_||_||_dSrL)rKrXr)rOrKrXrr2r2r3rPrsz_fdat.__init__r7rYcCs*||jdt|j||jd7_dS)Nrr )rXrKrSrrZr2r2r3rRwsz _fdat.writeNr[r2r2r2r3r\osr\c@s&eZdZUded<ded<ded<dS)_Frame Image.Imager.z tuple[int, int, int, int] | Nonerzdict[str, Any] encoderinfoNrr2r2r2r3r]|s r]r^rWr|zImage.Image | Nonezlist[Image.Image])r.rKrXr5r#r append_imagesr9c Cs`|jd}|jd|jdd}|jd|jdtj} |jd|jdtj} |rht|} nt|g|} g} d} | D]}t |D]}|j |kr| }n | |}|j }t|ttfr|| |d<n |durd|jvr|jd|d<t| ttfr| | |d<t| ttfr4| | |d<| d7} | rf| d}|jd}|jd}|tjkrt| dkrtj}|tjkr|j }tjd |jd }|j}|r||}n d |j}|||n|tjkr| d j}n|j}t| d | d }|jd d}|sj||dkrj||dkrjd|vrj|jd|d7<qnd}| t |||qqt| dkr|s| djS||dt!t| t!||r|j |kr| |}t"#|t$t%t&t'||t"(dd |jd|gd}t)| D]F\}}|j}|js6d |j}n|j}||}|j}|j}t*t+|dd}|d| }|d| }||dt!|t!|dt!|dt!|dt!|dt,|t,dt-|t-| |d7}|dkr|st"#|t$t%t&t'||t"(dd |jd|gn>t.|||}t"#|t$t%t&|t"(dd |jd|g|j/}qdS)Nrrrrrr r$r#)rrrrrF)Z alpha_onlysacTLrr*r)0r_rrr+r/r4r5 itertoolschainrIteratorr5rr=rlistrr1rr0r.r r3r4r6rcropr/r Zsubtract_moduloZgetbboxrer]rSr_saver rr7rVr enumeraterBroundo16rr\r) r.rKrXr5r#rr`rrrrrdZ im_framesZ frame_countim_seqim_framer_previousZ prev_disposalZ prev_blendZbase_imr,rdeltarr&Z frame_datar6Zframe_durationZframe_disposalZ frame_blendZ fdat_chunksr2r2r3_write_multiple_framess                                    rpr)r.rKfilenamer9cCst|||dddS)NT)save_all)rh)r.rKrqr2r2r3 _save_allsrsF)r.rKrqrXrrr9c( s\|r|jd|jd}t}t|jdg}t|g|D],}t|D]} || j | j qPqBdD]} | |vrtqqt| } t fddt dD} n |j } |j } | } | dkrPd|jvrtd |jd>d } n0|jrttt|jd d d d } nd } | d krP| dkr.d }n| d kr>d}nd }| d|7} |jdd|jdd|jdd|jddf|_zt| \}}}Wn<ty}z"d| d}t||WYd}~n d}~00|t||dt| dt| d ||ddd gd}|jd|jd}|rXd}|dt|}||d||d |jd!}|rgd"}|jD]}|dd\}}||vr||||||nR||vr||||n:|d drxt|d ko|d}|sx||||qx|j dkrR| d }|j d#d|}t||krF|d7}q,||d$||jd%|jd%d}|sz|dkr^|j dkr| } t!|t"r||d&|d| n0tdtd'|}d(|d}!||d&|!d| n~|j d)vr tdtd*|}||d&t#|nP|j d#krD|\}"}#}$||d&t#|"t#|#t#|$nd%|jvrd+}t|nB|j dkr|j$d,kr|j d,d-}!| } ||d&|!d| |jd.}%|%r||d/tt%|%dd0d1tt%|%d d0d1d2|r6d3d4g}|jD]6}|dd\}}||vr||||||q|jd5}&|&rt!|&t&j'r`|&(d6}&|&)d7rx|&d8d}&||d9|&|}'|rt*|||| |||}'|'rt+,|'t-t.t"t/||t+0d:d;|'j d|g|r8|jD]P}|dd\}}|d drt|d ko |d}|r||||q||dNrr`)r#rrc3s$|]tfddDVqdS)c3s|]}|VqdSrLr2)r frame_sizerr2r3r-rz"_save...N)max)rsizesrur3r-rz_save..r$rbitsr r(r'r%;optimizeFZcompress_levelra compress_type dictionaryrzcannot write mode z as PNGsIHDRrr)scHRMsgAMAssBITsRGBstIMErs ICC ProfilersiCCPrZpnginfo)ssPLTrrrrsPLTErstRNS)rrrOriz%cannot use transparency for this moder#ArspHYsrg?rGsbKGDshISTrr&rr)seXIfrrrtflush)3r_rrsetrcrdrrerr5r6rSrr(r;rrvrZgetdataZ encoderconfig _OUTMODESKeyErrorrvrRr rSr:rremoverrr.Z getpaletterr7rkZgetpalettemoderBr ZExiftobytes startswithrprrhr rrVrhasattrr)(r.rKrqrXrrrmodesr`rlrmr5r6Zoutmodecolorsryr#Z bit_depth color_typerrr@rZiccnamerCrZchunks_multiple_allowedZ info_chunkr\rZpalette_byte_numberZ palette_bytesrZ alpha_bytesalpharedgreenbluerrZ single_imr2rwr3rhs&     $                             "              rhrz list[tuple[bytes, bytes, bytes]])r.paramsr9c sVddlm}gdddddfdd }|}z||_t||d |W|`n|`0S) z4Return a list of PNG chunks representing this image.r)BytesIOrHr7rIrPcs0d|}tt|t|}|||fdS)Nr)rQrSrFrerTrr2r3res zgetchunks..appendr)iorr_rh)r.rrrerKr2rr3 getchunkss  rz.pngz.apngz image/png)r)K __future__rrcloggingrerprr:collections.abcrenumrtypingrrrrr r rr r rrr_binaryrrrrWrrrkrrSr getLoggerr,ricompilerrXr rrZ SAFEBLOCKr=rr+r4rArFrGr|ryrrrrrrrUrVr\r]rprsrhrZ register_openrDZ register_saveZregister_save_allZregister_extensionsZ register_mimer2r2r2r3!s              ^`m[   V