@niivue/vox-loader
Version: 
A MagicaVoxel vox image loader to be used with the NiiVue useLoader method
62 lines • 2 kB
JavaScript
// src/lib/loader.ts
import readVox from "vox-reader";
import * as nifti from "nifti-reader-js";
async function vox2nii(inBuffer, isVerbose = true) {
  try {
    let byteArray;
    if (inBuffer instanceof Uint8Array) {
      byteArray = inBuffer;
    } else if (inBuffer instanceof ArrayBuffer) {
      byteArray = new Uint8Array(inBuffer);
    } else {
      throw new Error("Unsupported input type: Expected Uint8Array or ArrayBuffer.");
    }
    console.log("here");
    const vox = readVox(byteArray);
    if (!vox || !vox.size || !vox.xyzi?.values || !vox.rgba?.values) {
      throw new Error("Invalid or empty MagicaVoxel file.");
    }
    const { x: width, y: height, z: depth } = vox.size;
    if (isVerbose) {
      console.log(`Loaded MagicaVoxel: ${width}x${height}x${depth}`);
    }
    const voxelData = new Uint8Array(width * height * depth * 4).fill(0);
    for (const voxel of vox.xyzi.values) {
      const { x, y, z, i } = voxel;
      const color = vox.rgba.values[i];
      if (color) {
        const index = (x + y * width + z * width * height) * 4;
        voxelData[index] = color.r;
        voxelData[index + 1] = color.g;
        voxelData[index + 2] = color.b;
        voxelData[index + 3] = color.a;
      }
    }
    const hdr = new nifti.NIFTI1();
    hdr.littleEndian = true;
    hdr.dims[0] = 3;
    hdr.dims[1] = width;
    hdr.dims[2] = height;
    hdr.dims[3] = depth;
    hdr.datatypeCode = 2304;
    hdr.numBitsPerVoxel = 32;
    hdr.pixDims = [1, 1, 1, 1, 1, 0, 0, 0];
    hdr.vox_offset = 352;
    hdr.scl_slope = 1;
    hdr.scl_inter = 0;
    hdr.qform_code = 0;
    hdr.sform_code = 0;
    hdr.magic = "n+1";
    const hdrBuffer = hdr.toArrayBuffer();
    const niftiData = new Uint8Array(hdrBuffer.byteLength + voxelData.byteLength);
    niftiData.set(new Uint8Array(hdrBuffer), 0);
    niftiData.set(voxelData, hdrBuffer.byteLength);
    return niftiData;
  } catch (error) {
    throw error;
  }
}
export {
  vox2nii
};
//# sourceMappingURL=loader.js.map