import ImageRegion from './ImageRegion.mjs'; export function makeGaussianKernel(size) { const sz = Math.ceil(size * 3); const kernel = new Float32Array(sz * 2 + 1); const norm = 1 / (size * Math.sqrt(Math.PI * 2)); const expNorm = -0.5 / (size * size); for(let i = -sz; i <= sz; ++ i) { kernel[i + sz] = Math.exp(i * i * expNorm) * norm; } return {kernel, sz}; } export function blur1D(region, size, {target = null} = {}) { const tgt = region.checkOrMakeTarget(target); const {width, height, stepX, stepY, dim} = region; const {kernel, sz} = makeGaussianKernel(size); for(let x = 0; x < width; ++ x) { const i0 = -Math.min(sz, x); const i1 = Math.min(sz, width - x); for(let d = 0; d < dim; ++ d) { const psx = region.indexOf(x, 0, d); const ptx = tgt.indexOf(x, 0, d); for(let y = 0; y < height; ++ y) { const ps = psx + y * stepY; let accum = 0; for(let i = i0; i < i1; ++ i) { accum += region.values[ps + i * stepX] * kernel[i + sz]; } tgt.values[ptx + y * tgt.stepY] = accum; } } } return tgt; } export function blur2D(region, size, {target = null, temp = null} = {}) { const tgt = region.checkOrMakeTarget(target); const tmp = blur1D(region, size, {target: temp}); blur1D(tmp.transposed(), size, {target: tgt.transposed()}); return tgt; } ImageRegion.prototype.blur = function(size, options) { return blur2D(this, size, options); };