diff --git a/.changeset/clever-moose-hear.md b/.changeset/clever-moose-hear.md new file mode 100644 index 00000000..509bee27 --- /dev/null +++ b/.changeset/clever-moose-hear.md @@ -0,0 +1,7 @@ +--- +"@zarrita/core": patch +--- + +Support read-only `bitround` codec + +Introduces `BitroundCodec` with a no-op for decoding because bit-rounding is lossy, and precision cannot be restored. Encoding is not yet implemented, reflecting zarrita's current focus on read-heavy contexts. Open an issue if encoding support is needed. diff --git a/packages/core/src/codecs.ts b/packages/core/src/codecs.ts index 07772061..2faea23b 100644 --- a/packages/core/src/codecs.ts +++ b/packages/core/src/codecs.ts @@ -1,6 +1,7 @@ import type { Codec as _Codec } from "numcodecs"; import type { Chunk, CodecMetadata, DataType } from "./metadata.js"; +import { BitroundCodec } from "./codecs/bitround.js"; import { BytesCodec } from "./codecs/bytes.js"; import { Crc32cCodec } from "./codecs/crc32c.js"; import { JsonCodec } from "./codecs/json2.js"; @@ -31,7 +32,8 @@ function create_default_registry(): Map Promise> { .set("bytes", () => BytesCodec) .set("crc32c", () => Crc32cCodec) .set("vlen-utf8", () => VLenUTF8) - .set("json2", () => JsonCodec); + .set("json2", () => JsonCodec) + .set("bitround", () => BitroundCodec); } export const registry: Map Promise> = diff --git a/packages/core/src/codecs/bitround.ts b/packages/core/src/codecs/bitround.ts new file mode 100644 index 00000000..7eb7863d --- /dev/null +++ b/packages/core/src/codecs/bitround.ts @@ -0,0 +1,53 @@ +import type { Chunk, Float32, Float64 } from "../metadata.js"; + +/** + * A codec for bit-rounding. + * + * Reduces floating-point precision by truncating mantissa bits during encoding. + * Decoding is a no-op as the process is lossy and precision cannot be restored. + * + * Note: {@link BitroundCodec.encode} is not yet implemented since Zarrita is + * primarily used in read-only contexts (web browser). If you need encoding support, + * please open an issue at {@link https://github.com/manzt/zarrita.js/issues}. + * + * @see {@link https://github.com/zarr-developers/numcodecs/blob/main/numcodecs/bitround.py} + * for the original Python implementation. + * + * @remarks + * Data types are not validated, and `float16` arrays are not supported (reflecting browser support). + */ +export class BitroundCodec { + kind = "array_to_array"; + + constructor(configuration: { keepbits: number }, _meta: { data_type: D }) { + if (configuration.keepbits < 0) { + throw new Error("keepbits must be zero or positive"); + } + } + + static fromConfig( + configuration: { keepbits: number }, + meta: { data_type: D }, + ): BitroundCodec { + return new BitroundCodec(configuration, meta); + } + + /** + * Encode a chunk of data with bit-rounding. + * @param _arr - The chunk to encode + */ + encode(_arr: Chunk): Chunk { + throw new Error( + "`BitroundCodec.encode` is not implemented. Please open an issue at https://github.com/manzt/zarrita.js/issues.", + ); + } + + /** + * Decode a chunk of data (no-op). + * @param arr - The chunk to decode + * @returns The decoded chunk + */ + decode(arr: Chunk): Chunk { + return arr; // No-op as bit-rounding is lossy + } +} diff --git a/packages/zarrita/index.test.ts b/packages/zarrita/index.test.ts index a0656581..9f79dd41 100644 --- a/packages/zarrita/index.test.ts +++ b/packages/zarrita/index.test.ts @@ -26,6 +26,7 @@ it("exports all the things", () => { "crc32c" => [Function], "vlen-utf8" => [Function], "json2" => [Function], + "bitround" => [Function], }, "root": [Function], "set": [Function],