Skip to content

Feature/j2kswift v3 integration#181

Merged
SureshKViswanathan merged 12 commits into
mainfrom
feature/j2kswift-v3-integration
Apr 21, 2026
Merged

Feature/j2kswift v3 integration#181
SureshKViswanathan merged 12 commits into
mainfrom
feature/j2kswift-v3-integration

Conversation

@SureshKViswanathan

Copy link
Copy Markdown
Contributor

No description provided.

raster and others added 12 commits April 20, 2026 10:57
…o v3.1.0

Matches toolchain already pinned in CI (SWIFT_VERSION 6.2, macos-15 runners with Xcode 16.2). Platform floors unchanged (macOS 14 / iOS 17 / visionOS 1); raising to macOS 15 is deferred to Milestone 1.0 when J2KSwift dependency is wired in.
…ion plan

JPEG XS is not part of the J2KSwift integration scope. Remove all Phase 10
JPEG XS / J2KXS references throughout the document:
- Executive summary sentence
- Section 1.1 J2KXS capability row
- Section 1.2 capability matrix JPEG XS row
- Section 2.1 J2KXS module map entry
- Section 2.3 J2KXS trait table row
- Section 3 Phase 10 JPEG XS section (removed)
- Section 3.9 deferred reference updated (Phase 11 → Phase 10)
- Section 7 execution order diagram

Former Phase 11 (docs/release) renumbered to Phase 10.
Completes Milestone 4.4 item and Phase 6 deliverable.

New public API in DICOMKit:

DICOMVolumeProgressiveUpdate (Sources/DICOMKit/DICOMVolume.swift)
- Sendable struct carrying sliceIndex, qualityLayer, totalLayers,
  sliceData, width, height, isVolumeComplete per JPIP quality pass.

DICOMFile.openVolumeProgressively(serverURL:sliceJPIPURIs:qualityLayers:)
(Sources/DICOMKit/DICOMKit+Volume.swift)
- AsyncStream<DICOMVolumeProgressiveUpdate> that fetches every slice
  at layer 1 first (fast overview), then iteratively refines up to
  qualityLayers passes. Designed for CT/MR studies too large to fetch
  at full quality in one round-trip.
- Failed slices are skipped (never abort the stream).

DICOMFile.openVolume(from:jpipServerURL:)
- Convenience overload for single-frame JPIP-referenced DICOM files:
  reads the JPIP URI from Pixel Data, fetches via DICOMJPIPClient,
  returns a single-slice DICOMVolume.

Tests (Tests/DICOMKitTests/JPIPTests.swift): +14 tests
- DICOMVolumeProgressiveUpdate Tests (6): property storage,
  isVolumeComplete, layer range, sliceData fidelity.
- Progressive Volume API Surface Tests (3): empty-URI stream
  terminates immediately, negative qualityLayers clamped to 1,
  Sendable conformance compile-time check.

Plan update (J2KSWIFT_V3_2_INTEGRATION_PLAN.md):
- Milestone 4.4 progressive JPIP item marked [x] with evidence.
- Phase 6 deferred items for dicom-viewer and DICOMStudio now [x].
- Phase 6 test count updated 28 → 42.
Add JP3D Multi-Planar Reconstruction (MPR) support for DICOMVolumes
decoded via the J2K3D codec.

New components:
- JP3DMPRSliceExtractor: Platform-independent axial, sagittal, and
  coronal slice extraction from DICOMVolume (frame-major voxel layout).
  Includes window/level application producing 8-bit grayscale buffers.
- JP3DMPRRenderHelpers: CGImage construction from 8-bit buffers,
  reference-line colour convention, and axis determination per plane pair.
- JP3DMPRViewModel (@observable): Manages three slice indices, crosshair
  synchronisation via MPRHelpers, and window/level state. Exposes
  setVolume(_:), setSliceIndex(_:for:), scroll(delta:in:),
  handleClick(x:y:in:), and setWindowLevel(center:width:).
- JP3DMPRView (SwiftUI): Three-panel layout (axial | sagittal | coronal)
  with Canvas image rendering, reference lines overlay, per-plane slice
  sliders, window/level sliders, crosshair-link and reference-line toggles.
  Full VoiceOver accessibility, NSLocalizedString localisation, Dynamic
  Type, and adjustable accessibility actions.

Tests:
- 37 new tests in JP3DMPRSliceExtractorTests.swift covering:
  - dimensionsModel conversion
  - sliceRange per plane
  - Axial slice extraction (dimensions, spacing, data size, voxel values)
  - Sagittal slice extraction (dimensions, spacing, data size, voxel values)
  - Coronal slice extraction (dimensions, spacing, data size, voxel values)
  - Window/level clamping and output size
  - JP3DMPRRenderHelpers (colours, axes, cgImage validity and dimensions)
  - JP3DMPRViewModel (initial state, setVolume, setSliceIndex clamping,
    scroll, window/level, crosshair linking, reference lines)

Plan: Mark Phase 8 JP3D MPR item [x] in J2KSWIFT_V3_2_INTEGRATION_PLAN.md.

Build: swift build — Build complete! (0 errors, 0 warnings)
Tests: swift test --filter JP3DMPR — 37/37 passed
Swift Testing requires @available on each @test function individually
when the suite struct itself does not carry @available. Matches the
pattern used by VolumeVisualizationViewModelTests.
Phase 9.2 — dicom-3d v1.5.0:
- Add `encode-volume` subcommand: encodes a DICOM slice series as a JP3D
  volumetric document via JP3DVolumeDocument; supports lossless, lossless-htj2k,
  lossy, and lossy-htj2k compression modes
- Add `decode-volume` subcommand: decodes a JP3D document back to individual
  DICOM slices (slice_0000.dcm … slice_NNNN.dcm)
- Add `inspect` subcommand: reads only the JSON sidecar (no codestream decode),
  displaying geometry, spacing, compression, and patient/study metadata
- Add `waitForTask` async bridge and `resolveInputFiles` directory helper
- Update dicom-3d README with JP3D sections and version history

Phase 10 — Documentation, Benchmarks, Release:
- Add Documentation/JPEG2000_GUIDE.md (transfer syntaxes, quick start,
  HTJ2K, JP3D, JPIP, hardware backends, CLI tools, benchmarks,
  troubleshooting, known limitations)
- Add dicom-j2k/README.md (subcommand table, transfer syntax table,
  fast-path transcoding note, test instructions)
- Update CHANGELOG.md: add [Unreleased] J2KSwift v3.2.0 integration entries
- Update Documentation/Architecture.md: full codec layering diagram,
  CodecBackend selection, macOS 14→15 floor
- Update Documentation/ConformanceStatement.md: v1.2.7, macOS 15,
  .92/.93/.94/.95 rows, codec section, JP3D private SOP, limitations 5–8
- Update PERFORMANCE_GUIDE.md: J2K/HTJ2K/JP3D section with decode table,
  backend speedups, JP3D throughput, JPIP latency, codec selection guide
- Update MILESTONES.md: Milestone 24 acceptance criteria (13 items, all ✅)
- Update README.md: J2KSwift integration bullets, transfer syntax table fixes,
  HTJ2K limitation removed
- Update J2KSWIFT_V3_2_INTEGRATION_PLAN.md: Phase 10 tasks marked complete,
  Section 4 Testing Strategy rewritten with real counts (677 tests/15 files),
  Acceptance Criteria checkboxes updated (9/10 met)

DICOMStudio progressive decode (Phase 8 follow-on):
- Add ProgressiveDecodeModel and ProgressiveImageView
- Wire progressive HTJ2K decoding into ImageDecodingService and
  ImageViewerViewModel/ImageViewerView

Tests:
- DICOM3DTests: add encode-volume/decode-volume/inspect scenario tests
  (lossless-HTJ2K round-trip, lossy round-trip, sidecar field verification,
  isJP3DVolumeDocument false-negative)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add J2KSwift v3.2 integration testing UI to DICOMStudio:

- J2KTestingView + J2KTestingViewModel: Interactive panel for verifying
  transfer syntax support matrix (decode/encode capability), running
  multi-iteration decode benchmarks per codec backend, and performing
  lossless/lossy round-trip tests with PSNR reporting
- CodecImageComparisonView: IDE-style 3-panel comparison (Raw | Encoded |
  Decoded) with synchronised zoom/pan for artefact inspection
- ViewerCommands: macOS menu bar commands for the image viewer
  (keyboard shortcuts via FocusedValues)
- ImageViewerView: additional codec inspector panel and layout updates
- WindowLevelPanel: refactor for cleaner SwiftUI layout
- CineControlsView: playback controls improvements
- ImageViewerViewModel: minor additions for codec info exposure
- ProgressiveImageView: minor fix
- dicom-3d: fix JP3DVolumeDocument.encode label (series:)
@SureshKViswanathan SureshKViswanathan merged commit 2134f0c into main Apr 21, 2026
10 of 17 checks passed
SureshKViswanathan pushed a commit that referenced this pull request Apr 23, 2026
Main's squash-merge of PR #181 lacked the 5 follow-up commits this branch
accumulated afterward (the debug-build warning, libopenjp2.a static link,
x86_64 Release exclusion, decodeGPU wiring, and the raw/encoded/decoded
size panel) plus the J2KSwift 4.0.1 bump. HEAD is a strict superset, so
conflicts were resolved by taking --ours throughout. DICOMCore builds clean
against the merged tree.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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