(function(){ var UPNG = {}; // Make available for import by `require()` var pako; if (typeof module == "object") {module.exports = UPNG;} else {window.UPNG = UPNG;} if (typeof require == "function") {pako = require("pako");} else {pako = window.pako;} function log() { if (typeof process=="undefined" || process.env.NODE_ENV=="development") console.log.apply(console, arguments); } (function(UPNG, pako){ UPNG.toRGBA8 = function(out) { var w = out.width, h = out.height; if(out.tabs.acTL==null) return [UPNG.toRGBA8.decodeImage(out.data, w, h, out).buffer]; var frms = []; if(out.frames[0].data==null) out.frames[0].data = out.data; var img, empty = new Uint8Array(w*h*4); for(var i=0; i>3)]>>(7-((i&7)<<0)))& 1), cj=3*j; bf[qi]=p[cj]; bf[qi+1]=p[cj+1]; bf[qi+2]=p[cj+2]; bf[qi+3]=(j>2)]>>(6-((i&3)<<1)))& 3), cj=3*j; bf[qi]=p[cj]; bf[qi+1]=p[cj+1]; bf[qi+2]=p[cj+2]; bf[qi+3]=(j>1)]>>(4-((i&1)<<2)))&15), cj=3*j; bf[qi]=p[cj]; bf[qi+1]=p[cj+1]; bf[qi+2]=p[cj+2]; bf[qi+3]=(j>3]>>(7 -((i&7) )))& 1), al=(gr==tr*255)?0:255; bf32[i]=(al<<24)|(gr<<16)|(gr<<8)|gr; } if(depth== 2) for(var i=0; i>2]>>(6 -((i&3)<<1)))& 3), al=(gr==tr* 85)?0:255; bf32[i]=(al<<24)|(gr<<16)|(gr<<8)|gr; } if(depth== 4) for(var i=0; i>1]>>(4 -((i&1)<<2)))&15), al=(gr==tr* 17)?0:255; bf32[i]=(al<<24)|(gr<<16)|(gr<<8)|gr; } if(depth== 8) for(var i=0; i>3, bpl = Math.ceil(w*bpp/8); var img = new Uint8Array( h * bpl ); var di = 0; var starting_row = [ 0, 0, 4, 0, 2, 0, 1 ]; var starting_col = [ 0, 4, 0, 2, 0, 1, 0 ]; var row_increment = [ 8, 8, 8, 4, 4, 2, 2 ]; var col_increment = [ 8, 8, 4, 4, 2, 2, 1 ]; var pass=0; while(pass<7) { var ri = row_increment[pass], ci = col_increment[pass]; var sw = 0, sh = 0; var cr = starting_row[pass]; while(cr>3]; val = (val>>(7-(cdi&7)))&1; img[row*bpl + (col>>3)] |= (val << (7-((col&3)<<0))); } if(bpp==2) { var val = data[cdi>>3]; val = (val>>(6-(cdi&7)))&3; img[row*bpl + (col>>2)] |= (val << (6-((col&3)<<1))); } if(bpp==4) { var val = data[cdi>>3]; val = (val>>(4-(cdi&7)))&15; img[row*bpl + (col>>1)] |= (val << (4-((col&1)<<2))); } if(bpp>=8) { var ii = row*bpl+col*cbpp; for(var j=0; j>3)+j]; } cdi+=bpp; col+=ci; } y++; row += ri; } if(sw*sh!=0) di += sh * (1 + bpll); pass = pass + 1; } return img; } UPNG.decode._getBPP = function(out) { var noc = [1,null,3,1,2,null,4][out.ctype]; return noc * out.depth; } UPNG.decode._filterZero = function(data, out, off, w, h) { var bpp = UPNG.decode._getBPP(out), bpl = Math.ceil(w*bpp/8), paeth = UPNG.decode._paeth; bpp = Math.ceil(bpp/8); for(var y=0; y>1) )&255; if(type==4) for(var x=bpp; x>1))&255; for(var x=bpp; x>1) )&255; } if(type==4) { for(var x= 0; x>8)&255; buff[p+1] = n&255; }, readUint : function(buff,p) { return (buff[p]*(256*256*256)) + ((buff[p+1]<<16) | (buff[p+2]<< 8) | buff[p+3]); }, writeUint : function(buff,p,n){ buff[p]=(n>>24)&255; buff[p+1]=(n>>16)&255; buff[p+2]=(n>>8)&255; buff[p+3]=n&255; }, readASCII : function(buff,p,l){ var s = ""; for(var i=0; i=0 && yoff>=0) { si = (y*sw+x)<<2; ti = (( yoff+y)*tw+xoff+x)<<2; } else { si = ((-yoff+y)*sw-xoff+x)<<2; ti = (y*tw+x)<<2; } if (mode==0) { tb[ti] = sb[si]; tb[ti+1] = sb[si+1]; tb[ti+2] = sb[si+2]; tb[ti+3] = sb[si+3]; } else if(mode==1) { var fa = sb[si+3]*(1/255), fr=sb[si]*fa, fg=sb[si+1]*fa, fb=sb[si+2]*fa; var ba = tb[ti+3]*(1/255), br=tb[ti]*ba, bg=tb[ti+1]*ba, bb=tb[ti+2]*ba; var ifa=1-fa, oa = fa+ba*ifa, ioa = (oa==0?0:1/oa); tb[ti+3] = 255*oa; tb[ti+0] = (fr+br*ifa)*ioa; tb[ti+1] = (fg+bg*ifa)*ioa; tb[ti+2] = (fb+bb*ifa)*ioa; } else if(mode==2){ // copy only differences, otherwise zero var fa = sb[si+3], fr=sb[si], fg=sb[si+1], fb=sb[si+2]; var ba = tb[ti+3], br=tb[ti], bg=tb[ti+1], bb=tb[ti+2]; if(fa==ba && fr==br && fg==bg && fb==bb) { tb[ti]=0; tb[ti+1]=0; tb[ti+2]=0; tb[ti+3]=0; } else { tb[ti]=fr; tb[ti+1]=fg; tb[ti+2]=fb; tb[ti+3]=fa; } } else if(mode==3){ // check if can be blended var fa = sb[si+3], fr=sb[si], fg=sb[si+1], fb=sb[si+2]; var ba = tb[ti+3], br=tb[ti], bg=tb[ti+1], bb=tb[ti+2]; if(fa==ba && fr==br && fg==bg && fb==bb) continue; //if(fa!=255 && ba!=0) return false; if(fa<220 && ba>20) return false; } } return true; } UPNG.encode = function(bufs, w, h, ps, dels, forbidPlte) { if(ps==null) ps=0; if(forbidPlte==null) forbidPlte = false; var nimg = UPNG.encode.compress(bufs, w, h, ps, false, forbidPlte); UPNG.encode.compressPNG(nimg, -1); return UPNG.encode._main(nimg, w, h, dels); } UPNG.encodeLL = function(bufs, w, h, cc, ac, depth, dels) { var nimg = { ctype: 0 + (cc==1 ? 0 : 2) + (ac==0 ? 0 : 4), depth: depth, frames: [] }; var bipp = (cc+ac)*depth, bipl = bipp * w; for(var i=0; i1, pltAlpha = false; var leng = 8 + (16+5+4) + (9+4) + (anim ? 20 : 0); if(nimg.ctype==3) { var dl = nimg.plte.length; for(var i=0; i>>24)!=255) pltAlpha = true; leng += (8 + dl*3 + 4) + (pltAlpha ? (8 + dl*1 + 4) : 0); } for(var j=0; j>>8)&255, b=(c>>>16)&255; data[offset+ti+0]=r; data[offset+ti+1]=g; data[offset+ti+2]=b; } offset+=dl*3; wUi(data,offset,crc(data,offset-dl*3-4,dl*3+4)); offset+=4; // crc if(pltAlpha) { wUi(data,offset, dl); offset+=4; wAs(data,offset,"tRNS"); offset+=4; for(var i=0; i>>24)&255; offset+=dl; wUi(data,offset,crc(data,offset-dl-4,dl+4)); offset+=4; // crc } } var fi = 0; for(var j=0; j>2, bln>>2)); for(var j=0; jnw && c==img32[i-nw]) ind[i]=ind[i-nw]; else { var cmc = cmap[c]; if(cmc==null) { cmap[c]=cmc=plte.length; plte.push(c); if(plte.length>=300) break; } ind[i]=cmc; } } } //console.log("make palette", Date.now()-time); time = Date.now(); } var cc=plte.length; //console.log("colors:",cc); if(cc<=256 && forbidPlte==false) { if(cc<= 2) depth=1; else if(cc<= 4) depth=2; else if(cc<=16) depth=4; else depth=8; if(forGIF) depth=8; } for(var j=0; j>1)] |= (inj[ii+x]<<(4-(x&1)*4)); else if(depth==2) for(var x=0; x>2)] |= (inj[ii+x]<<(6-(x&3)*2)); else if(depth==1) for(var x=0; x>3)] |= (inj[ii+x]<<(7-(x&7)*1)); } cimg=nimg; ctype=3; bpp=1; } else if(gotAlpha==false && frms.length==1) { // some next "reduced" frames may contain alpha for blending var nimg = new Uint8Array(nw*nh*3), area=nw*nh; for(var i=0; i palette indices", Date.now()-time); time = Date.now(); return {ctype:ctype, depth:depth, plte:plte, frames:frms }; } UPNG.encode.framize = function(bufs,w,h,forGIF,brute) { var frms = []; for(var j=0; jmax) max=x; if(ymay) may=y; } } var sarea = (max==-1) ? 1 : (max-mix+1)*(may-miy+1); if(sarea500000 && (t==2 || t==3 || t==4)) continue; for(var y=0; y>1) +256)&255; if(type==4) for(var x=bpp; x>1))&255; for(var x=bpp; x>1))&255; } if(type==4) { for(var x= 0; x>> 1); else c = c >>> 1; } tab[n] = c; } return tab; })(), update : function(c, buf, off, len) { for (var i=0; i>> 8); return c; }, crc : function(b,o,l) { return UPNG.crc.update(0xffffffff,b,o,l) ^ 0xffffffff; } } UPNG.quantize = function(abuf, ps) { var oimg = new Uint8Array(abuf), nimg = oimg.slice(0), nimg32 = new Uint32Array(nimg.buffer); var KD = UPNG.quantize.getKDtree(nimg, ps); var root = KD[0], leafs = KD[1]; var planeDst = UPNG.quantize.planeDst; var sb = oimg, tb = nimg32, len=sb.length; var inds = new Uint8Array(oimg.length>>2); for(var i=0; i>2] = nd.ind; tb[i>>2] = nd.est.rgba; } return { abuf:nimg.buffer, inds:inds, plte:leafs }; } UPNG.quantize.getKDtree = function(nimg, ps, err) { if(err==null) err = 0.0001; var nimg32 = new Uint32Array(nimg.buffer); var root = {i0:0, i1:nimg.length, bst:null, est:null, tdst:0, left:null, right:null }; // basic statistic, extra statistic root.bst = UPNG.quantize.stats( nimg,root.i0, root.i1 ); root.est = UPNG.quantize.estats( root.bst ); var leafs = [root]; while(leafs.length maxL) { maxL=leafs[i].est.L; mi=i; } if(maxL=s0 || node.i1<=s0); //console.log(maxL, leafs.length, mi); if(s0wrong) { node.est.L=0; continue; } var ln = {i0:node.i0, i1:s0, bst:null, est:null, tdst:0, left:null, right:null }; ln.bst = UPNG.quantize.stats( nimg, ln.i0, ln.i1 ); ln.est = UPNG.quantize.estats( ln.bst ); var rn = {i0:s0, i1:node.i1, bst:null, est:null, tdst:0, left:null, right:null }; rn.bst = {R:[], m:[], N:node.bst.N-ln.bst.N}; for(var i=0; i<16; i++) rn.bst.R[i] = node.bst.R[i]-ln.bst.R[i]; for(var i=0; i< 4; i++) rn.bst.m[i] = node.bst.m[i]-ln.bst.m[i]; rn.est = UPNG.quantize.estats( rn.bst ); node.left = ln; node.right = rn; leafs[mi]=ln; leafs.push(rn); } leafs.sort(function(a,b) { return b.bst.N-a.bst.N; }); for(var i=0; i0) { node0=nd.right; node1=nd.left; } var ln = UPNG.quantize.getNearest(node0, r,g,b,a); if(ln.tdst<=planeDst*planeDst) return ln; var rn = UPNG.quantize.getNearest(node1, r,g,b,a); return rn.tdst eMq) i1-=4; if(i0>=i1) break; var t = nimg32[i0>>2]; nimg32[i0>>2] = nimg32[i1>>2]; nimg32[i1>>2]=t; i0+=4; i1-=4; } while(vecDot(nimg, i0, e)>eMq) i0-=4; return i0+4; } UPNG.quantize.vecDot = function(nimg, i, e) { return nimg[i]*e[0] + nimg[i+1]*e[1] + nimg[i+2]*e[2] + nimg[i+3]*e[3]; } UPNG.quantize.stats = function(nimg, i0, i1){ var R = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; var m = [0,0,0,0]; var N = (i1-i0)>>2; for(var i=i0; i>>0) }; } UPNG.M4 = { multVec : function(m,v) { return [ m[ 0]*v[0] + m[ 1]*v[1] + m[ 2]*v[2] + m[ 3]*v[3], m[ 4]*v[0] + m[ 5]*v[1] + m[ 6]*v[2] + m[ 7]*v[3], m[ 8]*v[0] + m[ 9]*v[1] + m[10]*v[2] + m[11]*v[3], m[12]*v[0] + m[13]*v[1] + m[14]*v[2] + m[15]*v[3] ]; }, dot : function(x,y) { return x[0]*y[0]+x[1]*y[1]+x[2]*y[2]+x[3]*y[3]; }, sml : function(a,y) { return [a*y[0],a*y[1],a*y[2],a*y[3]]; } } UPNG.encode.concatRGBA = function(bufs, roundAlpha) { var tlen = 0; for(var i=0; i