@fideus-labs/fiff 0.1.2 → 0.2.0

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 CHANGED
@@ -11,11 +11,13 @@
11
11
  </p>
12
12
 
13
13
  <p align="center">
14
- Present <a href="https://docs.openmicroscopy.org/ome-model/latest/ome-tiff/">TIFF</a> and <a href="https://docs.openmicroscopy.org/ome-model/latest/ome-tiff/">OME-TIFF</a> files as a <a href="https://github.com/manzt/zarrita.js">zarrita.js</a> Zarr store following the <a href="https://ngff.openmicroscopy.org/0.5/">OME-Zarr v0.5</a> data model.
14
+ Read and write <a href="https://docs.openmicroscopy.org/ome-model/latest/ome-tiff/">OME-TIFF</a> files through a <a href="https://github.com/manzt/zarrita.js">zarrita.js</a> Zarr store following the <a href="https://ngff.openmicroscopy.org/0.5/">OME-Zarr v0.5</a> data model.
15
15
  </p>
16
16
 
17
17
  ## ✨ Features
18
18
 
19
+ ### Reading
20
+
19
21
  - 🚀 **Lazy HTTP range requests** -- Chunk data is fetched on demand via
20
22
  geotiff.js `readRasters()`, no full file download needed
21
23
  - 📐 **OME-XML support** -- Parses OME-XML metadata for dimensions, channels,
@@ -29,51 +31,192 @@
29
31
  - 📋 **OME-Zarr v0.5 output** -- Generates Zarr v3 metadata with
30
32
  `ome.multiscales` and `ome.omero` attributes
31
33
 
34
+ ### Writing
35
+
36
+ - 📝 **OME-TIFF generation** -- Convert ngff-zarr `Multiscales` objects to
37
+ valid OME-TIFF files with embedded OME-XML metadata
38
+ - 🔻 **Full pyramid support** -- Multi-resolution levels are written as SubIFDs,
39
+ matching the modern OME-TIFF pyramid convention
40
+ - 🗜️ **Deflate compression** -- Optional zlib/deflate compression for smaller
41
+ files, compatible with all major TIFF readers
42
+ - 📐 **5D support** -- Handles all dimension orders (XYZCT, XYZTC, etc.) and
43
+ arbitrary combinations of T, C, Z, Y, X axes
44
+
32
45
  ## 📦 Installation
33
46
 
34
47
  ```bash
35
48
  npm install @fideus-labs/fiff
36
49
  ```
37
50
 
38
- ## Quick Start
51
+ For write support, also install the optional peer dependency:
52
+
53
+ ```bash
54
+ npm install @fideus-labs/ngff-zarr
55
+ ```
56
+
57
+ ## ⚡ Usage
58
+
59
+ ### Reading: Open an OME-TIFF as a Zarr store
60
+
61
+ #### From a remote URL
62
+
63
+ ```typescript
64
+ import { TiffStore } from "@fideus-labs/fiff";
65
+ import * as zarr from "zarrita";
66
+
67
+ const store = await TiffStore.fromUrl("https://example.com/image.ome.tif");
68
+ const group = await zarr.open(store as unknown as zarr.Readable, { kind: "group" });
69
+
70
+ // Open the full-resolution array (level 0)
71
+ const arr = await zarr.open(group.resolve("0"), { kind: "array" });
72
+ const chunk = await zarr.get(arr);
73
+
74
+ console.log(chunk.shape); // e.g. [1, 3, 1, 512, 512]
75
+ console.log(chunk.data); // Float32Array, Uint16Array, etc.
76
+ ```
77
+
78
+ #### From an ArrayBuffer
79
+
80
+ ```typescript
81
+ const response = await fetch("https://example.com/image.tif");
82
+ const buffer = await response.arrayBuffer();
83
+ const store = await TiffStore.fromArrayBuffer(buffer);
84
+ ```
85
+
86
+ #### From a File / Blob
39
87
 
40
- ### From a remote URL
88
+ ```typescript
89
+ const file = document.querySelector("input[type=file]").files[0];
90
+ const store = await TiffStore.fromBlob(file);
91
+ ```
92
+
93
+ #### From an existing GeoTIFF instance
41
94
 
42
95
  ```typescript
43
- import { TiffStore } from "@fideus-labs/fiff"
44
- import * as zarr from "zarrita"
96
+ import { fromUrl } from "geotiff";
97
+
98
+ const tiff = await fromUrl("https://example.com/image.tif");
99
+ const store = await TiffStore.fromGeoTIFF(tiff);
100
+ ```
45
101
 
46
- const store = await TiffStore.fromUrl("https://example.com/image.ome.tif")
47
- const group = await zarr.open(store as unknown as zarr.Readable, { kind: "group" })
48
- const arr = await zarr.open(group.resolve("0"), { kind: "array" })
49
- const chunk = await zarr.get(arr)
102
+ #### Accessing store metadata
103
+
104
+ ```typescript
105
+ const store = await TiffStore.fromUrl("https://example.com/image.ome.tif");
106
+
107
+ store.levels; // number of resolution levels
108
+ store.dataType; // "uint16", "float32", etc.
109
+ store.dimensionNames; // ["t", "c", "z", "y", "x"]
110
+ store.getShape(0); // full-res shape, e.g. [1, 3, 1, 2048, 2048]
111
+ store.getShape(1); // level 1 shape, e.g. [1, 3, 1, 1024, 1024]
112
+ store.ome; // parsed OME-XML image metadata (if present)
113
+ store.pyramidInfo; // pyramid structure details
50
114
  ```
51
115
 
52
- ### From an ArrayBuffer
116
+ ### Writing: Convert ngff-zarr Multiscales to OME-TIFF
117
+
118
+ `toOmeTiff()` takes an ngff-zarr `Multiscales` object and returns a complete
119
+ OME-TIFF file as an `ArrayBuffer`.
120
+
121
+ #### Basic write
53
122
 
54
123
  ```typescript
55
- const response = await fetch("https://example.com/image.tif")
56
- const buffer = await response.arrayBuffer()
57
- const store = await TiffStore.fromArrayBuffer(buffer)
124
+ import { toOmeTiff } from "@fideus-labs/fiff";
125
+ import {
126
+ createNgffImage,
127
+ createAxis,
128
+ createDataset,
129
+ createMetadata,
130
+ createMultiscales,
131
+ } from "@fideus-labs/ngff-zarr";
132
+ import * as zarr from "zarrita";
133
+
134
+ // 1. Create an ngff-zarr image
135
+ const image = await createNgffImage(
136
+ [], // no parent images
137
+ [512, 512], // shape: [y, x]
138
+ "uint16", // data type
139
+ ["y", "x"], // dimension names
140
+ { y: 0.5, x: 0.5 }, // pixel spacing (micrometers)
141
+ { y: 0.0, x: 0.0 }, // origin offsets
142
+ "my-image",
143
+ );
144
+
145
+ // 2. Populate pixel data
146
+ const data = new Uint16Array(512 * 512);
147
+ for (let i = 0; i < data.length; i++) data[i] = i % 65536;
148
+ await zarr.set(image.data, null, {
149
+ data,
150
+ shape: [512, 512],
151
+ stride: [512, 1],
152
+ });
153
+
154
+ // 3. Build the Multiscales object
155
+ const axes = [
156
+ createAxis("y", "space", "micrometer"),
157
+ createAxis("x", "space", "micrometer"),
158
+ ];
159
+ const datasets = [createDataset("0", [0.5, 0.5], [0.0, 0.0])];
160
+ const metadata = createMetadata(axes, datasets, "my-image");
161
+ const multiscales = createMultiscales([image], metadata);
162
+
163
+ // 4. Write to OME-TIFF
164
+ const buffer = await toOmeTiff(multiscales);
165
+
166
+ // Save to disk (Node.js / Bun)
167
+ await Bun.write("output.ome.tif", buffer);
58
168
  ```
59
169
 
60
- ### From a File / Blob
170
+ #### Write options
61
171
 
62
172
  ```typescript
63
- const file = document.querySelector("input[type=file]").files[0]
64
- const store = await TiffStore.fromBlob(file)
173
+ const buffer = await toOmeTiff(multiscales, {
174
+ compression: "deflate", // "deflate" (default) or "none"
175
+ compressionLevel: 6, // 1-9, default 6 (only for deflate)
176
+ dimensionOrder: "XYZCT", // IFD layout order, default "XYZCT"
177
+ imageName: "my-image", // name in OME-XML metadata
178
+ creator: "my-app", // creator string in OME-XML
179
+ });
65
180
  ```
66
181
 
67
- ### From an existing GeoTIFF instance
182
+ #### Multi-resolution pyramids
183
+
184
+ When the `Multiscales` object contains multiple images (resolution levels),
185
+ all sub-resolution levels are written as SubIFDs:
68
186
 
69
187
  ```typescript
70
- import { fromUrl } from "geotiff"
188
+ const fullRes = await createNgffImage([], [1024, 1024], "uint16", ["y", "x"], ...);
189
+ const halfRes = await createNgffImage([], [512, 512], "uint16", ["y", "x"], ...);
190
+ // ... populate both images with zarr.set() ...
191
+
192
+ const datasets = [
193
+ createDataset("0", [0.5, 0.5], [0.0, 0.0]),
194
+ createDataset("1", [1.0, 1.0], [0.0, 0.0]),
195
+ ];
196
+ const metadata = createMetadata(axes, datasets, "pyramid");
197
+ const multiscales = createMultiscales([fullRes, halfRes], metadata);
198
+
199
+ const buffer = await toOmeTiff(multiscales);
200
+ // Result: OME-TIFF with full-res IFDs + half-res SubIFDs
201
+ ```
202
+
203
+ #### Round-trip: write then read back
71
204
 
72
- const tiff = await fromUrl("https://example.com/image.tif")
73
- const store = await TiffStore.fromGeoTIFF(tiff)
205
+ ```typescript
206
+ import { toOmeTiff, TiffStore } from "@fideus-labs/fiff";
207
+ import * as zarr from "zarrita";
208
+
209
+ const buffer = await toOmeTiff(multiscales);
210
+ const store = await TiffStore.fromArrayBuffer(buffer);
211
+ const group = await zarr.open(store as unknown as zarr.Readable, { kind: "group" });
212
+ const arr = await zarr.open(group.resolve("0"), { kind: "array" });
213
+ const result = await zarr.get(arr);
214
+ // result.data contains the original pixel values
74
215
  ```
75
216
 
76
- ## 🏭 Factory Methods
217
+ ## 🏭 Read API
218
+
219
+ ### Factory Methods
77
220
 
78
221
  | Method | Description |
79
222
  | --------------------------------- | ---------------------------------------------- |
@@ -82,7 +225,7 @@ const store = await TiffStore.fromGeoTIFF(tiff)
82
225
  | `TiffStore.fromBlob(blob)` | Open from a Blob or File |
83
226
  | `TiffStore.fromGeoTIFF(tiff)` | Open from an already-opened GeoTIFF instance |
84
227
 
85
- ## ⚙️ Options
228
+ ### Options
86
229
 
87
230
  All factory methods accept an optional `TiffStoreOptions` object:
88
231
 
@@ -91,7 +234,7 @@ All factory methods accept an optional `TiffStoreOptions` object:
91
234
  | `offsets` | `number[]` | `undefined` | Pre-computed IFD byte offsets for O(1) access |
92
235
  | `headers` | `Record<string, string>` | `undefined` | Additional HTTP headers for remote TIFF requests |
93
236
 
94
- ## 📖 Public Accessors
237
+ ### Public Accessors
95
238
 
96
239
  | Accessor | Type | Description |
97
240
  | --------------------- | -------------- | ---------------------------------- |
@@ -103,6 +246,27 @@ All factory methods accept an optional `TiffStoreOptions` object:
103
246
  | `store.getShape(l)` | `number[]` | Shape for resolution level `l` |
104
247
  | `store.getChunkShape(l)` | `number[]` | Chunk shape for resolution level `l` |
105
248
 
249
+ ## 📝 Write API
250
+
251
+ ### `toOmeTiff(multiscales, options?)`
252
+
253
+ | Parameter | Type | Description |
254
+ | ------------- | ------------- | ------------------------------------------------------ |
255
+ | `multiscales` | `Multiscales` | ngff-zarr Multiscales object with populated pixel data |
256
+ | `options` | `WriteOptions`| Optional writer configuration |
257
+
258
+ **Returns:** `Promise<ArrayBuffer>` -- a complete OME-TIFF file.
259
+
260
+ ### WriteOptions
261
+
262
+ | Option | Type | Default | Description |
263
+ | ------------------ | ---------------------- | ----------- | ---------------------------------------- |
264
+ | `compression` | `"none" \| "deflate"` | `"deflate"` | Pixel data compression |
265
+ | `compressionLevel` | `number` | `6` | Deflate level 1-9 (higher = smaller) |
266
+ | `dimensionOrder` | `string` | `"XYZCT"` | IFD plane layout order |
267
+ | `imageName` | `string` | `"image"` | Image name in OME-XML |
268
+ | `creator` | `string` | `"fiff"` | Creator string in OME-XML |
269
+
106
270
  ## 🛠️ Development
107
271
 
108
272
  ### 📋 Prerequisites
@@ -127,11 +291,14 @@ src/
127
291
  ome-xml.ts # OME-XML parser (dimensions, channels, DimensionOrder)
128
292
  ifd-indexer.ts # IFD-to-pyramid-level mapping (SubIFD/legacy/COG)
129
293
  chunk-reader.ts # Pixel data reading via geotiff.js readRasters
130
- dtypes.ts # TIFF SampleFormat -> Zarr data_type mapping
294
+ dtypes.ts # TIFF Zarr data_type mapping
131
295
  utils.ts # Key parsing, pixel window computation, encoding
296
+ write.ts # High-level toOmeTiff() writer
297
+ tiff-writer.ts # Low-level TIFF binary builder (IFDs, SubIFDs, deflate)
298
+ ome-xml-writer.ts # OME-XML generation from Multiscales metadata
132
299
  test/
133
300
  fixtures.ts # Test TIFF generation helpers
134
- *.test.ts # 120 tests across 8 files
301
+ *.test.ts # 175 tests across 11 files
135
302
  ```
136
303
 
137
304
  ### 📝 Commands
package/dist/dtypes.d.ts CHANGED
@@ -33,6 +33,21 @@ export declare function tiffDtypeToZarr(sampleFormat: number, bitsPerSample: num
33
33
  export declare function omePixelTypeToZarr(omeType: string): ZarrDataType;
34
34
  /** Number of bytes per element for a given Zarr data_type. */
35
35
  export declare function bytesPerElement(dtype: ZarrDataType): number;
36
+ /**
37
+ * Map a Zarr v3 data_type string to an OME-XML pixel Type string.
38
+ * Reverse of omePixelTypeToZarr.
39
+ */
40
+ export declare function zarrToOmePixelType(dtype: ZarrDataType): string;
41
+ /** TIFF tag values for a given Zarr data_type. */
42
+ export interface TiffDtypeInfo {
43
+ sampleFormat: number;
44
+ bitsPerSample: number;
45
+ }
46
+ /**
47
+ * Map a Zarr v3 data_type string to TIFF SampleFormat + BitsPerSample.
48
+ * Reverse of tiffDtypeToZarr.
49
+ */
50
+ export declare function zarrToTiffDtype(dtype: ZarrDataType): TiffDtypeInfo;
36
51
  /**
37
52
  * Get the appropriate TypedArray constructor for a Zarr data_type.
38
53
  */
@@ -1 +1 @@
1
- {"version":3,"file":"dtypes.d.ts","sourceRoot":"","sources":["../src/dtypes.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AAEH,yCAAyC;AACzC,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,OAAO,GACP,OAAO,GACP,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,SAAS,CAAC;AAEd,oCAAoC;AACpC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GACpB,YAAY,CAyCd;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAiBhE;AAED,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAY3D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,YAAY,GAClB;IACD,KAAK,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAC1D,UAAU,GACV,SAAS,GACT,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,GACV,YAAY,GACZ,YAAY,CAAC;CAClB,CAmBA"}
1
+ {"version":3,"file":"dtypes.d.ts","sourceRoot":"","sources":["../src/dtypes.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AAEH,yCAAyC;AACzC,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,OAAO,GACP,OAAO,GACP,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,SAAS,CAAC;AAEd,oCAAoC;AACpC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GACpB,YAAY,CAyCd;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAiBhE;AAED,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAY3D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAY9D;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAYlE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,YAAY,GAClB;IACD,KAAK,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAC1D,UAAU,GACV,SAAS,GACT,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,GACV,YAAY,GACZ,YAAY,CAAC;CAClB,CAmBA"}
package/dist/dtypes.js CHANGED
@@ -87,6 +87,40 @@ export function bytesPerElement(dtype) {
87
87
  };
88
88
  return map[dtype];
89
89
  }
90
+ /**
91
+ * Map a Zarr v3 data_type string to an OME-XML pixel Type string.
92
+ * Reverse of omePixelTypeToZarr.
93
+ */
94
+ export function zarrToOmePixelType(dtype) {
95
+ const map = {
96
+ int8: "int8",
97
+ int16: "int16",
98
+ int32: "int32",
99
+ uint8: "uint8",
100
+ uint16: "uint16",
101
+ uint32: "uint32",
102
+ float32: "float",
103
+ float64: "double",
104
+ };
105
+ return map[dtype];
106
+ }
107
+ /**
108
+ * Map a Zarr v3 data_type string to TIFF SampleFormat + BitsPerSample.
109
+ * Reverse of tiffDtypeToZarr.
110
+ */
111
+ export function zarrToTiffDtype(dtype) {
112
+ const map = {
113
+ uint8: { sampleFormat: SAMPLE_FORMAT_UINT, bitsPerSample: 8 },
114
+ uint16: { sampleFormat: SAMPLE_FORMAT_UINT, bitsPerSample: 16 },
115
+ uint32: { sampleFormat: SAMPLE_FORMAT_UINT, bitsPerSample: 32 },
116
+ int8: { sampleFormat: SAMPLE_FORMAT_INT, bitsPerSample: 8 },
117
+ int16: { sampleFormat: SAMPLE_FORMAT_INT, bitsPerSample: 16 },
118
+ int32: { sampleFormat: SAMPLE_FORMAT_INT, bitsPerSample: 32 },
119
+ float32: { sampleFormat: SAMPLE_FORMAT_FLOAT, bitsPerSample: 32 },
120
+ float64: { sampleFormat: SAMPLE_FORMAT_FLOAT, bitsPerSample: 64 },
121
+ };
122
+ return map[dtype];
123
+ }
90
124
  /**
91
125
  * Get the appropriate TypedArray constructor for a Zarr data_type.
92
126
  */
@@ -1 +1 @@
1
- {"version":3,"file":"dtypes.js","sourceRoot":"","sources":["../src/dtypes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dtypes.js","sourceRoot":"","sources":["../src/dtypes.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -20,7 +20,10 @@ export type { ZarrDataType } from "./dtypes.js";
20
20
  export type { OmeImage, OmePixels, OmeChannel, DimensionOrder } from "./ome-xml.js";
21
21
  export type { PyramidInfo, PlaneSelection } from "./ifd-indexer.js";
22
22
  export type { OmeAxis, OmeMultiscale, OmeDataset, OmeCoordinateTransformation, OmeroMetadata, OmeroChannel, ZarrGroupMetadata, ZarrArrayMetadata, } from "./metadata.js";
23
+ export { toOmeTiff, type WriteOptions } from "./write.js";
24
+ export { buildOmeXml, type OmeXmlWriterOptions, type DimensionInfo } from "./ome-xml-writer.js";
25
+ export { buildTiff, makeImageTags, compressDeflate, type WritableIfd, type TiffTag, type BuildTiffOptions, } from "./tiff-writer.js";
23
26
  export { parseOmeXml, isOmeXml, getIfdIndex } from "./ome-xml.js";
24
- export { tiffDtypeToZarr, omePixelTypeToZarr, bytesPerElement } from "./dtypes.js";
27
+ export { tiffDtypeToZarr, omePixelTypeToZarr, zarrToOmePixelType, zarrToTiffDtype, bytesPerElement, type TiffDtypeInfo, } from "./dtypes.js";
25
28
  export { parseStoreKey, computePixelWindow } from "./utils.js";
26
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACpF,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpE,YAAY,EACV,OAAO,EACP,aAAa,EACb,UAAU,EACV,2BAA2B,EAC3B,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACpF,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpE,YAAY,EACV,OAAO,EACP,aAAa,EACb,UAAU,EACV,2BAA2B,EAC3B,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAChG,OAAO,EACL,SAAS,EACT,aAAa,EACb,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -18,8 +18,12 @@
18
18
  * ```
19
19
  */
20
20
  export { TiffStore } from "./tiff-store.js";
21
+ // Writer
22
+ export { toOmeTiff } from "./write.js";
23
+ export { buildOmeXml } from "./ome-xml-writer.js";
24
+ export { buildTiff, makeImageTags, compressDeflate, } from "./tiff-writer.js";
21
25
  // Export utilities that may be useful
22
26
  export { parseOmeXml, isOmeXml, getIfdIndex } from "./ome-xml.js";
23
- export { tiffDtypeToZarr, omePixelTypeToZarr, bytesPerElement } from "./dtypes.js";
27
+ export { tiffDtypeToZarr, omePixelTypeToZarr, zarrToOmePixelType, zarrToTiffDtype, bytesPerElement, } from "./dtypes.js";
24
28
  export { parseStoreKey, computePixelWindow } from "./utils.js";
25
29
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,+BAA+B;AAE/B;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,SAAS,EAAyB,MAAM,iBAAiB,CAAC;AAiBnE,sCAAsC;AACtC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,+BAA+B;AAE/B;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,SAAS,EAAyB,MAAM,iBAAiB,CAAC;AAiBnE,SAAS;AACT,OAAO,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAgD,MAAM,qBAAqB,CAAC;AAChG,OAAO,EACL,SAAS,EACT,aAAa,EACb,eAAe,GAIhB,MAAM,kBAAkB,CAAC;AAE1B,sCAAsC;AACtC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,eAAe,GAEhB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * OME-XML writer: generates an OME-XML metadata string from an
3
+ * ngff-zarr Multiscales object.
4
+ *
5
+ * The generated XML follows the 2016-06 OME schema and embeds
6
+ * dimension sizes, pixel type, channel metadata, and physical
7
+ * sizes extracted from the Multiscales metadata.
8
+ */
9
+ import type { Multiscales } from "@fideus-labs/ngff-zarr";
10
+ import type { ZarrDataType } from "./dtypes.js";
11
+ /** Options for OME-XML generation. */
12
+ export interface OmeXmlWriterOptions {
13
+ /** DimensionOrder for the TIFF. Default: "XYZCT". */
14
+ dimensionOrder?: string;
15
+ /** Creator string embedded in the OME element. Default: "fiff". */
16
+ creator?: string;
17
+ /** Image name. Falls back to multiscales.metadata.name or "image". */
18
+ imageName?: string;
19
+ }
20
+ /** Extracted dimension info from a Multiscales object. */
21
+ export interface DimensionInfo {
22
+ sizeX: number;
23
+ sizeY: number;
24
+ sizeZ: number;
25
+ sizeC: number;
26
+ sizeT: number;
27
+ physicalSizeX?: number;
28
+ physicalSizeY?: number;
29
+ physicalSizeZ?: number;
30
+ physicalSizeXUnit?: string;
31
+ physicalSizeYUnit?: string;
32
+ physicalSizeZUnit?: string;
33
+ }
34
+ /**
35
+ * Generate an OME-XML metadata string from a Multiscales object.
36
+ *
37
+ * @param multiscales - The ngff-zarr Multiscales to generate XML for.
38
+ * @param dtype - The Zarr data type of the pixel data.
39
+ * @param options - Writer options.
40
+ * @returns A complete OME-XML string suitable for a TIFF ImageDescription tag.
41
+ */
42
+ export declare function buildOmeXml(multiscales: Multiscales, dtype: ZarrDataType, options?: OmeXmlWriterOptions): string;
43
+ /**
44
+ * Extract dimension sizes and physical sizes from a Multiscales object.
45
+ * Uses the highest-resolution image (images[0]).
46
+ */
47
+ export declare function extractDimensions(multiscales: Multiscales): DimensionInfo;
48
+ /**
49
+ * Convert a 6-digit hex color string (e.g. "FF0000") to a signed 32-bit RGBA int.
50
+ * Alpha defaults to 0xFF.
51
+ */
52
+ export declare function hexColorToOmeInt(hex: string): number;
53
+ /**
54
+ * Convert an OME signed 32-bit RGBA int to a 6-digit hex color string.
55
+ */
56
+ export declare function omeIntToHexColor(value: number): string;
57
+ //# sourceMappingURL=ome-xml-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ome-xml-writer.d.ts","sourceRoot":"","sources":["../src/ome-xml-writer.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,sCAAsC;AACtC,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,mBAAwB,GAChC,MAAM,CAuBR;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,aAAa,CA2DzE;AAyDD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAapD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUtD"}