/* COPYRIGHT Esri - https://js.arcgis.com/5.0/LICENSE.txt */
import{JSONMap as t}from"../../../core/jsonMap.js";import{mirror as e}from"./mirror.js";import o from"../../support/PixelBlock.js";const n=new t({1:"min",2:"max",3:"mean",4:"stddev",5:"median",6:"majority",7:"minority"},{useNumericKeys:!0});function s(t,e){const{fillNoDataOnly:o}=e,{band:n,width:s,height:r,mask:i,outBand:l}=t;if(o&&!i)return void l.set(n);const{statisticsType:a,kernelRows:c,kernelCols:f}=e,h="stddev"===a,u=s*r,m=new Float64Array(u),d=new Float64Array(u),y=new Uint32Array(u);for(let A=0;A<r;A++){const t=A*s;let e=0,o=0,r=0;for(let s=0;s<f;s++)i&&!i[t+s]||(e+=n[t+s],h&&(o+=n[t+s]**2),r++);m[t]=e,d[t]=o,y[t]=r;for(let l=1;l<=s-f;l++){const s=t+l-1,a=s+f;i?(i[s]&&(r--,e-=n[s],h&&(o-=n[s]**2)),i[a]&&(r++,e+=n[a],h&&(o+=n[a]**2))):(e-=n[s],e+=n[a],h&&(o-=n[s]**2,o+=n[a]**2)),m[t+l]=e,y[t+l]=r,h&&(d[t+l]=o)}}const k=new Float64Array(u),p=new Float64Array(u),w=new Uint32Array(u),M=c*s;for(let A=0;A<=s-f;A++){let t=0,e=0,o=0;for(let n=0;n<c;n++){const r=n*s+A;t+=m[r],o+=y[r],h&&(e+=d[r])}k[A]=t,p[A]=e,w[A]=o;for(let n=1;n<=r-c;n++){const r=(n-1)*s+A,i=r+M;t-=m[r],t+=m[i],o-=y[r],o+=y[i],h&&(e-=d[r],e+=d[i]),k[n*s+A]=t,p[n*s+A]=e,w[n*s+A]=o}}const g=Math.floor(c/2),b=Math.floor(f/2);for(let A=g;A<r-g;A++){const t=A*s;for(let e=b;e<s-b;e++){const n=(A-g)*s+e-b,r=w[n];if(0===r||o&&(!i||i[t+e]))continue;const a=k[n]/r,c=h?Math.sqrt((p[n]-k[n]*a)/r):a;l[t+e]=c,i&&(i[t+e]=255)}}}function r(t,e){const{fillNoDataOnly:o}=e,{band:n,width:s,height:r,mask:i,outBand:l}=t;if(o&&!i)return void l.set(n);const{kernelRows:a,kernelCols:c,statisticsType:f}=e,h=Math.floor(a/2),u=Math.floor(c/2),m="min"===f,d=l.slice(),y=new Uint32Array(s*r);for(let k=h;k<r-h;k++){const t=k*s;for(let e=u;e<s-u;e++){let o=m?Number.MAX_VALUE:-Number.MAX_VALUE,r=0;for(let l=0;l<a;l++)for(let a=0;a<c;a++){const c=t+e+(l-h)*s+a-u;i&&!i[c]||(o=m?Math.min(o,n[c]):Math.max(o,n[c]),r++)}i?(d[t+e]=0===r?0:o,y[t+e]=r):l[t+e]=0===r?0:o}}if(i)for(let k=h;k<r-h;k++){const t=k*s;for(let e=u;e<s-u;e++)if(y[t+e]){if(o&&i[t+e])continue;l[t+e]=d[t+e],i[t+e]=255}}}function i(t,e){const{fillNoDataOnly:o}=e,{band:n,width:s,height:r,mask:i,outBand:l}=t;if(o&&!i)return void l.set(n);const{kernelRows:a,kernelCols:c}=e,f=Math.floor(a/2),h=Math.floor(c/2),u=l.slice(),m=new Uint32Array(s*r);for(let d=f;d<r-f;d++){const t=d*s;for(let e=h;e<s-h;e++){if(o&&i?.[t+e])continue;const r=[];for(let o=0;o<a;o++)for(let l=0;l<c;l++){const a=t+e+(o-f)*s+l-h;i&&!i[a]||r.push(n[a])}r.length&&(r.sort((t,e)=>t-e),i?(u[t+e]=r[Math.floor((r.length-1)/2)],m[t+e]=r.length):l[t+e]=r[Math.floor((r.length-1)/2)])}}if(i)for(let d=f;d<r-f;d++){const t=d*s;for(let e=h;e<s-h;e++)if(m[t+e]){if(o&&i[t+e])continue;l[t+e]=u[t+e],i[t+e]=255}}}function l(t,e){const{fillNoDataOnly:o}=e,{band:n,width:s,height:r,mask:i,outBand:l}=t;if(o&&!i)return void l.set(n);const{kernelRows:a,kernelCols:c}=e,f=Math.floor(a/2),h=Math.floor(c/2),u="majority"===e.statisticsType,m=a*c,d=l.slice(),y=new Uint32Array(s*r);for(let k=f;k<r-f;k++){const t=k*s;for(let e=h;e<s-h;e++){if(o&&i?.[t+e])continue;const r=new Map;for(let o=0;o<a;o++)for(let l=0;l<c;l++){const a=t+e+(o-f)*s+l-h;if(i&&!i[a])continue;const c=n[a];r.set(c,r.has(c)?r.get(c)+1:1)}if(0===r.size)continue;let k=0,p=0,w=u?0:m+1;for(const t of r.keys())p=r.get(t),u===p>w&&(w=p,k=t);i?(d[t+e]=k,y[t+e]=r.size):l[t+e]=k}}if(i)for(let k=f;k<r-f;k++){const t=k*s;for(let e=h;e<s-h;e++)if(y[t+e]){if(o&&i[t+e])continue;l[t+e]=d[t+e],i[t+e]=255}}}function a(t,n){const{mask:a}=t,{fillNoDataOnly:c}=n;if(c&&!a)return t;const{pixels:f,width:h,height:u,bandMasks:m,pixelType:d}=t,y=f.length,k=h*u,p=[],{kernelRows:w,kernelCols:M,statisticsType:g,mirrorEdges:b}=n;if(c&&!a)return t;const A=n.outputPixelType??d,x=[];for(let j=0;j<y;j++){const t=f[j],d=o.createEmptyBand(A,k);c&&d.set(t);const y=m?.[j]??a,B=y?.slice()??null,N={band:t,width:h,height:u,mask:B,outBand:d};switch(g){case"min":case"max":r(N,n);break;case"mean":case"stddev":s(N,n);break;case"median":i(N,n);break;case"majority":case"minority":l(N,n)}b&&!c&&e(d,h,u,w,M),p.push(d),B&&x.push(B)}let B=x[0]??a;x.length!==y&&(x.length=0),y>1&&m?.length&&(B=o.combineBandMasks(m));const N=new o({pixelType:A,width:h,height:u,pixels:p,bandMasks:m&&x.length?x:null,mask:B});return N.updateStatistics(),N}export{a as computeFocalStatistics,n as statisticsTypeMap};
