@computationalpathologygroup/openslide-js 1.0.0-beta.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.
Files changed (69) hide show
  1. package/LICENSE +501 -0
  2. package/NOTICE +216 -0
  3. package/README.md +160 -0
  4. package/dist/cjs/deep-zoom.d.ts +66 -0
  5. package/dist/cjs/deep-zoom.d.ts.map +1 -0
  6. package/dist/cjs/deep-zoom.js +186 -0
  7. package/dist/cjs/deep-zoom.js.map +1 -0
  8. package/dist/cjs/errors.d.ts +9 -0
  9. package/dist/cjs/errors.d.ts.map +1 -0
  10. package/dist/cjs/errors.js +26 -0
  11. package/dist/cjs/errors.js.map +1 -0
  12. package/dist/cjs/index.d.ts +18 -0
  13. package/dist/cjs/index.d.ts.map +1 -0
  14. package/dist/cjs/index.js +27 -0
  15. package/dist/cjs/index.js.map +1 -0
  16. package/dist/cjs/openslide.d.ts +47 -0
  17. package/dist/cjs/openslide.d.ts.map +1 -0
  18. package/dist/cjs/openslide.js +191 -0
  19. package/dist/cjs/openslide.js.map +1 -0
  20. package/dist/cjs/package.json +1 -0
  21. package/dist/cjs/slide.d.ts +70 -0
  22. package/dist/cjs/slide.d.ts.map +1 -0
  23. package/dist/cjs/slide.js +139 -0
  24. package/dist/cjs/slide.js.map +1 -0
  25. package/dist/cjs/types.d.ts +150 -0
  26. package/dist/cjs/types.d.ts.map +1 -0
  27. package/dist/cjs/types.js +3 -0
  28. package/dist/cjs/types.js.map +1 -0
  29. package/dist/cjs/wasm/openslide.js +2 -0
  30. package/dist/cjs/wasm/openslide.wasm +0 -0
  31. package/dist/cjs/worker-api.d.ts +55 -0
  32. package/dist/cjs/worker-api.d.ts.map +1 -0
  33. package/dist/cjs/worker-api.js +287 -0
  34. package/dist/cjs/worker-api.js.map +1 -0
  35. package/dist/esm/deep-zoom.d.ts +66 -0
  36. package/dist/esm/deep-zoom.d.ts.map +1 -0
  37. package/dist/esm/deep-zoom.js +182 -0
  38. package/dist/esm/deep-zoom.js.map +1 -0
  39. package/dist/esm/errors.d.ts +9 -0
  40. package/dist/esm/errors.d.ts.map +1 -0
  41. package/dist/esm/errors.js +21 -0
  42. package/dist/esm/errors.js.map +1 -0
  43. package/dist/esm/index.d.ts +18 -0
  44. package/dist/esm/index.d.ts.map +1 -0
  45. package/dist/esm/index.js +19 -0
  46. package/dist/esm/index.js.map +1 -0
  47. package/dist/esm/openslide.d.ts +47 -0
  48. package/dist/esm/openslide.d.ts.map +1 -0
  49. package/dist/esm/openslide.js +187 -0
  50. package/dist/esm/openslide.js.map +1 -0
  51. package/dist/esm/slide.d.ts +70 -0
  52. package/dist/esm/slide.d.ts.map +1 -0
  53. package/dist/esm/slide.js +135 -0
  54. package/dist/esm/slide.js.map +1 -0
  55. package/dist/esm/types.d.ts +150 -0
  56. package/dist/esm/types.d.ts.map +1 -0
  57. package/dist/esm/types.js +2 -0
  58. package/dist/esm/types.js.map +1 -0
  59. package/dist/esm/wasm/openslide.js +2 -0
  60. package/dist/esm/wasm/openslide.wasm +0 -0
  61. package/dist/esm/worker-api.d.ts +55 -0
  62. package/dist/esm/worker-api.d.ts.map +1 -0
  63. package/dist/esm/worker-api.js +283 -0
  64. package/dist/esm/worker-api.js.map +1 -0
  65. package/dist/esm/worker.d.ts +8 -0
  66. package/dist/esm/worker.d.ts.map +1 -0
  67. package/dist/esm/worker.js +175 -0
  68. package/dist/esm/worker.js.map +1 -0
  69. package/package.json +74 -0
@@ -0,0 +1,287 @@
1
+ "use strict";
2
+ /**
3
+ * worker-api.ts
4
+ *
5
+ * Low-level bridge between JavaScript and the OpenSlide WASM module.
6
+ * Runs inside a Web Worker. Handles cwrap binding, memory management,
7
+ * virtual filesystem mounting, and pixel format conversion.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.WorkerApi = void 0;
11
+ class WorkerApi {
12
+ mod;
13
+ fn;
14
+ constructor(mod) {
15
+ this.mod = mod;
16
+ const cw = (name, ret, args) => mod.cwrap(name, ret, args, { async: true });
17
+ this.fn = {
18
+ open: cw('os_open', 'number', ['string']),
19
+ close: cw('os_close', null, ['number']),
20
+ getLevelCount: cw('os_get_level_count', 'number', ['number']),
21
+ getLevelDimensions: cw('os_get_level_dimensions', 'number', ['number', 'number']),
22
+ getLevelDownsample: cw('os_get_level_downsample', 'number', ['number', 'number']),
23
+ getBestLevelForDownsample: cw('os_get_best_level_for_downsample', 'number', ['number', 'number']),
24
+ readRegion: cw('os_read_region', 'number', ['number', 'bigint', 'bigint', 'number', 'bigint', 'bigint']),
25
+ freeResult: cw('os_free_result', null, ['number']),
26
+ getPropertyNames: cw('os_get_property_names', 'number', ['number']),
27
+ getPropertyValue: cw('os_get_property_value', 'number', ['number', 'string']),
28
+ getAssociatedImageNames: cw('os_get_associated_image_names', 'number', ['number']),
29
+ getAssociatedImageDimensions: cw('os_get_associated_image_dimensions', 'number', ['number', 'string']),
30
+ readAssociatedImage: cw('os_read_associated_image', 'number', ['number', 'string']),
31
+ getError: cw('os_get_error', 'number', ['number']),
32
+ getVersion: cw('os_get_version', 'number', []),
33
+ detectVendor: cw('os_detect_vendor', 'number', ['string']),
34
+ getIccProfileSize: cw('os_get_icc_profile_size', 'bigint', ['number']),
35
+ readIccProfile: cw('os_read_icc_profile', 'number', ['number']),
36
+ };
37
+ }
38
+ /** Check for an OpenSlide error after a call and throw if present. */
39
+ async checkError(handle) {
40
+ const errPtr = await this.fn.getError(handle);
41
+ if (errPtr) {
42
+ const msg = this.mod.UTF8ToString(errPtr);
43
+ throw new Error(msg);
44
+ }
45
+ }
46
+ /** Read a NULL-terminated array of C strings from a pointer. */
47
+ readStringArray(ptr) {
48
+ const results = [];
49
+ const ptrSize = 4; // wasm32
50
+ let offset = ptr;
51
+ while (true) {
52
+ const strPtr = this.mod.HEAP32[offset >> 2];
53
+ if (!strPtr)
54
+ break;
55
+ results.push(this.mod.UTF8ToString(strPtr));
56
+ offset += ptrSize;
57
+ }
58
+ return results;
59
+ }
60
+ /**
61
+ * Convert pre-multiplied ARGB (OpenSlide native) to straight RGBA.
62
+ * Operates in-place on a Uint8ClampedArray.
63
+ */
64
+ argbToRgba(buf) {
65
+ for (let i = 0; i < buf.length; i += 4) {
66
+ const a = buf[i + 3]; // In ARGB32 little-endian: byte order is B,G,R,A
67
+ // Actually OpenSlide stores as 0xAARRGGBB in native endian.
68
+ // On little-endian (wasm is LE): bytes are [B, G, R, A].
69
+ // We want RGBA: [R, G, B, A].
70
+ const b = buf[i];
71
+ const g = buf[i + 1];
72
+ const r = buf[i + 2];
73
+ // a is buf[i + 3]
74
+ if (a === 0) {
75
+ buf[i] = 0;
76
+ buf[i + 1] = 0;
77
+ buf[i + 2] = 0;
78
+ // buf[i + 3] already 0
79
+ }
80
+ else if (a === 255) {
81
+ buf[i] = r;
82
+ buf[i + 1] = g;
83
+ buf[i + 2] = b;
84
+ // alpha stays 255
85
+ }
86
+ else {
87
+ // Un-premultiply and swap channels
88
+ buf[i] = Math.min(255, (r * 255 / a) | 0);
89
+ buf[i + 1] = Math.min(255, (g * 255 / a) | 0);
90
+ buf[i + 2] = Math.min(255, (b * 255 / a) | 0);
91
+ // alpha stays
92
+ }
93
+ }
94
+ }
95
+ // --- Public API ---
96
+ async open(path) {
97
+ const handle = await this.fn.open(path);
98
+ if (!handle)
99
+ throw new Error(`Failed to open slide: ${path}`);
100
+ await this.checkError(handle);
101
+ return handle;
102
+ }
103
+ async close(handle) {
104
+ await this.fn.close(handle);
105
+ }
106
+ async getSlideInfo(handle) {
107
+ const levelCount = await this.fn.getLevelCount(handle);
108
+ await this.checkError(handle);
109
+ const levelDimensions = [];
110
+ const levelDownsamples = [];
111
+ for (let i = 0; i < levelCount; i++) {
112
+ const dimPtr = await this.fn.getLevelDimensions(handle, i);
113
+ const w = Number(this.mod.HEAP64[dimPtr >> 3]);
114
+ const h = Number(this.mod.HEAP64[(dimPtr >> 3) + 1]);
115
+ await this.fn.freeResult(dimPtr);
116
+ levelDimensions.push({ width: w, height: h });
117
+ const ds = await this.fn.getLevelDownsample(handle, i);
118
+ levelDownsamples.push(ds);
119
+ }
120
+ // Properties
121
+ const namesPtr = await this.fn.getPropertyNames(handle);
122
+ const propNames = this.readStringArray(namesPtr);
123
+ const properties = new Map();
124
+ for (const name of propNames) {
125
+ const valPtr = await this.fn.getPropertyValue(handle, name);
126
+ if (valPtr) {
127
+ properties.set(name, this.mod.UTF8ToString(valPtr));
128
+ }
129
+ }
130
+ // Associated images
131
+ const assocPtr = await this.fn.getAssociatedImageNames(handle);
132
+ const associatedImageNames = this.readStringArray(assocPtr);
133
+ return { levelCount, levelDimensions, levelDownsamples, properties, associatedImageNames };
134
+ }
135
+ /**
136
+ * Read a region and return the raw RGBA bytes as a transferable ArrayBuffer.
137
+ */
138
+ async readRegion(handle, x, y, level, w, h) {
139
+ const ptr = await this.fn.readRegion(handle, BigInt(x), BigInt(y), level, BigInt(w), BigInt(h));
140
+ await this.checkError(handle);
141
+ if (!ptr)
142
+ throw new Error('readRegion returned null');
143
+ const byteLength = w * h * 4;
144
+ const rgba = new Uint8ClampedArray(byteLength);
145
+ rgba.set(this.mod.HEAPU8.subarray(ptr, ptr + byteLength));
146
+ await this.fn.freeResult(ptr);
147
+ this.argbToRgba(rgba);
148
+ return rgba.buffer;
149
+ }
150
+ async readAssociatedImage(handle, name) {
151
+ const dimPtr = await this.fn.getAssociatedImageDimensions(handle, name);
152
+ const w = Number(this.mod.HEAP64[dimPtr >> 3]);
153
+ const h = Number(this.mod.HEAP64[(dimPtr >> 3) + 1]);
154
+ await this.fn.freeResult(dimPtr);
155
+ const ptr = await this.fn.readAssociatedImage(handle, name);
156
+ await this.checkError(handle);
157
+ if (!ptr)
158
+ throw new Error(`readAssociatedImage returned null for '${name}'`);
159
+ const byteLength = w * h * 4;
160
+ const rgba = new Uint8ClampedArray(byteLength);
161
+ rgba.set(this.mod.HEAPU8.subarray(ptr, ptr + byteLength));
162
+ await this.fn.freeResult(ptr);
163
+ this.argbToRgba(rgba);
164
+ return { buffer: rgba.buffer, width: w, height: h };
165
+ }
166
+ async getAssociatedImageDimensions(handle, name) {
167
+ const dimPtr = await this.fn.getAssociatedImageDimensions(handle, name);
168
+ const w = Number(this.mod.HEAP64[dimPtr >> 3]);
169
+ const h = Number(this.mod.HEAP64[(dimPtr >> 3) + 1]);
170
+ await this.fn.freeResult(dimPtr);
171
+ return { width: w, height: h };
172
+ }
173
+ async detectVendor(path) {
174
+ const ptr = await this.fn.detectVendor(path);
175
+ return ptr ? this.mod.UTF8ToString(ptr) : null;
176
+ }
177
+ async getVersion() {
178
+ const ptr = await this.fn.getVersion();
179
+ return ptr ? this.mod.UTF8ToString(ptr) : 'unknown';
180
+ }
181
+ async getIccProfile(handle) {
182
+ const size = await this.fn.getIccProfileSize(handle);
183
+ if (size <= 0n)
184
+ return null;
185
+ const ptr = await this.fn.readIccProfile(handle);
186
+ if (!ptr)
187
+ return null;
188
+ const numSize = Number(size);
189
+ const data = new Uint8Array(numSize);
190
+ data.set(this.mod.HEAPU8.subarray(ptr, ptr + numSize));
191
+ await this.fn.freeResult(ptr);
192
+ return data.buffer;
193
+ }
194
+ // --- Filesystem helpers ---
195
+ mountFiles(files, mountId) {
196
+ const dir = `/mnt/${mountId}`;
197
+ this.mod.FS.mkdir(dir);
198
+ this.mod.FS.mount(this.mod.WORKERFS, { files }, dir);
199
+ return `${dir}/${files[0].name}`;
200
+ }
201
+ /**
202
+ * Mount files with directory structure (for multi-file formats like MRXS).
203
+ *
204
+ * WORKERFS mounts are flat — each mount point gets a set of files with no
205
+ * subdirectories. So we group files by parent directory and create a separate
206
+ * WORKERFS mount for each group. The root dir must be created with mkdir
207
+ * first, then subdirectories get their own WORKERFS mounts.
208
+ *
209
+ * Layout for MRXS "image_1.mrxs" + "image_1/Slidedat.ini" + "image_1/Data0001.dat":
210
+ * /mnt/<id>/root/ ← WORKERFS mount with [image_1.mrxs]
211
+ * /mnt/<id>/root/image_1/ ← WORKERFS mount with [Slidedat.ini, Data0001.dat, ...]
212
+ */
213
+ mountDir(entries, indexFile, mountId) {
214
+ const base = `/mnt/${mountId}`;
215
+ this.mod.FS.mkdir(base);
216
+ const root = `${base}/root`;
217
+ this.mod.FS.mkdir(root);
218
+ // Group files by their immediate parent directory
219
+ const dirs = new Map();
220
+ for (const entry of entries) {
221
+ const lastSlash = entry.path.lastIndexOf('/');
222
+ const dir = lastSlash > 0 ? entry.path.slice(0, lastSlash) : '';
223
+ if (!dirs.has(dir))
224
+ dirs.set(dir, []);
225
+ dirs.get(dir).push(entry.file);
226
+ }
227
+ // First: create all subdirectory paths (before any WORKERFS mounts)
228
+ for (const dir of dirs.keys()) {
229
+ if (!dir)
230
+ continue;
231
+ const parts = dir.split('/');
232
+ let current = root;
233
+ for (const part of parts) {
234
+ current += '/' + part;
235
+ try {
236
+ this.mod.FS.mkdir(current);
237
+ }
238
+ catch { /* exists */ }
239
+ }
240
+ }
241
+ // Mount root-level files at /mnt/<id>/root/ only if there are root files
242
+ // BUT: we can only WORKERFS-mount on an empty directory, and we just created
243
+ // subdirs under root. So root-level files must be written via MEMFS instead.
244
+ const rootFiles = dirs.get('');
245
+ if (rootFiles) {
246
+ for (const file of rootFiles) {
247
+ // Write file content to MEMFS — we need to read the File synchronously,
248
+ // but we're in sync context. Use a WORKERFS trick: mount in a temp dir.
249
+ const tmpDir = `${base}/tmp_${Math.random().toString(36).slice(2, 6)}`;
250
+ this.mod.FS.mkdir(tmpDir);
251
+ this.mod.FS.mount(this.mod.WORKERFS, { files: [file] }, tmpDir);
252
+ // Read from temp and write to target
253
+ const data = this.mod.FS.readFile(`${tmpDir}/${file.name}`);
254
+ this.mod.FS.writeFile(`${root}/${file.name}`, data);
255
+ this.mod.FS.unmount(tmpDir);
256
+ this.mod.FS.rmdir(tmpDir);
257
+ }
258
+ }
259
+ // Mount each subdirectory group via WORKERFS
260
+ for (const [dir, files] of dirs) {
261
+ if (!dir)
262
+ continue; // root files already handled
263
+ const mountPoint = `${root}/${dir}`;
264
+ this.mod.FS.mount(this.mod.WORKERFS, { files }, mountPoint);
265
+ }
266
+ return `${root}/${indexFile}`;
267
+ }
268
+ mountUrl(url, mountId) {
269
+ const dir = `/mnt/${mountId}`;
270
+ this.mod.FS.mkdir(dir);
271
+ this.mod.FS.mount(this.mod.MEMFS, {}, dir);
272
+ this.mod.FS.createLazyFile(dir, 'remote', url, true, false);
273
+ return `${dir}/remote`;
274
+ }
275
+ unmount(mountId) {
276
+ const dir = `/mnt/${mountId}`;
277
+ try {
278
+ this.mod.FS.unmount(dir);
279
+ this.mod.FS.rmdir(dir);
280
+ }
281
+ catch {
282
+ // May already be unmounted
283
+ }
284
+ }
285
+ }
286
+ exports.WorkerApi = WorkerApi;
287
+ //# sourceMappingURL=worker-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-api.js","sourceRoot":"","sources":["../../src/worker-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * deep-zoom.ts
3
+ *
4
+ * Deep Zoom Image (DZI) tile generator. Maps DZI tile coordinates to
5
+ * OpenSlide region reads. Compatible with viewers like OpenSeadragon.
6
+ *
7
+ * Pure TypeScript — no WASM dependency. Operates on a Slide instance.
8
+ */
9
+ import type { Dimensions, DziInfo } from './types.js';
10
+ import type { Slide } from './slide.js';
11
+ export interface DeepZoomOptions {
12
+ /** Tile size in pixels (not counting overlap). Default: 254. */
13
+ tileSize?: number;
14
+ /** Overlap in pixels on each edge. Default: 1. */
15
+ overlap?: number;
16
+ /** Only render the non-empty region defined by bounds properties. Default: false. */
17
+ limitBounds?: boolean;
18
+ }
19
+ export declare class DeepZoomGenerator {
20
+ private slide;
21
+ private _tileSize;
22
+ private _overlap;
23
+ private _levelCount;
24
+ private _levelDimensions;
25
+ private _levelTiles;
26
+ private _tileCount;
27
+ private _l0Offset;
28
+ private _l0Size;
29
+ constructor(slide: Slide, options?: DeepZoomOptions);
30
+ /** Number of Deep Zoom levels (0 = smallest, last = full resolution). */
31
+ get levelCount(): number;
32
+ /** Total number of tiles across all levels. */
33
+ get tileCount(): number;
34
+ /** Pixel dimensions at each DZI level. */
35
+ get levelDimensions(): readonly Dimensions[];
36
+ /** Tile grid dimensions at each DZI level. */
37
+ get levelTiles(): readonly {
38
+ columns: number;
39
+ rows: number;
40
+ }[];
41
+ /**
42
+ * Get a single tile as ImageData.
43
+ *
44
+ * @param level - DZI level (0 = smallest).
45
+ * @param col - Column index.
46
+ * @param row - Row index.
47
+ */
48
+ getTile(level: number, col: number, row: number): Promise<ImageData>;
49
+ /**
50
+ * Generate the DZI XML descriptor string.
51
+ */
52
+ getDzi(format?: 'jpeg' | 'png'): string;
53
+ /** Structured DZI info (alternative to XML). */
54
+ getDziInfo(format?: 'jpeg' | 'png'): DziInfo;
55
+ /**
56
+ * Compute tile bounds within the DZI level coordinate space.
57
+ */
58
+ private getTileInfo;
59
+ /**
60
+ * Downsample a tile to the target dimensions using nearest-neighbor.
61
+ * This is a fallback; for better quality, users should use createImageBitmap
62
+ * in their viewer integration.
63
+ */
64
+ private resampleTile;
65
+ }
66
+ //# sourceMappingURL=deep-zoom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deep-zoom.d.ts","sourceRoot":"","sources":["../../src/deep-zoom.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IAGzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,gBAAgB,CAAe;IACvC,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,UAAU,CAAS;IAG3B,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,OAAO,CAA2B;gBAE9B,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,eAAe;IA8CnD,yEAAyE;IACzE,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,+CAA+C;IAC/C,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,0CAA0C;IAC1C,IAAI,eAAe,IAAI,SAAS,UAAU,EAAE,CAE3C;IAED,8CAA8C;IAC9C,IAAI,UAAU,IAAI,SAAS;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAE7D;IAED;;;;;;OAMG;IACG,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IA2C1E;;OAEG;IACH,MAAM,CAAC,MAAM,GAAE,MAAM,GAAG,KAAc,GAAG,MAAM;IAa/C,gDAAgD;IAChD,UAAU,CAAC,MAAM,GAAE,MAAM,GAAG,KAAc,GAAG,OAAO;IAapD;;OAEG;IACH,OAAO,CAAC,WAAW;IAgBnB;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAwBrB"}
@@ -0,0 +1,182 @@
1
+ /**
2
+ * deep-zoom.ts
3
+ *
4
+ * Deep Zoom Image (DZI) tile generator. Maps DZI tile coordinates to
5
+ * OpenSlide region reads. Compatible with viewers like OpenSeadragon.
6
+ *
7
+ * Pure TypeScript — no WASM dependency. Operates on a Slide instance.
8
+ */
9
+ export class DeepZoomGenerator {
10
+ slide;
11
+ _tileSize;
12
+ _overlap;
13
+ // Precomputed geometry
14
+ _levelCount;
15
+ _levelDimensions;
16
+ _levelTiles;
17
+ _tileCount;
18
+ // Slide region to render
19
+ _l0Offset;
20
+ _l0Size;
21
+ constructor(slide, options) {
22
+ this.slide = slide;
23
+ this._tileSize = options?.tileSize ?? 254;
24
+ this._overlap = options?.overlap ?? 1;
25
+ // Determine bounds
26
+ const props = slide.properties;
27
+ const limitBounds = options?.limitBounds ?? false;
28
+ if (limitBounds && props.has('openslide.bounds-x')) {
29
+ this._l0Offset = {
30
+ x: parseInt(props.get('openslide.bounds-x'), 10),
31
+ y: parseInt(props.get('openslide.bounds-y'), 10),
32
+ };
33
+ this._l0Size = {
34
+ w: parseInt(props.get('openslide.bounds-width'), 10),
35
+ h: parseInt(props.get('openslide.bounds-height'), 10),
36
+ };
37
+ }
38
+ else {
39
+ this._l0Offset = { x: 0, y: 0 };
40
+ this._l0Size = { w: slide.dimensions.width, h: slide.dimensions.height };
41
+ }
42
+ // Build the DZI level pyramid.
43
+ // DZI level 0 is the smallest (1x1), last level is full resolution.
44
+ const baseW = this._l0Size.w;
45
+ const baseH = this._l0Size.h;
46
+ this._levelCount = Math.ceil(Math.log2(Math.max(baseW, baseH))) + 1;
47
+ this._levelDimensions = [];
48
+ this._levelTiles = [];
49
+ this._tileCount = 0;
50
+ for (let i = 0; i < this._levelCount; i++) {
51
+ const scale = Math.pow(2, this._levelCount - 1 - i);
52
+ const w = Math.max(1, Math.ceil(baseW / scale));
53
+ const h = Math.max(1, Math.ceil(baseH / scale));
54
+ this._levelDimensions.push({ width: w, height: h });
55
+ const cols = Math.ceil(w / this._tileSize);
56
+ const rows = Math.ceil(h / this._tileSize);
57
+ this._levelTiles.push({ columns: cols, rows: rows });
58
+ this._tileCount += cols * rows;
59
+ }
60
+ }
61
+ /** Number of Deep Zoom levels (0 = smallest, last = full resolution). */
62
+ get levelCount() {
63
+ return this._levelCount;
64
+ }
65
+ /** Total number of tiles across all levels. */
66
+ get tileCount() {
67
+ return this._tileCount;
68
+ }
69
+ /** Pixel dimensions at each DZI level. */
70
+ get levelDimensions() {
71
+ return this._levelDimensions;
72
+ }
73
+ /** Tile grid dimensions at each DZI level. */
74
+ get levelTiles() {
75
+ return this._levelTiles;
76
+ }
77
+ /**
78
+ * Get a single tile as ImageData.
79
+ *
80
+ * @param level - DZI level (0 = smallest).
81
+ * @param col - Column index.
82
+ * @param row - Row index.
83
+ */
84
+ async getTile(level, col, row) {
85
+ if (level < 0 || level >= this._levelCount) {
86
+ throw new RangeError(`Level ${level} out of range [0, ${this._levelCount})`);
87
+ }
88
+ const grid = this._levelTiles[level];
89
+ if (col < 0 || col >= grid.columns || row < 0 || row >= grid.rows) {
90
+ throw new RangeError(`Tile (${col}, ${row}) out of range for level ${level}`);
91
+ }
92
+ const info = this.getTileInfo(level, col, row);
93
+ // Read from the slide at the best matching OpenSlide level
94
+ const dziDim = this._levelDimensions[level];
95
+ const downsample = this._l0Size.w / dziDim.width;
96
+ const slideLevel = this.slide.getBestLevelForDownsample(downsample);
97
+ const slideLevelDs = this.slide.levelDownsamples[slideLevel];
98
+ // Convert DZI tile coords to OpenSlide level-0 coords
99
+ const l0X = this._l0Offset.x + info.x * downsample;
100
+ const l0Y = this._l0Offset.y + info.y * downsample;
101
+ // Size to read at the slide level
102
+ const readW = Math.ceil(info.w * downsample / slideLevelDs);
103
+ const readH = Math.ceil(info.h * downsample / slideLevelDs);
104
+ const tile = await this.slide.readRegion(Math.round(l0X), Math.round(l0Y), slideLevel, readW, readH);
105
+ // If the read size matches the desired tile size, return directly
106
+ if (readW === info.w && readH === info.h) {
107
+ return tile;
108
+ }
109
+ // Otherwise, scale down to the exact tile dimensions using canvas
110
+ // (in a worker context, OffscreenCanvas; in main thread, regular canvas)
111
+ return this.resampleTile(tile, info.w, info.h);
112
+ }
113
+ /**
114
+ * Generate the DZI XML descriptor string.
115
+ */
116
+ getDzi(format = 'jpeg') {
117
+ const dim = this._levelDimensions[this._levelCount - 1];
118
+ return [
119
+ '<?xml version="1.0" encoding="UTF-8"?>',
120
+ `<Image xmlns="http://schemas.microsoft.com/deepzoom/2008"`,
121
+ ` TileSize="${this._tileSize}"`,
122
+ ` Overlap="${this._overlap}"`,
123
+ ` Format="${format}">`,
124
+ ` <Size Width="${dim.width}" Height="${dim.height}"/>`,
125
+ `</Image>`,
126
+ ].join('\n');
127
+ }
128
+ /** Structured DZI info (alternative to XML). */
129
+ getDziInfo(format = 'jpeg') {
130
+ const dim = this._levelDimensions[this._levelCount - 1];
131
+ return {
132
+ tileSize: this._tileSize,
133
+ overlap: this._overlap,
134
+ format,
135
+ width: dim.width,
136
+ height: dim.height,
137
+ };
138
+ }
139
+ // --- Internal ---
140
+ /**
141
+ * Compute tile bounds within the DZI level coordinate space.
142
+ */
143
+ getTileInfo(level, col, row) {
144
+ const dim = this._levelDimensions[level];
145
+ const ts = this._tileSize;
146
+ const ol = this._overlap;
147
+ // Tile origin (accounting for overlap on non-edge tiles)
148
+ const x = col === 0 ? 0 : col * ts - ol;
149
+ const y = row === 0 ? 0 : row * ts - ol;
150
+ // Tile extent
151
+ const x2 = Math.min((col + 1) * ts + ol, dim.width);
152
+ const y2 = Math.min((row + 1) * ts + ol, dim.height);
153
+ return { x, y, w: x2 - x, h: y2 - y };
154
+ }
155
+ /**
156
+ * Downsample a tile to the target dimensions using nearest-neighbor.
157
+ * This is a fallback; for better quality, users should use createImageBitmap
158
+ * in their viewer integration.
159
+ */
160
+ resampleTile(source, dstW, dstH) {
161
+ const srcW = source.width;
162
+ const srcH = source.height;
163
+ const src = source.data;
164
+ const dst = new Uint8ClampedArray(dstW * dstH * 4);
165
+ const xRatio = srcW / dstW;
166
+ const yRatio = srcH / dstH;
167
+ for (let dy = 0; dy < dstH; dy++) {
168
+ const sy = Math.min(Math.floor(dy * yRatio), srcH - 1);
169
+ for (let dx = 0; dx < dstW; dx++) {
170
+ const sx = Math.min(Math.floor(dx * xRatio), srcW - 1);
171
+ const si = (sy * srcW + sx) * 4;
172
+ const di = (dy * dstW + dx) * 4;
173
+ dst[di] = src[si];
174
+ dst[di + 1] = src[si + 1];
175
+ dst[di + 2] = src[si + 2];
176
+ dst[di + 3] = src[si + 3];
177
+ }
178
+ }
179
+ return new ImageData(dst, dstW, dstH);
180
+ }
181
+ }
182
+ //# sourceMappingURL=deep-zoom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deep-zoom.js","sourceRoot":"","sources":["../../src/deep-zoom.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /** Base error class for all OpenSlide errors. */
2
+ export declare class OpenSlideError extends Error {
3
+ constructor(message: unknown);
4
+ }
5
+ /** Thrown when the file format is not supported by OpenSlide. */
6
+ export declare class OpenSlideUnsupportedFormatError extends OpenSlideError {
7
+ constructor(message?: string);
8
+ }
9
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,OAAO;CAS7B;AAED,iEAAiE;AACjE,qBAAa,+BAAgC,SAAQ,cAAc;gBACrD,OAAO,CAAC,EAAE,MAAM;CAK7B"}
@@ -0,0 +1,21 @@
1
+ /** Base error class for all OpenSlide errors. */
2
+ export class OpenSlideError extends Error {
3
+ constructor(message) {
4
+ const msg = typeof message === 'string' ? message
5
+ : message instanceof Error ? message.message
6
+ : typeof message === 'object' && message !== null ? JSON.stringify(message)
7
+ : String(message);
8
+ super(msg);
9
+ this.name = 'OpenSlideError';
10
+ Object.setPrototypeOf(this, new.target.prototype);
11
+ }
12
+ }
13
+ /** Thrown when the file format is not supported by OpenSlide. */
14
+ export class OpenSlideUnsupportedFormatError extends OpenSlideError {
15
+ constructor(message) {
16
+ super(message ?? 'Unsupported slide format');
17
+ this.name = 'OpenSlideUnsupportedFormatError';
18
+ Object.setPrototypeOf(this, new.target.prototype);
19
+ }
20
+ }
21
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAgB;QAC1B,MAAM,GAAG,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO;YAC/C,CAAC,CAAC,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO;gBAC5C,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;oBAC3E,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,CAAC,GAAG,CAAC,CAAC;QACX,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAED,iEAAiE;AACjE,MAAM,OAAO,+BAAgC,SAAQ,cAAc;IACjE,YAAY,OAAgB;QAC1B,KAAK,CAAC,OAAO,IAAI,0BAA0B,CAAC,CAAC;QAC7C,IAAI,CAAC,IAAI,GAAG,iCAAiC,CAAC;QAC9C,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ export { OpenSlide } from './openslide.js';
2
+ export { Slide } from './slide.js';
3
+ export { DeepZoomGenerator } from './deep-zoom.js';
4
+ export type { DeepZoomOptions } from './deep-zoom.js';
5
+ export { OpenSlideError, OpenSlideUnsupportedFormatError } from './errors.js';
6
+ export type { Dimensions, SlideInfo, DziInfo, OpenSlideOptions, SlideSource, VirtualFile, } from './types.js';
7
+ export declare const PROPERTY_NAME_COMMENT = "openslide.comment";
8
+ export declare const PROPERTY_NAME_VENDOR = "openslide.vendor";
9
+ export declare const PROPERTY_NAME_QUICKHASH1 = "openslide.quickhash-1";
10
+ export declare const PROPERTY_NAME_BACKGROUND_COLOR = "openslide.background-color";
11
+ export declare const PROPERTY_NAME_OBJECTIVE_POWER = "openslide.objective-power";
12
+ export declare const PROPERTY_NAME_MPP_X = "openslide.mpp-x";
13
+ export declare const PROPERTY_NAME_MPP_Y = "openslide.mpp-y";
14
+ export declare const PROPERTY_NAME_BOUNDS_X = "openslide.bounds-x";
15
+ export declare const PROPERTY_NAME_BOUNDS_Y = "openslide.bounds-y";
16
+ export declare const PROPERTY_NAME_BOUNDS_WIDTH = "openslide.bounds-width";
17
+ export declare const PROPERTY_NAME_BOUNDS_HEIGHT = "openslide.bounds-height";
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGtD,OAAO,EAAE,cAAc,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AAG9E,YAAY,EACV,UAAU,EACV,SAAS,EACT,OAAO,EACP,gBAAgB,EAChB,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AACzD,eAAO,MAAM,oBAAoB,qBAAqB,CAAC;AACvD,eAAO,MAAM,wBAAwB,0BAA0B,CAAC;AAChE,eAAO,MAAM,8BAA8B,+BAA+B,CAAC;AAC3E,eAAO,MAAM,6BAA6B,8BAA8B,CAAC;AACzE,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AACrD,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AACrD,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAC3D,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAC3D,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AACnE,eAAO,MAAM,2BAA2B,4BAA4B,CAAC"}