Packages

Pure Elixir DICOM toolkit for P10 files, DICOM JSON, de-identification, and structured reports (all 33 PS3.16 root templates)

Current section

Files

Jump to
dicom CHANGELOG.md
Raw

CHANGELOG.md

# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.3.0] - 2026-03-17
### Added
- **62 transfer syntaxes** — expanded from 29 to all 49 active + 13 retired
DICOM transfer syntaxes. New fields: `retired` and `fragmentable` flags.
New functions: `retired?/1`, `fragmentable?/1`, `active/0`.
- **Complete PS3.6 tag dictionary** — 5,035 entries generated from innolitics
`attributes.json` via `mix dicom.gen_dictionary`. Keyword reverse lookup
with `find_by_keyword/1`, retired tag detection with `retired?/1`, and
expanded repeating group support (50XX curve, 60XX overlay, 7FXX waveform).
- **DICOM JSON model** (`Dicom.Json`) — encode/decode DataSets to/from the
DICOM JSON format (PS3.18 Annex F.2) for DICOMweb. Supports all VR types,
Person Name component groups, sequence recursion, InlineBinary (base64),
and BulkDataURI callbacks. Zero runtime dependencies — produces plain maps.
- **Pixel data frame extraction** (`Dicom.PixelData`) — extract individual
frames from native and encapsulated pixel data (PS3.5 Section A.4).
O(1) native frame access via `binary_part/3`. Encapsulated support with
Basic Offset Table, fragment-per-frame convention, and single-frame
concatenation. Functions: `frames/1`, `frame/2`, `frame_count/1`,
`encapsulated?/1`.
- **De-identification / anonymization** (`Dicom.DeIdentification`) — Basic
Application Level Confidentiality Profile (PS3.15 Table E.1-1) with action
codes D, Z, X, K, C, U. Consistent UID replacement across elements.
Configurable profile with 10 boolean options. Recursive SQ processing and
private tag stripping.
- **ISO 8859-{2..9} full lookup tables** — replaced identity mapping with
correct Unicode codepoint tables for all 8 ISO 8859 variants.
- **JIS X 0201 character set** — `ISO_IR 13` support for Roman + half-width
Katakana decoding.
- Mix task `mix dicom.gen_dictionary` for regenerating the tag dictionary
from the innolitics DICOM standard JSON source.
### Changed
- Expanded test suite to 621 tests (5 doctests, 4 property tests) at 91%+ coverage
- VR module exposes `string_vrs/0`, `numeric_vrs/0`, `binary_vrs/0` list accessors
- Transfer syntax `all/0` and `active/0` cached at compile time
### Fixed
- De-identification `:D` action now computes correct `byte_size` for dummy values
- ISO 8859-4 table: removed erroneous `0xE3` mapping
- Character set decoding DRYed with shared `decode_bytewise/3`
## [0.2.0] - 2026-03-17
### Added
- Streaming DICOM P10 parser via `Dicom.P10.Stream` with lazy, event-based parsing
- `Dicom.stream_parse/1` and `Dicom.stream_parse_file/2` convenience functions
- `Dicom.P10.Stream.parse/1` for in-memory binary streaming (`Stream.unfold/2`)
- `Dicom.P10.Stream.parse_file/2` for file I/O streaming (`Stream.resource/3`)
- `Dicom.P10.Stream.to_data_set/1` to materialize a stream into a `DataSet`
- Event types: `:file_meta_start`, `{:file_meta_end, ts_uid}`, `{:element, elem}`,
`{:sequence_start, tag, length}`, `:sequence_end`, `{:item_start, length}`,
`:item_end`, `{:pixel_data_start, tag, vr}`, `{:pixel_data_fragment, index, binary}`,
`:pixel_data_end`, `:end`, `{:error, reason}`
- Source abstraction (`Dicom.P10.Stream.Source`) for binary and file I/O with
64 KB read-ahead buffering
- State machine parser (`Dicom.P10.Stream.Parser`) supporting all 4 transfer
syntaxes, sequences, items, and encapsulated pixel data
- BEAM DICOM library comparison table in the README covering licensing, features,
test coverage, and CI status
- **Comprehensive PS3.6 data dictionary** — expanded from ~95 hand-written entries
to 5032 entries generated from the DICOM standard. Overlay repeating group (60XX)
support included. Previously-unknown tags (especially SQ) now resolve correctly
in Implicit VR parsing.
- **Specific Character Set support** (`Dicom.CharacterSet`) — decodes text values
according to (0008,0005). Supports default repertoire, ISO_IR 100 (Latin-1),
ISO 8859-2 through 9, and ISO_IR 192 (UTF-8). Returns explicit errors for
unsupported charsets instead of silently producing incorrect text.
- **Expanded transfer syntax registry** — from 9 to 29 entries. Added JPEG-LS,
JPEG 2000 Part 2, MPEG-2/4, HEVC/H.265, HTJ2K, and JPIP transfer syntaxes.
- Interoperability test suite exercising unknown TS rejection, expanded dictionary
in implicit VR parsing, rich multi-element roundtrips across all four uncompressed
transfer syntaxes, encapsulated pixel data with compressed TSes, and character set
integration through the parse pipeline.
### Fixed
- Reject serialization when required File Meta Information is missing
- Encode numeric values according to their VR width instead of forcing 32-bit
little-endian output
- Respect transfer syntax endianness for numeric value encoding and decoding
- Preserve leading spaces for padded text VRs such as `LT` and `UT`
- Return `{:error, :unexpected_end}` for truncated defined-length sequence payloads
instead of crashing the parser
- Tighten UID validation for invalid root arcs
### Changed
- **Strict transfer syntax policy** — `TransferSyntax.encoding/2` now returns
`{:error, :unknown_transfer_syntax}` for unrecognized UIDs instead of silently
falling back to Explicit VR Little Endian. Use `encoding(uid, lenient: true)` to
opt in to the old fallback behavior. Reader and writer now propagate this error.
- Expanded test coverage to 448 tests (streaming, big-endian numeric value
decode/encode, eager path, edge cases, property-based equivalence) at 91%+ coverage
## [0.1.0] - 2026-03-17
### Added
- P10 file parsing with `Dicom.parse/1` and `Dicom.parse_file/1`
- P10 file writing with `Dicom.write/1` and `Dicom.write_file/2`
- Data set creation and manipulation via `Dicom.DataSet`
- DICOM data dictionary (PS3.6) with tag lookup via `Dicom.Dictionary.Registry`
- Tag constants for common clinical attributes via `Dicom.Tag`
- UID constants for SOP Classes and Transfer Syntaxes via `Dicom.UID`
- UID generation and validation
- VR-aware value encoding and decoding via `Dicom.Value`
- Transfer syntax support:
- Implicit VR Little Endian
- Explicit VR Little Endian
- Explicit VR Big Endian (retired)
- Deflated Explicit VR Little Endian
- Sequence support (SQ) with defined and undefined length items
- Encapsulated pixel data with fragment parsing
- File Meta Information validation per PS3.10 Section 7.1
- Preamble validation and sanitization (PS3.10 Section 7.5)
- Data Set Trailing Padding support (FFFC,FFFC)
### Changed
- Expanded PS3.10 support with compliance tests, deflated transfer syntax support,
sequence handling, additional VR coverage, and Explicit VR Big Endian support
- Hardened parsing and validation around malformed input, edge cases, and file meta handling
- Optimized hot paths in the reader, writer, transfer syntax registry, and VR utilities
- Prepared the project for public release with CI, licensing, contribution policy,
security policy, and open-source documentation
### Performance
- Performance benchmarks (parse, write, roundtrip, VR lookup)
- 100% test coverage across all 12 modules (259 tests)
- Property-based tests with StreamData for encode/decode roundtrips
[Unreleased]: https://github.com/Balneario-de-Cofrentes/dicom/compare/v0.3.0...HEAD
[0.3.0]: https://github.com/Balneario-de-Cofrentes/dicom/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/Balneario-de-Cofrentes/dicom/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/Balneario-de-Cofrentes/dicom/commit/cdd216b7adc62cb8282f7a150130f7b51d7e724f