Conversation
Introduces JPEG 2000 (Part 1) decoding via JP2 wrapping and ImageIO, JPEG Baseline/Extended decoding, experimental JPEG-LS scaffolding (feature-flagged), and DICOM RLE (Annex G) decoding for mono8, mono16, and RGB8. Updates PixelService to dispatch to the appropriate decoder based on transfer syntax. Adds helpers for extracting pixel data from CGImage. Also includes new files for JPEG 2000 and JPEG-LS parsing/decoding, and minor docstring and copyright header updates.
Deleted the old DCMDecoder and related reference files. Updated README to reflect experimental JPEG-LS and RLE support. Added new Deflate IO module and comprehensive JPEG-LS test cases. Refactored and improved JPEG-LS decoder and parser implementations.
Introduces an 'inverted' property and setInvert() method to DicomPixelView, enabling inversion of window/level mapping for 8-bit and 16-bit images, including GPU and CPU paths. Also updates PixelService to preserve rescale slope/intercept for 8-bit decoded frames, ensuring correct downstream processing.
Introduces TLS configuration and context handling to DicomServer using swift-nio-ssl, allowing secure DICOM listener operation. Fixes CMoveRQ to correctly set CommandDataSetType and select the proper presentation context for Study/Patient Root MOVE. Adds unit tests for C-MOVE DIMSE packing to verify correct PDV and dataset handling.
Introduces Metal-based GPU acceleration for 16-bit VOI LUT mapping in DicomPixelView, including a new Metal shader and pipeline state. Adds a placeholder J2KNativeDecoder for native 16-bit JPEG2000/HTJ2K decoding, with PixelService updated to prefer this path when enabled. Also updates MetalAccelerator to support the new pipeline and refactors related code for performance and flexibility.
Introduces zero-copy frame access via memory-mapped files and a FrameIndex for efficient DICOM frame extraction. Adds DicomMetalView for GPU-first Metal rendering, new Metal shaders, and performance monitoring enhancements. Updates PixelService to support multi-frame decoding and improves networking PDU handling for large transfers. Includes new tests for frame indexing and memory mapping.
Introduces CompressedPixelRouter for centralized DICOM compressed pixel decoding and refactors PixelService to route compressed transfer syntaxes through it. Adds DcmSwiftPerformanceMonitor for GPU operation metrics, updates Metal view/device handling, and removes legacy performance monitoring. Includes integration and unit tests for compression support. Minor bugfixes and improvements in CStoreSCP and DicomPixelView.
There was a problem hiding this comment.
Codex Review: Here are some suggestions.
Reply with @codex fix comments to fix any unresolved comments.
About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you open a pull request for review, mark a draft as ready, or comment "@codex review". If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex fix this CI failure" or "@codex address that feedback".
| let bot = pixelSequence.basicOffsetTable() | ||
|
|
||
| if let bot = bot, bot.count > 0 { | ||
| // Parse BOT offsets | ||
| let frameCount = bot.count / 4 // Each offset is 4 bytes | ||
| var offsets: [Int] = [] | ||
|
|
||
| bot.withUnsafeBytes { rawBytes in | ||
| let uint32Pointer = rawBytes.bindMemory(to: UInt32.self) | ||
| for i in 0..<frameCount { | ||
| let offset = Int(UInt32(littleEndian: uint32Pointer[i])) | ||
| offsets.append(offset) | ||
| } | ||
| } | ||
|
|
||
| // Calculate frame lengths and build frame info | ||
| for i in 0..<frameCount { | ||
| let startOffset = offsets[i] | ||
| let endOffset = (i + 1 < offsets.count) ? offsets[i + 1] : bot.count | ||
| let length = endOffset - startOffset |
There was a problem hiding this comment.
[P0] Build encapsulated frame index using wrong BOT representation
The new FrameIndex.buildEncapsulatedFrameIndex treats pixelSequence.basicOffsetTable() as a raw Data buffer, dividing bot.count by 4 and accessing withUnsafeBytes. However the same commit changes PixelSequence.basicOffsetTable() to return [Int] offsets (one per frame). This mismatch prevents the project from compiling and, even if fixed by force-casting, would compute a quarter of the real frame count and use bot.count (the number of offsets) as the last frame’s byte length, yielding zero or negative sizes. The method should iterate the returned offset array directly and derive the last frame length from the fragment data size, not from the number of offsets.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Summary
- Updated
FrameIndex.buildEncapsulatedFrameIndexto iterate the[Int]BOT offsets, clamp each frame to the concatenated fragment data, and continue supporting the single-frame fallback when the BOT is empty. Sources/DcmSwift/Data/FrameIndex.swiftL94-L127
Testing
⚠️ swift test(fails: platform lacks theos.signpostmodule needed by graphics utilities)
Code Review: Compression Support PR #31Thank you for this comprehensive implementation of compression support for DcmSwift! This is a substantial contribution that adds critical functionality for handling compressed DICOM files. Here's my detailed review: 🎯 Overall AssessmentThis PR successfully implements support for multiple compression formats (RLE, JPEG-LS, JPEG 2000) with good test coverage. The implementation is well-structured with clear separation of concerns between different decoders. ✅ Strengths
🔍 Code Quality & Best PracticesPositive Observations:
Areas for Improvement:
🐛 Potential Issues
⚡ Performance Considerations
🔒 Security Concerns
🧪 Test CoverageThe test coverage looks comprehensive with both unit and integration tests. Suggestions:
📝 Minor Issues
💡 Suggestions for Future Improvements
✅ RecommendationThis PR is ready to merge with the understanding that the minor issues identified can be addressed in follow-up PRs. The core functionality is solid, well-tested, and adds significant value to the library. Consider creating GitHub issues for:
Great work on this substantial feature addition! 🎉 Review generated with assistance from Claude Code |
No description provided.