1
0
mirror of https://github.com/kettek/png-js synced 2025-03-14 06:24:30 -07:00
png-js/dist/png-js.es.min.js
2020-01-14 19:46:10 -08:00

2 lines
5.4 KiB
JavaScript

import fs from"fs";import zlib from"zlib";import{promisify}from"util";var range=function(t,e,i){for(var a=[],r=t<e,s=i?r?e+1:e-1:e,h=t;r?h<s:h>s;r?h++:h--)a.push(h);return a},classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},createClass=function(){function t(t,e){for(var i=0;i<e.length;i++){var a=e[i];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(t,a.key,a)}}return function(e,i,a){return i&&t(e.prototype,i),a&&t(e,a),e}}(),toConsumableArray=function(t){if(Array.isArray(t)){for(var e=0,i=Array(t.length);e<t.length;e++)i[e]=t[e];return i}return Array.from(t)},inflateAsync=promisify(zlib.inflate),readFileAsync=promisify(fs.readFile),IndexedPNG=function(){function t(e){classCallCheck(this,t),this.data=e,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.text={},this.process()}return createClass(t,[{key:"process",value:function(){for(var t=this,e=void 0;;){var i,a=this.readUInt32();switch(function(){var i=[];for(e=0;e<4;e++)i.push(String.fromCharCode(t.data[t.pos++]));return i}().join("")){case"IHDR":this.width=this.readUInt32(),this.height=this.readUInt32(),this.bits=this.data[this.pos++],this.colorType=this.data[this.pos++],this.compressionMethod=this.data[this.pos++],this.filterMethod=this.data[this.pos++],this.interlaceMethod=this.data[this.pos++];break;case"PLTE":this.palette=this.read(a);break;case"IDAT":for(e=0,i=a;e<i;e++)this.imgData.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:this.transparency.indexed=this.read(a);var r,s,h=this.transparency.indexed.length-1;if(h>0)for(e=0,r=0<=(s=h);r?e<s:e>s;r?e++:e--)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(a)[0];break;case 2:this.transparency.rgb=this.read(a)}break;case"tEXt":var o=this.read(a),n=o.indexOf(0),c=String.fromCharCode.apply(String,toConsumableArray(Array.from(o.slice(0,n)||[])));this.text[c]=String.fromCharCode.apply(String,toConsumableArray(Array.from(o.slice(n+1)||[])));break;case"IEND":this.colors=function(){switch(t.colorType){case 0:case 3:case 4:return 1;case 2:case 6:return 3}}(),this.hasAlphaChannel=[4,6].includes(this.colorType);var l=this.colors+(this.hasAlphaChannel?1:0);return this.pixelBitlength=this.bits*l,this.colorSpace=function(){switch(t.colors){case 1:return"DeviceGray";case 3:return"DeviceRGB"}}(),void(this.imgData=Buffer.from(this.imgData));default:this.pos+=a}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt IndexedPNG file")}}},{key:"read",value:function(t){var e=this;return range(0,t,!1).map(function(t){return e.data[e.pos++]})}},{key:"readUInt32",value:function(){return this.data[this.pos++]<<24|this.data[this.pos++]<<16|this.data[this.pos++]<<8|this.data[this.pos++]}},{key:"readUInt16",value:function(){return this.data[this.pos++]<<8|this.data[this.pos++]}},{key:"decodePixels",value:async function(){var t=void 0;try{t=await inflateAsync(this.imgData)}catch(t){throw t}for(var e=this.pixelBitlength/8,i=e*this.width,a=Buffer.allocUnsafe(i*this.height),r=t.length,s=0,h=0,o=0;h<r;){var n,c,l,d,p,f,u,y,w,v;switch(t[h++]){case 0:for(l=0,f=i;l<f;l++)a[o++]=t[h++];break;case 1:for(l=0,u=i;l<u;l++)n=t[h++],d=l<e?0:a[o-e],a[o++]=(n+d)%256;break;case 2:for(l=0,y=i;l<y;l++)n=t[h++],c=(l-l%e)/e,p=s&&a[(s-1)*i+c*e+l%e],a[o++]=(p+n)%256;break;case 3:for(l=0,w=i;l<w;l++)n=t[h++],c=(l-l%e)/e,d=l<e?0:a[o-e],p=s&&a[(s-1)*i+c*e+l%e],a[o++]=(n+Math.floor((d+p)/2))%256;break;case 4:for(l=0,v=i;l<v;l++){var g,m;n=t[h++],c=(l-l%e)/e,d=l<e?0:a[o-e],0===s?p=m=0:(p=a[(s-1)*i+c*e+l%e],m=c&&a[(s-1)*i+(c-1)*e+l%e]);var b=d+p-m,x=Math.abs(b-d),k=Math.abs(b-p),C=Math.abs(b-m);g=x<=k&&x<=C?d:k<=C?p:m,a[o++]=(n+g)%256}break;default:throw new Error("Invalid filter algorithm: "+t[h-1])}s++}return a}},{key:"decodePalette",value:function(){for(var t=this.palette,e=this.transparency.indexed||[],i=Buffer.allocUnsafe(t.length/3*4),a=0,r=(t.length,0),s=0,h=t.length;s<h;s+=3){var o;i[a++]=t[s],i[a++]=t[s+1],i[a++]=t[s+2],i[a++]=null!=(o=e[r++])?o:255}return i}},{key:"toPNGData",value:async function(t){var e=t.palette||this.decodedPalette;if(this.decodedPixels||await this.decode(),t.clip){if(void 0==t.clip.x&&(t.clip.x=0),void 0==t.clip.y&&(t.clip.y=0),void 0==t.clip.w&&(t.clip.w=this.width-t.clip.x),void 0==t.clip.h&&(t.clip.h=this.height-t.clip.y),t.clip.x<0||t.clip.x>=this.width)throw new Error("clip.x is out of bounds");if(t.clip.y<0||t.clip.y>=this.height)throw new Error("clip.y is out of bounds");if(t.clip.w<=0||t.clip.w>this.width)throw new Error("clip.w is out of bounds");if(t.clip.h<=0||t.clip.h>this.height)throw new Error("clip.h is out of bounds");for(var i=new Uint8ClampedArray(t.clip.w*t.clip.h*4),a=0;a<t.clip.w;a++)for(var r=0;r<t.clip.h;r++){var s=4*(a+r*t.clip.w),h=4*this.decodedPixels[a+t.clip.x+(r+t.clip.y)*this.width];i[s++]=e[h],i[s++]=e[h+1],i[s++]=e[h+2],i[s++]=e[h+3]}return{pixels:i,width:t.clip.w}}for(var o=new Uint8ClampedArray(4*this.decodedPixels.length),n=0,c=0;c<this.decodedPixels.length;c++){var l=4*this.decodedPixels[c];o[n++]=e[l],o[n++]=e[l+1],o[n++]=e[l+2],o[n++]=e[l+3]}return{pixels:o,width:this.width}}},{key:"toImageData",value:async function(t){var e=await this.toPNGData(t);return new ImageData(e.pixels,e.width)}},{key:"decode",value:async function(){this.decodedPalette=this.decodePalette(),this.decodedPixels=await this.decodePixels()}}]),t}();export default IndexedPNG;