@fideus-labs/ngff-zarr 0.2.4 → 0.2.6

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.
Files changed (192) hide show
  1. package/README.md +268 -76
  2. package/esm/browser-mod.js +1 -0
  3. package/esm/browser-mod.js.map +1 -0
  4. package/esm/io/from_ngff_zarr.d.ts.map +1 -1
  5. package/esm/io/from_ngff_zarr.js +23 -7
  6. package/esm/io/from_ngff_zarr.js.map +1 -0
  7. package/esm/io/hcs.js +1 -0
  8. package/esm/io/hcs.js.map +1 -0
  9. package/esm/io/itk_image_to_ngff_image.js +1 -0
  10. package/esm/io/itk_image_to_ngff_image.js.map +1 -0
  11. package/esm/io/ngff_image_to_itk_image.js +1 -0
  12. package/esm/io/ngff_image_to_itk_image.js.map +1 -0
  13. package/esm/io/to_ngff_image.js +1 -0
  14. package/esm/io/to_ngff_image.js.map +1 -0
  15. package/esm/io/to_ngff_zarr.d.ts.map +1 -1
  16. package/esm/io/to_ngff_zarr.js +35 -26
  17. package/esm/io/to_ngff_zarr.js.map +1 -0
  18. package/esm/methods/itkwasm-browser.js +1 -0
  19. package/esm/methods/itkwasm-browser.js.map +1 -0
  20. package/esm/methods/itkwasm-node.js +1 -0
  21. package/esm/methods/itkwasm-node.js.map +1 -0
  22. package/esm/methods/itkwasm-shared.js +1 -0
  23. package/esm/methods/itkwasm-shared.js.map +1 -0
  24. package/esm/methods/itkwasm.d.ts +14 -0
  25. package/esm/methods/itkwasm.d.ts.map +1 -0
  26. package/esm/methods/itkwasm.js +18 -0
  27. package/esm/methods/itkwasm.js.map +1 -0
  28. package/esm/mod.js +1 -0
  29. package/esm/mod.js.map +1 -0
  30. package/esm/process/to_multiscales-browser.js +1 -0
  31. package/esm/process/to_multiscales-browser.js.map +1 -0
  32. package/esm/process/to_multiscales-node.js +1 -0
  33. package/esm/process/to_multiscales-node.js.map +1 -0
  34. package/esm/process/to_multiscales-shared.js +1 -0
  35. package/esm/process/to_multiscales-shared.js.map +1 -0
  36. package/esm/schemas/coordinate_systems.js +1 -0
  37. package/esm/schemas/coordinate_systems.js.map +1 -0
  38. package/esm/schemas/index.js +1 -0
  39. package/esm/schemas/index.js.map +1 -0
  40. package/esm/schemas/methods.js +1 -0
  41. package/esm/schemas/methods.js.map +1 -0
  42. package/esm/schemas/multiscales.js +1 -0
  43. package/esm/schemas/multiscales.js.map +1 -0
  44. package/esm/schemas/ngff_image.js +1 -0
  45. package/esm/schemas/ngff_image.js.map +1 -0
  46. package/esm/schemas/ome_zarr.js +1 -0
  47. package/esm/schemas/ome_zarr.js.map +1 -0
  48. package/esm/schemas/rfc4.js +1 -0
  49. package/esm/schemas/rfc4.js.map +1 -0
  50. package/esm/schemas/units.js +1 -0
  51. package/esm/schemas/units.js.map +1 -0
  52. package/esm/schemas/zarr_metadata.js +1 -0
  53. package/esm/schemas/zarr_metadata.js.map +1 -0
  54. package/esm/types/array_interface.js +1 -0
  55. package/esm/types/array_interface.js.map +1 -0
  56. package/esm/types/hcs.js +1 -0
  57. package/esm/types/hcs.js.map +1 -0
  58. package/esm/types/methods.js +1 -0
  59. package/esm/types/methods.js.map +1 -0
  60. package/esm/types/multiscales.js +1 -0
  61. package/esm/types/multiscales.js.map +1 -0
  62. package/esm/types/ngff_image.js +1 -0
  63. package/esm/types/ngff_image.js.map +1 -0
  64. package/esm/types/rfc4.js +1 -0
  65. package/esm/types/rfc4.js.map +1 -0
  66. package/esm/types/units.js +1 -0
  67. package/esm/types/units.js.map +1 -0
  68. package/esm/types/zarr_metadata.js +1 -0
  69. package/esm/types/zarr_metadata.js.map +1 -0
  70. package/esm/utils/create_queue.js +1 -0
  71. package/esm/utils/create_queue.js.map +1 -0
  72. package/esm/utils/factory.js +1 -0
  73. package/esm/utils/factory.js.map +1 -0
  74. package/esm/utils/method_metadata.js +1 -0
  75. package/esm/utils/method_metadata.js.map +1 -0
  76. package/esm/utils/validation.js +1 -0
  77. package/esm/utils/validation.js.map +1 -0
  78. package/package.json +23 -34
  79. package/esm/_dnt.shims.d.ts +0 -2
  80. package/esm/_dnt.shims.d.ts.map +0 -1
  81. package/esm/_dnt.shims.js +0 -57
  82. package/esm/package.json +0 -3
  83. package/script/_dnt.shims.d.ts +0 -2
  84. package/script/_dnt.shims.d.ts.map +0 -1
  85. package/script/_dnt.shims.js +0 -60
  86. package/script/browser-mod.d.ts +0 -16
  87. package/script/browser-mod.d.ts.map +0 -1
  88. package/script/browser-mod.js +0 -51
  89. package/script/io/from_ngff_zarr.d.ts +0 -10
  90. package/script/io/from_ngff_zarr.d.ts.map +0 -1
  91. package/script/io/from_ngff_zarr.js +0 -234
  92. package/script/io/hcs.d.ts +0 -18
  93. package/script/io/hcs.d.ts.map +0 -1
  94. package/script/io/hcs.js +0 -55
  95. package/script/io/itk_image_to_ngff_image.d.ts +0 -30
  96. package/script/io/itk_image_to_ngff_image.d.ts.map +0 -1
  97. package/script/io/itk_image_to_ngff_image.js +0 -153
  98. package/script/io/ngff_image_to_itk_image.d.ts +0 -30
  99. package/script/io/ngff_image_to_itk_image.d.ts.map +0 -1
  100. package/script/io/ngff_image_to_itk_image.js +0 -244
  101. package/script/io/to_ngff_image.d.ts +0 -17
  102. package/script/io/to_ngff_image.d.ts.map +0 -1
  103. package/script/io/to_ngff_image.js +0 -162
  104. package/script/io/to_ngff_zarr.d.ts +0 -10
  105. package/script/io/to_ngff_zarr.d.ts.map +0 -1
  106. package/script/io/to_ngff_zarr.js +0 -346
  107. package/script/methods/itkwasm-browser.d.ts +0 -6
  108. package/script/methods/itkwasm-browser.d.ts.map +0 -1
  109. package/script/methods/itkwasm-browser.js +0 -488
  110. package/script/methods/itkwasm-node.d.ts +0 -6
  111. package/script/methods/itkwasm-node.d.ts.map +0 -1
  112. package/script/methods/itkwasm-node.js +0 -493
  113. package/script/methods/itkwasm-shared.d.ts +0 -68
  114. package/script/methods/itkwasm-shared.d.ts.map +0 -1
  115. package/script/methods/itkwasm-shared.js +0 -524
  116. package/script/mod.d.ts +0 -24
  117. package/script/mod.d.ts.map +0 -1
  118. package/script/mod.js +0 -50
  119. package/script/package.json +0 -3
  120. package/script/process/to_multiscales-browser.d.ts +0 -17
  121. package/script/process/to_multiscales-browser.d.ts.map +0 -1
  122. package/script/process/to_multiscales-browser.js +0 -17
  123. package/script/process/to_multiscales-node.d.ts +0 -18
  124. package/script/process/to_multiscales-node.d.ts.map +0 -1
  125. package/script/process/to_multiscales-node.js +0 -21
  126. package/script/process/to_multiscales-shared.d.ts +0 -28
  127. package/script/process/to_multiscales-shared.d.ts.map +0 -1
  128. package/script/process/to_multiscales-shared.js +0 -66
  129. package/script/schemas/coordinate_systems.d.ts +0 -251
  130. package/script/schemas/coordinate_systems.d.ts.map +0 -1
  131. package/script/schemas/coordinate_systems.js +0 -142
  132. package/script/schemas/index.d.ts +0 -9
  133. package/script/schemas/index.d.ts.map +0 -1
  134. package/script/schemas/index.js +0 -101
  135. package/script/schemas/methods.d.ts +0 -3
  136. package/script/schemas/methods.d.ts.map +0 -1
  137. package/script/schemas/methods.js +0 -11
  138. package/script/schemas/multiscales.d.ts +0 -4
  139. package/script/schemas/multiscales.d.ts.map +0 -1
  140. package/script/schemas/multiscales.js +0 -24
  141. package/script/schemas/ngff_image.d.ts +0 -20
  142. package/script/schemas/ngff_image.d.ts.map +0 -1
  143. package/script/schemas/ngff_image.js +0 -24
  144. package/script/schemas/ome_zarr.d.ts +0 -617
  145. package/script/schemas/ome_zarr.d.ts.map +0 -1
  146. package/script/schemas/ome_zarr.js +0 -211
  147. package/script/schemas/rfc4.d.ts +0 -334
  148. package/script/schemas/rfc4.d.ts.map +0 -1
  149. package/script/schemas/rfc4.js +0 -132
  150. package/script/schemas/units.d.ts +0 -78
  151. package/script/schemas/units.d.ts.map +0 -1
  152. package/script/schemas/units.js +0 -70
  153. package/script/schemas/zarr_metadata.d.ts +0 -55
  154. package/script/schemas/zarr_metadata.d.ts.map +0 -1
  155. package/script/schemas/zarr_metadata.js +0 -71
  156. package/script/types/array_interface.d.ts +0 -7
  157. package/script/types/array_interface.d.ts.map +0 -1
  158. package/script/types/array_interface.js +0 -2
  159. package/script/types/hcs.d.ts +0 -70
  160. package/script/types/hcs.d.ts.map +0 -1
  161. package/script/types/hcs.js +0 -233
  162. package/script/types/methods.d.ts +0 -7
  163. package/script/types/methods.d.ts.map +0 -1
  164. package/script/types/methods.js +0 -12
  165. package/script/types/multiscales.d.ts +0 -21
  166. package/script/types/multiscales.d.ts.map +0 -1
  167. package/script/types/multiscales.js +0 -38
  168. package/script/types/ngff_image.d.ts +0 -27
  169. package/script/types/ngff_image.d.ts.map +0 -1
  170. package/script/types/ngff_image.js +0 -48
  171. package/script/types/rfc4.d.ts +0 -94
  172. package/script/types/rfc4.d.ts.map +0 -1
  173. package/script/types/rfc4.js +0 -143
  174. package/script/types/units.d.ts +0 -12
  175. package/script/types/units.d.ts.map +0 -1
  176. package/script/types/units.js +0 -66
  177. package/script/types/zarr_metadata.d.ts +0 -58
  178. package/script/types/zarr_metadata.d.ts.map +0 -1
  179. package/script/types/zarr_metadata.js +0 -20
  180. package/script/utils/create_queue.d.ts +0 -6
  181. package/script/utils/create_queue.d.ts.map +0 -1
  182. package/script/utils/create_queue.js +0 -17
  183. package/script/utils/factory.d.ts +0 -13
  184. package/script/utils/factory.d.ts.map +0 -1
  185. package/script/utils/factory.js +0 -108
  186. package/script/utils/method_metadata.d.ts +0 -10
  187. package/script/utils/method_metadata.d.ts.map +0 -1
  188. package/script/utils/method_metadata.js +0 -40
  189. package/script/utils/validation.d.ts +0 -6
  190. package/script/utils/validation.d.ts.map +0 -1
  191. package/script/utils/validation.js +0 -78
  192. /package/{LICENSE → LICENSE.txt} +0 -0
@@ -1,493 +0,0 @@
1
- "use strict";
2
- // SPDX-FileCopyrightText: Copyright (c) Fideus Labs LLC
3
- // SPDX-License-Identifier: MIT
4
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
- if (k2 === undefined) k2 = k;
6
- var desc = Object.getOwnPropertyDescriptor(m, k);
7
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
- desc = { enumerable: true, get: function() { return m[k]; } };
9
- }
10
- Object.defineProperty(o, k2, desc);
11
- }) : (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- o[k2] = m[k];
14
- }));
15
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
16
- Object.defineProperty(o, "default", { enumerable: true, value: v });
17
- }) : function(o, v) {
18
- o["default"] = v;
19
- });
20
- var __importStar = (this && this.__importStar) || function (mod) {
21
- if (mod && mod.__esModule) return mod;
22
- var result = {};
23
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
24
- __setModuleDefault(result, mod);
25
- return result;
26
- };
27
- Object.defineProperty(exports, "__esModule", { value: true });
28
- exports.downsampleItkWasm = downsampleItkWasm;
29
- /**
30
- * Node-compatible ITK-Wasm downsampling support
31
- * Uses native WASM implementations from @itk-wasm/downsample
32
- *
33
- * Note: Imports Node-specific functions that are available when the
34
- * "node" condition is active in package.json exports resolution.
35
- * The @itk-wasm/downsample package uses conditional exports to provide
36
- * different implementations for browser vs Node environments.
37
- */
38
- const downsample_1 = require("@itk-wasm/downsample");
39
- const zarr = __importStar(require("zarrita"));
40
- const ngff_image_js_1 = require("../types/ngff_image.js");
41
- const itkwasm_shared_js_1 = require("./itkwasm-shared.js");
42
- /**
43
- * Perform Gaussian downsampling using ITK-Wasm (browser version)
44
- */
45
- async function downsampleGaussian(image, dimFactors, spatialDims) {
46
- // Handle time dimension by processing each time slice independently
47
- if (image.dims.includes("t")) {
48
- const tDimIndex = image.dims.indexOf("t");
49
- const tSize = image.data.shape[tDimIndex];
50
- const newDims = image.dims.filter((dim) => dim !== "t");
51
- // Downsample each time slice
52
- const downsampledSlices = [];
53
- for (let t = 0; t < tSize; t++) {
54
- // Extract time slice
55
- const selection = new Array(image.data.shape.length).fill(null);
56
- selection[tDimIndex] = t;
57
- const sliceData = await zarr.get(image.data, selection);
58
- // Create temporary zarr array for this slice
59
- const sliceStore = new Map();
60
- const sliceRoot = zarr.root(sliceStore);
61
- const sliceShape = image.data.shape.filter((_, i) => i !== tDimIndex);
62
- const sliceChunkShape = sliceShape.map((s) => Math.min(s, 256));
63
- const sliceArray = await zarr.create(sliceRoot.resolve("slice"), {
64
- shape: sliceShape,
65
- chunk_shape: sliceChunkShape,
66
- data_type: image.data.dtype,
67
- fill_value: 0,
68
- });
69
- const fullSelection = new Array(sliceShape.length).fill(null);
70
- await zarr.set(sliceArray, fullSelection, sliceData);
71
- // Create NgffImage for this slice (without 't' dimension)
72
- const sliceImage = new ngff_image_js_1.NgffImage({
73
- data: sliceArray,
74
- dims: newDims,
75
- scale: Object.fromEntries(Object.entries(image.scale).filter(([dim]) => dim !== "t")),
76
- translation: Object.fromEntries(Object.entries(image.translation).filter(([dim]) => dim !== "t")),
77
- name: image.name,
78
- axesUnits: image.axesUnits
79
- ? Object.fromEntries(Object.entries(image.axesUnits).filter(([dim]) => dim !== "t"))
80
- : undefined,
81
- computedCallbacks: image.computedCallbacks,
82
- });
83
- // Recursively downsample this slice (without 't', so no infinite loop)
84
- const downsampledSlice = await downsampleGaussian(sliceImage, dimFactors, spatialDims);
85
- downsampledSlices.push(downsampledSlice.data);
86
- }
87
- // Combine downsampled slices back into a single array with 't' dimension
88
- const firstSlice = downsampledSlices[0];
89
- const combinedShape = [...image.data.shape];
90
- combinedShape[tDimIndex] = tSize;
91
- // Update spatial dimensions based on downsampled size
92
- for (let i = 0; i < image.dims.length; i++) {
93
- if (i !== tDimIndex) {
94
- const sliceIndex = i < tDimIndex ? i : i - 1;
95
- combinedShape[i] = firstSlice.shape[sliceIndex];
96
- }
97
- }
98
- // Create combined array
99
- const combinedStore = new Map();
100
- const combinedRoot = zarr.root(combinedStore);
101
- const combinedArray = await zarr.create(combinedRoot.resolve("combined"), {
102
- shape: combinedShape,
103
- chunk_shape: combinedShape.map((s) => Math.min(s, 256)),
104
- data_type: image.data.dtype,
105
- fill_value: 0,
106
- });
107
- // Copy each downsampled slice into the combined array
108
- for (let t = 0; t < tSize; t++) {
109
- const sliceData = await zarr.get(downsampledSlices[t]);
110
- const targetSelection = new Array(combinedShape.length).fill(null);
111
- targetSelection[tDimIndex] = t;
112
- await zarr.set(combinedArray, targetSelection, sliceData);
113
- }
114
- // Compute new metadata (time dimension unchanged, spatial dimensions downsampled)
115
- const [translation, scale] = (0, itkwasm_shared_js_1.nextScaleMetadata)(image, dimFactors, spatialDims);
116
- return new ngff_image_js_1.NgffImage({
117
- data: combinedArray,
118
- dims: image.dims,
119
- scale: { ...image.scale, ...scale },
120
- translation: { ...image.translation, ...translation },
121
- name: image.name,
122
- axesUnits: image.axesUnits,
123
- computedCallbacks: image.computedCallbacks,
124
- });
125
- }
126
- const isVector = image.dims.includes("c");
127
- // Convert to ITK-Wasm format
128
- const itkImage = await (0, itkwasm_shared_js_1.zarrToItkImage)(image.data, image.dims, isVector);
129
- // Prepare shrink factors - need to be for ALL dimensions in ITK order (reversed)
130
- const shrinkFactors = [];
131
- for (let i = image.dims.length - 1; i >= 0; i--) {
132
- const dim = image.dims[i];
133
- if (itkwasm_shared_js_1.SPATIAL_DIMS.includes(dim)) {
134
- shrinkFactors.push(dimFactors[dim] || 1);
135
- }
136
- }
137
- // Use all zeros for cropRadius
138
- const cropRadius = new Array(shrinkFactors.length).fill(0);
139
- // Perform downsampling using browser-compatible function
140
- const { downsampled } = await (0, downsample_1.downsampleNode)(itkImage, {
141
- shrinkFactors,
142
- cropRadius: cropRadius,
143
- });
144
- // Compute new metadata
145
- const [translation, scale] = (0, itkwasm_shared_js_1.nextScaleMetadata)(image, dimFactors, spatialDims);
146
- // Convert back to zarr array in a new in-memory store
147
- const store = new Map();
148
- const chunkShape = downsampled.size.map((s) => Math.min(s, 256)).reverse();
149
- const array = await (0, itkwasm_shared_js_1.itkImageToZarr)(downsampled, store, "image", chunkShape, image.dims);
150
- return new ngff_image_js_1.NgffImage({
151
- data: array,
152
- dims: image.dims,
153
- scale,
154
- translation,
155
- name: image.name,
156
- axesUnits: image.axesUnits,
157
- computedCallbacks: image.computedCallbacks,
158
- });
159
- }
160
- /**
161
- * Perform bin shrink downsampling using ITK-Wasm (browser version)
162
- */
163
- async function downsampleBinShrinkImpl(image, dimFactors, spatialDims) {
164
- // Handle time dimension by processing each time slice independently
165
- if (image.dims.includes("t")) {
166
- const tDimIndex = image.dims.indexOf("t");
167
- const tSize = image.data.shape[tDimIndex];
168
- const newDims = image.dims.filter((dim) => dim !== "t");
169
- // Downsample each time slice
170
- const downsampledSlices = [];
171
- for (let t = 0; t < tSize; t++) {
172
- // Extract time slice
173
- const selection = new Array(image.data.shape.length).fill(null);
174
- selection[tDimIndex] = t;
175
- const sliceData = await zarr.get(image.data, selection);
176
- // Create temporary zarr array for this slice
177
- const sliceStore = new Map();
178
- const sliceRoot = zarr.root(sliceStore);
179
- const sliceShape = image.data.shape.filter((_, i) => i !== tDimIndex);
180
- const sliceChunkShape = sliceShape.map((s) => Math.min(s, 256));
181
- const sliceArray = await zarr.create(sliceRoot.resolve("slice"), {
182
- shape: sliceShape,
183
- chunk_shape: sliceChunkShape,
184
- data_type: image.data.dtype,
185
- fill_value: 0,
186
- });
187
- const fullSelection = new Array(sliceShape.length).fill(null);
188
- await zarr.set(sliceArray, fullSelection, sliceData);
189
- // Create NgffImage for this slice (without 't' dimension)
190
- const sliceImage = new ngff_image_js_1.NgffImage({
191
- data: sliceArray,
192
- dims: newDims,
193
- scale: Object.fromEntries(Object.entries(image.scale).filter(([dim]) => dim !== "t")),
194
- translation: Object.fromEntries(Object.entries(image.translation).filter(([dim]) => dim !== "t")),
195
- name: image.name,
196
- axesUnits: image.axesUnits
197
- ? Object.fromEntries(Object.entries(image.axesUnits).filter(([dim]) => dim !== "t"))
198
- : undefined,
199
- computedCallbacks: image.computedCallbacks,
200
- });
201
- // Recursively downsample this slice
202
- const downsampledSlice = await downsampleBinShrinkImpl(sliceImage, dimFactors, spatialDims);
203
- downsampledSlices.push(downsampledSlice.data);
204
- }
205
- // Combine downsampled slices back into a single array with 't' dimension
206
- const firstSlice = downsampledSlices[0];
207
- const combinedShape = [...image.data.shape];
208
- combinedShape[tDimIndex] = tSize;
209
- // Update spatial dimensions based on downsampled size
210
- for (let i = 0; i < image.dims.length; i++) {
211
- if (i !== tDimIndex) {
212
- const sliceIndex = i < tDimIndex ? i : i - 1;
213
- combinedShape[i] = firstSlice.shape[sliceIndex];
214
- }
215
- }
216
- // Create combined array
217
- const combinedStore = new Map();
218
- const combinedRoot = zarr.root(combinedStore);
219
- const combinedArray = await zarr.create(combinedRoot.resolve("combined"), {
220
- shape: combinedShape,
221
- chunk_shape: combinedShape.map((s) => Math.min(s, 256)),
222
- data_type: image.data.dtype,
223
- fill_value: 0,
224
- });
225
- // Copy each downsampled slice into the combined array
226
- for (let t = 0; t < tSize; t++) {
227
- const sliceData = await zarr.get(downsampledSlices[t]);
228
- const targetSelection = new Array(combinedShape.length).fill(null);
229
- targetSelection[tDimIndex] = t;
230
- await zarr.set(combinedArray, targetSelection, sliceData);
231
- }
232
- // Compute new metadata
233
- const [translation, scale] = (0, itkwasm_shared_js_1.nextScaleMetadata)(image, dimFactors, spatialDims);
234
- return new ngff_image_js_1.NgffImage({
235
- data: combinedArray,
236
- dims: image.dims,
237
- scale: { ...image.scale, ...scale },
238
- translation: { ...image.translation, ...translation },
239
- name: image.name,
240
- axesUnits: image.axesUnits,
241
- computedCallbacks: image.computedCallbacks,
242
- });
243
- }
244
- const isVector = image.dims.includes("c");
245
- // Convert to ITK-Wasm format
246
- const itkImage = await (0, itkwasm_shared_js_1.zarrToItkImage)(image.data, image.dims, isVector);
247
- // Prepare shrink factors - only for spatial dimensions in ITK order (reversed)
248
- const shrinkFactors = [];
249
- for (let i = image.dims.length - 1; i >= 0; i--) {
250
- const dim = image.dims[i];
251
- if (itkwasm_shared_js_1.SPATIAL_DIMS.includes(dim)) {
252
- shrinkFactors.push(dimFactors[dim] || 1);
253
- }
254
- }
255
- // Perform downsampling using browser-compatible function
256
- const { downsampled } = await (0, downsample_1.downsampleBinShrinkNode)(itkImage, {
257
- shrinkFactors,
258
- });
259
- // Compute new metadata
260
- const [translation, scale] = (0, itkwasm_shared_js_1.nextScaleMetadata)(image, dimFactors, spatialDims);
261
- // Convert back to zarr array in a new in-memory store
262
- const store = new Map();
263
- const chunkShape = downsampled.size.map((s) => Math.min(s, 256)).reverse();
264
- const array = await (0, itkwasm_shared_js_1.itkImageToZarr)(downsampled, store, "image", chunkShape, image.dims);
265
- return new ngff_image_js_1.NgffImage({
266
- data: array,
267
- dims: image.dims,
268
- scale,
269
- translation,
270
- name: image.name,
271
- axesUnits: image.axesUnits,
272
- computedCallbacks: image.computedCallbacks,
273
- });
274
- }
275
- /**
276
- * Perform label image downsampling using ITK-Wasm (browser version)
277
- */
278
- async function downsampleLabelImageImpl(image, dimFactors, spatialDims) {
279
- // Handle time dimension by processing each time slice independently
280
- if (image.dims.includes("t")) {
281
- const tDimIndex = image.dims.indexOf("t");
282
- const tSize = image.data.shape[tDimIndex];
283
- const newDims = image.dims.filter((dim) => dim !== "t");
284
- // Downsample each time slice
285
- const downsampledSlices = [];
286
- for (let t = 0; t < tSize; t++) {
287
- // Extract time slice
288
- const selection = new Array(image.data.shape.length).fill(null);
289
- selection[tDimIndex] = t;
290
- const sliceData = await zarr.get(image.data, selection);
291
- // Create temporary zarr array for this slice
292
- const sliceStore = new Map();
293
- const sliceRoot = zarr.root(sliceStore);
294
- const sliceShape = image.data.shape.filter((_, i) => i !== tDimIndex);
295
- const sliceChunkShape = sliceShape.map((s) => Math.min(s, 256));
296
- const sliceArray = await zarr.create(sliceRoot.resolve("slice"), {
297
- shape: sliceShape,
298
- chunk_shape: sliceChunkShape,
299
- data_type: image.data.dtype,
300
- fill_value: 0,
301
- });
302
- const fullSelection = new Array(sliceShape.length).fill(null);
303
- await zarr.set(sliceArray, fullSelection, sliceData);
304
- // Create NgffImage for this slice (without 't' dimension)
305
- const sliceImage = new ngff_image_js_1.NgffImage({
306
- data: sliceArray,
307
- dims: newDims,
308
- scale: Object.fromEntries(Object.entries(image.scale).filter(([dim]) => dim !== "t")),
309
- translation: Object.fromEntries(Object.entries(image.translation).filter(([dim]) => dim !== "t")),
310
- name: image.name,
311
- axesUnits: image.axesUnits
312
- ? Object.fromEntries(Object.entries(image.axesUnits).filter(([dim]) => dim !== "t"))
313
- : undefined,
314
- computedCallbacks: image.computedCallbacks,
315
- });
316
- // Recursively downsample this slice
317
- const downsampledSlice = await downsampleLabelImageImpl(sliceImage, dimFactors, spatialDims);
318
- downsampledSlices.push(downsampledSlice.data);
319
- }
320
- // Combine downsampled slices back into a single array with 't' dimension
321
- const firstSlice = downsampledSlices[0];
322
- const combinedShape = [...image.data.shape];
323
- combinedShape[tDimIndex] = tSize;
324
- // Update spatial dimensions based on downsampled size
325
- for (let i = 0; i < image.dims.length; i++) {
326
- if (i !== tDimIndex) {
327
- const sliceIndex = i < tDimIndex ? i : i - 1;
328
- combinedShape[i] = firstSlice.shape[sliceIndex];
329
- }
330
- }
331
- // Create combined array
332
- const combinedStore = new Map();
333
- const combinedRoot = zarr.root(combinedStore);
334
- const combinedArray = await zarr.create(combinedRoot.resolve("combined"), {
335
- shape: combinedShape,
336
- chunk_shape: combinedShape.map((s) => Math.min(s, 256)),
337
- data_type: image.data.dtype,
338
- fill_value: 0,
339
- });
340
- // Copy each downsampled slice into the combined array
341
- for (let t = 0; t < tSize; t++) {
342
- const sliceData = await zarr.get(downsampledSlices[t]);
343
- const targetSelection = new Array(combinedShape.length).fill(null);
344
- targetSelection[tDimIndex] = t;
345
- await zarr.set(combinedArray, targetSelection, sliceData);
346
- }
347
- // Compute new metadata
348
- const [translation, scale] = (0, itkwasm_shared_js_1.nextScaleMetadata)(image, dimFactors, spatialDims);
349
- return new ngff_image_js_1.NgffImage({
350
- data: combinedArray,
351
- dims: image.dims,
352
- scale: { ...image.scale, ...scale },
353
- translation: { ...image.translation, ...translation },
354
- name: image.name,
355
- axesUnits: image.axesUnits,
356
- computedCallbacks: image.computedCallbacks,
357
- });
358
- }
359
- const isVector = image.dims.includes("c");
360
- // Convert to ITK-Wasm format
361
- const itkImage = await (0, itkwasm_shared_js_1.zarrToItkImage)(image.data, image.dims, isVector);
362
- // Prepare shrink factors - need to be for ALL dimensions in ITK order (reversed)
363
- const shrinkFactors = [];
364
- for (let i = image.dims.length - 1; i >= 0; i--) {
365
- const dim = image.dims[i];
366
- if (itkwasm_shared_js_1.SPATIAL_DIMS.includes(dim)) {
367
- shrinkFactors.push(dimFactors[dim] || 1);
368
- }
369
- else {
370
- shrinkFactors.push(1); // Non-spatial dimensions don't shrink
371
- }
372
- }
373
- // Use all zeros for cropRadius
374
- const cropRadius = new Array(shrinkFactors.length).fill(0);
375
- // Perform downsampling using browser-compatible function
376
- const { downsampled } = await (0, downsample_1.downsampleLabelImageNode)(itkImage, {
377
- shrinkFactors,
378
- cropRadius: cropRadius,
379
- });
380
- // Compute new metadata
381
- const [translation, scale] = (0, itkwasm_shared_js_1.nextScaleMetadata)(image, dimFactors, spatialDims);
382
- // Convert back to zarr array in a new in-memory store
383
- const store = new Map();
384
- const chunkShape = downsampled.size.map((s) => Math.min(s, 256)).reverse();
385
- const array = await (0, itkwasm_shared_js_1.itkImageToZarr)(downsampled, store, "image", chunkShape, image.dims);
386
- return new ngff_image_js_1.NgffImage({
387
- data: array,
388
- dims: image.dims,
389
- scale,
390
- translation,
391
- name: image.name,
392
- axesUnits: image.axesUnits,
393
- computedCallbacks: image.computedCallbacks,
394
- });
395
- }
396
- /**
397
- * Main downsampling function for ITK-Wasm (browser version)
398
- */
399
- async function downsampleItkWasm(ngffImage, scaleFactors, smoothing) {
400
- const multiscales = [ngffImage];
401
- const dims = ngffImage.dims;
402
- const spatialDims = dims.filter((dim) => itkwasm_shared_js_1.SPATIAL_DIMS.includes(dim));
403
- let previousImage = ngffImage;
404
- let previousDimFactors = {};
405
- for (const dim of dims)
406
- previousDimFactors[dim] = 1;
407
- for (let i = 0; i < scaleFactors.length; i++) {
408
- const scaleFactor = scaleFactors[i];
409
- let sourceImage;
410
- let sourceDimFactors;
411
- if (smoothing === "bin_shrink") {
412
- // Purely incremental: scaleFactor is the shrink for this step
413
- sourceImage = previousImage;
414
- sourceDimFactors = {};
415
- if (typeof scaleFactor === "number") {
416
- for (const dim of spatialDims)
417
- sourceDimFactors[dim] = scaleFactor;
418
- }
419
- else {
420
- for (const dim of spatialDims) {
421
- sourceDimFactors[dim] = scaleFactor[dim] || 1;
422
- }
423
- }
424
- for (const dim of dims) {
425
- if (!(dim in sourceDimFactors))
426
- sourceDimFactors[dim] = 1;
427
- }
428
- }
429
- else {
430
- // Hybrid absolute strategy
431
- const dimFactors = (0, itkwasm_shared_js_1.dimScaleFactors)(dims, scaleFactor, previousDimFactors, ngffImage, previousImage);
432
- let canDownsampleIncrementally = true;
433
- for (const dim of Object.keys(dimFactors)) {
434
- const dimIndex = ngffImage.dims.indexOf(dim);
435
- if (dimIndex >= 0) {
436
- const originalSize = ngffImage.data.shape[dimIndex];
437
- const targetSize = Math.floor(originalSize /
438
- (typeof scaleFactor === "number"
439
- ? scaleFactor
440
- : scaleFactor[dim]));
441
- const prevDimIndex = previousImage.dims.indexOf(dim);
442
- const previousSize = previousImage.data.shape[prevDimIndex];
443
- if (Math.floor(previousSize / dimFactors[dim]) !== targetSize) {
444
- canDownsampleIncrementally = false;
445
- break;
446
- }
447
- }
448
- }
449
- if (canDownsampleIncrementally) {
450
- sourceImage = previousImage;
451
- sourceDimFactors = dimFactors;
452
- }
453
- else {
454
- sourceImage = ngffImage;
455
- const originalDimFactors = {};
456
- for (const dim of dims)
457
- originalDimFactors[dim] = 1;
458
- sourceDimFactors = (0, itkwasm_shared_js_1.dimScaleFactors)(dims, scaleFactor, originalDimFactors);
459
- }
460
- }
461
- let downsampled;
462
- if (smoothing === "gaussian") {
463
- downsampled = await downsampleGaussian(sourceImage, sourceDimFactors, spatialDims);
464
- }
465
- else if (smoothing === "bin_shrink") {
466
- downsampled = await downsampleBinShrinkImpl(sourceImage, sourceDimFactors, spatialDims);
467
- }
468
- else if (smoothing === "label_image") {
469
- downsampled = await downsampleLabelImageImpl(sourceImage, sourceDimFactors, spatialDims);
470
- }
471
- else {
472
- throw new Error(`Unknown smoothing method: ${smoothing}`);
473
- }
474
- multiscales.push(downsampled);
475
- previousImage = downsampled;
476
- if (smoothing === "bin_shrink") {
477
- if (typeof scaleFactor === "number") {
478
- for (const dim of spatialDims) {
479
- previousDimFactors[dim] *= scaleFactor;
480
- }
481
- }
482
- else {
483
- for (const dim of spatialDims) {
484
- previousDimFactors[dim] *= scaleFactor[dim] || 1;
485
- }
486
- }
487
- }
488
- else {
489
- previousDimFactors = (0, itkwasm_shared_js_1.updatePreviousDimFactors)(scaleFactor, spatialDims, previousDimFactors);
490
- }
491
- }
492
- return multiscales;
493
- }
@@ -1,68 +0,0 @@
1
- /**
2
- * Shared helper functions for ITK-Wasm downsampling
3
- * Used by both browser and Node implementations
4
- */
5
- import type { Image } from "itk-wasm";
6
- import * as zarr from "zarrita";
7
- import { NgffImage } from "../types/ngff_image.js";
8
- export declare const SPATIAL_DIMS: string[];
9
- export interface DimFactors {
10
- [key: string]: number;
11
- }
12
- /**
13
- * Calculate the incremental factor needed to reach the target size from the previous size.
14
- * This ensures exact target sizes when downsampling incrementally.
15
- */
16
- export declare function calculateIncrementalFactor(previousSize: number, targetSize: number): number;
17
- /**
18
- * Convert dimension scale factors to ITK-Wasm format
19
- * This computes the incremental scale factor relative to the previous scale,
20
- * not the absolute scale factor from the original image.
21
- *
22
- * When originalImage and previousImage are provided, calculates the exact
23
- * incremental factor needed to reach the target size from the previous size.
24
- * This ensures we get exact 1x, 2x, 3x, 4x sizes even with incremental downsampling.
25
- */
26
- export declare function dimScaleFactors(dims: string[], scaleFactor: Record<string, number> | number, previousDimFactors: DimFactors, originalImage?: NgffImage, previousImage?: NgffImage): DimFactors;
27
- /**
28
- * Update previous dimension factors
29
- */
30
- export declare function updatePreviousDimFactors(scaleFactor: Record<string, number> | number, spatialDims: string[], previousDimFactors: DimFactors): DimFactors;
31
- /**
32
- * Compute next scale metadata
33
- */
34
- export declare function nextScaleMetadata(image: NgffImage, dimFactors: DimFactors, spatialDims: string[]): [Record<string, number>, Record<string, number>];
35
- /**
36
- * Get ITK component type from typed array
37
- */
38
- export declare function getItkComponentType(data: unknown): "uint8" | "int8" | "uint16" | "int16" | "uint32" | "int32" | "float32" | "float64";
39
- /**
40
- * Create identity matrix for ITK direction
41
- */
42
- export declare function createIdentityMatrix(dimension: number): Float64Array;
43
- /**
44
- * Transpose array data according to permutation
45
- */
46
- export declare function transposeArray(data: unknown, shape: number[], permutation: number[], componentType: "uint8" | "int8" | "uint16" | "int16" | "uint32" | "int32" | "float32" | "float64"): Float32Array | Float64Array | Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array;
47
- /**
48
- * Convert zarr array to ITK-Wasm Image format
49
- * If isVector is true, ensures "c" dimension is last by transposing if needed
50
- */
51
- export declare function zarrToItkImage(array: zarr.Array<zarr.DataType, zarr.Readable>, dims: string[], isVector?: boolean): Promise<Image>;
52
- /**
53
- * Convert ITK-Wasm Image back to zarr array
54
- * Uses the provided store instead of creating a new one
55
- *
56
- * Important: ITK-Wasm stores size in physical space order [x, y, z], but data in
57
- * column-major order (x contiguous). This column-major layout with size [x, y, z]
58
- * is equivalent to C-order (row-major) with shape [z, y, x]. We reverse the size
59
- * to get the zarr shape and use C-order strides for that reversed shape.
60
- *
61
- * @param itkImage - The ITK-Wasm image to convert
62
- * @param store - The zarr store to write to
63
- * @param path - The path within the store
64
- * @param chunkShape - The chunk shape (in spatial dimension order, will be adjusted for components)
65
- * @param targetDims - The target dimension order (e.g., ["c", "z", "y", "x"])
66
- */
67
- export declare function itkImageToZarr(itkImage: Image, store: Map<string, Uint8Array>, path: string, chunkShape: number[], targetDims?: string[]): Promise<zarr.Array<zarr.DataType, zarr.Readable>>;
68
- //# sourceMappingURL=itkwasm-shared.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"itkwasm-shared.d.ts","sourceRoot":"","sources":["../../src/methods/itkwasm-shared.ts"],"names":[],"mappings":"AAGA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,eAAO,MAAM,YAAY,UAAkB,CAAC;AAE5C,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,MAAM,CAsBR;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EAAE,EACd,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAC5C,kBAAkB,EAAE,UAAU,EAC9B,aAAa,CAAC,EAAE,SAAS,EACzB,aAAa,CAAC,EAAE,SAAS,GACxB,UAAU,CAqEZ;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAC5C,WAAW,EAAE,MAAM,EAAE,EACrB,kBAAkB,EAAE,UAAU,GAC7B,UAAU,CAcZ;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,MAAM,EAAE,GACpB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkBlD;AAsCD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,OAAO,GAEX,OAAO,GACP,MAAM,GACN,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,OAAO,GACP,SAAS,GACT,SAAS,CASZ;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAMpE;AAcD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,MAAM,EAAE,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,aAAa,EACT,OAAO,GACP,MAAM,GACN,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,OAAO,GACP,SAAS,GACT,SAAS,GAEX,YAAY,GACZ,YAAY,GACZ,UAAU,GACV,SAAS,GACT,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,CAqFb;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EAC/C,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,UAAQ,GACf,OAAO,CAAC,KAAK,CAAC,CAqFhB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,KAAK,EACf,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAC9B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,CAAC,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAoJnD"}