in src/engine/loaders/voltools.js [286:345]
static scaleTextureDown(loader, pixelsSrc, xDimDst, yDimDst, zDimDst) {
const ACC_BITS = 10;
const ACC_HALF = 1 << (ACC_BITS - 1);
const xyzDimDst = xDimDst * yDimDst * zDimDst;
const pixelsDst = new Uint8Array(xyzDimDst);
const xDimSrc = loader.m_xDim;
const yDimSrc = loader.m_yDim;
const zDimSrc = loader.m_zDim;
const isCorrectDim = xDimSrc > xDimDst || yDimSrc > yDimDst || zDimSrc > zDimDst;
if (!isCorrectDim) {
return null;
}
const xyDimSrc = xDimSrc * yDimSrc;
const xStep = Math.floor((xDimSrc << ACC_BITS) / xDimDst);
const yStep = Math.floor((yDimSrc << ACC_BITS) / yDimDst);
const zStep = Math.floor((zDimSrc << ACC_BITS) / zDimDst);
let indDst = 0;
let zSrcAccL = ACC_HALF;
let zSrcAccH = zSrcAccL + zStep;
for (let zDst = 0; zDst < zDimDst; zDst++, zSrcAccL += zStep, zSrcAccH += zStep) {
const zSrcL = zSrcAccL >> ACC_BITS;
const zSrcH = zSrcAccH >> ACC_BITS;
let ySrcAccL = ACC_HALF;
let ySrcAccH = ySrcAccL + yStep;
for (let yDst = 0; yDst < yDimDst; yDst++, ySrcAccL += yStep, ySrcAccH += yStep) {
const ySrcL = ySrcAccL >> ACC_BITS;
const ySrcH = ySrcAccH >> ACC_BITS;
let xSrcAccL = ACC_HALF;
let xSrcAccH = xSrcAccL + xStep;
for (let xDst = 0; xDst < xDimDst; xDst++, xSrcAccL += xStep, xSrcAccH += xStep) {
const xSrcL = xSrcAccL >> ACC_BITS;
const xSrcH = xSrcAccH >> ACC_BITS;
// Accumulate sum
let sum = 0;
let numPixels = 0;
for (let z = zSrcL, zOff = zSrcL * xyDimSrc; z < zSrcH; z++, zOff += xyDimSrc) {
for (let y = ySrcL, yOff = ySrcL * xDimSrc; y < ySrcH; y++, yOff += xDimSrc) {
for (let x = xSrcL; x < xSrcH; x++) {
const offSrc = x + yOff + zOff;
sum += pixelsSrc[offSrc];
numPixels++;
} // for (x)
} // for (y)
} // for (z)
sum = Math.floor(sum / numPixels);
pixelsDst[indDst++] = sum;
} // for (xDst)
} // for (yDst)
} // for (zDst)
loader.m_xDim = xDimDst;
loader.m_yDim = yDimDst;
loader.m_zDim = zDimDst;
return pixelsDst;
} // end of scaleTextureDown