dist-mcp / fpzip / decompress.js
dist-mcp / fpzip / decompress.js
import fpzipModule from './fpzip_loader.js';
let _fpzip = null;
async function loadFpzip() {
if (!_fpzip)
_fpzip = await fpzipModule();
return _fpzip;
}
export async function decompress(data) {
const fpzip = await loadFpzip();
let inputPtr = null;
let headerPtr = null;
let outputPtr = null;
try {
// Allocate memory for the input data
inputPtr = fpzip._malloc(data.length);
fpzip.HEAPU8.set(data, inputPtr);
// Extract header (type/prec/dims) so we can size the output buffer.
headerPtr = fpzip._malloc(6 * 4);
const outTypePtr = headerPtr + 0 * 4;
const outPrecPtr = headerPtr + 1 * 4;
const outNxPtr = headerPtr + 2 * 4;
const outNyPtr = headerPtr + 3 * 4;
const outNzPtr = headerPtr + 4 * 4;
const outNfPtr = headerPtr + 5 * 4;
const headerOk = fpzip._fpzip_get_header(inputPtr, outTypePtr, outPrecPtr, outNxPtr, outNyPtr, outNzPtr, outNfPtr);
if (!headerOk) {
throw new Error(`Failed to read fpzip header (errno=${fpzip._fpzip_errno_code()})`);
}
const heap32 = new Int32Array(fpzip.HEAPU8.buffer);
const base = headerPtr >> 2;
const type = heap32[base + 0];
const nx = heap32[base + 2];
const ny = heap32[base + 3];
const nz = heap32[base + 4];
const nf = heap32[base + 5];
if (type !== 0) {
throw new Error(`fpzip stream is not float32 (type=${type})`);
}
const nValues = nx * ny * nz * nf;
const outBytes = nValues * 4;
outputPtr = fpzip._malloc(outBytes);
const bytesRead = fpzip._fpzip_decompress_f32(inputPtr, outputPtr);
if (!bytesRead) {
throw new Error(`Failed to decompress fpzip stream: ${fpzip._fpzip_errno_code()}`);
}
const floats = new Float32Array(nValues);
floats.set(new Float32Array(fpzip.HEAPU8.buffer, outputPtr, nValues));
return floats;
}
finally {
if (inputPtr !== null)
fpzip._free(inputPtr);
if (headerPtr !== null)
fpzip._free(headerPtr);
if (outputPtr !== null)
fpzip._free(outputPtr);
}
}
export async function compress(data, precBits = 0, dims) {
const fpzip = await loadFpzip();
let inputPtr = null;
let outputPtr = null;
try {
inputPtr = fpzip._malloc(data.length * 4);
new Float32Array(fpzip.HEAPU8.buffer).set(data, inputPtr >> 2);
// Start with a conservative cap; fpzip should typically compress, but in worst
// case it can slightly expand due to headers.
let cap = Math.max(256, data.length * 4 + 1024);
for (let attempt = 0; attempt < 8; attempt++) {
if (outputPtr !== null)
fpzip._free(outputPtr);
outputPtr = fpzip._malloc(cap);
let bytesWritten;
if (dims) {
// NNC-compatible compression with proper tensor dimensions
// NNC sets: nx=dims[last], ny=dims[last-1], nz=dims[last-2]
// For [height, width, channels]: nx=channels, ny=width, nz=height
bytesWritten = fpzip._fpzip_compress_f32_dims(inputPtr, dims.nx, dims.ny, dims.nz, dims.nf ?? 1, precBits, outputPtr, cap);
}
else {
// Legacy flattened mode
bytesWritten = fpzip._fpzip_compress_f32(inputPtr, data.length, precBits, outputPtr, cap);
}
if (bytesWritten > 0) {
const out = new Uint8Array(bytesWritten);
out.set(fpzip.HEAPU8.subarray(outputPtr, outputPtr + bytesWritten));
return out;
}
// Retry with a larger buffer if we overflowed.
cap *= 2;
}
throw new Error(`Failed to compress fpzip stream after retries: ${fpzip._fpzip_errno_code()}`);
}
finally {
if (inputPtr !== null)
fpzip._free(inputPtr);
if (outputPtr !== null)
fpzip._free(outputPtr);
}
}
import fpzipModule from './fpzip_loader.js';
let _fpzip = null;
async function loadFpzip() {
if (!_fpzip)
_fpzip = await fpzipModule();
return _fpzip;
}
export async function decompress(data) {
const fpzip = await loadFpzip();
let inputPtr = null;
let headerPtr = null;
let outputPtr = null;
try {
// Allocate memory for the input data
inputPtr = fpzip._malloc(data.length);
fpzip.HEAPU8.set(data, inputPtr);
// Extract header (type/prec/dims) so we can size the output buffer.
headerPtr = fpzip._malloc(6 * 4);
const outTypePtr = headerPtr + 0 * 4;
const outPrecPtr = headerPtr + 1 * 4;
const outNxPtr = headerPtr + 2 * 4;
const outNyPtr = headerPtr + 3 * 4;
const outNzPtr = headerPtr + 4 * 4;
const outNfPtr = headerPtr + 5 * 4;
const headerOk = fpzip._fpzip_get_header(inputPtr, outTypePtr, outPrecPtr, outNxPtr, outNyPtr, outNzPtr, outNfPtr);
if (!headerOk) {
throw new Error(`Failed to read fpzip header (errno=${fpzip._fpzip_errno_code()})`);
}
const heap32 = new Int32Array(fpzip.HEAPU8.buffer);
const base = headerPtr >> 2;
const type = heap32[base + 0];
const nx = heap32[base + 2];
const ny = heap32[base + 3];
const nz = heap32[base + 4];
const nf = heap32[base + 5];
if (type !== 0) {
throw new Error(`fpzip stream is not float32 (type=${type})`);
}
const nValues = nx * ny * nz * nf;
const outBytes = nValues * 4;
outputPtr = fpzip._malloc(outBytes);
const bytesRead = fpzip._fpzip_decompress_f32(inputPtr, outputPtr);
if (!bytesRead) {
throw new Error(`Failed to decompress fpzip stream: ${fpzip._fpzip_errno_code()}`);
}
const floats = new Float32Array(nValues);
floats.set(new Float32Array(fpzip.HEAPU8.buffer, outputPtr, nValues));
return floats;
}
finally {
if (inputPtr !== null)
fpzip._free(inputPtr);
if (headerPtr !== null)
fpzip._free(headerPtr);
if (outputPtr !== null)
fpzip._free(outputPtr);
}
}
export async function compress(data, precBits = 0, dims) {
const fpzip = await loadFpzip();
let inputPtr = null;
let outputPtr = null;
try {
inputPtr = fpzip._malloc(data.length * 4);
new Float32Array(fpzip.HEAPU8.buffer).set(data, inputPtr >> 2);
// Start with a conservative cap; fpzip should typically compress, but in worst
// case it can slightly expand due to headers.
let cap = Math.max(256, data.length * 4 + 1024);
for (let attempt = 0; attempt < 8; attempt++) {
if (outputPtr !== null)
fpzip._free(outputPtr);
outputPtr = fpzip._malloc(cap);
let bytesWritten;
if (dims) {
// NNC-compatible compression with proper tensor dimensions
// NNC sets: nx=dims[last], ny=dims[last-1], nz=dims[last-2]
// For [height, width, channels]: nx=channels, ny=width, nz=height
bytesWritten = fpzip._fpzip_compress_f32_dims(inputPtr, dims.nx, dims.ny, dims.nz, dims.nf ?? 1, precBits, outputPtr, cap);
}
else {
// Legacy flattened mode
bytesWritten = fpzip._fpzip_compress_f32(inputPtr, data.length, precBits, outputPtr, cap);
}
if (bytesWritten > 0) {
const out = new Uint8Array(bytesWritten);
out.set(fpzip.HEAPU8.subarray(outputPtr, outputPtr + bytesWritten));
return out;
}
// Retry with a larger buffer if we overflowed.
cap *= 2;
}
throw new Error(`Failed to compress fpzip stream after retries: ${fpzip._fpzip_errno_code()}`);
}
finally {
if (inputPtr !== null)
fpzip._free(inputPtr);
if (outputPtr !== null)
fpzip._free(outputPtr);
}
}