@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
package/NOTICE ADDED
@@ -0,0 +1,216 @@
1
+ openslide-js
2
+
3
+ This product is distributed under the GNU Lesser General Public License,
4
+ version 2.1 only (LGPL-2.1-only). See the LICENSE file in the repository
5
+ root for the full license text.
6
+
7
+ This product bundles and is built from several third-party components,
8
+ each carrying its own license. The notices below identify those
9
+ components, their upstream sources, and the licenses under which they
10
+ are distributed.
11
+
12
+ ================================================================================
13
+ 1. Bundled into wasm/dist/openslide.wasm
14
+ ================================================================================
15
+
16
+ The compiled WebAssembly artifact wasm/dist/openslide.wasm statically
17
+ links the following projects. Each retains its own license; the
18
+ combined binary is distributed under LGPL-2.1-only (the strongest
19
+ copyleft of any bundled component).
20
+
21
+ OpenSlide
22
+ Upstream: https://openslide.org
23
+ https://github.com/openslide/openslide
24
+ Pin: v4.0.0 tagged release (matches the official binary
25
+ distribution openslide-bin v4.0.0.13)
26
+ License: LGPL-2.1-only
27
+ Note: Modified via wasm/patches/openslide.patch — eight small
28
+ mechanical _with_data thunk wrappers for GLib sort
29
+ callbacks under Emscripten's strict call_indirect type
30
+ check. The complete corresponding source, including the
31
+ patch and the fetch script that pins the upstream tag,
32
+ is available in the wasm/ directory of this repository.
33
+ Also: wasm/dependencies/fetch-openslide.sh removes
34
+ subdir('tools') from upstream meson.build via sed
35
+ (Emscripten cannot link native helper executables).
36
+
37
+ GLib
38
+ Upstream: https://gitlab.gnome.org/GNOME/glib
39
+ Pin: 2.88.1
40
+ License: LGPL-2.1-or-later
41
+ Note: Modified via wasm/patches/glib.patch (10-patch mailbox
42
+ series from wasm-vips by Kleis Auke Wolthuizen, see
43
+ Section 3).
44
+
45
+ Cairo
46
+ Upstream: https://gitlab.freedesktop.org/cairo/cairo
47
+ Pin: 1.18.4
48
+ License: LGPL-2.1-only OR MPL-1.1
49
+ Note: Unmodified upstream source.
50
+
51
+ gdk-pixbuf
52
+ Upstream: https://gitlab.gnome.org/GNOME/gdk-pixbuf
53
+ Pin: 2.42.12
54
+ License: LGPL-2.1-or-later
55
+ Note: Modified via wasm/patches/gdk-pixbuf.patch — ~9 lines
56
+ wrapping the gdkpixbuf_bin executables foreach in
57
+ `if not meson.is_cross_build()`. Strategy informed by
58
+ discere-os/gdk-pixbuf.wasm (see Section 3).
59
+
60
+ fontconfig
61
+ Upstream: https://gitlab.freedesktop.org/fontconfig/fontconfig
62
+ Pin: 2.17.1
63
+ License: MIT (HPND-style)
64
+ Note: Unmodified upstream source. Upstream commit e3563fa2
65
+ (May 2023) migrated src/meson.build to meson's built-in
66
+ cc.preprocess(), making it Emscripten-buildable without
67
+ any compiler-detection patch.
68
+
69
+ pixman
70
+ Upstream: https://gitlab.freedesktop.org/pixman/pixman
71
+ License: MIT
72
+
73
+ FreeType
74
+ Upstream: https://freetype.org
75
+ License: FTL OR GPL-2.0-or-later
76
+
77
+ libtiff
78
+ Upstream: https://gitlab.com/libtiff/libtiff
79
+ License: libtiff (BSD-style)
80
+
81
+ libjpeg-turbo
82
+ Upstream: https://libjpeg-turbo.org
83
+ License: IJG AND BSD-3-Clause AND Zlib
84
+
85
+ OpenJPEG
86
+ Upstream: https://www.openjpeg.org
87
+ License: BSD-2-Clause
88
+
89
+ libpng
90
+ Upstream: http://www.libpng.org/pub/png/libpng.html
91
+ License: libpng-2.0
92
+
93
+ libxml2
94
+ Upstream: https://gitlab.gnome.org/GNOME/libxml2
95
+ License: MIT
96
+
97
+ Expat (libexpat)
98
+ Upstream: https://libexpat.github.io
99
+ License: MIT
100
+
101
+ zlib
102
+ Upstream: https://www.zlib.net
103
+ License: Zlib
104
+
105
+ zstd
106
+ Upstream: https://github.com/facebook/zstd
107
+ License: BSD-3-Clause OR GPL-2.0-only
108
+
109
+ libffi
110
+ Upstream: https://github.com/libffi/libffi
111
+ License: MIT
112
+
113
+ SQLite
114
+ Upstream: https://www.sqlite.org
115
+ License: blessing (public-domain dedication)
116
+
117
+ ================================================================================
118
+ 2. Source availability (LGPL-2.1 §6)
119
+ ================================================================================
120
+
121
+ The LGPL-2.1-licensed components above (notably OpenSlide, GLib, Cairo,
122
+ and gdk-pixbuf) require that the complete corresponding source of the
123
+ combined work be available to recipients.
124
+
125
+ The complete corresponding source is the contents of the openslide-js
126
+ repository at https://github.com/computationalpathologygroup/openslide-js,
127
+ specifically the wasm/ directory, which contains:
128
+
129
+ - Dockerfile + build.sh — the deterministic build pipeline
130
+ - dependencies/fetch-*.sh — one fetch script per bundled project,
131
+ pinning the exact upstream commit/release used
132
+ - patches/*.patch — every modification applied to upstream sources
133
+ - openslide-api.c + emscripten-crossfile.meson — the linker glue
134
+ and Emscripten cross-compilation configuration
135
+
136
+ Reproducing the bundled wasm binary from these sources requires Docker
137
+ and is documented in README.md under "Building the WASM module".
138
+
139
+ ================================================================================
140
+ 3. Build infrastructure attribution
141
+ ================================================================================
142
+
143
+ The WebAssembly build pipeline under wasm/ incorporates work from the
144
+ following upstream projects. Both are MIT-licensed and compatible with
145
+ openslide-js's LGPL-2.1-only distribution.
146
+
147
+ @conflux-xyz/openslide-wasm
148
+ Upstream: https://github.com/conflux-xyz/openslide-wasm
149
+ https://www.npmjs.com/package/@conflux-xyz/openslide-wasm
150
+ License: MIT (declared in the package's npm package.json; the
151
+ upstream GitHub repository does not currently carry an
152
+ explicit LICENSE file)
153
+ Used for: The overall WASM build pipeline — the Emscripten base
154
+ image and required packages, the meson and
155
+ cmake flag sets for each bundled native library, and
156
+ the emscripten meson cross-file. No source patches to
157
+ bundled libraries are derived from this project;
158
+ all four originally-imported patches (cairo,
159
+ fontconfig, gdk-pixbuf, openslide) have meson options,
160
+ upstream version upgrades, single-line sed transforms
161
+ in the fetch scripts, code informed by other projects
162
+ (see entries below).
163
+
164
+ wasm-vips (by Kleis Auke Wolthuizen)
165
+ Upstream: https://github.com/kleisauke/wasm-vips
166
+ License: MIT
167
+ Used for: The GLib WebAssembly patch series carried in
168
+ wasm/patches/glib.patch. Per-patch author lines are
169
+ preserved in the patch's mailbox-format headers.
170
+
171
+ VitoVan/pango-cairo-wasm (by Vito Van)
172
+ Upstream: https://github.com/VitoVan/pango-cairo-wasm
173
+ License: WTFPL (Do What The Fuck You Want To Public License)
174
+ Used for: The strategic insight that cairo can be cross-built for
175
+ WebAssembly with no source patches: cairo's util/
176
+ meson.build gates each helper executable
177
+ (cairo-gobject, cairo-script, cairo-trace, cairo-fdr) on
178
+ feature_conf flags, and the top-level executable loop
179
+ iterates an empty list when gtk_dep is not found. With
180
+ openslide-js's dependency set, none of those targets are
181
+ triggered, so the previous wasm/patches/cairo.patch
182
+ (which removed `subdir('util')`) is unnecessary.
183
+
184
+ discere-os/gdk-pixbuf.wasm and discere-os/fontconfig.wasm
185
+ (by Isaac Johnston / Superstruct Ltd)
186
+ Upstream: https://github.com/discere-os/gdk-pixbuf.wasm
187
+ https://github.com/discere-os/fontconfig.wasm
188
+ License: LGPL-2.1-or-later (gdk-pixbuf.wasm, matching upstream);
189
+ upstream fontconfig license + MIT build infrastructure
190
+ (fontconfig.wasm)
191
+ Used for: (1) For gdk-pixbuf — the strategy to cross-build cleanly
192
+ under Emscripten without source patches to the C loader
193
+ code: relying on the pre-existing upstream gating of
194
+ USE_GMODULE on GLib's pkg-config-advertised
195
+ `gmodule_supported` value, and the `builtin_loaders=all`
196
+ meson option for the loader-plugin loop. The thin patch
197
+ at wasm/patches/gdk-pixbuf.patch (only gating helper
198
+ executables on `meson.is_cross_build()`) is original
199
+ openslide-js code.
200
+ (2) For fontconfig — the strategy of pinning fontconfig
201
+ 2.17.1 (which contains upstream commit e3563fa2,
202
+ May 2023, migrating src/meson.build to meson's built-in
203
+ cc.preprocess()), eliminating the conflux-xyz-derived
204
+ `cc.get_id() == 'clang' or ...emscripten` workaround
205
+ entirely. No patch is needed at fontconfig 2.17.1+.
206
+
207
+ The Emscripten C glue at wasm/openslide-api.c is distributed under
208
+ LGPL-2.1-only because it links directly against OpenSlide.
209
+
210
+ ================================================================================
211
+ 4. No warranty
212
+ ================================================================================
213
+
214
+ This software is provided "as is", without warranty of any kind,
215
+ express or implied. See the LICENSE file for the full LGPL-2.1-only
216
+ disclaimer of warranty.
package/README.md ADDED
@@ -0,0 +1,160 @@
1
+ # openslide-js
2
+
3
+ Client-side whole-slide image library powered by [OpenSlide](https://openslide.org) and WebAssembly.
4
+
5
+ Runs entirely in the browser — no server required.
6
+
7
+ > For native (Linux / Windows / macOS) usage, see [openslide-bin](https://github.com/openslide/openslide-bin) — the OpenSlide team's official binary distribution of the same C library used by openslide-python, openslide-java, and other native consumers. openslide-js is the WebAssembly sibling: same upstream OpenSlide and dependency pins (v4.0.0, GLib 2.88.1, Cairo 1.18.4, libdicom 1.0.5, etc.) compiled for the browser via Emscripten, with a TypeScript wrapper API on top.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @computationalpathologygroup/openslide-js
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```typescript
18
+ import { OpenSlide } from '@computationalpathologygroup/openslide-js';
19
+
20
+ const openslide = await OpenSlide.initialize();
21
+ const slide = await openslide.open(file); // File | File[] | URL | string
22
+
23
+ console.log(slide.levelCount);
24
+ console.log(slide.properties);
25
+
26
+ const imageData = await slide.readRegion(x, y, level, width, height);
27
+ slide.close();
28
+ ```
29
+
30
+ ### Multi-file formats (MIRAX, VMS)
31
+
32
+ ```typescript
33
+ import { OpenSlide, type VirtualFile } from '@computationalpathologygroup/openslide-js';
34
+
35
+ const entries: VirtualFile[] = [
36
+ { path: 'slide.mrxs', file: mrxsFile },
37
+ { path: 'slide/Slidedat.ini', file: datFile },
38
+ // ... remaining files
39
+ ];
40
+
41
+ const slide = await openslide.open(entries);
42
+ ```
43
+
44
+ ### Deep Zoom
45
+
46
+ Slides are read sparsely — only the byte ranges needed to decode the requested Deep Zoom tiles are accessed, via HTTP range requests for URLs (the origin must serve `Accept-Ranges: bytes`) or via the browser's File API for local files — so multi-gigabyte whole-slide images can be browsed in the viewport without ever loading the full file into memory.
47
+
48
+ ```typescript
49
+ import { DeepZoomGenerator } from '@computationalpathologygroup/openslide-js';
50
+
51
+ const dz = new DeepZoomGenerator(slide);
52
+ const tile = await dz.getTile(level, col, row); // returns ImageData
53
+ const xml = dz.getDzi('jpeg');
54
+ ```
55
+
56
+ ## Format Support
57
+
58
+ openslide-js supports the same whole-slide image formats as [OpenSlide](https://openslide.org), running entirely client-side via WebAssembly. Some formats have limitations in the browser environment.
59
+
60
+ ### Single-File Formats
61
+
62
+ | Vendor | Format | Extension | Compression | Support level |
63
+ |:-------|:-------|:----------|:------------|:------:|
64
+ | Aperio | SVS | `.svs` | JPEG | :white_check_mark: Full |
65
+ | Aperio | SVS | `.svs` | JPEG 2000 | :white_check_mark: Full |
66
+ | Generic | Tiled TIFF | `.tiff` | Mixed | :white_check_mark: Full |
67
+ | Hamamatsu | NDPI | `.ndpi` | JPEG | :white_check_mark: Full |
68
+ | Leica | SCN (brightfield) | `.scn` | JPEG | :white_check_mark: Full |
69
+ | Philips | TIFF | `.tiff` | JPEG | :white_check_mark: Full |
70
+
71
+ ### Multi-File Formats
72
+
73
+ | Vendor | Format | Extension | Support level | Notes |
74
+ |:-------|:-------|:----------|:------:|:------|
75
+ | DICOM | WSI | `.dcm` | :white_check_mark: Full | Opened via `VirtualFile[]` directory mounting |
76
+ | Hamamatsu | VMS | `.vms` | :white_check_mark: Full | Opened via `VirtualFile[]` directory mounting |
77
+ | Mirax | MRXS | `.mrxs` | :white_check_mark: Full | Opened via `VirtualFile[]` directory mounting |
78
+ | Trestle | TIF | `.tif` | :white_check_mark: Full | Opened via `VirtualFile[]` directory mounting |
79
+
80
+ ### Unsupported
81
+
82
+ | Vendor | Format | Extension | Support level | Limitation |
83
+ |:-------|:-------|:----------|:------:|:-----------|
84
+ | Leica | SCN (fluorescence) | `.scn` | :x: No | No main brightfield image in fluorescence-only files |
85
+ | Olympus | VSI | `.vsi` | :x: No | VSI opener cannot find companion ETS directory via WORKERFS |
86
+ | Ventana | BIF | `.bif` | :x: No | `LEFT` direction attribute not supported |
87
+ | Zeiss | CZI | `.czi` | :x: No | Vendor detection not in OpenSlide v4.0.0 (added upstream post-release); JPEG XR codec also not compiled |
88
+ | Zeiss | ZVI | `.zvi` | :x: No | OLE2 compound documents cannot be read via HTTP |
89
+
90
+ ### Not Yet Tested
91
+
92
+ | Vendor | Format | Extension | Support level | Notes |
93
+ |:-------|:-------|:----------|:------|
94
+ | Sakura | SVSLIDE | `.svslide` | SQLite-based, needs filesystem access |
95
+
96
+ > **Test coverage:** 292 integration tests across 15 formats (10 single-file + 5 multi-file), running in headless Chromium via Playwright.
97
+ > Run locally with `npm run test:integration` or containerized with `npm run test:integration:docker`.
98
+
99
+ ## Requirements
100
+
101
+ The WASM module uses `SharedArrayBuffer` and requires the following HTTP headers:
102
+
103
+ ```
104
+ Cross-Origin-Opener-Policy: same-origin
105
+ Cross-Origin-Embedder-Policy: require-corp
106
+ ```
107
+
108
+ ## Building the WASM module
109
+
110
+ Requires Docker.
111
+
112
+ ```bash
113
+ docker build -t openslide-js ./wasm
114
+ mkdir -p wasm/dist
115
+ docker run --rm -v "$(pwd)/wasm/dist:/output" openslide-js
116
+ ```
117
+
118
+ Output: `wasm/dist/openslide.js` and `wasm/dist/openslide.wasm`.
119
+
120
+ ## Building the TypeScript layer
121
+
122
+ ```bash
123
+ npm run build:ts
124
+ ```
125
+
126
+ ## Test Data
127
+
128
+ Integration tests require whole-slide image files that are not bundled in this repository (they are git-ignored). Download them with:
129
+
130
+ ```bash
131
+ npm run test:integration:fixtures
132
+ ```
133
+
134
+ This runs `test/integration/download-fixtures.mjs`, which:
135
+
136
+ 1. Fetches the [upstream index.json](https://openslide.cs.cmu.edu/download/openslide-testdata/index.json) and updates the local `test/data/index.json` if it has changed.
137
+ 2. Downloads every file listed in the index into `test/data/`, preserving the subdirectory layout.
138
+ 3. Verifies each file's SHA-256 hash. Files already present with a matching hash are skipped.
139
+ 4. Extracts ZIP archives (multi-file formats) into sibling directories.
140
+
141
+ Re-running the script is safe and idempotent — only missing or stale files are re-downloaded. The total download size is roughly 20 GiB for the full index.
142
+
143
+ ## Acknowledgements
144
+
145
+ The WASM build pipeline under `wasm/` incorporates work from two upstream projects, both MIT-licensed:
146
+
147
+ - [wasm-vips](https://github.com/kleisauke/wasm-vips) by Kleis Auke Wolthuizen (MIT) — the GLib WebAssembly patch series in `wasm/patches/glib.patch` (per-patch author lines preserved in the mailbox headers).
148
+ - [@conflux-xyz/openslide-wasm](https://github.com/conflux-xyz/openslide-wasm) (MIT, per its npm package) — informed the build strategy
149
+ - [discere-os/gdk-pixbuf.wasm](https://github.com/discere-os/gdk-pixbuf.wasm) and [discere-os/fontconfig.wasm](https://github.com/discere-os/fontconfig.wasm) by Isaac Johnston — informed (a) the patch-light gdk-pixbuf cross-build strategy (lean on upstream's conditional `USE_GMODULE` gating + `-Dbuiltin_loaders=all` rather than stripping C code) and (b) the choice to pin fontconfig at 2.17.1, where upstream's `cc.preprocess()` migration (May 2023) eliminates the need for any compiler-detection patch.
150
+ - [VitoVan/pango-cairo-wasm](https://github.com/VitoVan/pango-cairo-wasm) by Vito Van (WTFPL) — demonstrated that cairo cross-builds cleanly under Emscripten without any source patches; its meson invocation strategy informed dropping `wasm/patches/cairo.patch` entirely.
151
+
152
+ See [NOTICE](NOTICE) for the full third-party attribution, including every component statically linked into `wasm/dist/openslide.wasm` and LGPL-2.1 §6 source-availability information.
153
+
154
+ ## Contributing
155
+
156
+ Patches welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) first — it documents how openslide-js handles third-party code, the preferred order of fixes (upstream meson option → sed transform → minimal patch), and the attribution rules that keep the project legally clean.
157
+
158
+ ## License
159
+
160
+ LGPL-2.1-only — see [LICENSE](LICENSE) and [NOTICE](NOTICE).
@@ -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,186 @@
1
+ "use strict";
2
+ /**
3
+ * deep-zoom.ts
4
+ *
5
+ * Deep Zoom Image (DZI) tile generator. Maps DZI tile coordinates to
6
+ * OpenSlide region reads. Compatible with viewers like OpenSeadragon.
7
+ *
8
+ * Pure TypeScript — no WASM dependency. Operates on a Slide instance.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.DeepZoomGenerator = void 0;
12
+ class DeepZoomGenerator {
13
+ slide;
14
+ _tileSize;
15
+ _overlap;
16
+ // Precomputed geometry
17
+ _levelCount;
18
+ _levelDimensions;
19
+ _levelTiles;
20
+ _tileCount;
21
+ // Slide region to render
22
+ _l0Offset;
23
+ _l0Size;
24
+ constructor(slide, options) {
25
+ this.slide = slide;
26
+ this._tileSize = options?.tileSize ?? 254;
27
+ this._overlap = options?.overlap ?? 1;
28
+ // Determine bounds
29
+ const props = slide.properties;
30
+ const limitBounds = options?.limitBounds ?? false;
31
+ if (limitBounds && props.has('openslide.bounds-x')) {
32
+ this._l0Offset = {
33
+ x: parseInt(props.get('openslide.bounds-x'), 10),
34
+ y: parseInt(props.get('openslide.bounds-y'), 10),
35
+ };
36
+ this._l0Size = {
37
+ w: parseInt(props.get('openslide.bounds-width'), 10),
38
+ h: parseInt(props.get('openslide.bounds-height'), 10),
39
+ };
40
+ }
41
+ else {
42
+ this._l0Offset = { x: 0, y: 0 };
43
+ this._l0Size = { w: slide.dimensions.width, h: slide.dimensions.height };
44
+ }
45
+ // Build the DZI level pyramid.
46
+ // DZI level 0 is the smallest (1x1), last level is full resolution.
47
+ const baseW = this._l0Size.w;
48
+ const baseH = this._l0Size.h;
49
+ this._levelCount = Math.ceil(Math.log2(Math.max(baseW, baseH))) + 1;
50
+ this._levelDimensions = [];
51
+ this._levelTiles = [];
52
+ this._tileCount = 0;
53
+ for (let i = 0; i < this._levelCount; i++) {
54
+ const scale = Math.pow(2, this._levelCount - 1 - i);
55
+ const w = Math.max(1, Math.ceil(baseW / scale));
56
+ const h = Math.max(1, Math.ceil(baseH / scale));
57
+ this._levelDimensions.push({ width: w, height: h });
58
+ const cols = Math.ceil(w / this._tileSize);
59
+ const rows = Math.ceil(h / this._tileSize);
60
+ this._levelTiles.push({ columns: cols, rows: rows });
61
+ this._tileCount += cols * rows;
62
+ }
63
+ }
64
+ /** Number of Deep Zoom levels (0 = smallest, last = full resolution). */
65
+ get levelCount() {
66
+ return this._levelCount;
67
+ }
68
+ /** Total number of tiles across all levels. */
69
+ get tileCount() {
70
+ return this._tileCount;
71
+ }
72
+ /** Pixel dimensions at each DZI level. */
73
+ get levelDimensions() {
74
+ return this._levelDimensions;
75
+ }
76
+ /** Tile grid dimensions at each DZI level. */
77
+ get levelTiles() {
78
+ return this._levelTiles;
79
+ }
80
+ /**
81
+ * Get a single tile as ImageData.
82
+ *
83
+ * @param level - DZI level (0 = smallest).
84
+ * @param col - Column index.
85
+ * @param row - Row index.
86
+ */
87
+ async getTile(level, col, row) {
88
+ if (level < 0 || level >= this._levelCount) {
89
+ throw new RangeError(`Level ${level} out of range [0, ${this._levelCount})`);
90
+ }
91
+ const grid = this._levelTiles[level];
92
+ if (col < 0 || col >= grid.columns || row < 0 || row >= grid.rows) {
93
+ throw new RangeError(`Tile (${col}, ${row}) out of range for level ${level}`);
94
+ }
95
+ const info = this.getTileInfo(level, col, row);
96
+ // Read from the slide at the best matching OpenSlide level
97
+ const dziDim = this._levelDimensions[level];
98
+ const downsample = this._l0Size.w / dziDim.width;
99
+ const slideLevel = this.slide.getBestLevelForDownsample(downsample);
100
+ const slideLevelDs = this.slide.levelDownsamples[slideLevel];
101
+ // Convert DZI tile coords to OpenSlide level-0 coords
102
+ const l0X = this._l0Offset.x + info.x * downsample;
103
+ const l0Y = this._l0Offset.y + info.y * downsample;
104
+ // Size to read at the slide level
105
+ const readW = Math.ceil(info.w * downsample / slideLevelDs);
106
+ const readH = Math.ceil(info.h * downsample / slideLevelDs);
107
+ const tile = await this.slide.readRegion(Math.round(l0X), Math.round(l0Y), slideLevel, readW, readH);
108
+ // If the read size matches the desired tile size, return directly
109
+ if (readW === info.w && readH === info.h) {
110
+ return tile;
111
+ }
112
+ // Otherwise, scale down to the exact tile dimensions using canvas
113
+ // (in a worker context, OffscreenCanvas; in main thread, regular canvas)
114
+ return this.resampleTile(tile, info.w, info.h);
115
+ }
116
+ /**
117
+ * Generate the DZI XML descriptor string.
118
+ */
119
+ getDzi(format = 'jpeg') {
120
+ const dim = this._levelDimensions[this._levelCount - 1];
121
+ return [
122
+ '<?xml version="1.0" encoding="UTF-8"?>',
123
+ `<Image xmlns="http://schemas.microsoft.com/deepzoom/2008"`,
124
+ ` TileSize="${this._tileSize}"`,
125
+ ` Overlap="${this._overlap}"`,
126
+ ` Format="${format}">`,
127
+ ` <Size Width="${dim.width}" Height="${dim.height}"/>`,
128
+ `</Image>`,
129
+ ].join('\n');
130
+ }
131
+ /** Structured DZI info (alternative to XML). */
132
+ getDziInfo(format = 'jpeg') {
133
+ const dim = this._levelDimensions[this._levelCount - 1];
134
+ return {
135
+ tileSize: this._tileSize,
136
+ overlap: this._overlap,
137
+ format,
138
+ width: dim.width,
139
+ height: dim.height,
140
+ };
141
+ }
142
+ // --- Internal ---
143
+ /**
144
+ * Compute tile bounds within the DZI level coordinate space.
145
+ */
146
+ getTileInfo(level, col, row) {
147
+ const dim = this._levelDimensions[level];
148
+ const ts = this._tileSize;
149
+ const ol = this._overlap;
150
+ // Tile origin (accounting for overlap on non-edge tiles)
151
+ const x = col === 0 ? 0 : col * ts - ol;
152
+ const y = row === 0 ? 0 : row * ts - ol;
153
+ // Tile extent
154
+ const x2 = Math.min((col + 1) * ts + ol, dim.width);
155
+ const y2 = Math.min((row + 1) * ts + ol, dim.height);
156
+ return { x, y, w: x2 - x, h: y2 - y };
157
+ }
158
+ /**
159
+ * Downsample a tile to the target dimensions using nearest-neighbor.
160
+ * This is a fallback; for better quality, users should use createImageBitmap
161
+ * in their viewer integration.
162
+ */
163
+ resampleTile(source, dstW, dstH) {
164
+ const srcW = source.width;
165
+ const srcH = source.height;
166
+ const src = source.data;
167
+ const dst = new Uint8ClampedArray(dstW * dstH * 4);
168
+ const xRatio = srcW / dstW;
169
+ const yRatio = srcH / dstH;
170
+ for (let dy = 0; dy < dstH; dy++) {
171
+ const sy = Math.min(Math.floor(dy * yRatio), srcH - 1);
172
+ for (let dx = 0; dx < dstW; dx++) {
173
+ const sx = Math.min(Math.floor(dx * xRatio), srcW - 1);
174
+ const si = (sy * srcW + sx) * 4;
175
+ const di = (dy * dstW + dx) * 4;
176
+ dst[di] = src[si];
177
+ dst[di + 1] = src[si + 1];
178
+ dst[di + 2] = src[si + 2];
179
+ dst[di + 3] = src[si + 3];
180
+ }
181
+ }
182
+ return new ImageData(dst, dstW, dstH);
183
+ }
184
+ }
185
+ exports.DeepZoomGenerator = DeepZoomGenerator;
186
+ //# 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"}