UNPKG

@niivue/vox-loader

Version:

A MagicaVoxel vox image loader to be used with the NiiVue useLoader method

94 lines (91 loc) 3.07 kB
#!/usr/bin/env node // src/vox2nii.ts import * as fs from "fs/promises"; import path from "path"; import { fileURLToPath } from "url"; // 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; } } // src/vox2nii.ts import { performance } from "perf_hooks"; var __filename = fileURLToPath(import.meta.url); var __dirname = path.dirname(__filename); if (process.argv.length < 3) { console.error("Usage: node vox2nii.js <input.vox>"); process.exit(1); } var inputFile = process.argv[2]; var outputFile = inputFile.replace(/\.vox$/, ".nii"); async function convertVoxToNifti() { try { const startTime = performance.now(); const buffer = await fs.readFile(inputFile); let niftiData = await vox2nii(buffer); await fs.writeFile(outputFile, Buffer.from(niftiData.buffer)); console.log(`Saved NIfTI file: ${outputFile}`); console.log(`Converted to ${outputFile} in ${performance.now() - startTime}ms`); } catch (error) { if (error instanceof Error) { console.error("Error processing file:", error.message); } else { console.error("Error processing file:", String(error)); } } } convertVoxToNifti(); //# sourceMappingURL=vox2nii.js.map