From bd6222774edcec1608a6842d0b06a637a4acef59 Mon Sep 17 00:00:00 2001 From: One Date: Wed, 9 Jul 2025 10:13:51 +0800 Subject: Release --- assets/hrm.png | Bin 0 -> 99852 bytes assets/npyjs.js | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 assets/hrm.png create mode 100644 assets/npyjs.js (limited to 'assets') diff --git a/assets/hrm.png b/assets/hrm.png new file mode 100644 index 0000000..e6c2f10 Binary files /dev/null and b/assets/hrm.png differ diff --git a/assets/npyjs.js b/assets/npyjs.js new file mode 100644 index 0000000..b474575 --- /dev/null +++ b/assets/npyjs.js @@ -0,0 +1,176 @@ +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; + } +} -- cgit v1.2.3