UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

6 lines (5 loc) • 13.3 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.33/esri/copyright.txt for details. */ import t from"../../../core/Error.js";import{assertIsSome as e}from"../../../core/maybe.js";import a from"../PixelBlock.js";import{SimpleBandStatistics as i}from"../SimpleBandStatistics.js";import s from"./ImageCanvasDecoder.js";import r from"./JpgPlus.js";import{load as n,decode as o}from"./Lerc.js";import{decode as h}from"./Lzw.js";import{convertNoDataToMask as c}from"./pixelRangeUtils.js";import{Z as l}from"../../../chunks/Zlib.js";import p from"./Raw.js";import{decodeTileOrStrip as d,decode as u}from"./TiffDecoder.js";import{isPlatformLittleEndian as f}from"./utils.js";var m=function(t){var e,a,i,s,r,n;function o(t){var e,a,i,s,r,n,o,h,c,l,p,d,u;for(this.data=t,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.animation=null,this.text={},r=null;;){switch(e=this.readUInt32(),h=function(){var t,e;for(e=[],t=0;t<4;++t)e.push(String.fromCharCode(this.data[this.pos++]));return e}.call(this).join(""),h){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"acTL":this.animation={numFrames:this.readUInt32(),numPlays:this.readUInt32()||1/0,frames:[]};break;case"PLTE":this.palette=this.read(e);break;case"fcTL":r&&this.animation.frames.push(r),this.pos+=4,r={width:this.readUInt32(),height:this.readUInt32(),xOffset:this.readUInt32(),yOffset:this.readUInt32()},s=this.readUInt16(),i=this.readUInt16()||100,r.delay=1e3*s/i,r.disposeOp=this.data[this.pos++],r.blendOp=this.data[this.pos++],r.data=[];break;case"IDAT":case"fdAT":for("fdAT"===h&&(this.pos+=4,e-=4),t=(null!=r?r.data:void 0)||this.imgData,p=0;0<=e?p<e:p>e;0<=e?++p:--p)t.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:if(this.transparency.indexed=this.read(e),(c=255-this.transparency.indexed.length)>0)for(d=0;0<=c?d<c:d>c;0<=c?++d:--d)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(e)[0];break;case 2:this.transparency.rgb=this.read(e)}break;case"tEXt":n=(l=this.read(e)).indexOf(0),o=String.fromCharCode.apply(String,l.slice(0,n)),this.text[o]=String.fromCharCode.apply(String,l.slice(n+1));break;case"IEND":return r&&this.animation.frames.push(r),this.colors=function(){switch(this.colorType){case 0:case 3:case 4:return 1;case 2:case 6:return 3}}.call(this),this.hasAlphaChannel=4===(u=this.colorType)||6===u,a=this.colors+(this.hasAlphaChannel?1:0),this.pixelBitlength=this.bits*a,this.colorSpace=function(){switch(this.colors){case 1:return"DeviceGray";case 3:return"DeviceRGB"}}.call(this),void(this.imgData=new Uint8Array(this.imgData));default:this.pos+=e}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}return o.load=function(t,e,a){var i;return"function"==typeof e&&(a=e),(i=new XMLHttpRequest).open("GET",t,!0),i.responseType="arraybuffer",i.onload=function(){var t;return t=new o(new Uint8Array(i.response||i.mozResponseArrayBuffer)),"function"==typeof(null!=e?e.getContext:void 0)&&t.render(e),"function"==typeof a?a(t):void 0},i.send(null)},a=1,i=2,e=0,o.prototype.read=function(t){var e,a;for(a=[],e=0;0<=t?e<t:e>t;0<=t?++e:--e)a.push(this.data[this.pos++]);return a},o.prototype.readUInt32=function(){return this.data[this.pos++]<<24|this.data[this.pos++]<<16|this.data[this.pos++]<<8|this.data[this.pos++]},o.prototype.readUInt16=function(){return this.data[this.pos++]<<8|this.data[this.pos++]},o.prototype.decodePixels=function(t){var e,a,i,s,r,n,o,h,c,p,d,u,f,m,g,w,y,x,b,k,T,I,A;if(null==t&&(t=this.imgData),0===t.length)return new Uint8Array(0);for(t=(t=new l(t)).getBytes(),w=(u=this.pixelBitlength/8)*this.width,f=new Uint8Array(w*this.height),n=t.length,g=0,m=0,a=0;m<n;){switch(t[m++]){case 0:for(s=b=0;b<w;s=b+=1)f[a++]=t[m++];break;case 1:for(s=k=0;k<w;s=k+=1)e=t[m++],r=s<u?0:f[a-u],f[a++]=(e+r)%256;break;case 2:for(s=T=0;T<w;s=T+=1)e=t[m++],i=(s-s%u)/u,y=g&&f[(g-1)*w+i*u+s%u],f[a++]=(y+e)%256;break;case 3:for(s=I=0;I<w;s=I+=1)e=t[m++],i=(s-s%u)/u,r=s<u?0:f[a-u],y=g&&f[(g-1)*w+i*u+s%u],f[a++]=(e+Math.floor((r+y)/2))%256;break;case 4:for(s=A=0;A<w;s=A+=1)e=t[m++],i=(s-s%u)/u,r=s<u?0:f[a-u],0===g?y=x=0:(y=f[(g-1)*w+i*u+s%u],x=i&&f[(g-1)*w+(i-1)*u+s%u]),o=r+y-x,h=Math.abs(o-r),p=Math.abs(o-y),d=Math.abs(o-x),c=h<=p&&h<=d?r:p<=d?y:x,f[a++]=(e+c)%256;break;default:throw new Error("Invalid filter algorithm: "+t[m-1])}g++}return f},o.prototype.decodePalette=function(){var t,e,a,i,s,r,n,o,h;for(a=this.palette,r=this.transparency.indexed||[],s=new Uint8Array((r.length||0)+a.length),i=0,a.length,t=0,e=n=0,o=a.length;n<o;e=n+=3)s[i++]=a[e],s[i++]=a[e+1],s[i++]=a[e+2],s[i++]=null!=(h=r[t++])?h:255;return s},o.prototype.copyToImageData=function(t,e){var a,i,s,r,n,o,h,c,l,p,d;if(i=this.colors,l=null,a=this.hasAlphaChannel,this.palette.length&&(l=null!=(d=this._decodedPalette)?d:this._decodedPalette=this.decodePalette(),i=4,a=!0),c=(s=t.data||t).length,n=l||e,r=o=0,1===i)for(;r<c;)h=l?4*e[r/4]:o,p=n[h++],s[r++]=p,s[r++]=p,s[r++]=p,s[r++]=a?n[h++]:this.transparency.grayscale&&this.transparency.grayscale===p?0:255,o=h;else for(;r<c;)h=l?4*e[r/4]:o,s[r++]=n[h++],s[r++]=n[h++],s[r++]=n[h++],s[r++]=a?n[h++]:this.transparency.rgb&&this.transparency.rgb[1]===n[h-3]&&this.transparency.rgb[3]===n[h-2]&&this.transparency.rgb[5]===n[h-1]?0:255,o=h},o.prototype.decode=function(){var t;return t=new Uint8Array(this.width*this.height*4),this.copyToImageData(t,this.decodePixels()),t},r=t.document&&t.document.createElement("canvas"),n=r&&r.getContext("2d"),s=function(t){var e;return n.width=t.width,n.height=t.height,n.clearRect(0,0,t.width,t.height),n.putImageData(t,0,0),(e=new Image).src=r.toDataURL(),e},o.prototype.decodeFrames=function(t){var e,a,i,r,n,o,h,c;if(this.animation){for(c=[],a=n=0,o=(h=this.animation.frames).length;n<o;a=++n)e=h[a],i=t.createImageData(e.width,e.height),r=this.decodePixels(new Uint8Array(e.data)),this.copyToImageData(i,r),e.imageData=i,c.push(e.image=s(i));return c}},o.prototype.renderFrame=function(t,s){var r,n,o;return r=(n=this.animation.frames)[s],o=n[s-1],0===s&&t.clearRect(0,0,this.width,this.height),(null!=o?o.disposeOp:void 0)===a?t.clearRect(o.xOffset,o.yOffset,o.width,o.height):(null!=o?o.disposeOp:void 0)===i&&t.putImageData(o.imageData,o.xOffset,o.yOffset),r.blendOp===e&&t.clearRect(r.xOffset,r.yOffset,r.width,r.height),t.drawImage(r.image,r.xOffset,r.yOffset)},o.prototype.animate=function(t){var e,a,i,s,r,n,o=this;return a=0,n=this.animation,s=n.numFrames,i=n.frames,r=n.numPlays,(e=function(){var n,h;if(n=a++%s,h=i[n],o.renderFrame(t,n),s>1&&a/s<r)return o.animation._timeout=setTimeout(e,h.delay)})()},o.prototype.stopAnimation=function(){var t;return clearTimeout(null!=(t=this.animation)?t._timeout:void 0)},o.prototype.render=function(t){var e,a;return t._png&&t._png.stopAnimation(),t._png=this,t.width=this.width,t.height=this.height,e=t.getContext("2d"),this.animation?(this.decodeFrames(e),this.animate(e)):(a=e.createImageData(this.width,this.height),this.copyToImageData(a,this.decodePixels()),e.putImageData(a,0,0))},o}(self);const g=new Set(["jpg","png","bmp","gif"]);async function w(e,s){if(!f)throw new t("rasterCoded:decode","lerc decoder is not supported on big endian platform");await n();const{offset:r}=s,{width:h,height:c,pixelType:l,statistics:p,depthCount:d,noDataValues:u,bandMasks:m,pixels:g,mask:w}=o(e,{inputOffset:r,returnInterleaved:s.returnInterleaved}),y=new a({width:h,height:c,pixelType:l.toLowerCase(),pixels:g,mask:w,statistics:p.map((({minValue:t,maxValue:e})=>new i(t,e))),bandMasks:m,depthCount:d,noDataValues:u});return p?.length||y.updateStatistics(),y}async function y(t,i){const s=await u(t,{...i,noDataValue:i.tiffNoDataValue,matchAllNoData:i.matchAllNoData});e(s);const r=new a({width:s.width,height:s.height,pixels:s.pixels,pixelType:s.pixelType.toLowerCase(),mask:s.mask,bandMasks:s.bandMasks,statistics:null});return r.updateStatistics(),r}async function x(t,e){const i=await d(t,e.customOptions),s=new a({width:i.width,height:i.height,pixels:i.pixels,pixelType:i.pixelType.toLowerCase(),mask:i.mask,statistics:null});return s.updateStatistics(),s}function b(t,e){const i=e.pixelType||"u8",s=a.getPixelArrayConstructor(i),r="u8"===i?t:new s(t.buffer),n=[],o=e.planes||1;if(1===o)n.push(r);else for(let a=0;a<o;a++){const i=(e.width||1)*(e.height||t.length),h=new s(i);for(let t=0;t<i;t++)h[t]=r[t*o+a];n.push(h)}const h=new a({width:e.width||1,height:e.height||t.length,pixels:n,pixelType:i,statistics:null});return h.updateStatistics(),h}function k(t,e){return b(new l(new Uint8Array(t)).getBytes(),e)}function T(t,e){return b(h(t,e.offset,e.eof,!e.isInputBigEndian),e)}function I(t,e,i){const{pixelTypeCtor:s}=S(e.pixelType),r=(0,p.decode)(t,{width:e.width,height:e.height,pixelType:s,format:i}),n=new a({width:e.width,height:e.height,pixels:r.pixels,pixelType:e.pixelType,mask:r.mask,statistics:null});return n.updateStatistics(),n}function A(t,e){const i=r.decode(t,e.hasNoZlibMask??void 0),s=new a({width:i.width,height:i.height,pixels:i.pixels,pixelType:"u8",mask:i.mask,statistics:null});return s.updateStatistics(),s}function C(t,e){const i=new Uint8Array(t),s=new m(i),{width:r,height:n}=e,o=r*n,h=s.decode();let c,l=0,p=0;const d=new Uint8Array(o);for(l=0;l<o;l++)d[l]=h[4*l+3];const u=new a({width:r,height:n,pixels:[],pixelType:"u8",mask:d,statistics:[]});for(l=0;l<3;l++){for(c=new Uint8Array(o),p=0;p<o;p++)c[p]=h[4*p+l];u.addData({pixels:c})}return u.updateStatistics(),u}async function v(t,e,i,r){const n=new s,o={applyJpegMask:!1,format:e,...i},h=await n.decode(t,o,r),c=new a(h);return c.updateStatistics(),c}function D(e){if(null==e)throw new t("rasterCodec:decode","parameter encodeddata is required.");const a=new Uint8Array(e,0,10);let i="";return 255===a[0]&&216===a[1]?i="jpg":137===a[0]&&80===a[1]&&78===a[2]&&71===a[3]?i="png":67===a[0]&&110===a[1]&&116===a[2]&&90===a[3]&&73===a[4]&&109===a[5]&&97===a[6]&&103===a[7]&&101===a[8]&&32===a[9]?i="lerc":76===a[0]&&101===a[1]&&114===a[2]&&99===a[3]&&50===a[4]&&32===a[5]?i="lerc2":73===a[0]&&73===a[1]&&42===a[2]&&0===a[3]||77===a[0]&&77===a[1]&&0===a[2]&&42===a[3]||73===a[0]&&73===a[1]&&43===a[2]&&0===a[3]||77===a[0]&&77===a[1]&&0===a[2]&&43===a[3]?i="tiff":71===a[0]&&73===a[1]&&70===a[2]?i="gif":66===a[0]&&77===a[1]?i="bmp":String.fromCharCode.apply(null,a).toLowerCase().includes("error")&&(i="error"),i}function U(e){let a=null;switch(e){case"lerc":case"lerc2":a=w;break;case"jpg":a=A;break;case"png":a=C;break;case"bsq":case"bip":a=(t,a)=>I(t,a,e);break;case"tiff":a=y;break;case"deflate":a=k;break;case"lzw":a=T;break;case"error":a=()=>{throw new t("rasterCodec:decode","input data contains error")};break;default:a=()=>{throw new t("rasterCodec:decode","unsupported raster format")}}return a}function S(t){let e=null,a=null;switch(t?t.toLowerCase():"f32"){case"u1":case"u2":case"u4":case"u8":a=255,e=Uint8Array;break;case"u16":a=a||65535,e=Uint16Array;break;case"u32":a=a||2**32-1,e=Uint32Array;break;case"s8":a=a||-128,e=Int8Array;break;case"s16":a=a||-32768,e=Int16Array;break;case"s32":a=a||0-2**31,e=Int32Array;break;default:e=Float32Array}return{pixelTypeCtor:e,noDataValue:a}}function O(t,e=1){if(!t)return;const{pixels:i,width:s,height:r,mask:n}=t;if(!i||0===i.length)return;const o=i.length,h=s-1,c=r-1,l=[];let p,d,u,f,m,g,w=null;const y=a.getPixelArrayConstructor(t.pixelType);if(0===e){for(p=0;p<o;p++){for(m=i[p],g=new y(h*c),d=0;d<c;d++)for(f=d*s,u=0;u<h;u++)g[d*h+u]=m[f+u];l.push(g)}if(null!=n)for(w=new Uint8Array(h*c),d=0;d<c;d++)for(f=d*s,u=0;u<h;u++)w[d*h+u]=n[f+u]}else{for(p=0;p<o;p++){for(m=i[p],g=new y(h*c),d=0;d<c;d++)for(f=d*s,u=0;u<h;u++)g[d*h+u]=(m[f+u]+m[f+u+1]+m[f+s+u]+m[f+s+u+1])/4;l.push(g)}if(n)for(w=new Uint8Array(h*c),d=0;d<c;d++)for(f=d*s,u=0;u<h;u++)w[d*h+u]=Math.min.apply(null,[n[f+u],n[f+u+1],n[f+s+u],n[f+s+u+1]])}t.width=h,t.height=c,t.mask=w,t.pixels=l}function P(t){let e=D(t);return"lerc2"===e?e="lerc":"error"===e&&(e=""),e}async function j(e,i={},s){if(null==e)throw new t("rasterCodec:decode","missing encodeddata parameter.");let r=i.format?.toLowerCase();if(!("bsq"!==r&&"bip"!==r||null!=i.width&&null!=i.height))throw new t("rasterCodec:decode","requires width and height in options parameter.");if("tiff"===r&&i.customOptions)return x(e,i);if((!r||"bsq"!==r&&"bip"!==r&&"deflate"!==r&&"lzw"!==r)&&(r=D(e)),i.useCanvas&&g.has(r))return v(e,r,i,s);const n=U(r);let o;i.isPoint&&(null!=(i={...i}).width&&i.width++,null!=i.height&&i.height++);const{offsets:h}=i;if(h&&h.length>1){const t=h.map(((t,a)=>n(e.slice(t,h[a+1]),i))),s=await Promise.all(t);o=s[0],o.pixels=s.map((t=>t.pixels[0]));const r=s.map((t=>t.mask));s.some((t=>null!=t))&&(r.forEach(((t,e)=>{null==t&&(r[e]=new Uint8Array(o.width*o.height).fill(255))})),o.bandMasks=r,o.mask=a.combineBandMasks(r)),o.updateStatistics()}else o=await n(e,{...i,offset:h?.[0]??i.offset});return"jpg"!==r&&null!=i.noDataValue&&1===o.depthCount&&c(o,i.noDataValue,{customFloatTolerance:i.tolerance}),i.isPoint&&O(o),o}export{j as decode,P as getFormat};