zarrextra 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/{chunkDecode-Dtm8HfWS.js → chunkDecode-CvE5qLLQ.js} +1 -1
- package/dist/{chunkDecode-Dtm8HfWS.js.map → chunkDecode-CvE5qLLQ.js.map} +1 -1
- package/dist/codec-worker.js +7263 -3152
- package/dist/codec-worker.js.map +1 -1
- package/dist/index.js +264 -125
- package/dist/index.js.map +1 -1
- package/dist/workers/index.d.ts.map +1 -1
- package/dist/workers.js +2 -2
- package/dist/workers.js.map +1 -1
- package/package.json +6 -3
- package/dist/codecs-DNu3yP16.js +0 -158
- package/dist/codecs-DNu3yP16.js.map +0 -1
- package/dist/workers/codec-worker-init.d.ts +0 -2
- package/dist/workers/codec-worker-init.d.ts.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/result.ts","../src/types.ts","../src/prefixedStore.ts","../src/htj2k-encode.ts","../src/omeZarr.ts","../src/index.ts"],"sourcesContent":["/**\n * Result type for explicit error handling without exceptions.\n * Inspired by Rust's Result<T, E>.\n *\n * This type is useful for operations that can fail, especially in zarr operations\n * where errors should be handled explicitly rather than thrown as exceptions.\n *\n * Note: This is a custom implementation for simplicity. We may review using\n * an existing Result library (such as neverthrow) in the future,\n * but for now this provides a lightweight, dependency-free solution.\n */\n\n/**\n * A Result type for explicit error handling without exceptions.\n * Inspired by Rust's Result<T, E>.\n */\nexport type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };\n\n/** Create a successful Result */\nexport const Ok = <T>(value: T): Result<T, never> => ({ ok: true, value });\n\n/** Create a failed Result */\nexport const Err = <E>(error: E): Result<never, E> => ({ ok: false, error });\n\n/** Type guard for Ok results */\nexport const isOk = <T, E>(result: Result<T, E>): result is { ok: true; value: T } => result.ok;\n\n/** Type guard for Err results */\nexport const isErr = <T, E>(result: Result<T, E>): result is { ok: false; error: E } => !result.ok;\n\n/**\n * Unwrap a Result, throwing if it's an error.\n * Use when you want to convert back to exception-based error handling.\n */\nexport const unwrap = <T, E>(result: Result<T, E>): T => {\n if (result.ok) return result.value;\n throw result.error instanceof Error ? result.error : new Error(String(result.error));\n};\n\n/**\n * Unwrap a Result with a default value for errors.\n */\nexport const unwrapOr = <T, E>(result: Result<T, E>, defaultValue: T): T => {\n return result.ok ? result.value : defaultValue;\n};\n","import type * as zarr from 'zarrita';\n\n/**\n * Supported inputs for opening a store.\n */\nexport type StoreReference = string | zarr.Readable;\n\ntype Store = zarr.Readable;\n\n/**\n * Zarr attributes type - a record of string keys to unknown values\n */\nexport type ZAttrsAny = Record<string, unknown>;\n\n/**\n * Symbol key for storing zarr attributes in the tree structure\n */\nexport const ATTRS_KEY = Symbol('attrs');\n\n/**\n * Symbol key for storing zarr array metadata\n */\nexport const ZARRAY_KEY = Symbol('.zarray');\n\n/**\n * Lazy zarr array type - represents a zarr array with a `get()` method for loading it,\n * and `.zarray` from consolidated metadata.\n */\nexport type LazyZarrArray<T extends zarr.DataType> = {\n [ATTRS_KEY]?: ZAttrsAny;\n [ZARRAY_KEY]: ZAttrsAny;\n get: () => Promise<zarr.Array<T>>;\n};\n\n/**\n * Zarr tree type\n *\n * This is a tree of zarr arrays and groups, with the leaves being lazy arrays.\n * It is used to represent the structure of the zarr store.\n * Leaf type subject to change.\n */\nexport interface ZarrTree {\n [ATTRS_KEY]?: ZAttrsAny;\n [key: string]: ZarrTree | LazyZarrArray<zarr.DataType>;\n}\n\n/**\n * Zarr v3 array node metadata\n */\nexport type ZarrV3ArrayNode = {\n shape: number[];\n data_type: string;\n chunk_grid: {\n name: string;\n configuration: {\n chunk_shape: number[];\n };\n };\n chunk_key_encoding: {\n name: string;\n configuration: {\n separator: string;\n };\n };\n fill_value: number | string | boolean;\n codecs: Array<{\n name: string;\n configuration?: Record<string, unknown>;\n }>;\n attributes: Record<string, unknown>;\n dimension_names: string[];\n zarr_format: number;\n node_type: 'array';\n storage_transformers: unknown[];\n};\n\n/**\n * Zarr v3 group node metadata\n */\nexport type ZarrV3GroupNode = {\n attributes: Record<string, unknown>;\n zarr_format: number;\n consolidated_metadata: {\n kind: string;\n must_understand: boolean;\n metadata: Record<string, unknown>;\n };\n node_type: 'group';\n};\n\n/**\n * Zarr v3 consolidated metadata structure (zarr.json)\n * The actual structure has metadata nested under consolidated_metadata.metadata\n * with path keys like \"images/blobs_image\", \"labels/blobs_labels\", etc.\n * Each entry can be either a group node or an array node.\n */\nexport type ZarrV3Metadata = {\n attributes: Record<string, unknown>;\n zarr_format: number;\n consolidated_metadata: {\n kind: string;\n must_understand: boolean;\n metadata: Record<string, ZarrV3GroupNode | ZarrV3ArrayNode>;\n };\n node_type: 'group';\n};\n\n/**\n * This type is liable to change in future - for now, it has `zarritaStore` which is the `ListableStore` from `zarrita`,\n * and `tree: ZarrTree` which has the object hierarchy as described in the consolidated metadata as a mostly \"Plain Old Javascript Object\",\n * but with (weakly typed) `Symbol`-keyed `attrs` & `.zarray` properties where available, and a `get()` on leaf nodes\n * for requesting array data.\n *\n * The use of `Symbol('attrs')` is intended to make these properties easy to access, but not appear when using `Object.keys()` etc.\n */\nexport type ConsolidatedStore = {\n zarritaStore: zarr.Listable<Store>;\n tree: ZarrTree;\n};\n","import type * as zarr from 'zarrita';\n\nfunction toAbsolutePath(path: string): zarr.AbsolutePath {\n const trimmed = path.replace(/^\\/+|\\/+$/g, '');\n // Zarrita brands absolute paths as template-literal types; normalization above enforces it.\n return (trimmed ? `/${trimmed}` : '/') as zarr.AbsolutePath;\n}\n\nfunction joinAbsolutePath(prefix: string, key: zarr.AbsolutePath): zarr.AbsolutePath {\n const normalizedPrefix = toAbsolutePath(prefix);\n if (normalizedPrefix === '/') {\n return key;\n }\n if (key === '/') {\n return normalizedPrefix;\n }\n // Both sides are absolute Zarr paths; concatenating preserves the leading slash.\n return `${normalizedPrefix}${key}` as zarr.AbsolutePath;\n}\n\n/**\n * Create a read-only store view rooted at `prefix`.\n *\n * This is useful when callers have a SpatialData root store but a downstream\n * reader expects the supplied store root to be an individual image/table group.\n */\nexport function createPrefixedStore(store: zarr.Readable, prefix: string): zarr.AsyncReadable {\n return {\n async get(key: zarr.AbsolutePath, opts?: zarr.GetOptions) {\n return await store.get(joinAbsolutePath(prefix, key), opts);\n },\n getRange: store.getRange\n ? async (key: zarr.AbsolutePath, range: zarr.RangeQuery, opts?: zarr.GetOptions) =>\n await store.getRange?.(joinAbsolutePath(prefix, key), range, opts)\n : undefined,\n };\n}\n","import { createWasmLocateFile, type OpenJphFactory, type RegisterImageCodecOptions } from './codecs';\n\nexport type Htj2kPlaneDtype = 'uint8' | 'int8' | 'uint16' | 'int16';\n\nexport type Htj2kEncodeOptions = {\n /** Lossless when true. Defaults to true for fixture-style writes. */\n reversible?: boolean;\n /** OpenJPH quantization factor when irreversible (lower = higher fidelity, larger output). */\n quality?: number;\n locateFile?: RegisterImageCodecOptions['locateFile'];\n};\n\ntype Htj2kFrameInfo = {\n width: number;\n height: number;\n bitsPerSample: 8 | 16;\n isSigned: boolean;\n componentCount: 1;\n isUsingColorTransform: false;\n};\n\ntype Htj2kEncoderClass = new () => {\n /** OpenJPH WASM API: `setQuality(reversible, quality)`; quality is a quantization factor (lower = better). */\n setQuality(reversible: boolean, quality: number): void;\n getDecodedBuffer(frame: Htj2kFrameInfo): ArrayBufferView;\n encode(): void;\n getEncodedBuffer(): Uint8Array;\n};\n\nexport type OpenJphEncoder = (\n plane: Uint8Array | Uint16Array | Int8Array | Int16Array,\n size: { width: number; height: number },\n options?: Pick<Htj2kEncodeOptions, 'reversible' | 'quality'>\n) => Promise<Uint8Array>;\n\nconst dynamicImport = new Function('specifier', 'return import(specifier)') as (\n specifier: string\n) => Promise<Record<string, unknown>>;\n\nfunction bitsPerSampleForPlane(\n plane: Uint8Array | Uint16Array | Int8Array | Int16Array\n): 8 | 16 {\n return plane instanceof Uint16Array || plane instanceof Int16Array ? 16 : 8;\n}\n\nfunction isSignedPlane(plane: Uint8Array | Uint16Array | Int8Array | Int16Array): boolean {\n return plane instanceof Int8Array || plane instanceof Int16Array;\n}\n\nfunction frameInfoForPlane(\n plane: Uint8Array | Uint16Array | Int8Array | Int16Array,\n size: { width: number; height: number }\n): Htj2kFrameInfo {\n const { width, height } = size;\n const expectedValues = width * height;\n if (plane.length !== expectedValues) {\n throw new Error(\n `HTJ2K plane has ${plane.length} samples, expected ${expectedValues} for ${width}x${height}.`\n );\n }\n return {\n width,\n height,\n bitsPerSample: bitsPerSampleForPlane(plane),\n isSigned: isSignedPlane(plane),\n componentCount: 1,\n isUsingColorTransform: false,\n };\n}\n\n/** Create an HTJ2K encoder backed by an OpenJPH WASM factory. */\nexport function createOpenJphEncoder(\n factory: OpenJphFactory,\n options: Pick<Htj2kEncodeOptions, 'locateFile'> = {}\n): OpenJphEncoder {\n let runtimePromise: Promise<Record<string, unknown>> | undefined;\n\n async function getRuntime() {\n runtimePromise ??= Promise.resolve(\n factory({\n locateFile: options.locateFile,\n })\n );\n return await runtimePromise;\n }\n\n return async (plane, size, encodeOptions = {}) => {\n const runtime = await getRuntime();\n const Encoder = runtime.HTJ2KEncoder as Htj2kEncoderClass | undefined;\n if (!Encoder) {\n throw new Error('OpenJPH runtime does not expose HTJ2KEncoder.');\n }\n\n const reversible = encodeOptions.reversible ?? true;\n const quality = encodeOptions.quality ?? 0;\n const frame = frameInfoForPlane(plane, size);\n const encoder = new Encoder();\n encoder.setQuality(reversible, quality);\n\n const buffer = encoder.getDecodedBuffer(frame);\n const target =\n frame.bitsPerSample === 16\n ? new Uint16Array(buffer.buffer, buffer.byteOffset, plane.length)\n : new Uint8Array(buffer.buffer, buffer.byteOffset, plane.length);\n target.set(plane);\n encoder.encode();\n return encoder.getEncodedBuffer();\n };\n}\n\n/** Load the optional OpenJPH WASM encoder from @cornerstonejs/codec-openjph. */\nexport async function loadOpenJphEncoder(\n options: Htj2kEncodeOptions = {}\n): Promise<OpenJphEncoder> {\n const factoryMod = await dynamicImport('@cornerstonejs/codec-openjph/wasmjs').catch(() =>\n dynamicImport('@cornerstonejs/codec-openjph')\n );\n const factory = (factoryMod.default ?? factoryMod.OpenJPHJS ?? factoryMod) as unknown;\n if (typeof factory !== 'function') {\n throw new Error('Could not find an OpenJPH factory export in @cornerstonejs/codec-openjph.');\n }\n const wasmMod = await dynamicImport('@cornerstonejs/codec-openjph/wasm').catch(() => null);\n const wasmAsset = wasmMod ? ((wasmMod.default ?? wasmMod) as string | undefined) : undefined;\n const locateFile =\n options.locateFile ?? (wasmAsset ? createWasmLocateFile(wasmAsset) : undefined);\n return createOpenJphEncoder(factory as OpenJphFactory, { locateFile });\n}\n\nexport function planeArrayForDtype(\n dtype: Htj2kPlaneDtype,\n bytes: Uint8Array\n) {\n switch (dtype) {\n case 'uint8':\n return bytes;\n case 'int8':\n return new Int8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n case 'uint16':\n return new Uint16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2);\n case 'int16':\n return new Int16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2);\n default:\n throw new Error(`Unsupported HTJ2K plane dtype '${dtype}'.`);\n }\n}\n\n/** Encode one 2D plane to an HTJ2K bitstream. */\nexport async function encodeHtj2kPlane(\n plane: Uint8Array | Uint16Array | Int8Array | Int16Array,\n size: { width: number; height: number },\n options: Htj2kEncodeOptions = {}\n): Promise<Uint8Array> {\n const encoder = await loadOpenJphEncoder(options);\n return await encoder(plane, size, options);\n}\n","import * as zarr from 'zarrita';\nimport { getZarrChunk } from './chunkDecode';\n\nexport type RasterSelection = Record<string, number> | number[];\n\nexport interface VivCompatiblePixelSource {\n labels: string[];\n tileSize: number;\n shape: number[];\n dtype: string;\n meta?: { physicalSizes?: { x?: { size: number; unit: string } } };\n getRaster(props: { selection: RasterSelection; signal?: AbortSignal }): Promise<{\n data: unknown;\n width: number;\n height: number;\n }>;\n getTile(props: {\n x: number;\n y: number;\n selection: RasterSelection;\n signal?: AbortSignal;\n }): Promise<{\n data: unknown;\n width: number;\n height: number;\n }>;\n onTileError(err: Error): void;\n}\n\ntype OmeAxis = { name: string; type?: string; unit?: string };\ntype OmeMultiscaleAttrs = {\n datasets?: Array<{ path: string }>;\n axes?: Array<string | OmeAxis>;\n};\ntype OmeRootAttrs = {\n multiscales?: OmeMultiscaleAttrs[];\n omero?: unknown;\n [key: string]: unknown;\n};\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isOmeAxis(value: unknown): value is OmeAxis {\n return isObject(value) && typeof value.name === 'string';\n}\n\nfunction isOmeDataset(value: unknown): value is { path: string } {\n return isObject(value) && typeof value.path === 'string';\n}\n\nfunction isOmeMultiscaleAttrs(value: unknown): value is OmeMultiscaleAttrs {\n if (!isObject(value)) return false;\n const datasets = value.datasets;\n if (datasets !== undefined) {\n if (!Array.isArray(datasets)) return false;\n if (!datasets.every(isOmeDataset)) return false;\n }\n const axes = value.axes;\n if (axes !== undefined) {\n if (!Array.isArray(axes)) return false;\n if (!axes.every((axis) => typeof axis === 'string' || isOmeAxis(axis))) return false;\n }\n return true;\n}\n\nfunction getOmeRootAttrs(attrs: Record<string, unknown>): OmeRootAttrs {\n const candidate = isObject(attrs.ome) ? attrs.ome : attrs;\n if (!('multiscales' in candidate)) {\n return candidate;\n }\n if (!Array.isArray(candidate.multiscales)) {\n throw new Error('OME-Zarr `multiscales` attribute must be an array.');\n }\n if (!candidate.multiscales.every(isOmeMultiscaleAttrs)) {\n throw new Error('OME-Zarr `multiscales` entries must contain valid dataset paths and axes.');\n }\n return candidate;\n}\n\nfunction isInterleaved(shape: number[], labels?: string[]) {\n const lastDimSize = shape[shape.length - 1];\n if (lastDimSize !== 3 && lastDimSize !== 4) {\n return false;\n }\n if (labels?.some((label) => label.toLowerCase() === 'c')) {\n return false;\n }\n return true;\n}\n\nfunction axisIndex(labels: string[], axis: 'x' | 'y'): number {\n const index = labels.findIndex((label) => label.toLowerCase() === axis);\n if (index === -1) {\n throw new Error(`OME-Zarr labels must include '${axis}' axis.`);\n }\n return index;\n}\n\nfunction spatialAxisIndices(shape: number[], labels: string[]): { xIndex: number; yIndex: number } {\n if (isInterleaved(shape, labels)) {\n const len = shape.length;\n return { yIndex: len - 3, xIndex: len - 2 };\n }\n return { yIndex: axisIndex(labels, 'y'), xIndex: axisIndex(labels, 'x') };\n}\n\nfunction spatialDimensions(shape: number[], labels: string[]): [number, number] {\n const { xIndex, yIndex } = spatialAxisIndices(shape, labels);\n return [shape[yIndex] ?? 0, shape[xIndex] ?? 0];\n}\n\nfunction spatialDimensionsFromChunk(\n chunkShape: number[],\n sourceShape: number[],\n labels: string[]\n): [number, number] {\n if (isInterleaved(sourceShape, labels)) {\n const [height, width] = chunkShape.slice(-3);\n return [height ?? 0, width ?? 0];\n }\n if (chunkShape.length >= 2) {\n const [height, width] = chunkShape.slice(-2);\n return [height ?? 0, width ?? 0];\n }\n return [chunkShape[0] ?? 0, 0];\n}\n\nfunction getImageSize(source: { shape: number[]; labels: string[] }) {\n const [height, width] = spatialDimensions(source.shape, source.labels);\n return { height, width };\n}\n\nfunction prevPowerOf2(x: number): number {\n return 2 ** Math.floor(Math.log2(x));\n}\n\nfunction guessTileSize(arr: zarr.Array<zarr.DataType>, labels: string[]): number {\n if (isInterleaved(arr.shape, labels)) {\n const [yChunk, xChunk] = arr.chunks.slice(-3);\n return prevPowerOf2(Math.min(yChunk ?? 1, xChunk ?? 1));\n }\n const yChunk = arr.chunks[axisIndex(labels, 'y')];\n const xChunk = arr.chunks[axisIndex(labels, 'x')];\n return prevPowerOf2(Math.min(yChunk ?? 1, xChunk ?? 1));\n}\n\nfunction labelsFromAxes(axes: OmeMultiscaleAttrs['axes'] | undefined): string[] {\n if (!axes) return ['t', 'c', 'z', 'y', 'x'];\n return axes.map((axis) => (typeof axis === 'string' ? axis : axis.name));\n}\n\nfunction normalizeDtype(dtype: string): string {\n const lookup: Record<string, string> = {\n u1: 'Uint8',\n u2: 'Uint16',\n u4: 'Uint32',\n i1: 'Int8',\n i2: 'Int16',\n i4: 'Int32',\n f4: 'Float32',\n f8: 'Float64',\n uint8: 'Uint8',\n uint16: 'Uint16',\n uint32: 'Uint32',\n int8: 'Int8',\n int16: 'Int16',\n int32: 'Int32',\n float32: 'Float32',\n float64: 'Float64',\n };\n return lookup[dtype.toLowerCase()] ?? dtype.charAt(0).toUpperCase() + dtype.slice(1);\n}\n\nfunction getIndexer(labels: string[]) {\n const labelSet = new Set(labels);\n if (labelSet.size !== labels.length) {\n throw new Error('OME-Zarr labels must be unique.');\n }\n return (selection: RasterSelection): Array<number | zarr.Slice | null> => {\n if (Array.isArray(selection)) {\n return [...selection];\n }\n const indexed: Array<number | zarr.Slice | null> = Array(labels.length).fill(0);\n for (const [key, value] of Object.entries(selection)) {\n const index = labels.indexOf(key);\n if (index === -1) {\n throw new Error(`Invalid OME-Zarr selection axis '${key}'.`);\n }\n indexed[index] = value;\n }\n return indexed;\n };\n}\n\nclass BoundsCheckError extends Error {}\n\nclass ZarrPixelSource implements VivCompatiblePixelSource {\n private readonly indexer: ReturnType<typeof getIndexer>;\n\n constructor(\n private readonly data: zarr.Array<zarr.DataType>,\n public readonly labels: string[],\n public readonly tileSize: number\n ) {\n this.indexer = getIndexer(labels);\n }\n\n get shape() {\n return this.data.shape;\n }\n\n get dtype() {\n return normalizeDtype(this.data.dtype);\n }\n\n private chunkIndex(\n selection: RasterSelection,\n tile: { x: number | zarr.Slice | null; y: number | zarr.Slice | null }\n ) {\n const { xIndex, yIndex } = spatialAxisIndices(this.data.shape, this.labels);\n const sel = this.indexer(selection);\n sel[xIndex] = tile.x;\n sel[yIndex] = tile.y;\n return sel;\n }\n\n private getSlices(x: number, y: number) {\n const { height, width } = getImageSize(this);\n const xStart = x * this.tileSize;\n const xStop = Math.min((x + 1) * this.tileSize, width);\n const yStart = y * this.tileSize;\n const yStop = Math.min((y + 1) * this.tileSize, height);\n\n if (xStart >= xStop || yStart >= yStop) {\n throw new BoundsCheckError('Tile slice is zero-sized or inverted.');\n }\n if (xStart < 0 || yStart < 0 || xStop > width || yStop > height) {\n throw new BoundsCheckError('Tile slice is out of bounds.');\n }\n\n return [zarr.slice(xStart, xStop), zarr.slice(yStart, yStop)];\n }\n\n private async getRaw(\n selection: Array<number | zarr.Slice | null>,\n signal?: AbortSignal\n ): Promise<zarr.Chunk<zarr.DataType>> {\n return await getZarrChunk(this.data, selection, { signal });\n }\n\n async getRaster({ selection, signal }: { selection: RasterSelection; signal?: AbortSignal }) {\n const sel = this.chunkIndex(selection, { x: null, y: null });\n const result = await this.getRaw(sel, signal);\n const [height, width] = spatialDimensionsFromChunk(\n result.shape,\n this.data.shape,\n this.labels\n );\n return { data: result.data, width, height };\n }\n\n async getTile({\n x,\n y,\n selection,\n signal,\n }: {\n x: number;\n y: number;\n selection: RasterSelection;\n signal?: AbortSignal;\n }) {\n const [xSlice, ySlice] = this.getSlices(x, y);\n const sel = this.chunkIndex(selection, { x: xSlice, y: ySlice });\n const result = await this.getRaw(sel, signal);\n const [height, width] = spatialDimensionsFromChunk(\n result.shape,\n this.data.shape,\n this.labels\n );\n return { data: result.data, width, height };\n }\n\n onTileError(err: Error) {\n if (!(err instanceof BoundsCheckError)) {\n throw err;\n }\n }\n}\n\nasync function loadMultiscales(store: zarr.AsyncReadable) {\n const readable = await zarr.withMaybeConsolidatedMetadata(store);\n const root = zarr.root(readable);\n const group = await zarr.open(root, { kind: 'group' });\n const rootAttrs = getOmeRootAttrs(group.attrs);\n const firstMultiscale = rootAttrs.multiscales?.[0];\n const paths: string[] = firstMultiscale?.datasets?.map((dataset) => dataset.path) ?? ['0'];\n const labels = labelsFromAxes(firstMultiscale?.axes);\n const data: Array<zarr.Array<zarr.DataType>> = await Promise.all(\n paths.map((path: string) => zarr.open(root.resolve(path), { kind: 'array' }))\n );\n return { data, labels, rootAttrs };\n}\n\n/** Load an OME-Zarr multiscale image from a Zarrita readable store. */\nexport async function loadOmeZarrMultiscalesFromStore(\n store: zarr.AsyncReadable\n): Promise<VivCompatiblePixelSource[]> {\n const { data, labels } = await loadMultiscales(store);\n if (data.length === 0) {\n throw new Error('OME-Zarr multiscale dataset is empty or has no valid arrays.');\n }\n const tileSize = guessTileSize(data[0], labels);\n return data.map((arr: zarr.Array<zarr.DataType>) => new ZarrPixelSource(arr, labels, tileSize));\n}\n","import * as zarr from 'zarrita';\nimport { Err, Ok, type Result } from './result';\nimport type {\n ConsolidatedStore,\n LazyZarrArray,\n StoreReference,\n ZAttrsAny,\n ZarrTree,\n} from './types';\nimport { ATTRS_KEY, ZARRAY_KEY } from './types';\n\nconst decoder = new TextDecoder();\n\nfunction isReadableStore(source: StoreReference): source is zarr.Readable {\n return typeof source !== 'string';\n}\n\nfunction isListableStore(store: zarr.Readable): store is zarr.Listable<zarr.Readable> {\n return 'contents' in store && typeof store.contents === 'function';\n}\n\nfunction normalizeStringSource(source: string): string {\n return source.replace(/\\/+$/, '');\n}\n\nfunction describeSource(source: StoreReference): string {\n return typeof source === 'string' ? source : '[store instance]';\n}\n\nfunction metadataKeysForPath(\n path: zarr.AbsolutePath,\n kind: 'array' | 'group'\n): zarr.AbsolutePath[] {\n const basePath = path === '/' ? '' : path;\n if (kind === 'array') {\n return [`${basePath}/zarr.json`, `${basePath}/.zarray`] as zarr.AbsolutePath[];\n }\n return [`${basePath}/zarr.json`, `${basePath}/.zgroup`] as zarr.AbsolutePath[];\n}\n\nasync function readMetadataJson(\n store: zarr.Readable,\n path: zarr.AbsolutePath,\n kind: 'array' | 'group'\n): Promise<ZAttrsAny | undefined> {\n for (const metadataKey of metadataKeysForPath(path, kind)) {\n const bytes = await store.get(metadataKey);\n if (bytes) {\n return JSON.parse(decoder.decode(bytes)) as ZAttrsAny;\n }\n }\n return undefined;\n}\n\nasync function readNodeAttrs(\n root: zarr.Group<zarr.Readable>,\n path: zarr.AbsolutePath,\n kind: 'array' | 'group'\n): Promise<ZAttrsAny> {\n if (path === '/') {\n return root.attrs;\n }\n\n const node =\n kind === 'array'\n ? await zarr.open(root.resolve(path), { kind: 'array' })\n : await zarr.open(root.resolve(path), { kind: 'group' });\n return node.attrs;\n}\n\nfunction sortContentsByDepth(\n a: { path: zarr.AbsolutePath },\n b: { path: zarr.AbsolutePath }\n): number {\n const depthA = a.path.split('/').filter(Boolean).length;\n const depthB = b.path.split('/').filter(Boolean).length;\n return depthA - depthB;\n}\n\nasync function parseStoreContents(store: zarr.Listable<zarr.Readable>): Promise<ZarrTree> {\n const root = await zarr.open(store, { kind: 'group' });\n const tree: ZarrTree = {\n [ATTRS_KEY]: root.attrs,\n };\n const contents = store.contents().sort(sortContentsByDepth);\n\n for (const { path, kind } of contents) {\n if (path === '/') continue;\n\n const pathParts = path.split('/').filter(Boolean);\n let currentNode = tree;\n\n for (const [index, part] of pathParts.entries()) {\n if (!(part in currentNode)) {\n const isLeaf = index === pathParts.length - 1;\n\n if (!isLeaf) {\n currentNode[part] = {};\n } else {\n const absolutePath = `/${pathParts.slice(0, index + 1).join('/')}` as zarr.AbsolutePath;\n const attrs = await readNodeAttrs(root, absolutePath, kind);\n\n if (kind === 'array') {\n const arrayMetadata = await readMetadataJson(store, absolutePath, 'array');\n if (!arrayMetadata) {\n throw new Error(`Missing array metadata for '${absolutePath}'`);\n }\n\n const leafNode: LazyZarrArray<zarr.DataType> = {\n [ATTRS_KEY]: attrs,\n [ZARRAY_KEY]: arrayMetadata,\n get: () => zarr.open(root.resolve(absolutePath), { kind: 'array' }),\n };\n currentNode[part] = leafNode;\n } else {\n currentNode[part] = {\n [ATTRS_KEY]: attrs,\n };\n }\n }\n }\n\n currentNode = currentNode[part] as ZarrTree;\n }\n }\n\n return tree;\n}\n\nasync function resolveListableStore(source: StoreReference): Promise<zarr.Listable<zarr.Readable>> {\n const store = isReadableStore(source)\n ? source\n : new zarr.FetchStore(normalizeStringSource(source));\n\n if (isListableStore(store)) {\n return store;\n }\n\n try {\n return await zarr.withConsolidatedMetadata(store as zarr.AsyncReadable);\n } catch (defaultError) {\n try {\n return await zarr.withConsolidatedMetadata(store as zarr.AsyncReadable, {\n format: 'v2',\n metadataKey: 'zmetadata',\n });\n } catch {\n throw defaultError;\n }\n }\n}\n\n/**\n * Open a zarr store or store-backed source and return a parsed tree representation.\n */\nexport async function openExtraConsolidated(\n source: StoreReference\n): Promise<Result<ConsolidatedStore>> {\n try {\n const zarritaStore = await resolveListableStore(source);\n const tree = await parseStoreContents(zarritaStore);\n return Ok({ zarritaStore, tree });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return Err(new Error(`Failed to open zarr store '${describeSource(source)}': ${errorMessage}`));\n }\n}\n\n/**\n * Deep clone a ZarrTree, converting Symbol-keyed attrs to string keys for serialization/debugging\n */\nexport function serializeZarrTree(obj: ZarrTree | unknown): unknown {\n if (obj === null || typeof obj !== 'object') return obj;\n\n const result: Record<string, unknown> = {};\n\n if (ATTRS_KEY in obj && obj[ATTRS_KEY]) {\n result._attrs = obj[ATTRS_KEY];\n }\n if (ZARRAY_KEY in obj && obj[ZARRAY_KEY]) {\n result._zarray = obj[ZARRAY_KEY];\n }\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n // @ts-expect-error - Indexing unknown object for serialization.\n const val = obj[key];\n if (typeof val === 'function') {\n result[key] = '<function>';\n } else {\n result[key] = serializeZarrTree(val);\n }\n }\n }\n\n return result;\n}\n\nexport type {\n StoreReference,\n ZarrTree,\n ConsolidatedStore,\n LazyZarrArray,\n ZAttrsAny,\n} from './types';\nexport { ATTRS_KEY, ZARRAY_KEY } from './types';\nexport { createPrefixedStore } from './prefixedStore';\nexport {\n createOpenJpegDecoder,\n createOpenJphDecoder,\n createWasmLocateFile,\n registerJpeg2kCodec,\n registerExperimentalHtj2kCodec,\n type ImageCodecDecoder,\n type OpenJpegFactory,\n type OpenJphFactory,\n type RegisterImageCodecOptions,\n} from './codecs';\nexport {\n createOpenJphEncoder,\n encodeHtj2kPlane,\n loadOpenJphEncoder,\n planeArrayForDtype,\n type Htj2kEncodeOptions,\n type Htj2kPlaneDtype,\n type OpenJphEncoder,\n} from './htj2k-encode';\nexport {\n loadOmeZarrMultiscalesFromStore,\n type VivCompatiblePixelSource,\n type RasterSelection,\n} from './omeZarr';\n\nexport type { Result } from './result';\nexport { Ok, Err, isOk, isErr, unwrap, unwrapOr } from './result';\n"],"mappings":";;;;AAmBA,IAAa,KAAS,OAAgC;CAAE,IAAI;CAAM;CAAO,GAG5D,KAAU,OAAgC;CAAE,IAAI;CAAO;CAAO,GAG9D,KAAc,MAA2D,EAAO,IAGhF,KAAe,MAA4D,CAAC,EAAO,IAMnF,KAAgB,MAA4B;AACvD,KAAI,EAAO,GAAI,QAAO,EAAO;AAC7B,OAAM,EAAO,iBAAiB,QAAQ,EAAO,QAAY,MAAM,OAAO,EAAO,MAAM,CAAC;GAMzE,KAAkB,GAAsB,MAC5C,EAAO,KAAK,EAAO,QAAQ,GC1BvB,IAAY,OAAO,QAAQ,EAK3B,IAAa,OAAO,UAAU;;;ACpB3C,SAAS,EAAe,GAAiC;CACvD,IAAM,IAAU,EAAK,QAAQ,cAAc,GAAG;AAE9C,QAAQ,IAAU,IAAI,MAAY;;AAGpC,SAAS,EAAiB,GAAgB,GAA2C;CACnF,IAAM,IAAmB,EAAe,EAAO;AAQ/C,QAPI,MAAqB,MAChB,IAEL,MAAQ,MACH,IAGF,GAAG,IAAmB;;AAS/B,SAAgB,EAAoB,GAAsB,GAAoC;AAC5F,QAAO;EACL,MAAM,IAAI,GAAwB,GAAwB;AACxD,UAAO,MAAM,EAAM,IAAI,EAAiB,GAAQ,EAAI,EAAE,EAAK;;EAE7D,UAAU,EAAM,WACZ,OAAO,GAAwB,GAAwB,MACrD,MAAM,EAAM,WAAW,EAAiB,GAAQ,EAAI,EAAE,GAAO,EAAK,GACpE,KAAA;EACL;;;;ACAH,IAAM,IAAoB,SAAS,aAAa,2BAA2B;AAI3E,SAAS,EACP,GACQ;AACR,QAAO,aAAiB,eAAe,aAAiB,aAAa,KAAK;;AAG5E,SAAS,EAAc,GAAmE;AACxF,QAAO,aAAiB,aAAa,aAAiB;;AAGxD,SAAS,EACP,GACA,GACgB;CAChB,IAAM,EAAE,UAAO,cAAW,GACpB,IAAiB,IAAQ;AAC/B,KAAI,EAAM,WAAW,EACnB,OAAU,MACR,mBAAmB,EAAM,OAAO,qBAAqB,EAAe,OAAO,EAAM,GAAG,EAAO,GAC5F;AAEH,QAAO;EACL;EACA;EACA,eAAe,EAAsB,EAAM;EAC3C,UAAU,EAAc,EAAM;EAC9B,gBAAgB;EAChB,uBAAuB;EACxB;;AAIH,SAAgB,EACd,GACA,IAAkD,EAAE,EACpC;CAChB,IAAI;CAEJ,eAAe,IAAa;AAM1B,SALA,MAAmB,QAAQ,QACzB,EAAQ,EACN,YAAY,EAAQ,YACrB,CAAC,CACH,EACM,MAAM;;AAGf,QAAO,OAAO,GAAO,GAAM,IAAgB,EAAE,KAAK;EAEhD,IAAM,KADU,MAAM,GAAY,EACV;AACxB,MAAI,CAAC,EACH,OAAU,MAAM,gDAAgD;EAGlE,IAAM,IAAa,EAAc,cAAc,IACzC,IAAU,EAAc,WAAW,GACnC,IAAQ,EAAkB,GAAO,EAAK,EACtC,IAAU,IAAI,GAAS;AAC7B,IAAQ,WAAW,GAAY,EAAQ;EAEvC,IAAM,IAAS,EAAQ,iBAAiB,EAAM;AAO9C,UALE,EAAM,kBAAkB,KACpB,IAAI,YAAY,EAAO,QAAQ,EAAO,YAAY,EAAM,OAAO,GAC/D,IAAI,WAAW,EAAO,QAAQ,EAAO,YAAY,EAAM,OAAO,EAC7D,IAAI,EAAM,EACjB,EAAQ,QAAQ,EACT,EAAQ,kBAAkB;;;AAKrC,eAAsB,EACpB,IAA8B,EAAE,EACP;CACzB,IAAM,IAAa,MAAM,EAAc,sCAAsC,CAAC,YAC5E,EAAc,+BAA+B,CAC9C,EACK,IAAW,EAAW,WAAW,EAAW,aAAa;AAC/D,KAAI,OAAO,KAAY,WACrB,OAAU,MAAM,4EAA4E;CAE9F,IAAM,IAAU,MAAM,EAAc,oCAAoC,CAAC,YAAY,KAAK,EACpF,IAAY,IAAY,EAAQ,WAAW,IAAkC,KAAA;AAGnF,QAAO,EAAqB,GAA2B,EAAE,YADvD,EAAQ,eAAe,IAAY,EAAqB,EAAU,GAAG,KAAA,IACF,CAAC;;AAGxE,SAAgB,GACd,GACA,GACA;AACA,SAAQ,GAAR;EACE,KAAK,QACH,QAAO;EACT,KAAK,OACH,QAAO,IAAI,UAAU,EAAM,QAAQ,EAAM,YAAY,EAAM,WAAW;EACxE,KAAK,SACH,QAAO,IAAI,YAAY,EAAM,QAAQ,EAAM,YAAY,EAAM,aAAa,EAAE;EAC9E,KAAK,QACH,QAAO,IAAI,WAAW,EAAM,QAAQ,EAAM,YAAY,EAAM,aAAa,EAAE;EAC7E,QACE,OAAU,MAAM,kCAAkC,EAAM,IAAI;;;AAKlE,eAAsB,EACpB,GACA,GACA,IAA8B,EAAE,EACX;AAErB,QAAO,OADS,MAAM,EAAmB,EAAQ,EAC5B,GAAO,GAAM,EAAQ;;;;ACjH5C,SAAS,EAAS,GAAkD;AAClE,QAAO,OAAO,KAAU,cAAY,KAAkB,CAAC,MAAM,QAAQ,EAAM;;AAG7E,SAAS,EAAU,GAAkC;AACnD,QAAO,EAAS,EAAM,IAAI,OAAO,EAAM,QAAS;;AAGlD,SAAS,EAAa,GAA2C;AAC/D,QAAO,EAAS,EAAM,IAAI,OAAO,EAAM,QAAS;;AAGlD,SAAS,EAAqB,GAA6C;AACzE,KAAI,CAAC,EAAS,EAAM,CAAE,QAAO;CAC7B,IAAM,IAAW,EAAM;AACvB,KAAI,MAAa,KAAA,MACX,CAAC,MAAM,QAAQ,EAAS,IACxB,CAAC,EAAS,MAAM,EAAa,EAAE,QAAO;CAE5C,IAAM,IAAO,EAAM;AAKnB,QAJA,EAAI,MAAS,KAAA,MACP,CAAC,MAAM,QAAQ,EAAK,IACpB,CAAC,EAAK,OAAO,MAAS,OAAO,KAAS,YAAY,EAAU,EAAK,CAAC;;AAK1E,SAAS,EAAgB,GAA8C;CACrE,IAAM,IAAY,EAAS,EAAM,IAAI,GAAG,EAAM,MAAM;AACpD,KAAI,EAAE,iBAAiB,GACrB,QAAO;AAET,KAAI,CAAC,MAAM,QAAQ,EAAU,YAAY,CACvC,OAAU,MAAM,qDAAqD;AAEvE,KAAI,CAAC,EAAU,YAAY,MAAM,EAAqB,CACpD,OAAU,MAAM,4EAA4E;AAE9F,QAAO;;AAGT,SAAS,EAAc,GAAiB,GAAmB;CACzD,IAAM,IAAc,EAAM,EAAM,SAAS;AAOzC,QAHA,EAHI,MAAgB,KAAK,MAAgB,KAGrC,GAAQ,MAAM,MAAU,EAAM,aAAa,KAAK,IAAI;;AAM1D,SAAS,EAAU,GAAkB,GAAyB;CAC5D,IAAM,IAAQ,EAAO,WAAW,MAAU,EAAM,aAAa,KAAK,EAAK;AACvE,KAAI,MAAU,GACZ,OAAU,MAAM,iCAAiC,EAAK,SAAS;AAEjE,QAAO;;AAGT,SAAS,EAAmB,GAAiB,GAAsD;AACjG,KAAI,EAAc,GAAO,EAAO,EAAE;EAChC,IAAM,IAAM,EAAM;AAClB,SAAO;GAAE,QAAQ,IAAM;GAAG,QAAQ,IAAM;GAAG;;AAE7C,QAAO;EAAE,QAAQ,EAAU,GAAQ,IAAI;EAAE,QAAQ,EAAU,GAAQ,IAAI;EAAE;;AAG3E,SAAS,EAAkB,GAAiB,GAAoC;CAC9E,IAAM,EAAE,WAAQ,cAAW,EAAmB,GAAO,EAAO;AAC5D,QAAO,CAAC,EAAM,MAAW,GAAG,EAAM,MAAW,EAAE;;AAGjD,SAAS,EACP,GACA,GACA,GACkB;AAClB,KAAI,EAAc,GAAa,EAAO,EAAE;EACtC,IAAM,CAAC,GAAQ,KAAS,EAAW,MAAM,GAAG;AAC5C,SAAO,CAAC,KAAU,GAAG,KAAS,EAAE;;AAElC,KAAI,EAAW,UAAU,GAAG;EAC1B,IAAM,CAAC,GAAQ,KAAS,EAAW,MAAM,GAAG;AAC5C,SAAO,CAAC,KAAU,GAAG,KAAS,EAAE;;AAElC,QAAO,CAAC,EAAW,MAAM,GAAG,EAAE;;AAGhC,SAAS,EAAa,GAA+C;CACnE,IAAM,CAAC,GAAQ,KAAS,EAAkB,EAAO,OAAO,EAAO,OAAO;AACtE,QAAO;EAAE;EAAQ;EAAO;;AAG1B,SAAS,EAAa,GAAmB;AACvC,QAAO,KAAK,KAAK,MAAM,KAAK,KAAK,EAAE,CAAC;;AAGtC,SAAS,EAAc,GAAgC,GAA0B;AAC/E,KAAI,EAAc,EAAI,OAAO,EAAO,EAAE;EACpC,IAAM,CAAC,GAAQ,KAAU,EAAI,OAAO,MAAM,GAAG;AAC7C,SAAO,EAAa,KAAK,IAAI,KAAU,GAAG,KAAU,EAAE,CAAC;;CAEzD,IAAM,IAAS,EAAI,OAAO,EAAU,GAAQ,IAAI,GAC1C,IAAS,EAAI,OAAO,EAAU,GAAQ,IAAI;AAChD,QAAO,EAAa,KAAK,IAAI,KAAU,GAAG,KAAU,EAAE,CAAC;;AAGzD,SAAS,EAAe,GAAwD;AAE9E,QADK,IACE,EAAK,KAAK,MAAU,OAAO,KAAS,WAAW,IAAO,EAAK,KAAM,GADtD;EAAC;EAAK;EAAK;EAAK;EAAK;EAAI;;AAI7C,SAAS,EAAe,GAAuB;AAmB7C,QAlBuC;EACrC,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,QAAQ;EACR,MAAM;EACN,OAAO;EACP,OAAO;EACP,SAAS;EACT,SAAS;EACV,CACa,EAAM,aAAa,KAAK,EAAM,OAAO,EAAE,CAAC,aAAa,GAAG,EAAM,MAAM,EAAE;;AAGtF,SAAS,GAAW,GAAkB;AAEpC,KADiB,IAAI,IAAI,EAAO,CACnB,SAAS,EAAO,OAC3B,OAAU,MAAM,kCAAkC;AAEpD,SAAQ,MAAkE;AACxE,MAAI,MAAM,QAAQ,EAAU,CAC1B,QAAO,CAAC,GAAG,EAAU;EAEvB,IAAM,IAA6C,MAAM,EAAO,OAAO,CAAC,KAAK,EAAE;AAC/E,OAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,EAAU,EAAE;GACpD,IAAM,IAAQ,EAAO,QAAQ,EAAI;AACjC,OAAI,MAAU,GACZ,OAAU,MAAM,oCAAoC,EAAI,IAAI;AAE9D,KAAQ,KAAS;;AAEnB,SAAO;;;AAIX,IAAM,IAAN,cAA+B,MAAM,IAE/B,IAAN,MAA0D;CAGxD,YACE,GACA,GACA,GACA;AACA,EAJiB,KAAA,OAAA,GACD,KAAA,SAAA,GACA,KAAA,WAAA,GAEhB,KAAK,UAAU,GAAW,EAAO;;CAGnC,IAAI,QAAQ;AACV,SAAO,KAAK,KAAK;;CAGnB,IAAI,QAAQ;AACV,SAAO,EAAe,KAAK,KAAK,MAAM;;CAGxC,WACE,GACA,GACA;EACA,IAAM,EAAE,WAAQ,cAAW,EAAmB,KAAK,KAAK,OAAO,KAAK,OAAO,EACrE,IAAM,KAAK,QAAQ,EAAU;AAGnC,SAFA,EAAI,KAAU,EAAK,GACnB,EAAI,KAAU,EAAK,GACZ;;CAGT,UAAkB,GAAW,GAAW;EACtC,IAAM,EAAE,WAAQ,aAAU,EAAa,KAAK,EACtC,IAAS,IAAI,KAAK,UAClB,IAAQ,KAAK,KAAK,IAAI,KAAK,KAAK,UAAU,EAAM,EAChD,IAAS,IAAI,KAAK,UAClB,IAAQ,KAAK,KAAK,IAAI,KAAK,KAAK,UAAU,EAAO;AAEvD,MAAI,KAAU,KAAS,KAAU,EAC/B,OAAM,IAAI,EAAiB,wCAAwC;AAErE,MAAI,IAAS,KAAK,IAAS,KAAK,IAAQ,KAAS,IAAQ,EACvD,OAAM,IAAI,EAAiB,+BAA+B;AAG5D,SAAO,CAAC,EAAK,MAAM,GAAQ,EAAM,EAAE,EAAK,MAAM,GAAQ,EAAM,CAAC;;CAG/D,MAAc,OACZ,GACA,GACoC;AACpC,SAAO,MAAM,EAAa,KAAK,MAAM,GAAW,EAAE,WAAQ,CAAC;;CAG7D,MAAM,UAAU,EAAE,cAAW,aAAgE;EAC3F,IAAM,IAAM,KAAK,WAAW,GAAW;GAAE,GAAG;GAAM,GAAG;GAAM,CAAC,EACtD,IAAS,MAAM,KAAK,OAAO,GAAK,EAAO,EACvC,CAAC,GAAQ,KAAS,EACtB,EAAO,OACP,KAAK,KAAK,OACV,KAAK,OACN;AACD,SAAO;GAAE,MAAM,EAAO;GAAM;GAAO;GAAQ;;CAG7C,MAAM,QAAQ,EACZ,MACA,MACA,cACA,aAMC;EACD,IAAM,CAAC,GAAQ,KAAU,KAAK,UAAU,GAAG,EAAE,EACvC,IAAM,KAAK,WAAW,GAAW;GAAE,GAAG;GAAQ,GAAG;GAAQ,CAAC,EAC1D,IAAS,MAAM,KAAK,OAAO,GAAK,EAAO,EACvC,CAAC,GAAQ,KAAS,EACtB,EAAO,OACP,KAAK,KAAK,OACV,KAAK,OACN;AACD,SAAO;GAAE,MAAM,EAAO;GAAM;GAAO;GAAQ;;CAG7C,YAAY,GAAY;AACtB,MAAI,EAAE,aAAe,GACnB,OAAM;;;AAKZ,eAAe,EAAgB,GAA2B;CACxD,IAAM,IAAW,MAAM,EAAK,8BAA8B,EAAM,EAC1D,IAAO,EAAK,KAAK,EAAS,EAE1B,IAAY,GADJ,MAAM,EAAK,KAAK,GAAM,EAAE,MAAM,SAAS,CAAC,EACd,MAAM,EACxC,IAAkB,EAAU,cAAc,IAC1C,IAAkB,GAAiB,UAAU,KAAK,MAAY,EAAQ,KAAK,IAAI,CAAC,IAAI,EACpF,IAAS,EAAe,GAAiB,KAAK;AAIpD,QAAO;EAAE,MAHsC,MAAM,QAAQ,IAC3D,EAAM,KAAK,MAAiB,EAAK,KAAK,EAAK,QAAQ,EAAK,EAAE,EAAE,MAAM,SAAS,CAAC,CAAC,CAC9E;EACc;EAAQ;EAAW;;AAIpC,eAAsB,EACpB,GACqC;CACrC,IAAM,EAAE,SAAM,cAAW,MAAM,EAAgB,EAAM;AACrD,KAAI,EAAK,WAAW,EAClB,OAAU,MAAM,+DAA+D;CAEjF,IAAM,IAAW,EAAc,EAAK,IAAI,EAAO;AAC/C,QAAO,EAAK,KAAK,MAAmC,IAAI,EAAgB,GAAK,GAAQ,EAAS,CAAC;;;;AChTjG,IAAM,IAAU,IAAI,aAAa;AAEjC,SAAS,EAAgB,GAAiD;AACxE,QAAO,OAAO,KAAW;;AAG3B,SAAS,EAAgB,GAA6D;AACpF,QAAO,cAAc,KAAS,OAAO,EAAM,YAAa;;AAG1D,SAAS,EAAsB,GAAwB;AACrD,QAAO,EAAO,QAAQ,QAAQ,GAAG;;AAGnC,SAAS,EAAe,GAAgC;AACtD,QAAO,OAAO,KAAW,WAAW,IAAS;;AAG/C,SAAS,EACP,GACA,GACqB;CACrB,IAAM,IAAW,MAAS,MAAM,KAAK;AAIrC,QAHI,MAAS,UACJ,CAAC,GAAG,EAAS,aAAa,GAAG,EAAS,UAAU,GAElD,CAAC,GAAG,EAAS,aAAa,GAAG,EAAS,UAAU;;AAGzD,eAAe,EACb,GACA,GACA,GACgC;AAChC,MAAK,IAAM,KAAe,EAAoB,GAAM,EAAK,EAAE;EACzD,IAAM,IAAQ,MAAM,EAAM,IAAI,EAAY;AAC1C,MAAI,EACF,QAAO,KAAK,MAAM,EAAQ,OAAO,EAAM,CAAC;;;AAM9C,eAAe,EACb,GACA,GACA,GACoB;AASpB,QARI,MAAS,MACJ,EAAK,SAIZ,MAAS,UACL,MAAM,EAAK,KAAK,EAAK,QAAQ,EAAK,EAAE,EAAE,MAAM,SAAS,CAAC,GACtD,MAAM,EAAK,KAAK,EAAK,QAAQ,EAAK,EAAE,EAAE,MAAM,SAAS,CAAC,EAChD;;AAGd,SAAS,EACP,GACA,GACQ;AAGR,QAFe,EAAE,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CAAC,SAClC,EAAE,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CAAC;;AAInD,eAAe,GAAmB,GAAwD;CACxF,IAAM,IAAO,MAAM,EAAK,KAAK,GAAO,EAAE,MAAM,SAAS,CAAC,EAChD,IAAiB,GACpB,IAAY,EAAK,OACnB,EACK,IAAW,EAAM,UAAU,CAAC,KAAK,EAAoB;AAE3D,MAAK,IAAM,EAAE,SAAM,aAAU,GAAU;AACrC,MAAI,MAAS,IAAK;EAElB,IAAM,IAAY,EAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,EAC7C,IAAc;AAElB,OAAK,IAAM,CAAC,GAAO,MAAS,EAAU,SAAS,EAAE;AAC/C,OAAI,EAAE,KAAQ,GAGZ,KAFe,MAAU,EAAU,SAAS,EAG1C,GAAY,KAAQ,EAAE;QACjB;IACL,IAAM,IAAe,IAAI,EAAU,MAAM,GAAG,IAAQ,EAAE,CAAC,KAAK,IAAI,IAC1D,IAAQ,MAAM,EAAc,GAAM,GAAc,EAAK;AAE3D,QAAI,MAAS,SAAS;KACpB,IAAM,IAAgB,MAAM,EAAiB,GAAO,GAAc,QAAQ;AAC1E,SAAI,CAAC,EACH,OAAU,MAAM,+BAA+B,EAAa,GAAG;AAQjE,OAAY,KALmC;OAC5C,IAAY;OACZ,IAAa;MACd,WAAW,EAAK,KAAK,EAAK,QAAQ,EAAa,EAAE,EAAE,MAAM,SAAS,CAAC;MACpE;UAGD,GAAY,KAAQ,GACjB,IAAY,GACd;;AAKP,OAAc,EAAY;;;AAI9B,QAAO;;AAGT,eAAe,GAAqB,GAA+D;CACjG,IAAM,IAAQ,EAAgB,EAAO,GACjC,IACA,IAAI,EAAK,WAAW,EAAsB,EAAO,CAAC;AAEtD,KAAI,EAAgB,EAAM,CACxB,QAAO;AAGT,KAAI;AACF,SAAO,MAAM,EAAK,yBAAyB,EAA4B;UAChE,GAAc;AACrB,MAAI;AACF,UAAO,MAAM,EAAK,yBAAyB,GAA6B;IACtE,QAAQ;IACR,aAAa;IACd,CAAC;UACI;AACN,SAAM;;;;AAQZ,eAAsB,GACpB,GACoC;AACpC,KAAI;EACF,IAAM,IAAe,MAAM,GAAqB,EAAO;AAEvD,SAAO,EAAG;GAAE;GAAc,MADb,MAAM,GAAmB,EAAa;GACnB,CAAC;UAC1B,GAAO;EACd,IAAM,IAAe,aAAiB,QAAQ,EAAM,UAAU,OAAO,EAAM;AAC3E,SAAO,EAAI,gBAAI,MAAM,8BAA8B,EAAe,EAAO,CAAC,KAAK,IAAe,CAAC;;;AAOnG,SAAgB,EAAkB,GAAkC;AAClE,KAAoB,OAAO,KAAQ,aAA/B,EAAyC,QAAO;CAEpD,IAAM,IAAkC,EAAE;AAK1C,CAHI,KAAa,KAAO,EAAI,OAC1B,EAAO,SAAS,EAAI,KAElB,KAAc,KAAO,EAAI,OAC3B,EAAO,UAAU,EAAI;AAGvB,MAAK,IAAM,KAAO,EAChB,KAAI,OAAO,UAAU,eAAe,KAAK,GAAK,EAAI,EAAE;EAElD,IAAM,IAAM,EAAI;AAChB,EAAI,OAAO,KAAQ,aACjB,EAAO,KAAO,eAEd,EAAO,KAAO,EAAkB,EAAI;;AAK1C,QAAO"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/result.ts","../src/types.ts","../src/prefixedStore.ts","../src/codecs.ts","../src/htj2k-encode.ts","../src/omeZarr.ts","../src/index.ts"],"sourcesContent":["/**\n * Result type for explicit error handling without exceptions.\n * Inspired by Rust's Result<T, E>.\n *\n * This type is useful for operations that can fail, especially in zarr operations\n * where errors should be handled explicitly rather than thrown as exceptions.\n *\n * Note: This is a custom implementation for simplicity. We may review using\n * an existing Result library (such as neverthrow) in the future,\n * but for now this provides a lightweight, dependency-free solution.\n */\n\n/**\n * A Result type for explicit error handling without exceptions.\n * Inspired by Rust's Result<T, E>.\n */\nexport type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };\n\n/** Create a successful Result */\nexport const Ok = <T>(value: T): Result<T, never> => ({ ok: true, value });\n\n/** Create a failed Result */\nexport const Err = <E>(error: E): Result<never, E> => ({ ok: false, error });\n\n/** Type guard for Ok results */\nexport const isOk = <T, E>(result: Result<T, E>): result is { ok: true; value: T } => result.ok;\n\n/** Type guard for Err results */\nexport const isErr = <T, E>(result: Result<T, E>): result is { ok: false; error: E } => !result.ok;\n\n/**\n * Unwrap a Result, throwing if it's an error.\n * Use when you want to convert back to exception-based error handling.\n */\nexport const unwrap = <T, E>(result: Result<T, E>): T => {\n if (result.ok) return result.value;\n throw result.error instanceof Error ? result.error : new Error(String(result.error));\n};\n\n/**\n * Unwrap a Result with a default value for errors.\n */\nexport const unwrapOr = <T, E>(result: Result<T, E>, defaultValue: T): T => {\n return result.ok ? result.value : defaultValue;\n};\n","import type * as zarr from 'zarrita';\n\n/**\n * Supported inputs for opening a store.\n */\nexport type StoreReference = string | zarr.Readable;\n\ntype Store = zarr.Readable;\n\n/**\n * Zarr attributes type - a record of string keys to unknown values\n */\nexport type ZAttrsAny = Record<string, unknown>;\n\n/**\n * Symbol key for storing zarr attributes in the tree structure\n */\nexport const ATTRS_KEY = Symbol('attrs');\n\n/**\n * Symbol key for storing zarr array metadata\n */\nexport const ZARRAY_KEY = Symbol('.zarray');\n\n/**\n * Lazy zarr array type - represents a zarr array with a `get()` method for loading it,\n * and `.zarray` from consolidated metadata.\n */\nexport type LazyZarrArray<T extends zarr.DataType> = {\n [ATTRS_KEY]?: ZAttrsAny;\n [ZARRAY_KEY]: ZAttrsAny;\n get: () => Promise<zarr.Array<T>>;\n};\n\n/**\n * Zarr tree type\n *\n * This is a tree of zarr arrays and groups, with the leaves being lazy arrays.\n * It is used to represent the structure of the zarr store.\n * Leaf type subject to change.\n */\nexport interface ZarrTree {\n [ATTRS_KEY]?: ZAttrsAny;\n [key: string]: ZarrTree | LazyZarrArray<zarr.DataType>;\n}\n\n/**\n * Zarr v3 array node metadata\n */\nexport type ZarrV3ArrayNode = {\n shape: number[];\n data_type: string;\n chunk_grid: {\n name: string;\n configuration: {\n chunk_shape: number[];\n };\n };\n chunk_key_encoding: {\n name: string;\n configuration: {\n separator: string;\n };\n };\n fill_value: number | string | boolean;\n codecs: Array<{\n name: string;\n configuration?: Record<string, unknown>;\n }>;\n attributes: Record<string, unknown>;\n dimension_names: string[];\n zarr_format: number;\n node_type: 'array';\n storage_transformers: unknown[];\n};\n\n/**\n * Zarr v3 group node metadata\n */\nexport type ZarrV3GroupNode = {\n attributes: Record<string, unknown>;\n zarr_format: number;\n consolidated_metadata: {\n kind: string;\n must_understand: boolean;\n metadata: Record<string, unknown>;\n };\n node_type: 'group';\n};\n\n/**\n * Zarr v3 consolidated metadata structure (zarr.json)\n * The actual structure has metadata nested under consolidated_metadata.metadata\n * with path keys like \"images/blobs_image\", \"labels/blobs_labels\", etc.\n * Each entry can be either a group node or an array node.\n */\nexport type ZarrV3Metadata = {\n attributes: Record<string, unknown>;\n zarr_format: number;\n consolidated_metadata: {\n kind: string;\n must_understand: boolean;\n metadata: Record<string, ZarrV3GroupNode | ZarrV3ArrayNode>;\n };\n node_type: 'group';\n};\n\n/**\n * This type is liable to change in future - for now, it has `zarritaStore` which is the `ListableStore` from `zarrita`,\n * and `tree: ZarrTree` which has the object hierarchy as described in the consolidated metadata as a mostly \"Plain Old Javascript Object\",\n * but with (weakly typed) `Symbol`-keyed `attrs` & `.zarray` properties where available, and a `get()` on leaf nodes\n * for requesting array data.\n *\n * The use of `Symbol('attrs')` is intended to make these properties easy to access, but not appear when using `Object.keys()` etc.\n */\nexport type ConsolidatedStore = {\n zarritaStore: zarr.Listable<Store>;\n tree: ZarrTree;\n};\n","import type * as zarr from 'zarrita';\n\nfunction toAbsolutePath(path: string): zarr.AbsolutePath {\n const trimmed = path.replace(/^\\/+|\\/+$/g, '');\n // Zarrita brands absolute paths as template-literal types; normalization above enforces it.\n return (trimmed ? `/${trimmed}` : '/') as zarr.AbsolutePath;\n}\n\nfunction joinAbsolutePath(prefix: string, key: zarr.AbsolutePath): zarr.AbsolutePath {\n const normalizedPrefix = toAbsolutePath(prefix);\n if (normalizedPrefix === '/') {\n return key;\n }\n if (key === '/') {\n return normalizedPrefix;\n }\n // Both sides are absolute Zarr paths; concatenating preserves the leading slash.\n return `${normalizedPrefix}${key}` as zarr.AbsolutePath;\n}\n\n/**\n * Create a read-only store view rooted at `prefix`.\n *\n * This is useful when callers have a SpatialData root store but a downstream\n * reader expects the supplied store root to be an individual image/table group.\n */\nexport function createPrefixedStore(store: zarr.Readable, prefix: string): zarr.AsyncReadable {\n return {\n async get(key: zarr.AbsolutePath, opts?: zarr.GetOptions) {\n return await store.get(joinAbsolutePath(prefix, key), opts);\n },\n getRange: store.getRange\n ? async (key: zarr.AbsolutePath, range: zarr.RangeQuery, opts?: zarr.GetOptions) =>\n await store.getRange?.(joinAbsolutePath(prefix, key), range, opts)\n : undefined,\n };\n}\n","import * as zarr from 'zarrita';\n\ntype ChunkMetadata<D extends zarr.DataType = zarr.DataType> = {\n dataType: D;\n shape: number[];\n codecs: zarr.CodecMetadata[];\n fillValue: zarr.Scalar<D> | null;\n};\n\n/** Chunk metadata from zarrita (camelCase) or fizarrita workers (snake_case). */\ntype ChunkMetadataInput = Partial<ChunkMetadata> & {\n data_type?: zarr.DataType;\n chunk_shape?: number[];\n fill_value?: zarr.Scalar<zarr.DataType> | null;\n};\n\nfunction normalizeChunkMetadata(meta: ChunkMetadataInput): ChunkMetadata {\n const dataType = meta.dataType ?? meta.data_type;\n const shape = meta.shape ?? meta.chunk_shape;\n if (!dataType) {\n throw new Error('Chunk metadata is missing dataType / data_type.');\n }\n if (!shape) {\n throw new Error('Chunk metadata is missing shape / chunk_shape.');\n }\n return {\n dataType,\n shape,\n codecs: meta.codecs ?? [],\n fillValue: meta.fillValue ?? meta.fill_value ?? null,\n };\n}\n\ntype Codec = {\n kind?: 'array_to_array' | 'array_to_bytes' | 'bytes_to_bytes';\n encode(data: unknown): Promise<Uint8Array> | Uint8Array;\n decode(data: Uint8Array): Promise<zarr.Chunk<zarr.DataType>> | zarr.Chunk<zarr.DataType>;\n};\n\ntype CodecEntry = {\n kind?: Codec['kind'];\n fromConfig: (config: unknown, meta: ChunkMetadata) => Codec;\n};\n\nexport type DecodedImageBytes = ArrayBuffer | ArrayBufferView;\n\nexport type ImageCodecDecoder = (\n encoded: Uint8Array,\n meta: ChunkMetadata,\n config: unknown\n) => Promise<DecodedImageBytes> | DecodedImageBytes;\n\nexport interface RegisterImageCodecOptions {\n /**\n * Override the codec ids registered into Zarrita's global registry.\n * Defaults include the standard registry id and a pragmatic alias.\n */\n ids?: string[];\n /** Custom decoder used by tests or applications with their own WASM loading. */\n decoder?: ImageCodecDecoder;\n /** Optional Emscripten locateFile hook for bundled WASM decoders. */\n locateFile?: (path: string, prefix: string) => string;\n}\n\nexport type OpenJpegFactory = (opts?: {\n locateFile?: RegisterImageCodecOptions['locateFile'];\n}) => Promise<Record<string, unknown>> | Record<string, unknown>;\n\nexport type OpenJphFactory = (opts?: {\n locateFile?: RegisterImageCodecOptions['locateFile'];\n}) => Promise<Record<string, unknown>> | Record<string, unknown>;\n\n/** Emscripten locateFile hook that resolves bundled codec WASM to a bundler URL. */\nexport function createWasmLocateFile(\n wasmUrl: string\n): NonNullable<RegisterImageCodecOptions['locateFile']> {\n return (path, _prefix) => (path.endsWith('.wasm') ? wasmUrl : path);\n}\n\nconst JPEG2K_CODEC_IDS = ['imagecodecs_jpeg2k', 'numcodecs.imagecodecs_jpeg2k', 'jpeg2k'];\nconst HTJ2K_OPENJPH_CODEC_ID = 'experimental.openjph_htj2k';\nconst HTJ2K_LEGACY_CODEC_IDS = [\n 'experimental.imagecodecs_htj2k',\n 'imagecodecs_htj2k',\n 'numcodecs.imagecodecs_htj2k',\n];\nconst HTJ2K_CODEC_IDS = [HTJ2K_OPENJPH_CODEC_ID, ...HTJ2K_LEGACY_CODEC_IDS];\n\nconst dynamicImport = new Function('specifier', 'return import(specifier)') as (\n specifier: string\n) => Promise<Record<string, unknown>>;\n\nfunction unsupportedEncode(codecName: string): never {\n throw new Error(`${codecName} encode is not implemented in zarrextra; decode-only for now.`);\n}\n\nfunction toUint8Array(data: DecodedImageBytes): Uint8Array {\n if (data instanceof Uint8Array) {\n return data;\n }\n if (ArrayBuffer.isView(data)) {\n return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n }\n return new Uint8Array(data);\n}\n\nfunction copyArrayBufferView(bytes: Uint8Array): ArrayBuffer {\n const copy = new ArrayBuffer(bytes.byteLength);\n new Uint8Array(copy).set(bytes);\n return copy;\n}\n\nfunction product(values: number[]): number {\n return values.reduce((acc, value) => acc * value, 1);\n}\n\nfunction getStrides(shape: number[]): number[] {\n const stride = new Array<number>(shape.length);\n let step = 1;\n for (let index = shape.length - 1; index >= 0; index -= 1) {\n stride[index] = step;\n step *= shape[index] ?? 1;\n }\n return stride;\n}\n\nfunction typedArrayFromDecodedBytes(\n decoded: DecodedImageBytes,\n meta: ChunkMetadata\n): zarr.TypedArray<zarr.DataType> {\n if (Array.isArray(decoded)) {\n throw new Error('Image codec decoder returned a plain array; expected binary data.');\n }\n\n const decodedBytes = toUint8Array(decoded);\n const buffer = copyArrayBufferView(decodedBytes);\n const expectedValues = product(meta.shape);\n\n let data: zarr.TypedArray<zarr.DataType>;\n switch (meta.dataType) {\n case 'uint8':\n data = new Uint8Array(buffer);\n break;\n case 'int8':\n data = new Int8Array(buffer);\n break;\n case 'uint16':\n data = new Uint16Array(buffer);\n break;\n case 'int16':\n data = new Int16Array(buffer);\n break;\n case 'uint32':\n data = new Uint32Array(buffer);\n break;\n case 'int32':\n data = new Int32Array(buffer);\n break;\n case 'float32':\n data = new Float32Array(buffer);\n break;\n case 'float64':\n data = new Float64Array(buffer);\n break;\n default:\n throw new Error(`Image codec does not support Zarrita dtype '${meta.dataType}'.`);\n }\n\n if (data.length !== expectedValues) {\n throw new Error(\n `Image codec decoded ${data.length} values, expected ${expectedValues} for chunk shape ` +\n `[${meta.shape.join(', ')}].`\n );\n }\n\n return data;\n}\n\nfunction createImageCodecEntry(\n codecName: string,\n decoder: ImageCodecDecoder\n): () => Promise<CodecEntry> {\n return async () => ({\n kind: 'array_to_bytes',\n fromConfig(config: unknown, meta: ChunkMetadataInput): Codec {\n const chunkMeta = normalizeChunkMetadata(meta);\n return {\n kind: 'array_to_bytes',\n encode: () => unsupportedEncode(codecName),\n async decode(encoded: Uint8Array) {\n const decoded = await decoder(encoded, chunkMeta, config);\n return {\n data: typedArrayFromDecodedBytes(decoded, chunkMeta),\n shape: chunkMeta.shape,\n stride: getStrides(chunkMeta.shape),\n };\n },\n };\n },\n });\n}\n\n/**\n * Adapt zarrita's built-in registry codecs for fizarrita's worker metadata\n * (`data_type`, `chunk_shape`) before fizarrita's codec worker loads.\n */\nexport function wrapZarrRegistryForFizarritaWorker() {\n const { registry } = zarr;\n for (const [id, factory] of [...registry.entries()]) {\n registry.set(id, async () => {\n const entry = await factory();\n if (typeof entry.fromConfig !== 'function') {\n return entry;\n }\n const fromConfig = entry.fromConfig.bind(entry);\n return {\n ...entry,\n fromConfig(config: unknown, meta: ChunkMetadataInput) {\n return fromConfig(config, normalizeChunkMetadata(meta));\n },\n };\n });\n }\n}\n\nexport function createOpenJpegDecoder(\n factory: OpenJpegFactory,\n options: Pick<RegisterImageCodecOptions, 'locateFile'> = {}\n): ImageCodecDecoder {\n let runtimePromise: Promise<Record<string, unknown>> | undefined;\n async function getRuntime() {\n runtimePromise ??= Promise.resolve(\n factory({\n locateFile: options.locateFile,\n })\n );\n return await runtimePromise;\n }\n return async (encoded) => {\n const runtime = await getRuntime();\n const Decoder = runtime.J2KDecoder as\n | (new () => {\n getEncodedBuffer(length: number): Uint8Array;\n decode(): void;\n getDecodedBuffer(): DecodedImageBytes;\n })\n | undefined;\n if (!Decoder) {\n throw new Error('OpenJPEG runtime does not expose J2KDecoder.');\n }\n const decoder = new Decoder();\n decoder.getEncodedBuffer(encoded.length).set(encoded);\n decoder.decode();\n return decoder.getDecodedBuffer();\n };\n}\n\nasync function loadOpenJpegDecoder(options: RegisterImageCodecOptions): Promise<ImageCodecDecoder> {\n const mod = await dynamicImport('@cornerstonejs/codec-openjpeg/decode').catch(() =>\n dynamicImport('@cornerstonejs/codec-openjpeg')\n );\n const factory = (mod.default ?? mod.OpenJPEGJS ?? mod.OpenJPEGWASM ?? mod) as unknown;\n if (typeof factory !== 'function') {\n throw new Error('Could not find an OpenJPEG factory export in @cornerstonejs/codec-openjpeg.');\n }\n return createOpenJpegDecoder(factory as OpenJpegFactory, options);\n}\n\ntype Htj2kDecoderClass = new () => {\n getEncodedBuffer(length: number): Uint8Array;\n decode(): void;\n getDecodedBuffer(): DecodedImageBytes;\n};\n\nexport function createOpenJphDecoder(\n factory: OpenJphFactory,\n options: Pick<RegisterImageCodecOptions, 'locateFile'> = {}\n): ImageCodecDecoder {\n let runtimePromise: Promise<Record<string, unknown>> | undefined;\n async function getRuntime() {\n runtimePromise ??= Promise.resolve(\n factory({\n locateFile: options.locateFile,\n })\n );\n return await runtimePromise;\n }\n return async (encoded) => {\n const runtime = await getRuntime();\n const Decoder = (runtime.HTJ2KDecoder ?? runtime.JPHDecoder ?? runtime.J2KDecoder) as\n | Htj2kDecoderClass\n | undefined;\n if (!Decoder) {\n throw new Error(\n 'OpenJPH runtime does not expose a known decoder class; pass a custom decoder option.'\n );\n }\n const decoder = new Decoder();\n decoder.getEncodedBuffer(encoded.length).set(encoded);\n decoder.decode();\n return decoder.getDecodedBuffer();\n };\n}\n\nasync function loadOpenJphDecoder(options: RegisterImageCodecOptions): Promise<ImageCodecDecoder> {\n const factoryMod = await dynamicImport('@cornerstonejs/codec-openjph/wasmjs').catch(() =>\n dynamicImport('@cornerstonejs/codec-openjph')\n );\n const factory = (factoryMod.default ?? factoryMod.OpenJPHJS ?? factoryMod) as unknown;\n if (typeof factory !== 'function') {\n throw new Error('Could not find an OpenJPH factory export in @cornerstonejs/codec-openjph.');\n }\n const wasmMod = await dynamicImport('@cornerstonejs/codec-openjph/wasm').catch(() => null);\n const wasmAsset = wasmMod ? ((wasmMod.default ?? wasmMod) as string | undefined) : undefined;\n const locateFile =\n options.locateFile ?? (wasmAsset ? createWasmLocateFile(wasmAsset) : undefined);\n return createOpenJphDecoder(factory as OpenJphFactory, { locateFile });\n}\n\nfunction registerImageCodec(\n codecName: string,\n defaultIds: string[],\n defaultDecoder: (options: RegisterImageCodecOptions) => Promise<ImageCodecDecoder>,\n options: RegisterImageCodecOptions = {}\n) {\n const ids = options.ids ?? defaultIds;\n let decoderPromise: Promise<ImageCodecDecoder> | undefined;\n const getDecoder = async () => {\n decoderPromise ??= Promise.resolve(options.decoder ?? defaultDecoder(options));\n return await decoderPromise;\n };\n\n for (const id of ids) {\n (zarr.registry as Map<string, () => Promise<unknown>>).set(\n id,\n createImageCodecEntry(codecName, async (encoded, meta, config) => {\n const decoder = await getDecoder();\n return await decoder(encoded, meta, config);\n })\n );\n }\n}\n\n/** Register decode support for the standard `imagecodecs_jpeg2k` Zarr codec id. */\nexport function registerJpeg2kCodec(options: RegisterImageCodecOptions = {}) {\n registerImageCodec('imagecodecs_jpeg2k', JPEG2K_CODEC_IDS, loadOpenJpegDecoder, options);\n}\n\n/**\n * Register HTJ2K decode support for OpenJPH-encoded stores and legacy ids.\n *\n * New writes use `experimental.openjph_htj2k`. Older fixtures may use\n * `experimental.imagecodecs_htj2k`; both decode through the same OpenJPH WASM path.\n */\nexport function registerExperimentalHtj2kCodec(options: RegisterImageCodecOptions = {}) {\n registerImageCodec(\n HTJ2K_OPENJPH_CODEC_ID,\n HTJ2K_CODEC_IDS,\n loadOpenJphDecoder,\n options\n );\n}\n","import { createWasmLocateFile, type OpenJphFactory, type RegisterImageCodecOptions } from './codecs';\n\nexport type Htj2kPlaneDtype = 'uint8' | 'int8' | 'uint16' | 'int16';\n\nexport type Htj2kEncodeOptions = {\n /** Lossless when true. Defaults to true for fixture-style writes. */\n reversible?: boolean;\n /** OpenJPH quantization factor when irreversible (lower = higher fidelity, larger output). */\n quality?: number;\n locateFile?: RegisterImageCodecOptions['locateFile'];\n};\n\ntype Htj2kFrameInfo = {\n width: number;\n height: number;\n bitsPerSample: 8 | 16;\n isSigned: boolean;\n componentCount: 1;\n isUsingColorTransform: false;\n};\n\ntype Htj2kEncoderClass = new () => {\n /** OpenJPH WASM API: `setQuality(reversible, quality)`; quality is a quantization factor (lower = better). */\n setQuality(reversible: boolean, quality: number): void;\n getDecodedBuffer(frame: Htj2kFrameInfo): ArrayBufferView;\n encode(): void;\n getEncodedBuffer(): Uint8Array;\n};\n\nexport type OpenJphEncoder = (\n plane: Uint8Array | Uint16Array | Int8Array | Int16Array,\n size: { width: number; height: number },\n options?: Pick<Htj2kEncodeOptions, 'reversible' | 'quality'>\n) => Promise<Uint8Array>;\n\nconst dynamicImport = new Function('specifier', 'return import(specifier)') as (\n specifier: string\n) => Promise<Record<string, unknown>>;\n\nfunction bitsPerSampleForPlane(\n plane: Uint8Array | Uint16Array | Int8Array | Int16Array\n): 8 | 16 {\n return plane instanceof Uint16Array || plane instanceof Int16Array ? 16 : 8;\n}\n\nfunction isSignedPlane(plane: Uint8Array | Uint16Array | Int8Array | Int16Array): boolean {\n return plane instanceof Int8Array || plane instanceof Int16Array;\n}\n\nfunction frameInfoForPlane(\n plane: Uint8Array | Uint16Array | Int8Array | Int16Array,\n size: { width: number; height: number }\n): Htj2kFrameInfo {\n const { width, height } = size;\n const expectedValues = width * height;\n if (plane.length !== expectedValues) {\n throw new Error(\n `HTJ2K plane has ${plane.length} samples, expected ${expectedValues} for ${width}x${height}.`\n );\n }\n return {\n width,\n height,\n bitsPerSample: bitsPerSampleForPlane(plane),\n isSigned: isSignedPlane(plane),\n componentCount: 1,\n isUsingColorTransform: false,\n };\n}\n\n/** Create an HTJ2K encoder backed by an OpenJPH WASM factory. */\nexport function createOpenJphEncoder(\n factory: OpenJphFactory,\n options: Pick<Htj2kEncodeOptions, 'locateFile'> = {}\n): OpenJphEncoder {\n let runtimePromise: Promise<Record<string, unknown>> | undefined;\n\n async function getRuntime() {\n runtimePromise ??= Promise.resolve(\n factory({\n locateFile: options.locateFile,\n })\n );\n return await runtimePromise;\n }\n\n return async (plane, size, encodeOptions = {}) => {\n const runtime = await getRuntime();\n const Encoder = runtime.HTJ2KEncoder as Htj2kEncoderClass | undefined;\n if (!Encoder) {\n throw new Error('OpenJPH runtime does not expose HTJ2KEncoder.');\n }\n\n const reversible = encodeOptions.reversible ?? true;\n const quality = encodeOptions.quality ?? 0;\n const frame = frameInfoForPlane(plane, size);\n const encoder = new Encoder();\n encoder.setQuality(reversible, quality);\n\n const buffer = encoder.getDecodedBuffer(frame);\n const target =\n frame.bitsPerSample === 16\n ? new Uint16Array(buffer.buffer, buffer.byteOffset, plane.length)\n : new Uint8Array(buffer.buffer, buffer.byteOffset, plane.length);\n target.set(plane);\n encoder.encode();\n return encoder.getEncodedBuffer();\n };\n}\n\n/** Load the optional OpenJPH WASM encoder from @cornerstonejs/codec-openjph. */\nexport async function loadOpenJphEncoder(\n options: Htj2kEncodeOptions = {}\n): Promise<OpenJphEncoder> {\n const factoryMod = await dynamicImport('@cornerstonejs/codec-openjph/wasmjs').catch(() =>\n dynamicImport('@cornerstonejs/codec-openjph')\n );\n const factory = (factoryMod.default ?? factoryMod.OpenJPHJS ?? factoryMod) as unknown;\n if (typeof factory !== 'function') {\n throw new Error('Could not find an OpenJPH factory export in @cornerstonejs/codec-openjph.');\n }\n const wasmMod = await dynamicImport('@cornerstonejs/codec-openjph/wasm').catch(() => null);\n const wasmAsset = wasmMod ? ((wasmMod.default ?? wasmMod) as string | undefined) : undefined;\n const locateFile =\n options.locateFile ?? (wasmAsset ? createWasmLocateFile(wasmAsset) : undefined);\n return createOpenJphEncoder(factory as OpenJphFactory, { locateFile });\n}\n\nexport function planeArrayForDtype(\n dtype: Htj2kPlaneDtype,\n bytes: Uint8Array\n) {\n switch (dtype) {\n case 'uint8':\n return bytes;\n case 'int8':\n return new Int8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n case 'uint16':\n return new Uint16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2);\n case 'int16':\n return new Int16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2);\n default:\n throw new Error(`Unsupported HTJ2K plane dtype '${dtype}'.`);\n }\n}\n\n/** Encode one 2D plane to an HTJ2K bitstream. */\nexport async function encodeHtj2kPlane(\n plane: Uint8Array | Uint16Array | Int8Array | Int16Array,\n size: { width: number; height: number },\n options: Htj2kEncodeOptions = {}\n): Promise<Uint8Array> {\n const encoder = await loadOpenJphEncoder(options);\n return await encoder(plane, size, options);\n}\n","import * as zarr from 'zarrita';\nimport { getZarrChunk } from './chunkDecode';\n\nexport type RasterSelection = Record<string, number> | number[];\n\nexport interface VivCompatiblePixelSource {\n labels: string[];\n tileSize: number;\n shape: number[];\n dtype: string;\n meta?: { physicalSizes?: { x?: { size: number; unit: string } } };\n getRaster(props: { selection: RasterSelection; signal?: AbortSignal }): Promise<{\n data: unknown;\n width: number;\n height: number;\n }>;\n getTile(props: {\n x: number;\n y: number;\n selection: RasterSelection;\n signal?: AbortSignal;\n }): Promise<{\n data: unknown;\n width: number;\n height: number;\n }>;\n onTileError(err: Error): void;\n}\n\ntype OmeAxis = { name: string; type?: string; unit?: string };\ntype OmeMultiscaleAttrs = {\n datasets?: Array<{ path: string }>;\n axes?: Array<string | OmeAxis>;\n};\ntype OmeRootAttrs = {\n multiscales?: OmeMultiscaleAttrs[];\n omero?: unknown;\n [key: string]: unknown;\n};\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isOmeAxis(value: unknown): value is OmeAxis {\n return isObject(value) && typeof value.name === 'string';\n}\n\nfunction isOmeDataset(value: unknown): value is { path: string } {\n return isObject(value) && typeof value.path === 'string';\n}\n\nfunction isOmeMultiscaleAttrs(value: unknown): value is OmeMultiscaleAttrs {\n if (!isObject(value)) return false;\n const datasets = value.datasets;\n if (datasets !== undefined) {\n if (!Array.isArray(datasets)) return false;\n if (!datasets.every(isOmeDataset)) return false;\n }\n const axes = value.axes;\n if (axes !== undefined) {\n if (!Array.isArray(axes)) return false;\n if (!axes.every((axis) => typeof axis === 'string' || isOmeAxis(axis))) return false;\n }\n return true;\n}\n\nfunction getOmeRootAttrs(attrs: Record<string, unknown>): OmeRootAttrs {\n const candidate = isObject(attrs.ome) ? attrs.ome : attrs;\n if (!('multiscales' in candidate)) {\n return candidate;\n }\n if (!Array.isArray(candidate.multiscales)) {\n throw new Error('OME-Zarr `multiscales` attribute must be an array.');\n }\n if (!candidate.multiscales.every(isOmeMultiscaleAttrs)) {\n throw new Error('OME-Zarr `multiscales` entries must contain valid dataset paths and axes.');\n }\n return candidate;\n}\n\nfunction isInterleaved(shape: number[], labels?: string[]) {\n const lastDimSize = shape[shape.length - 1];\n if (lastDimSize !== 3 && lastDimSize !== 4) {\n return false;\n }\n if (labels?.some((label) => label.toLowerCase() === 'c')) {\n return false;\n }\n return true;\n}\n\nfunction axisIndex(labels: string[], axis: 'x' | 'y'): number {\n const index = labels.findIndex((label) => label.toLowerCase() === axis);\n if (index === -1) {\n throw new Error(`OME-Zarr labels must include '${axis}' axis.`);\n }\n return index;\n}\n\nfunction spatialAxisIndices(shape: number[], labels: string[]): { xIndex: number; yIndex: number } {\n if (isInterleaved(shape, labels)) {\n const len = shape.length;\n return { yIndex: len - 3, xIndex: len - 2 };\n }\n return { yIndex: axisIndex(labels, 'y'), xIndex: axisIndex(labels, 'x') };\n}\n\nfunction spatialDimensions(shape: number[], labels: string[]): [number, number] {\n const { xIndex, yIndex } = spatialAxisIndices(shape, labels);\n return [shape[yIndex] ?? 0, shape[xIndex] ?? 0];\n}\n\nfunction spatialDimensionsFromChunk(\n chunkShape: number[],\n sourceShape: number[],\n labels: string[]\n): [number, number] {\n if (isInterleaved(sourceShape, labels)) {\n const [height, width] = chunkShape.slice(-3);\n return [height ?? 0, width ?? 0];\n }\n if (chunkShape.length >= 2) {\n const [height, width] = chunkShape.slice(-2);\n return [height ?? 0, width ?? 0];\n }\n return [chunkShape[0] ?? 0, 0];\n}\n\nfunction getImageSize(source: { shape: number[]; labels: string[] }) {\n const [height, width] = spatialDimensions(source.shape, source.labels);\n return { height, width };\n}\n\nfunction prevPowerOf2(x: number): number {\n return 2 ** Math.floor(Math.log2(x));\n}\n\nfunction guessTileSize(arr: zarr.Array<zarr.DataType>, labels: string[]): number {\n if (isInterleaved(arr.shape, labels)) {\n const [yChunk, xChunk] = arr.chunks.slice(-3);\n return prevPowerOf2(Math.min(yChunk ?? 1, xChunk ?? 1));\n }\n const yChunk = arr.chunks[axisIndex(labels, 'y')];\n const xChunk = arr.chunks[axisIndex(labels, 'x')];\n return prevPowerOf2(Math.min(yChunk ?? 1, xChunk ?? 1));\n}\n\nfunction labelsFromAxes(axes: OmeMultiscaleAttrs['axes'] | undefined): string[] {\n if (!axes) return ['t', 'c', 'z', 'y', 'x'];\n return axes.map((axis) => (typeof axis === 'string' ? axis : axis.name));\n}\n\nfunction normalizeDtype(dtype: string): string {\n const lookup: Record<string, string> = {\n u1: 'Uint8',\n u2: 'Uint16',\n u4: 'Uint32',\n i1: 'Int8',\n i2: 'Int16',\n i4: 'Int32',\n f4: 'Float32',\n f8: 'Float64',\n uint8: 'Uint8',\n uint16: 'Uint16',\n uint32: 'Uint32',\n int8: 'Int8',\n int16: 'Int16',\n int32: 'Int32',\n float32: 'Float32',\n float64: 'Float64',\n };\n return lookup[dtype.toLowerCase()] ?? dtype.charAt(0).toUpperCase() + dtype.slice(1);\n}\n\nfunction getIndexer(labels: string[]) {\n const labelSet = new Set(labels);\n if (labelSet.size !== labels.length) {\n throw new Error('OME-Zarr labels must be unique.');\n }\n return (selection: RasterSelection): Array<number | zarr.Slice | null> => {\n if (Array.isArray(selection)) {\n return [...selection];\n }\n const indexed: Array<number | zarr.Slice | null> = Array(labels.length).fill(0);\n for (const [key, value] of Object.entries(selection)) {\n const index = labels.indexOf(key);\n if (index === -1) {\n throw new Error(`Invalid OME-Zarr selection axis '${key}'.`);\n }\n indexed[index] = value;\n }\n return indexed;\n };\n}\n\nclass BoundsCheckError extends Error {}\n\nclass ZarrPixelSource implements VivCompatiblePixelSource {\n private readonly indexer: ReturnType<typeof getIndexer>;\n\n constructor(\n private readonly data: zarr.Array<zarr.DataType>,\n public readonly labels: string[],\n public readonly tileSize: number\n ) {\n this.indexer = getIndexer(labels);\n }\n\n get shape() {\n return this.data.shape;\n }\n\n get dtype() {\n return normalizeDtype(this.data.dtype);\n }\n\n private chunkIndex(\n selection: RasterSelection,\n tile: { x: number | zarr.Slice | null; y: number | zarr.Slice | null }\n ) {\n const { xIndex, yIndex } = spatialAxisIndices(this.data.shape, this.labels);\n const sel = this.indexer(selection);\n sel[xIndex] = tile.x;\n sel[yIndex] = tile.y;\n return sel;\n }\n\n private getSlices(x: number, y: number) {\n const { height, width } = getImageSize(this);\n const xStart = x * this.tileSize;\n const xStop = Math.min((x + 1) * this.tileSize, width);\n const yStart = y * this.tileSize;\n const yStop = Math.min((y + 1) * this.tileSize, height);\n\n if (xStart >= xStop || yStart >= yStop) {\n throw new BoundsCheckError('Tile slice is zero-sized or inverted.');\n }\n if (xStart < 0 || yStart < 0 || xStop > width || yStop > height) {\n throw new BoundsCheckError('Tile slice is out of bounds.');\n }\n\n return [zarr.slice(xStart, xStop), zarr.slice(yStart, yStop)];\n }\n\n private async getRaw(\n selection: Array<number | zarr.Slice | null>,\n signal?: AbortSignal\n ): Promise<zarr.Chunk<zarr.DataType>> {\n return await getZarrChunk(this.data, selection, { signal });\n }\n\n async getRaster({ selection, signal }: { selection: RasterSelection; signal?: AbortSignal }) {\n const sel = this.chunkIndex(selection, { x: null, y: null });\n const result = await this.getRaw(sel, signal);\n const [height, width] = spatialDimensionsFromChunk(\n result.shape,\n this.data.shape,\n this.labels\n );\n return { data: result.data, width, height };\n }\n\n async getTile({\n x,\n y,\n selection,\n signal,\n }: {\n x: number;\n y: number;\n selection: RasterSelection;\n signal?: AbortSignal;\n }) {\n const [xSlice, ySlice] = this.getSlices(x, y);\n const sel = this.chunkIndex(selection, { x: xSlice, y: ySlice });\n const result = await this.getRaw(sel, signal);\n const [height, width] = spatialDimensionsFromChunk(\n result.shape,\n this.data.shape,\n this.labels\n );\n return { data: result.data, width, height };\n }\n\n onTileError(err: Error) {\n if (!(err instanceof BoundsCheckError)) {\n throw err;\n }\n }\n}\n\nasync function loadMultiscales(store: zarr.AsyncReadable) {\n const readable = await zarr.withMaybeConsolidatedMetadata(store);\n const root = zarr.root(readable);\n const group = await zarr.open(root, { kind: 'group' });\n const rootAttrs = getOmeRootAttrs(group.attrs);\n const firstMultiscale = rootAttrs.multiscales?.[0];\n const paths: string[] = firstMultiscale?.datasets?.map((dataset) => dataset.path) ?? ['0'];\n const labels = labelsFromAxes(firstMultiscale?.axes);\n const data: Array<zarr.Array<zarr.DataType>> = await Promise.all(\n paths.map((path: string) => zarr.open(root.resolve(path), { kind: 'array' }))\n );\n return { data, labels, rootAttrs };\n}\n\n/** Load an OME-Zarr multiscale image from a Zarrita readable store. */\nexport async function loadOmeZarrMultiscalesFromStore(\n store: zarr.AsyncReadable\n): Promise<VivCompatiblePixelSource[]> {\n const { data, labels } = await loadMultiscales(store);\n if (data.length === 0) {\n throw new Error('OME-Zarr multiscale dataset is empty or has no valid arrays.');\n }\n const tileSize = guessTileSize(data[0], labels);\n return data.map((arr: zarr.Array<zarr.DataType>) => new ZarrPixelSource(arr, labels, tileSize));\n}\n","import * as zarr from 'zarrita';\nimport { Err, Ok, type Result } from './result';\nimport type {\n ConsolidatedStore,\n LazyZarrArray,\n StoreReference,\n ZAttrsAny,\n ZarrTree,\n} from './types';\nimport { ATTRS_KEY, ZARRAY_KEY } from './types';\n\nconst decoder = new TextDecoder();\n\nfunction isReadableStore(source: StoreReference): source is zarr.Readable {\n return typeof source !== 'string';\n}\n\nfunction isListableStore(store: zarr.Readable): store is zarr.Listable<zarr.Readable> {\n return 'contents' in store && typeof store.contents === 'function';\n}\n\nfunction normalizeStringSource(source: string): string {\n return source.replace(/\\/+$/, '');\n}\n\nfunction describeSource(source: StoreReference): string {\n return typeof source === 'string' ? source : '[store instance]';\n}\n\nfunction metadataKeysForPath(\n path: zarr.AbsolutePath,\n kind: 'array' | 'group'\n): zarr.AbsolutePath[] {\n const basePath = path === '/' ? '' : path;\n if (kind === 'array') {\n return [`${basePath}/zarr.json`, `${basePath}/.zarray`] as zarr.AbsolutePath[];\n }\n return [`${basePath}/zarr.json`, `${basePath}/.zgroup`] as zarr.AbsolutePath[];\n}\n\nasync function readMetadataJson(\n store: zarr.Readable,\n path: zarr.AbsolutePath,\n kind: 'array' | 'group'\n): Promise<ZAttrsAny | undefined> {\n for (const metadataKey of metadataKeysForPath(path, kind)) {\n const bytes = await store.get(metadataKey);\n if (bytes) {\n return JSON.parse(decoder.decode(bytes)) as ZAttrsAny;\n }\n }\n return undefined;\n}\n\nasync function readNodeAttrs(\n root: zarr.Group<zarr.Readable>,\n path: zarr.AbsolutePath,\n kind: 'array' | 'group'\n): Promise<ZAttrsAny> {\n if (path === '/') {\n return root.attrs;\n }\n\n const node =\n kind === 'array'\n ? await zarr.open(root.resolve(path), { kind: 'array' })\n : await zarr.open(root.resolve(path), { kind: 'group' });\n return node.attrs;\n}\n\nfunction sortContentsByDepth(\n a: { path: zarr.AbsolutePath },\n b: { path: zarr.AbsolutePath }\n): number {\n const depthA = a.path.split('/').filter(Boolean).length;\n const depthB = b.path.split('/').filter(Boolean).length;\n return depthA - depthB;\n}\n\nasync function parseStoreContents(store: zarr.Listable<zarr.Readable>): Promise<ZarrTree> {\n const root = await zarr.open(store, { kind: 'group' });\n const tree: ZarrTree = {\n [ATTRS_KEY]: root.attrs,\n };\n const contents = store.contents().sort(sortContentsByDepth);\n\n for (const { path, kind } of contents) {\n if (path === '/') continue;\n\n const pathParts = path.split('/').filter(Boolean);\n let currentNode = tree;\n\n for (const [index, part] of pathParts.entries()) {\n if (!(part in currentNode)) {\n const isLeaf = index === pathParts.length - 1;\n\n if (!isLeaf) {\n currentNode[part] = {};\n } else {\n const absolutePath = `/${pathParts.slice(0, index + 1).join('/')}` as zarr.AbsolutePath;\n const attrs = await readNodeAttrs(root, absolutePath, kind);\n\n if (kind === 'array') {\n const arrayMetadata = await readMetadataJson(store, absolutePath, 'array');\n if (!arrayMetadata) {\n throw new Error(`Missing array metadata for '${absolutePath}'`);\n }\n\n const leafNode: LazyZarrArray<zarr.DataType> = {\n [ATTRS_KEY]: attrs,\n [ZARRAY_KEY]: arrayMetadata,\n get: () => zarr.open(root.resolve(absolutePath), { kind: 'array' }),\n };\n currentNode[part] = leafNode;\n } else {\n currentNode[part] = {\n [ATTRS_KEY]: attrs,\n };\n }\n }\n }\n\n currentNode = currentNode[part] as ZarrTree;\n }\n }\n\n return tree;\n}\n\nasync function resolveListableStore(source: StoreReference): Promise<zarr.Listable<zarr.Readable>> {\n const store = isReadableStore(source)\n ? source\n : new zarr.FetchStore(normalizeStringSource(source));\n\n if (isListableStore(store)) {\n return store;\n }\n\n try {\n return await zarr.withConsolidatedMetadata(store as zarr.AsyncReadable);\n } catch (defaultError) {\n try {\n return await zarr.withConsolidatedMetadata(store as zarr.AsyncReadable, {\n format: 'v2',\n metadataKey: 'zmetadata',\n });\n } catch {\n throw defaultError;\n }\n }\n}\n\n/**\n * Open a zarr store or store-backed source and return a parsed tree representation.\n */\nexport async function openExtraConsolidated(\n source: StoreReference\n): Promise<Result<ConsolidatedStore>> {\n try {\n const zarritaStore = await resolveListableStore(source);\n const tree = await parseStoreContents(zarritaStore);\n return Ok({ zarritaStore, tree });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return Err(new Error(`Failed to open zarr store '${describeSource(source)}': ${errorMessage}`));\n }\n}\n\n/**\n * Deep clone a ZarrTree, converting Symbol-keyed attrs to string keys for serialization/debugging\n */\nexport function serializeZarrTree(obj: ZarrTree | unknown): unknown {\n if (obj === null || typeof obj !== 'object') return obj;\n\n const result: Record<string, unknown> = {};\n\n if (ATTRS_KEY in obj && obj[ATTRS_KEY]) {\n result._attrs = obj[ATTRS_KEY];\n }\n if (ZARRAY_KEY in obj && obj[ZARRAY_KEY]) {\n result._zarray = obj[ZARRAY_KEY];\n }\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n // @ts-expect-error - Indexing unknown object for serialization.\n const val = obj[key];\n if (typeof val === 'function') {\n result[key] = '<function>';\n } else {\n result[key] = serializeZarrTree(val);\n }\n }\n }\n\n return result;\n}\n\nexport type {\n StoreReference,\n ZarrTree,\n ConsolidatedStore,\n LazyZarrArray,\n ZAttrsAny,\n} from './types';\nexport { ATTRS_KEY, ZARRAY_KEY } from './types';\nexport { createPrefixedStore } from './prefixedStore';\nexport {\n createOpenJpegDecoder,\n createOpenJphDecoder,\n createWasmLocateFile,\n registerJpeg2kCodec,\n registerExperimentalHtj2kCodec,\n type ImageCodecDecoder,\n type OpenJpegFactory,\n type OpenJphFactory,\n type RegisterImageCodecOptions,\n} from './codecs';\nexport {\n createOpenJphEncoder,\n encodeHtj2kPlane,\n loadOpenJphEncoder,\n planeArrayForDtype,\n type Htj2kEncodeOptions,\n type Htj2kPlaneDtype,\n type OpenJphEncoder,\n} from './htj2k-encode';\nexport {\n loadOmeZarrMultiscalesFromStore,\n type VivCompatiblePixelSource,\n type RasterSelection,\n} from './omeZarr';\n\nexport type { Result } from './result';\nexport { Ok, Err, isOk, isErr, unwrap, unwrapOr } from './result';\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAa,KAAK,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG3F,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,MAAM,8BAA8B,GAAG;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAa,KAAK,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG3F,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,MAAM,8BAA8B,GAAG;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB,CAAC;AAkBF,uFAAuF;AACvF,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,8BAAmC,cAoBnF;AAED,2EAA2E;AAC3E,wBAAgB,wBAAwB,SAMvC;AAED,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
|
package/dist/workers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as e, r as t } from "./chunkDecode-
|
|
1
|
+
import { n as e, r as t } from "./chunkDecode-CvE5qLLQ.js";
|
|
2
2
|
import { WorkerPool as n } from "@fideus-labs/worker-pool";
|
|
3
3
|
import { getWorker as r } from "@fideus-labs/fizarrita";
|
|
4
4
|
//#region src/workers/index.ts
|
|
@@ -7,7 +7,7 @@ function a() {
|
|
|
7
7
|
return typeof navigator < "u" && navigator.hardwareConcurrency ? Math.min(navigator.hardwareConcurrency, 4) : 4;
|
|
8
8
|
}
|
|
9
9
|
function o() {
|
|
10
|
-
return new URL("
|
|
10
|
+
return new URL("./codec-worker.js", import.meta.url);
|
|
11
11
|
}
|
|
12
12
|
t(r);
|
|
13
13
|
function s(t = {}) {
|
package/dist/workers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workers.js","names":[],"sources":["../src/workers/index.ts"],"sourcesContent":["import { WorkerPool } from '@fideus-labs/worker-pool';\nimport { getWorker, type ChunkCache, type GetWorkerOptions } from '@fideus-labs/fizarrita';\nimport { setChunkDecodeBackend, setFizarritaGetWorker } from '../chunkDecode';\n\nexport type { ChunkCache } from '@fideus-labs/fizarrita';\n\nexport type EnableWorkerChunkDecodeOptions = {\n workers?: number;\n workerUrl?: string | URL;\n useSharedArrayBuffer?: boolean;\n cache?: ChunkCache;\n};\n\nlet activePool: WorkerPool | undefined;\n\nfunction defaultWorkerCount() {\n if (typeof navigator !== 'undefined' && navigator.hardwareConcurrency) {\n return Math.min(navigator.hardwareConcurrency, 4);\n }\n return 4;\n}\n\nfunction defaultWorkerUrl() {\n
|
|
1
|
+
{"version":3,"file":"workers.js","names":[],"sources":["../src/workers/index.ts"],"sourcesContent":["import { WorkerPool } from '@fideus-labs/worker-pool';\nimport { getWorker, type ChunkCache, type GetWorkerOptions } from '@fideus-labs/fizarrita';\nimport { setChunkDecodeBackend, setFizarritaGetWorker } from '../chunkDecode';\n\nexport type { ChunkCache } from '@fideus-labs/fizarrita';\n\nexport type EnableWorkerChunkDecodeOptions = {\n workers?: number;\n workerUrl?: string | URL;\n useSharedArrayBuffer?: boolean;\n cache?: ChunkCache;\n};\n\nlet activePool: WorkerPool | undefined;\n\nfunction defaultWorkerCount() {\n if (typeof navigator !== 'undefined' && navigator.hardwareConcurrency) {\n return Math.min(navigator.hardwareConcurrency, 4);\n }\n return 4;\n}\n\nfunction defaultWorkerUrl() {\n const workerFile = './codec-worker.js';\n return new URL(workerFile, import.meta.url);\n}\n\nsetFizarritaGetWorker(getWorker);\n\n/** Enable fizarrita worker-pool chunk decode for all subsequent getZarrChunk reads. */\nexport function enableWorkerChunkDecode(options: EnableWorkerChunkDecodeOptions = {}) {\n if (activePool) {\n disableWorkerChunkDecode();\n }\n\n const pool = new WorkerPool(options.workers ?? defaultWorkerCount());\n activePool = pool;\n\n const workerUrl = options.workerUrl ?? defaultWorkerUrl();\n setChunkDecodeBackend({\n kind: 'fizarrita',\n pool,\n options: {\n workerUrl,\n useSharedArrayBuffer: options.useSharedArrayBuffer,\n cache: options.cache,\n },\n });\n\n return pool;\n}\n\n/** Terminate worker pool and restore main-thread zarr.get chunk decode. */\nexport function disableWorkerChunkDecode() {\n if (activePool) {\n activePool.terminateWorkers();\n activePool = undefined;\n }\n setChunkDecodeBackend({ kind: 'main' });\n}\n\nexport type { GetWorkerOptions };\n"],"mappings":";;;;AAaA,IAAI;AAEJ,SAAS,IAAqB;AAI5B,QAHI,OAAO,YAAc,OAAe,UAAU,sBACzC,KAAK,IAAI,UAAU,qBAAqB,EAAE,GAE5C;;AAGT,SAAS,IAAmB;AAE1B,QAAO,IAAI,IADQ,qBACQ,OAAO,KAAK,IAAI;;AAG7C,EAAsB,EAAU;AAGhC,SAAgB,EAAwB,IAA0C,EAAE,EAAE;AACpF,CAAI,KACF,GAA0B;CAG5B,IAAM,IAAO,IAAI,EAAW,EAAQ,WAAW,GAAoB,CAAC;AAcpE,QAbA,IAAa,GAGb,EAAsB;EACpB,MAAM;EACN;EACA,SAAS;GACP,WALc,EAAQ,aAAa,GAAkB;GAMrD,sBAAsB,EAAQ;GAC9B,OAAO,EAAQ;GAChB;EACF,CAAC,EAEK;;AAIT,SAAgB,IAA2B;AAKzC,CAJA,AAEE,OADA,EAAW,kBAAkB,EAChB,KAAA,IAEf,EAAsB,EAAE,MAAM,QAAQ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zarrextra",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Extra utilities for working with zarr stores using zarrita",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
"import": "./dist/index.js"
|
|
12
12
|
},
|
|
13
13
|
"./workers": {
|
|
14
|
-
"types": "./dist/workers.d.ts",
|
|
14
|
+
"types": "./dist/workers/index.d.ts",
|
|
15
15
|
"import": "./dist/workers.js"
|
|
16
|
+
},
|
|
17
|
+
"./codec-worker": {
|
|
18
|
+
"import": "./dist/codec-worker.js"
|
|
16
19
|
}
|
|
17
20
|
},
|
|
18
21
|
"files": [
|
|
@@ -47,7 +50,7 @@
|
|
|
47
50
|
"@fideus-labs/worker-pool": "^1.0.0"
|
|
48
51
|
},
|
|
49
52
|
"scripts": {
|
|
50
|
-
"build": "vite build",
|
|
53
|
+
"build": "vite build && vite build --mode codec-worker",
|
|
51
54
|
"dev": "vite build --watch",
|
|
52
55
|
"test": "vitest run",
|
|
53
56
|
"test:watch": "vitest",
|
package/dist/codecs-DNu3yP16.js
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import * as e from "zarrita";
|
|
2
|
-
//#region src/codecs.ts
|
|
3
|
-
function t(e) {
|
|
4
|
-
let t = e.dataType ?? e.data_type, n = e.shape ?? e.chunk_shape;
|
|
5
|
-
if (!t) throw Error("Chunk metadata is missing dataType / data_type.");
|
|
6
|
-
if (!n) throw Error("Chunk metadata is missing shape / chunk_shape.");
|
|
7
|
-
return {
|
|
8
|
-
dataType: t,
|
|
9
|
-
shape: n,
|
|
10
|
-
codecs: e.codecs ?? [],
|
|
11
|
-
fillValue: e.fillValue ?? e.fill_value ?? null
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
function n(e) {
|
|
15
|
-
return (t, n) => t.endsWith(".wasm") ? e : t;
|
|
16
|
-
}
|
|
17
|
-
var r = [
|
|
18
|
-
"imagecodecs_jpeg2k",
|
|
19
|
-
"numcodecs.imagecodecs_jpeg2k",
|
|
20
|
-
"jpeg2k"
|
|
21
|
-
], i = "experimental.openjph_htj2k", a = [i, ...[
|
|
22
|
-
"experimental.imagecodecs_htj2k",
|
|
23
|
-
"imagecodecs_htj2k",
|
|
24
|
-
"numcodecs.imagecodecs_htj2k"
|
|
25
|
-
]], o = Function("specifier", "return import(specifier)");
|
|
26
|
-
function s(e) {
|
|
27
|
-
throw Error(`${e} encode is not implemented in zarrextra; decode-only for now.`);
|
|
28
|
-
}
|
|
29
|
-
function c(e) {
|
|
30
|
-
return e instanceof Uint8Array ? e : ArrayBuffer.isView(e) ? new Uint8Array(e.buffer, e.byteOffset, e.byteLength) : new Uint8Array(e);
|
|
31
|
-
}
|
|
32
|
-
function l(e) {
|
|
33
|
-
let t = new ArrayBuffer(e.byteLength);
|
|
34
|
-
return new Uint8Array(t).set(e), t;
|
|
35
|
-
}
|
|
36
|
-
function u(e) {
|
|
37
|
-
return e.reduce((e, t) => e * t, 1);
|
|
38
|
-
}
|
|
39
|
-
function d(e) {
|
|
40
|
-
let t = Array(e.length), n = 1;
|
|
41
|
-
for (let r = e.length - 1; r >= 0; --r) t[r] = n, n *= e[r] ?? 1;
|
|
42
|
-
return t;
|
|
43
|
-
}
|
|
44
|
-
function f(e, t) {
|
|
45
|
-
if (Array.isArray(e)) throw Error("Image codec decoder returned a plain array; expected binary data.");
|
|
46
|
-
let n = l(c(e)), r = u(t.shape), i;
|
|
47
|
-
switch (t.dataType) {
|
|
48
|
-
case "uint8":
|
|
49
|
-
i = new Uint8Array(n);
|
|
50
|
-
break;
|
|
51
|
-
case "int8":
|
|
52
|
-
i = new Int8Array(n);
|
|
53
|
-
break;
|
|
54
|
-
case "uint16":
|
|
55
|
-
i = new Uint16Array(n);
|
|
56
|
-
break;
|
|
57
|
-
case "int16":
|
|
58
|
-
i = new Int16Array(n);
|
|
59
|
-
break;
|
|
60
|
-
case "uint32":
|
|
61
|
-
i = new Uint32Array(n);
|
|
62
|
-
break;
|
|
63
|
-
case "int32":
|
|
64
|
-
i = new Int32Array(n);
|
|
65
|
-
break;
|
|
66
|
-
case "float32":
|
|
67
|
-
i = new Float32Array(n);
|
|
68
|
-
break;
|
|
69
|
-
case "float64":
|
|
70
|
-
i = new Float64Array(n);
|
|
71
|
-
break;
|
|
72
|
-
default: throw Error(`Image codec does not support Zarrita dtype '${t.dataType}'.`);
|
|
73
|
-
}
|
|
74
|
-
if (i.length !== r) throw Error(`Image codec decoded ${i.length} values, expected ${r} for chunk shape [${t.shape.join(", ")}].`);
|
|
75
|
-
return i;
|
|
76
|
-
}
|
|
77
|
-
function p(e, n) {
|
|
78
|
-
return async () => ({
|
|
79
|
-
kind: "array_to_bytes",
|
|
80
|
-
fromConfig(r, i) {
|
|
81
|
-
let a = t(i);
|
|
82
|
-
return {
|
|
83
|
-
kind: "array_to_bytes",
|
|
84
|
-
encode: () => s(e),
|
|
85
|
-
async decode(e) {
|
|
86
|
-
return {
|
|
87
|
-
data: f(await n(e, a, r), a),
|
|
88
|
-
shape: a.shape,
|
|
89
|
-
stride: d(a.shape)
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
function m() {
|
|
97
|
-
let { registry: n } = e;
|
|
98
|
-
for (let [e, r] of [...n.entries()]) n.set(e, async () => {
|
|
99
|
-
let e = await r();
|
|
100
|
-
if (typeof e.fromConfig != "function") return e;
|
|
101
|
-
let n = e.fromConfig.bind(e);
|
|
102
|
-
return {
|
|
103
|
-
...e,
|
|
104
|
-
fromConfig(e, r) {
|
|
105
|
-
return n(e, t(r));
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
function h(e, t = {}) {
|
|
111
|
-
let n;
|
|
112
|
-
async function r() {
|
|
113
|
-
return n ??= Promise.resolve(e({ locateFile: t.locateFile })), await n;
|
|
114
|
-
}
|
|
115
|
-
return async (e) => {
|
|
116
|
-
let t = (await r()).J2KDecoder;
|
|
117
|
-
if (!t) throw Error("OpenJPEG runtime does not expose J2KDecoder.");
|
|
118
|
-
let n = new t();
|
|
119
|
-
return n.getEncodedBuffer(e.length).set(e), n.decode(), n.getDecodedBuffer();
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
async function g(e) {
|
|
123
|
-
let t = await o("@cornerstonejs/codec-openjpeg/decode").catch(() => o("@cornerstonejs/codec-openjpeg")), n = t.default ?? t.OpenJPEGJS ?? t.OpenJPEGWASM ?? t;
|
|
124
|
-
if (typeof n != "function") throw Error("Could not find an OpenJPEG factory export in @cornerstonejs/codec-openjpeg.");
|
|
125
|
-
return h(n, e);
|
|
126
|
-
}
|
|
127
|
-
function _(e, t = {}) {
|
|
128
|
-
let n;
|
|
129
|
-
async function r() {
|
|
130
|
-
return n ??= Promise.resolve(e({ locateFile: t.locateFile })), await n;
|
|
131
|
-
}
|
|
132
|
-
return async (e) => {
|
|
133
|
-
let t = await r(), n = t.HTJ2KDecoder ?? t.JPHDecoder ?? t.J2KDecoder;
|
|
134
|
-
if (!n) throw Error("OpenJPH runtime does not expose a known decoder class; pass a custom decoder option.");
|
|
135
|
-
let i = new n();
|
|
136
|
-
return i.getEncodedBuffer(e.length).set(e), i.decode(), i.getDecodedBuffer();
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
async function v(e) {
|
|
140
|
-
let t = await o("@cornerstonejs/codec-openjph/wasmjs").catch(() => o("@cornerstonejs/codec-openjph")), r = t.default ?? t.OpenJPHJS ?? t;
|
|
141
|
-
if (typeof r != "function") throw Error("Could not find an OpenJPH factory export in @cornerstonejs/codec-openjph.");
|
|
142
|
-
let i = await o("@cornerstonejs/codec-openjph/wasm").catch(() => null), a = i ? i.default ?? i : void 0;
|
|
143
|
-
return _(r, { locateFile: e.locateFile ?? (a ? n(a) : void 0) });
|
|
144
|
-
}
|
|
145
|
-
function y(t, n, r, i = {}) {
|
|
146
|
-
let a = i.ids ?? n, o, s = async () => (o ??= Promise.resolve(i.decoder ?? r(i)), await o);
|
|
147
|
-
for (let n of a) e.registry.set(n, p(t, async (e, t, n) => await (await s())(e, t, n)));
|
|
148
|
-
}
|
|
149
|
-
function b(e = {}) {
|
|
150
|
-
y("imagecodecs_jpeg2k", r, g, e);
|
|
151
|
-
}
|
|
152
|
-
function x(e = {}) {
|
|
153
|
-
y(i, a, v, e);
|
|
154
|
-
}
|
|
155
|
-
//#endregion
|
|
156
|
-
export { b as a, x as i, _ as n, m as o, n as r, h as t };
|
|
157
|
-
|
|
158
|
-
//# sourceMappingURL=codecs-DNu3yP16.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codecs-DNu3yP16.js","names":[],"sources":["../src/codecs.ts"],"sourcesContent":["import * as zarr from 'zarrita';\n\ntype ChunkMetadata<D extends zarr.DataType = zarr.DataType> = {\n dataType: D;\n shape: number[];\n codecs: zarr.CodecMetadata[];\n fillValue: zarr.Scalar<D> | null;\n};\n\n/** Chunk metadata from zarrita (camelCase) or fizarrita workers (snake_case). */\ntype ChunkMetadataInput = Partial<ChunkMetadata> & {\n data_type?: zarr.DataType;\n chunk_shape?: number[];\n fill_value?: zarr.Scalar<zarr.DataType> | null;\n};\n\nfunction normalizeChunkMetadata(meta: ChunkMetadataInput): ChunkMetadata {\n const dataType = meta.dataType ?? meta.data_type;\n const shape = meta.shape ?? meta.chunk_shape;\n if (!dataType) {\n throw new Error('Chunk metadata is missing dataType / data_type.');\n }\n if (!shape) {\n throw new Error('Chunk metadata is missing shape / chunk_shape.');\n }\n return {\n dataType,\n shape,\n codecs: meta.codecs ?? [],\n fillValue: meta.fillValue ?? meta.fill_value ?? null,\n };\n}\n\ntype Codec = {\n kind?: 'array_to_array' | 'array_to_bytes' | 'bytes_to_bytes';\n encode(data: unknown): Promise<Uint8Array> | Uint8Array;\n decode(data: Uint8Array): Promise<zarr.Chunk<zarr.DataType>> | zarr.Chunk<zarr.DataType>;\n};\n\ntype CodecEntry = {\n kind?: Codec['kind'];\n fromConfig: (config: unknown, meta: ChunkMetadata) => Codec;\n};\n\nexport type DecodedImageBytes = ArrayBuffer | ArrayBufferView;\n\nexport type ImageCodecDecoder = (\n encoded: Uint8Array,\n meta: ChunkMetadata,\n config: unknown\n) => Promise<DecodedImageBytes> | DecodedImageBytes;\n\nexport interface RegisterImageCodecOptions {\n /**\n * Override the codec ids registered into Zarrita's global registry.\n * Defaults include the standard registry id and a pragmatic alias.\n */\n ids?: string[];\n /** Custom decoder used by tests or applications with their own WASM loading. */\n decoder?: ImageCodecDecoder;\n /** Optional Emscripten locateFile hook for bundled WASM decoders. */\n locateFile?: (path: string, prefix: string) => string;\n}\n\nexport type OpenJpegFactory = (opts?: {\n locateFile?: RegisterImageCodecOptions['locateFile'];\n}) => Promise<Record<string, unknown>> | Record<string, unknown>;\n\nexport type OpenJphFactory = (opts?: {\n locateFile?: RegisterImageCodecOptions['locateFile'];\n}) => Promise<Record<string, unknown>> | Record<string, unknown>;\n\n/** Emscripten locateFile hook that resolves bundled codec WASM to a bundler URL. */\nexport function createWasmLocateFile(\n wasmUrl: string\n): NonNullable<RegisterImageCodecOptions['locateFile']> {\n return (path, _prefix) => (path.endsWith('.wasm') ? wasmUrl : path);\n}\n\nconst JPEG2K_CODEC_IDS = ['imagecodecs_jpeg2k', 'numcodecs.imagecodecs_jpeg2k', 'jpeg2k'];\nconst HTJ2K_OPENJPH_CODEC_ID = 'experimental.openjph_htj2k';\nconst HTJ2K_LEGACY_CODEC_IDS = [\n 'experimental.imagecodecs_htj2k',\n 'imagecodecs_htj2k',\n 'numcodecs.imagecodecs_htj2k',\n];\nconst HTJ2K_CODEC_IDS = [HTJ2K_OPENJPH_CODEC_ID, ...HTJ2K_LEGACY_CODEC_IDS];\n\nconst dynamicImport = new Function('specifier', 'return import(specifier)') as (\n specifier: string\n) => Promise<Record<string, unknown>>;\n\nfunction unsupportedEncode(codecName: string): never {\n throw new Error(`${codecName} encode is not implemented in zarrextra; decode-only for now.`);\n}\n\nfunction toUint8Array(data: DecodedImageBytes): Uint8Array {\n if (data instanceof Uint8Array) {\n return data;\n }\n if (ArrayBuffer.isView(data)) {\n return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n }\n return new Uint8Array(data);\n}\n\nfunction copyArrayBufferView(bytes: Uint8Array): ArrayBuffer {\n const copy = new ArrayBuffer(bytes.byteLength);\n new Uint8Array(copy).set(bytes);\n return copy;\n}\n\nfunction product(values: number[]): number {\n return values.reduce((acc, value) => acc * value, 1);\n}\n\nfunction getStrides(shape: number[]): number[] {\n const stride = new Array<number>(shape.length);\n let step = 1;\n for (let index = shape.length - 1; index >= 0; index -= 1) {\n stride[index] = step;\n step *= shape[index] ?? 1;\n }\n return stride;\n}\n\nfunction typedArrayFromDecodedBytes(\n decoded: DecodedImageBytes,\n meta: ChunkMetadata\n): zarr.TypedArray<zarr.DataType> {\n if (Array.isArray(decoded)) {\n throw new Error('Image codec decoder returned a plain array; expected binary data.');\n }\n\n const decodedBytes = toUint8Array(decoded);\n const buffer = copyArrayBufferView(decodedBytes);\n const expectedValues = product(meta.shape);\n\n let data: zarr.TypedArray<zarr.DataType>;\n switch (meta.dataType) {\n case 'uint8':\n data = new Uint8Array(buffer);\n break;\n case 'int8':\n data = new Int8Array(buffer);\n break;\n case 'uint16':\n data = new Uint16Array(buffer);\n break;\n case 'int16':\n data = new Int16Array(buffer);\n break;\n case 'uint32':\n data = new Uint32Array(buffer);\n break;\n case 'int32':\n data = new Int32Array(buffer);\n break;\n case 'float32':\n data = new Float32Array(buffer);\n break;\n case 'float64':\n data = new Float64Array(buffer);\n break;\n default:\n throw new Error(`Image codec does not support Zarrita dtype '${meta.dataType}'.`);\n }\n\n if (data.length !== expectedValues) {\n throw new Error(\n `Image codec decoded ${data.length} values, expected ${expectedValues} for chunk shape ` +\n `[${meta.shape.join(', ')}].`\n );\n }\n\n return data;\n}\n\nfunction createImageCodecEntry(\n codecName: string,\n decoder: ImageCodecDecoder\n): () => Promise<CodecEntry> {\n return async () => ({\n kind: 'array_to_bytes',\n fromConfig(config: unknown, meta: ChunkMetadataInput): Codec {\n const chunkMeta = normalizeChunkMetadata(meta);\n return {\n kind: 'array_to_bytes',\n encode: () => unsupportedEncode(codecName),\n async decode(encoded: Uint8Array) {\n const decoded = await decoder(encoded, chunkMeta, config);\n return {\n data: typedArrayFromDecodedBytes(decoded, chunkMeta),\n shape: chunkMeta.shape,\n stride: getStrides(chunkMeta.shape),\n };\n },\n };\n },\n });\n}\n\n/**\n * Adapt zarrita's built-in registry codecs for fizarrita's worker metadata\n * (`data_type`, `chunk_shape`) before fizarrita's codec worker loads.\n */\nexport function wrapZarrRegistryForFizarritaWorker() {\n const { registry } = zarr;\n for (const [id, factory] of [...registry.entries()]) {\n registry.set(id, async () => {\n const entry = await factory();\n if (typeof entry.fromConfig !== 'function') {\n return entry;\n }\n const fromConfig = entry.fromConfig.bind(entry);\n return {\n ...entry,\n fromConfig(config: unknown, meta: ChunkMetadataInput) {\n return fromConfig(config, normalizeChunkMetadata(meta));\n },\n };\n });\n }\n}\n\nexport function createOpenJpegDecoder(\n factory: OpenJpegFactory,\n options: Pick<RegisterImageCodecOptions, 'locateFile'> = {}\n): ImageCodecDecoder {\n let runtimePromise: Promise<Record<string, unknown>> | undefined;\n async function getRuntime() {\n runtimePromise ??= Promise.resolve(\n factory({\n locateFile: options.locateFile,\n })\n );\n return await runtimePromise;\n }\n return async (encoded) => {\n const runtime = await getRuntime();\n const Decoder = runtime.J2KDecoder as\n | (new () => {\n getEncodedBuffer(length: number): Uint8Array;\n decode(): void;\n getDecodedBuffer(): DecodedImageBytes;\n })\n | undefined;\n if (!Decoder) {\n throw new Error('OpenJPEG runtime does not expose J2KDecoder.');\n }\n const decoder = new Decoder();\n decoder.getEncodedBuffer(encoded.length).set(encoded);\n decoder.decode();\n return decoder.getDecodedBuffer();\n };\n}\n\nasync function loadOpenJpegDecoder(options: RegisterImageCodecOptions): Promise<ImageCodecDecoder> {\n const mod = await dynamicImport('@cornerstonejs/codec-openjpeg/decode').catch(() =>\n dynamicImport('@cornerstonejs/codec-openjpeg')\n );\n const factory = (mod.default ?? mod.OpenJPEGJS ?? mod.OpenJPEGWASM ?? mod) as unknown;\n if (typeof factory !== 'function') {\n throw new Error('Could not find an OpenJPEG factory export in @cornerstonejs/codec-openjpeg.');\n }\n return createOpenJpegDecoder(factory as OpenJpegFactory, options);\n}\n\ntype Htj2kDecoderClass = new () => {\n getEncodedBuffer(length: number): Uint8Array;\n decode(): void;\n getDecodedBuffer(): DecodedImageBytes;\n};\n\nexport function createOpenJphDecoder(\n factory: OpenJphFactory,\n options: Pick<RegisterImageCodecOptions, 'locateFile'> = {}\n): ImageCodecDecoder {\n let runtimePromise: Promise<Record<string, unknown>> | undefined;\n async function getRuntime() {\n runtimePromise ??= Promise.resolve(\n factory({\n locateFile: options.locateFile,\n })\n );\n return await runtimePromise;\n }\n return async (encoded) => {\n const runtime = await getRuntime();\n const Decoder = (runtime.HTJ2KDecoder ?? runtime.JPHDecoder ?? runtime.J2KDecoder) as\n | Htj2kDecoderClass\n | undefined;\n if (!Decoder) {\n throw new Error(\n 'OpenJPH runtime does not expose a known decoder class; pass a custom decoder option.'\n );\n }\n const decoder = new Decoder();\n decoder.getEncodedBuffer(encoded.length).set(encoded);\n decoder.decode();\n return decoder.getDecodedBuffer();\n };\n}\n\nasync function loadOpenJphDecoder(options: RegisterImageCodecOptions): Promise<ImageCodecDecoder> {\n const factoryMod = await dynamicImport('@cornerstonejs/codec-openjph/wasmjs').catch(() =>\n dynamicImport('@cornerstonejs/codec-openjph')\n );\n const factory = (factoryMod.default ?? factoryMod.OpenJPHJS ?? factoryMod) as unknown;\n if (typeof factory !== 'function') {\n throw new Error('Could not find an OpenJPH factory export in @cornerstonejs/codec-openjph.');\n }\n const wasmMod = await dynamicImport('@cornerstonejs/codec-openjph/wasm').catch(() => null);\n const wasmAsset = wasmMod ? ((wasmMod.default ?? wasmMod) as string | undefined) : undefined;\n const locateFile =\n options.locateFile ?? (wasmAsset ? createWasmLocateFile(wasmAsset) : undefined);\n return createOpenJphDecoder(factory as OpenJphFactory, { locateFile });\n}\n\nfunction registerImageCodec(\n codecName: string,\n defaultIds: string[],\n defaultDecoder: (options: RegisterImageCodecOptions) => Promise<ImageCodecDecoder>,\n options: RegisterImageCodecOptions = {}\n) {\n const ids = options.ids ?? defaultIds;\n let decoderPromise: Promise<ImageCodecDecoder> | undefined;\n const getDecoder = async () => {\n decoderPromise ??= Promise.resolve(options.decoder ?? defaultDecoder(options));\n return await decoderPromise;\n };\n\n for (const id of ids) {\n (zarr.registry as Map<string, () => Promise<unknown>>).set(\n id,\n createImageCodecEntry(codecName, async (encoded, meta, config) => {\n const decoder = await getDecoder();\n return await decoder(encoded, meta, config);\n })\n );\n }\n}\n\n/** Register decode support for the standard `imagecodecs_jpeg2k` Zarr codec id. */\nexport function registerJpeg2kCodec(options: RegisterImageCodecOptions = {}) {\n registerImageCodec('imagecodecs_jpeg2k', JPEG2K_CODEC_IDS, loadOpenJpegDecoder, options);\n}\n\n/**\n * Register HTJ2K decode support for OpenJPH-encoded stores and legacy ids.\n *\n * New writes use `experimental.openjph_htj2k`. Older fixtures may use\n * `experimental.imagecodecs_htj2k`; both decode through the same OpenJPH WASM path.\n */\nexport function registerExperimentalHtj2kCodec(options: RegisterImageCodecOptions = {}) {\n registerImageCodec(\n HTJ2K_OPENJPH_CODEC_ID,\n HTJ2K_CODEC_IDS,\n loadOpenJphDecoder,\n options\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codec-worker-init.d.ts","sourceRoot":"","sources":["../../src/workers/codec-worker-init.ts"],"names":[],"mappings":""}
|