Skip to content

Fix RangeErrors with large images#856

Draft
PaulHax wants to merge 3 commits intobug-reportfrom
range-fix
Draft

Fix RangeErrors with large images#856
PaulHax wants to merge 3 commits intobug-reportfrom
range-fix

Conversation

@PaulHax
Copy link
Copy Markdown
Collaborator

@PaulHax PaulHax commented Mar 27, 2026

closes #852

PaulHax added 3 commits March 26, 2026 19:49
VTK.js DataArray.getState() calls Array.from() on typed arrays, which
OOMs for images >~180M voxels. Temporarily swap data arrays with empty
before getState(), then inject the original TypedArrays into the state.
Structured clone handles TypedArrays efficiently for worker transfer.

Also surface save errors as user-visible notifications (SaveSession.vue
had try/finally but no catch).
The singleton ITK-wasm worker accumulates WASM heap across readImage
calls. When loading a session with a large base image (~361MB) followed
by a labelmap (~180MB), the heap can exceed 2GB. Emscripten's ccall
returns pointers as signed i32, so pointers >2^31 wrap negative,
causing RangeError.

Reset the worker before deserializing segment groups to give each
labelmap read a fresh WASM heap, preventing the overflow.
Rewrite session-large-uri-base test to actually trigger the signed
pointer overflow bug. Uses a ZIP-based session with a Float32
1024×1024×256 base image (1GB raw, pushes WASM heap past 2GB) and
an embedded .nii.gz labelmap referenced via `path` in segmentGroups.

Key changes:
- ZIP session format with `path`-based labelmap triggers readImage()
  on the shared ITK-wasm worker (the old dataSourceId approach used
  cached data and never hit the bug path)
- Float32 base image grows the WASM heap past 2GB so output pointers
  exceed 2^31 and wrap negative via Emscripten's signed i32 ccall
- .nii.gz labelmap format is critical: .vti uses a separate JS reader
  that never touches the ITK-wasm worker
- Wait for async labelmap deserialization via notification/segment-group
  detection (it completes after views render)

Verified: fails with RangeError when resetWorker() is removed,
passes when the fix is active.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant