class npyjs { constructor(opts) { if (opts && !('convertFloat16' in opts)) { console.warn([ "npyjs constructor now accepts {convertFloat16?: boolean}.", "For usage, go to https://github.com/jhuapl-boss/npyjs." ].join(" ")); } this.convertFloat16 = opts?.convertFloat16 ?? true; this.dtypes = { "> 15) & 0x1; const exponent = (float16 >> 10) & 0x1f; const fraction = float16 & 0x3ff; // Handle special cases if (exponent === 0) { if (fraction === 0) { // Zero return sign ? -0 : 0; } // Denormalized number return (sign ? -1 : 1) * Math.pow(2, -14) * (fraction / 0x400); } else if (exponent === 0x1f) { if (fraction === 0) { // Infinity return sign ? -Infinity : Infinity; } // NaN return NaN; } // Normalized number return (sign ? -1 : 1) * Math.pow(2, exponent - 15) * (1 + fraction / 0x400); } parse(arrayBufferContents) { // const version = arrayBufferContents.slice(6, 8); // Uint8-encoded const headerLength = new DataView(arrayBufferContents.slice(8, 10)).getUint8(0); const offsetBytes = 10 + headerLength; const hcontents = new TextDecoder("utf-8").decode( new Uint8Array(arrayBufferContents.slice(10, 10 + headerLength)) ); const header = JSON.parse( hcontents .toLowerCase() // True -> true .replace(/'/g, '"') .replace("(", "[") .replace(/,*\),*/g, "]") ); const shape = header.shape; const dtype = this.dtypes[header.descr]; if (!dtype) { console.error(`Unsupported dtype: ${header.descr}`); return null; } const nums = new dtype.arrayConstructor( arrayBufferContents, offsetBytes ); // Convert float16 to float32 if converter exists const data = dtype.converter ? dtype.converter.call(this, nums) : nums; return { dtype: dtype.name, data: data, shape, fortranOrder: header.fortran_order }; } async load(filename, callback, fetchArgs) { /* Loads an array from a stream of bytes. */ fetchArgs = fetchArgs || {}; let arrayBuf; // If filename is ArrayBuffer if (filename instanceof ArrayBuffer) { arrayBuf = filename; } // If filename is a file path else { const resp = await fetch(filename, { ...fetchArgs }); arrayBuf = await resp.arrayBuffer(); } const result = this.parse(arrayBuf); if (callback) { return callback(result); } return result; } }