omezarr-tilesource 0.5.0 → 0.7.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 +188 -58
- package/dist/omezarr-tilesource.d.ts +521 -24
- package/dist/omezarr-tilesource.js +229 -104
- package/package.json +1 -1
|
@@ -2,43 +2,174 @@ import e from "@zarrita/storage/zip";
|
|
|
2
2
|
import { NgffImage as t, getSlices as n, renderChunks as r } from "ome-zarr.js";
|
|
3
3
|
import i from "openseadragon";
|
|
4
4
|
import * as a from "zarrita";
|
|
5
|
+
//#region src/utils.ts
|
|
6
|
+
var o = /* @__PURE__ */ new WeakMap();
|
|
7
|
+
function s(e) {
|
|
8
|
+
if (e instanceof Blob) {
|
|
9
|
+
let t = o.get(e);
|
|
10
|
+
return t === void 0 && (t = URL.createObjectURL(e), o.set(e, t)), new URL(t);
|
|
11
|
+
}
|
|
12
|
+
return new URL(e, globalThis.document?.baseURI);
|
|
13
|
+
}
|
|
14
|
+
function c(e) {
|
|
15
|
+
try {
|
|
16
|
+
return s(e).pathname.endsWith(".ozx");
|
|
17
|
+
} catch {
|
|
18
|
+
return e.toString().endsWith(".ozx");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function l(e) {
|
|
22
|
+
let { data: t } = e;
|
|
23
|
+
return t instanceof Int8Array ? [-128, 127] : t instanceof Uint8Array ? [0, 255] : t instanceof Int16Array ? [-32768, 32767] : t instanceof Uint16Array ? [0, 65535] : t instanceof Int32Array ? [-2147483648, 2147483647] : t instanceof Uint32Array ? [0, 4294967295] : t instanceof BigInt64Array ? [-(2 ** 63), 2 ** 63 - 1] : t instanceof BigUint64Array ? [0, 2 ** 64 - 1] : [0, 1];
|
|
24
|
+
}
|
|
25
|
+
function u(e) {
|
|
26
|
+
let t = 2166136261;
|
|
27
|
+
for (let n = 0; n < e.length; n++) t = Math.imul(t ^ e.charCodeAt(n), 16777619);
|
|
28
|
+
return t >>> 0;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
5
31
|
//#region src/OMEZarrTileSource.ts
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
32
|
+
var d = class o extends i.TileSource {
|
|
33
|
+
blob;
|
|
34
|
+
zip = !1;
|
|
35
|
+
_t;
|
|
36
|
+
_z;
|
|
37
|
+
_c;
|
|
38
|
+
_renderSettings;
|
|
39
|
+
_renderSettingsHash;
|
|
13
40
|
width = 10;
|
|
14
41
|
height = 10;
|
|
15
|
-
|
|
16
|
-
_arrays;
|
|
42
|
+
_loaded;
|
|
17
43
|
_readyPromise = new Promise((e, t) => {
|
|
18
44
|
this.addOnceHandler("ready", () => e(this)), this.addOnceHandler("open-failed", (e) => t(Error(e.message)));
|
|
19
45
|
});
|
|
20
46
|
static {
|
|
21
47
|
o._learnConverters(i);
|
|
22
48
|
}
|
|
23
|
-
static
|
|
24
|
-
|
|
49
|
+
static enable(e = i) {
|
|
50
|
+
Object.assign(e, { OMEZarrTileSource: o }), o._learnConverters(e);
|
|
51
|
+
}
|
|
52
|
+
static async loadOMEZarr(n, r, i) {
|
|
53
|
+
let { signal: a } = i ?? {};
|
|
54
|
+
a?.throwIfAborted();
|
|
55
|
+
let o;
|
|
56
|
+
if (n instanceof Blob) {
|
|
57
|
+
if (r === !1) throw Error("only zipped OME-Zarr files can be loaded from a Blob");
|
|
58
|
+
o = e.fromBlob(n);
|
|
59
|
+
} else {
|
|
60
|
+
let t = s(n);
|
|
61
|
+
o = r ?? c(t) ? e.fromUrl(t) : n.toString();
|
|
62
|
+
}
|
|
63
|
+
let l = await t.load(o, { signal: a });
|
|
64
|
+
return {
|
|
65
|
+
image: l,
|
|
66
|
+
arrays: await Promise.all(l.paths.map((e) => l.openArray(e, { signal: a })))
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
static async open(e, t, n) {
|
|
70
|
+
let { signal: r } = n ?? {};
|
|
71
|
+
return r?.throwIfAborted(), t ??= typeof e == "string" || e instanceof URL || e instanceof Blob ? await o.loadOMEZarr(e, void 0, { signal: r }) : await o.loadOMEZarr(e.url, e.zip, { signal: r }), new o(e, t).whenReady();
|
|
72
|
+
}
|
|
73
|
+
static render(e) {
|
|
74
|
+
let { chunks: t, ranges: n, colors: i, lutsOrColorMaps: a, inverteds: o, autoBoost: s } = e, c = t[0].shape[1], l = t[0].shape[0], u = document.createElement("canvas");
|
|
75
|
+
u.width = c, u.height = l;
|
|
76
|
+
let d = u.getContext("2d");
|
|
77
|
+
if (d === null) throw Error("failed to get 2D canvas context");
|
|
78
|
+
let f = r(t, n, i, a.map((e) => Array.isArray(e) ? [...e] : e), o, s), p = new ImageData(f, c, l);
|
|
79
|
+
return d.putImageData(p, 0, 0), d;
|
|
25
80
|
}
|
|
26
81
|
constructor(e, t) {
|
|
27
|
-
typeof e == "string"
|
|
82
|
+
let n = typeof e == "string" || e instanceof URL || e instanceof Blob ? { url: e } : e, r = s(n.url);
|
|
83
|
+
if (n.url instanceof Blob && n.zip === !1) throw Error("zip must not be false for a Blob (only zipped OME-Zarr files can be loaded from a Blob)");
|
|
84
|
+
let i;
|
|
85
|
+
if (n.c !== void 0) if (Array.isArray(n.c)) {
|
|
86
|
+
if (n.c.length === 0) throw Error("c array must be non-empty");
|
|
87
|
+
i = n.c;
|
|
88
|
+
} else i = [n.c];
|
|
89
|
+
let a = o._normalize(n, "range", (e) => Array.isArray(e) && e.length === 2 && e.every((e) => typeof e == "number"), i), l = o._normalize(n, "color", (e) => Array.isArray(e) && e.length === 3 && e.every((e) => typeof e == "number"), i), d = o._normalize(n, "lutOrColorMap", (e) => e instanceof Map || Array.isArray(e) && e.length > 0 && e.every((e) => Array.isArray(e) && (e.length === 3 || e.length === 4) && e.every((e) => typeof e == "number")), i), f = o._normalize(n, "inverted", (e) => typeof e == "boolean", i);
|
|
90
|
+
super(r.toString()), this.url = r.toString(), this.blob = n.url instanceof Blob ? n.url : void 0, this.zip = n.zip ?? (this.blob !== void 0 || c(r)), this._t = n.t, this._z = n.z, this._c = i, this._renderSettings = {
|
|
91
|
+
ranges: a,
|
|
92
|
+
colors: l,
|
|
93
|
+
lutsOrColorMaps: d,
|
|
94
|
+
inverteds: f,
|
|
95
|
+
autoBoost: n.autoBoost ?? !1
|
|
96
|
+
}, this._renderSettingsHash = u(JSON.stringify({
|
|
97
|
+
...this._renderSettings,
|
|
98
|
+
lutsOrColorMaps: d?.map((e) => e instanceof Map ? [...e].sort(([e], [t]) => e - t) : e)
|
|
99
|
+
})), this._loaded = t, this._readyPromise.catch(() => {});
|
|
100
|
+
}
|
|
101
|
+
get loaded() {
|
|
102
|
+
if (this._loaded === void 0) throw Error("tile source not ready");
|
|
103
|
+
return this._loaded;
|
|
104
|
+
}
|
|
105
|
+
get t() {
|
|
106
|
+
return this._t === void 0 ? this._loaded?.image.omero?.rdefs?.defaultT : this._t;
|
|
107
|
+
}
|
|
108
|
+
get z() {
|
|
109
|
+
return this._z === void 0 ? this._loaded?.image.omero?.rdefs?.defaultZ : this._z;
|
|
110
|
+
}
|
|
111
|
+
get cs() {
|
|
112
|
+
return this._c === void 0 ? this._loaded?.image.omero?.channels?.flatMap((e, t) => e.active === !1 ? [] : [t]) : this._c;
|
|
113
|
+
}
|
|
114
|
+
get channels() {
|
|
115
|
+
return this._c === void 0 ? this._loaded?.image.omero?.channels?.filter((e) => e.active !== !1) : this._c.map((e) => this._loaded?.image.omero?.channels?.[e]);
|
|
116
|
+
}
|
|
117
|
+
get ranges() {
|
|
118
|
+
let e = this.channels, t = (e) => {
|
|
119
|
+
if (e?.window.start !== void 0 && e.window.end !== void 0) return [e.window.start, e.window.end];
|
|
120
|
+
};
|
|
121
|
+
return o._repeat(this._renderSettings.ranges, e)?.map((n, r) => n ?? t(e?.[r]));
|
|
122
|
+
}
|
|
123
|
+
get colors() {
|
|
124
|
+
let e = this.channels, t = (e) => {
|
|
125
|
+
if (e === void 0) return;
|
|
126
|
+
let t = /^#?([0-9A-Fa-f]{6})$/.exec(e.color)?.[1];
|
|
127
|
+
if (t !== void 0) return [
|
|
128
|
+
parseInt(t.slice(0, 2), 16),
|
|
129
|
+
parseInt(t.slice(2, 4), 16),
|
|
130
|
+
parseInt(t.slice(4, 6), 16)
|
|
131
|
+
];
|
|
132
|
+
};
|
|
133
|
+
return o._repeat(this._renderSettings.colors, e)?.map((n, r) => n ?? t(e?.[r]));
|
|
28
134
|
}
|
|
29
|
-
get
|
|
30
|
-
|
|
31
|
-
return this.
|
|
135
|
+
get lutsOrColorMaps() {
|
|
136
|
+
let e = this.channels, t = (e) => e?.lut ?? e?.colorMap;
|
|
137
|
+
return o._repeat(this._renderSettings.lutsOrColorMaps, e)?.map((n, r) => n ?? t(e?.[r]));
|
|
32
138
|
}
|
|
33
|
-
get
|
|
34
|
-
|
|
35
|
-
return this.
|
|
139
|
+
get inverteds() {
|
|
140
|
+
let e = this.channels;
|
|
141
|
+
return o._repeat(this._renderSettings.inverteds, e)?.map((t, n) => t ?? e?.[n]?.inverted);
|
|
142
|
+
}
|
|
143
|
+
get autoBoost() {
|
|
144
|
+
return this._renderSettings.autoBoost;
|
|
36
145
|
}
|
|
37
146
|
whenReady() {
|
|
38
147
|
return this._readyPromise;
|
|
39
148
|
}
|
|
149
|
+
getWidth(e = this.maxLevel) {
|
|
150
|
+
if (e < 0 || e > this.maxLevel) throw Error("level out of bounds");
|
|
151
|
+
return o._getAxisSize(this.loaded, "x", this.maxLevel - e);
|
|
152
|
+
}
|
|
153
|
+
getHeight(e = this.maxLevel) {
|
|
154
|
+
if (e < 0 || e > this.maxLevel) throw Error("level out of bounds");
|
|
155
|
+
return o._getAxisSize(this.loaded, "y", this.maxLevel - e);
|
|
156
|
+
}
|
|
157
|
+
loadChunks(e, t, r) {
|
|
158
|
+
let i = {
|
|
159
|
+
t: this.t,
|
|
160
|
+
z: this.z
|
|
161
|
+
};
|
|
162
|
+
if (t !== void 0) {
|
|
163
|
+
let { x: n, y: r } = this.getNumTiles(e);
|
|
164
|
+
if (t.x < 0 || t.x >= n || t.y < 0 || t.y >= r) throw Error("tile out of bounds");
|
|
165
|
+
let a = this.getTileWidth(e), o = this.getTileHeight(e);
|
|
166
|
+
i.x = [t.x * a, (t.x + 1) * a], i.y = [t.y * o, (t.y + 1) * o];
|
|
167
|
+
}
|
|
168
|
+
let s = o._getAxisSize(this.loaded, "c"), c = n(this.cs ?? Array.from({ length: s }, (e, t) => t), this.loaded.arrays[this.maxLevel - e].shape, this.loaded.image.getAxesNames(), i);
|
|
169
|
+
return Promise.all(c.map((t) => a.get(this.loaded.arrays[this.maxLevel - e], t, r)));
|
|
170
|
+
}
|
|
40
171
|
supports(e) {
|
|
41
|
-
return Array.isArray(e) || e instanceof Document ? !1 : typeof e == "string" ? e
|
|
172
|
+
return Array.isArray(e) || e instanceof Document ? !1 : typeof e == "string" ? c(e) : "type" in e && e.type === "ome-zarr";
|
|
42
173
|
}
|
|
43
174
|
configure(e, t, n = null) {
|
|
44
175
|
if (Array.isArray(e)) throw Error("configuration from array is not supported");
|
|
@@ -53,11 +184,11 @@ var o = class o extends i.TileSource {
|
|
|
53
184
|
};
|
|
54
185
|
}
|
|
55
186
|
equals(e) {
|
|
56
|
-
return e instanceof o && this.url === e.url && this.zip === e.zip && this.
|
|
187
|
+
return e instanceof o && this.url === e.url && this.zip === e.zip && this.t === e.t && this.z === e.z && this.cs?.join(",") === e.cs?.join(",") && this._renderSettingsHash === e._renderSettingsHash;
|
|
57
188
|
}
|
|
58
|
-
getImageInfo(
|
|
59
|
-
Promise.resolve(this.
|
|
60
|
-
let t = e.getAxesNames();
|
|
189
|
+
getImageInfo(e) {
|
|
190
|
+
Promise.resolve(this._loaded ?? o.loadOMEZarr(this.blob ?? e, this.zip)).then((e) => {
|
|
191
|
+
let t = e.image.getAxesNames();
|
|
61
192
|
for (let e of t) if (![
|
|
62
193
|
"t",
|
|
63
194
|
"c",
|
|
@@ -67,38 +198,39 @@ var o = class o extends i.TileSource {
|
|
|
67
198
|
].includes(e)) throw Error(`unsupported axis: ${e}`);
|
|
68
199
|
if (!t.includes("x") || !t.includes("y")) throw Error("missing X or Y axis");
|
|
69
200
|
if (t.indexOf("y") > t.indexOf("x")) throw Error("X axis must come after Y axis");
|
|
70
|
-
let n =
|
|
71
|
-
if (this.
|
|
72
|
-
let
|
|
73
|
-
if (this.
|
|
74
|
-
let
|
|
75
|
-
if (this.
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
this.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
message: `failed to get image info for ${n}: ${e}`,
|
|
84
|
-
source: n
|
|
201
|
+
let n = o._getAxisSize(e, "t");
|
|
202
|
+
if (this._t !== void 0 && (this._t < 0 || this._t >= n)) throw Error(`Invalid t index ${this._t} for image with ${n} timepoints`);
|
|
203
|
+
let r = o._getAxisSize(e, "z");
|
|
204
|
+
if (this._z !== void 0 && (this._z < 0 || this._z >= r)) throw Error(`Invalid z index ${this._z} for image with ${r} z-slices`);
|
|
205
|
+
let i = o._getAxisSize(e, "c");
|
|
206
|
+
if (this._c !== void 0 && this._c.some((e) => e < 0 || e >= i)) throw Error(`Invalid c indices [${this._c?.join(", ")}] for image with ${i} channels`);
|
|
207
|
+
if (e.image.omero !== void 0 && e.image.omero.channels !== void 0 && e.image.omero.channels.length !== i) throw Error(`OME-Zarr metadata lists ${e.image.omero.channels.length} channels, but the image has ${i}`);
|
|
208
|
+
if (this._c === void 0 && e.image.omero !== void 0 && e.image.omero.channels !== void 0 && !e.image.omero.channels.some((e) => e.active !== !1)) throw Error("No active channels; specify c or activate channels in the OME-Zarr metadata");
|
|
209
|
+
this._loaded = e, this.width = e.arrays[0].shape[t.indexOf("x")], this.height = e.arrays[0].shape[t.indexOf("y")], this.maxLevel = e.arrays.length - 1, this.raiseEvent("ready", { tileSource: this });
|
|
210
|
+
}).catch((t) => {
|
|
211
|
+
this._loaded = void 0, this.width = 10, this.height = 10, this.maxLevel = 0, this.raiseEvent("open-failed", {
|
|
212
|
+
message: `failed to get image info for ${e}: ${t}`,
|
|
213
|
+
source: e
|
|
85
214
|
});
|
|
86
215
|
});
|
|
87
216
|
}
|
|
88
217
|
getTileWidth(e) {
|
|
89
|
-
|
|
218
|
+
let { image: t, arrays: n } = this.loaded;
|
|
90
219
|
if (e < 0 || e > this.maxLevel) throw Error("level out of bounds");
|
|
91
|
-
return
|
|
220
|
+
return n[this.maxLevel - e].chunks[t.getAxesNames().indexOf("x")];
|
|
92
221
|
}
|
|
93
222
|
getTileHeight(e) {
|
|
94
|
-
|
|
223
|
+
let { image: t, arrays: n } = this.loaded;
|
|
95
224
|
if (e < 0 || e > this.maxLevel) throw Error("level out of bounds");
|
|
96
|
-
return
|
|
225
|
+
return n[this.maxLevel - e].chunks[t.getAxesNames().indexOf("y")];
|
|
97
226
|
}
|
|
98
227
|
getLevelScale(e) {
|
|
99
|
-
if (this._image === void 0 || this._arrays === void 0) throw Error("tile source not ready");
|
|
100
228
|
if (e < 0 || e > this.maxLevel) throw Error("level out of bounds");
|
|
101
|
-
return this.
|
|
229
|
+
return this.getWidth(e) / this.width;
|
|
230
|
+
}
|
|
231
|
+
getNumTiles(e) {
|
|
232
|
+
if (e < 0 || e > this.maxLevel) throw Error("level out of bounds");
|
|
233
|
+
return new i.Point(Math.ceil(this.getWidth(e) / this.getTileWidth(e)), Math.ceil(this.getHeight(e) / this.getTileHeight(e)));
|
|
102
234
|
}
|
|
103
235
|
getTileUrl(e, t, n) {
|
|
104
236
|
let r = new URLSearchParams();
|
|
@@ -106,84 +238,77 @@ var o = class o extends i.TileSource {
|
|
|
106
238
|
}
|
|
107
239
|
getTileHashKey(e, t, n) {
|
|
108
240
|
let r = new URL(this.url);
|
|
109
|
-
return r.searchParams.append("
|
|
241
|
+
return r.searchParams.append("zip", this.zip.toString()), this.t !== void 0 && r.searchParams.append("t", this.t.toString()), this.z !== void 0 && r.searchParams.append("z", this.z.toString()), this.cs !== void 0 && r.searchParams.append("c", this.cs.join(",")), r.searchParams.append("y", n.toString()), r.searchParams.append("x", t.toString()), r.searchParams.append("level", e.toString()), r.searchParams.append("render", this._renderSettingsHash.toString(16)), r.toString();
|
|
110
242
|
}
|
|
111
243
|
downloadTileStart(e) {
|
|
112
|
-
let t = e.userData,
|
|
113
|
-
t.abortController =
|
|
114
|
-
let
|
|
244
|
+
let t = e.userData, n = new AbortController();
|
|
245
|
+
t.abortController = n;
|
|
246
|
+
let r = new URLSearchParams(e.src), i = +r.get("level"), a = +r.get("x"), o = +r.get("y");
|
|
115
247
|
try {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
r
|
|
248
|
+
this.loadChunks(i, {
|
|
249
|
+
x: a,
|
|
250
|
+
y: o
|
|
251
|
+
}, { signal: n.signal }).then((n) => {
|
|
252
|
+
let r = this.ranges, i = this.colors, a = this.inverteds, o = this.lutsOrColorMaps, s = this.autoBoost, c = {
|
|
253
|
+
chunks: n,
|
|
254
|
+
ranges: n.map((e, t) => {
|
|
255
|
+
let [n, i] = r?.[t] ?? l(e);
|
|
256
|
+
return n < i ? [n, i] : [n, n + 1];
|
|
257
|
+
}),
|
|
258
|
+
colors: n.map((e, t) => i?.[t] ?? [
|
|
259
|
+
255,
|
|
260
|
+
255,
|
|
261
|
+
255
|
|
262
|
+
]),
|
|
263
|
+
lutsOrColorMaps: n.map((e, t) => o?.[t]),
|
|
264
|
+
inverteds: n.map((e, t) => a?.[t] ?? !1),
|
|
265
|
+
autoBoost: s
|
|
266
|
+
};
|
|
267
|
+
t.abortController = void 0, e.finish(c, null, "ome-zarr");
|
|
268
|
+
}, (t) => {
|
|
269
|
+
let r = n.signal.aborted;
|
|
270
|
+
n.abort(), r || e.fail(`failed to load chunks for level=${i}, x=${a}, y=${o}: ${String(t)}`, null);
|
|
138
271
|
});
|
|
139
272
|
} catch (t) {
|
|
140
|
-
e.fail(`failed to download tile for level=${
|
|
273
|
+
e.fail(`failed to download tile for level=${i}, x=${a}, y=${o}: ${String(t)}`, null);
|
|
141
274
|
}
|
|
142
275
|
}
|
|
143
276
|
downloadTileAbort(e) {
|
|
144
277
|
let t = e.userData;
|
|
145
278
|
t.abortController !== void 0 && (t.abortController.abort(), t.abortController = void 0);
|
|
146
279
|
}
|
|
147
|
-
static
|
|
148
|
-
|
|
280
|
+
static _normalize(e, t, n, r) {
|
|
281
|
+
let i = e[t];
|
|
282
|
+
if (i !== void 0) {
|
|
283
|
+
if (n(i)) {
|
|
284
|
+
let e = i;
|
|
285
|
+
return r === void 0 ? [e] : r.map(() => e);
|
|
286
|
+
}
|
|
287
|
+
if (!Array.isArray(i) || !i.every((e) => e === void 0 || n(e))) throw Error(`${t} must be a value or an array of values`);
|
|
288
|
+
if (i.length === 0) throw Error(`${t} array must be non-empty`);
|
|
289
|
+
if (r !== void 0 && i.length !== r.length) throw Error(`${t} array length ${i.length} does not match number of channels ${r.length} in c`);
|
|
290
|
+
return i;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
static _repeat(e, t) {
|
|
294
|
+
return e === void 0 ? t?.map(() => void 0) : e.length === 1 && t !== void 0 ? t.map(() => e[0]) : e;
|
|
149
295
|
}
|
|
150
296
|
static _learnConverters(e) {
|
|
151
|
-
e.converter.existsType("ome-zarr") || (e.converter.learn("ome-zarr", "context2d", (e,
|
|
297
|
+
e.converter.existsType("ome-zarr") || (e.converter.learn("ome-zarr", "context2d", (e, t) => o.render(t), 1, 1), e.converter.learn("ome-zarr", "ome-zarr", (e, t) => ({
|
|
152
298
|
...t,
|
|
153
|
-
|
|
154
|
-
...
|
|
155
|
-
data:
|
|
156
|
-
}
|
|
299
|
+
chunks: t.chunks.map((e) => ({
|
|
300
|
+
...e,
|
|
301
|
+
data: e.data.slice()
|
|
302
|
+
}))
|
|
157
303
|
})));
|
|
158
304
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
static _render(e, t, n) {
|
|
163
|
-
let i = t.map((e) => {
|
|
164
|
-
let t = e.color.replace(/^#/, "");
|
|
165
|
-
return [
|
|
166
|
-
parseInt(t.slice(0, 2), 16),
|
|
167
|
-
parseInt(t.slice(2, 4), 16),
|
|
168
|
-
parseInt(t.slice(4, 6), 16)
|
|
169
|
-
];
|
|
170
|
-
}), a = r(e, t.map((t, n) => {
|
|
171
|
-
let [r, i] = t.window.start !== void 0 && t.window.end !== void 0 ? [t.window.start, t.window.end] : o._getDataTypeRange(e[n]);
|
|
172
|
-
return r < i ? [r, i] : [r, r + 1];
|
|
173
|
-
}), i, t.map((e) => e.lut ?? e.colorMap), t.map((e) => e.inverted === !0), n), s = e[0].shape[1], c = e[0].shape[0], l = document.createElement("canvas");
|
|
174
|
-
l.width = s, l.height = c;
|
|
175
|
-
let u = l.getContext("2d");
|
|
176
|
-
if (u === null) throw Error("failed to get 2D canvas context");
|
|
177
|
-
let d = new ImageData(a, s, c);
|
|
178
|
-
return u.putImageData(d, 0, 0), u;
|
|
179
|
-
}
|
|
180
|
-
static _getDataTypeRange(e) {
|
|
181
|
-
let { data: t } = e;
|
|
182
|
-
return t instanceof Int8Array ? [-128, 127] : t instanceof Uint8Array ? [0, 255] : t instanceof Int16Array ? [-32768, 32767] : t instanceof Uint16Array ? [0, 65535] : t instanceof Int32Array ? [-2147483648, 2147483647] : t instanceof Uint32Array ? [0, 4294967295] : t instanceof BigInt64Array ? [-(2 ** 63), 2 ** 63 - 1] : t instanceof BigUint64Array ? [0, 2 ** 64 - 1] : [0, 1];
|
|
305
|
+
static _getAxisSize(e, t, n = 0) {
|
|
306
|
+
let r = e.image.getAxesNames().indexOf(t);
|
|
307
|
+
return r >= 0 ? e.arrays[n].shape[r] : 1;
|
|
183
308
|
}
|
|
184
309
|
};
|
|
185
310
|
//#endregion
|
|
186
311
|
//#region src/main.ts
|
|
187
|
-
globalThis.OpenSeadragon &&
|
|
312
|
+
globalThis.OpenSeadragon && d.enable(globalThis.OpenSeadragon);
|
|
188
313
|
//#endregion
|
|
189
|
-
export {
|
|
314
|
+
export { d as OMEZarrTileSource, u as fnv1a, l as getDataTypeRange, c as isOZX, s as resolveUrl };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omezarr-tilesource",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "An OpenSeadragon tile source for the OME-Zarr bioimage file format",
|
|
5
5
|
"homepage": "https://github.com/TissUUmaps/OMEZarrTileSource#readme",
|
|
6
6
|
"bugs": "https://github.com/TissUUmaps/OMEZarrTileSource/issues",
|