release: v10.19.0 — J2KDICOMHelpers Phase 2 (Pixel Data encapsulation)#455
Merged
Conversation
Adds DICOM Pixel Data encapsulation helpers to the J2KDICOMHelpers
library (introduced in v10.17.0). Wraps J2K codestreams into DICOM
Pixel Data Item bytes (PS3.5 §A.4) for the write side, and parses
them back for the read side.
New public surface:
* J2KDICOMPixelDataEncapsulator.encapsulateItem(_:) — single J2K
codestream → one DICOM Pixel Data Item (8-byte header FFFE,E000
+ LE u32 length + payload + optional 0x00 pad per PS3.5 §6.4)
* J2KDICOMPixelDataEncapsulator.encapsulateFrames(_:includeBOT:) —
multiple frames → BOT (optional contents) + per-frame Items +
Sequence Delimitation Item. BOT entries are little-endian u32
offsets measured from the start of the first frame Item per
current DICOM Standard.
* J2KDICOMPixelDataDecapsulator.extractFrames(_:) — parses an
encapsulated sequence back into per-frame J2K codestreams.
Strips trailing 0x00 pad bytes when detected via the
EOC-then-pad pattern (0xFF 0xD9 0x00).
* J2KDICOMPixelDataError — Sendable, Equatable error type with
cases: truncated, itemTagExpected, itemLengthOverrun,
malformedSequenceDelimitation.
Write-side use case: encode an image via J2KSwift, wrap as Pixel
Data via encapsulateFrames, hand the bytes off to your DICOM
writer for insertion at (7FE0,0010) with VR OB + undefined length.
Read-side use case: extract codestreams from your DICOM library's
Pixel Data bytes via extractFrames, decode each frame via
J2KDecoder.
Phase 2 scope is narrower than the original v10.17 plan (which
contemplated full DICOM file parsing extraction). Refined to the
wire-format layer specifically:
(a) Consumers should use their own DICOM library for file parsing
(pydicom, DICOMKit, dcm4che — all do this correctly).
(b) The J2K-specific wire format wasn't previously available —
consumers had to hand-roll the byte layout (the pattern was
test-scaffolding in J2KStrictCrossCodecValidationTests:170-194).
ADR-004 compliant: no DICOM library dependency added anywhere; rules
codified directly from PS3.5 §A.4 / §6.4. Pure additive surface on
the existing J2KDICOMHelpers library; no signature changes elsewhere;
codestream bytes byte-identical to v10.18.0.
Validation:
- V10_31_PixelDataEncapsulationTests 12/12 PASS release mode
- swift test --filter J2KDICOMHelpers regression 38/38 PASS
(26 V10_29 Phase 1 + 12 V10_31 Phase 2)
- swift test --filter JP3D regression 532/532 PASS
- Mandatory commit gate (release mode) 7/7 PASS
MINOR per RELEASING.md — pure additive surface, no removal, no
signature change. Also bumps getVersion() 10.18.0 → 10.19.0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
J2KDICOMHelperslibrary (introduced in v10.17.0):J2KDICOMPixelDataEncapsulator.encapsulateItem(_:)+.encapsulateFrames(_:includeBOT:)for the write side,J2KDICOMPixelDataDecapsulator.extractFrames(_:)for the read side,J2KDICOMPixelDataErrorfor typed failures.What's New
J2KDICOMPixelDataEncapsulator.encapsulateItem(_:)J2KDICOMPixelDataEncapsulator.encapsulateFrames(_:includeBOT:)J2KDICOMPixelDataDecapsulator.extractFrames(_:)J2KDICOMPixelDataErrorSendable, Equatableerror typeCorrectness gate (release mode)
V10_31_PixelDataEncapsulationTests12/12 PASS (encapsulateItem even+odd length, padding correctness; encapsulateFrames single+multi frame with empty and populated BOT; round-trip byte-exact; pad stripping; truncated/invalid input rejection; error type Equatable)swift test --filter J2KDICOMHelpersregression 38/38 PASS (26 V10_29 Phase 1 + 12 V10_31 Phase 2)swift test --filter JP3Dregression 532/532 PASS (1 pre-existing skip)J2KMedicalCorpusEncodePerformanceTests2/2 PASSJ2KMedicalCorpusPerformanceTests2/2 PASSJ2KStrictCrossCodecValidationTests3/3 PASSMandatory commit gate: 7/7 PASS release mode.
Phase 2 scope rationale
The original v10.17.0 plan named Phase 2 as "DICOM file parser extraction from
J2KCLI/DICOMSupport.swift". On closer inspection, full file parsing pulls in ~400 LOC of consumer-side responsibility (group 0002 walking, dataset tag walker, multi-frame layout, photometric handling). Consumers using pydicom / DICOMKit / dcm4che already do that correctly. What's been missing — and what v10.19.0 ships — is the J2K-specific wire format for the Pixel Data element: the encapsulator/decapsulator pair. This is immediately useful for the write side (encode via J2KSwift → embed in DICOM file) and replaces hand-rolled byte construction (which existed as test-scaffolding inJ2KStrictCrossCodecValidationTests.swift:170-194).Full file parser extraction stays a Phase 3 candidate.
Test plan
getVersion()bumped 10.18.0 → 10.19.0🤖 Generated with Claude Code