Skip to content

v1.3.0

Choose a tag to compare

@github-actions github-actions released this 26 Jul 21:49
· 124 commits to main since this release
b9b58e7

Upgrade from 1.2.0 without delay. The ItemTag constant in 1.2.0 was wrong, so the
nested sequence parsing introduced in that release failed on every real DICOM file
containing a sequence. 1.2.0 should be skipped.

Added

  • C-GET sub-operations — a C-GET previously invoked the handler and returned a status
    but transferred nothing. The SCP now sends matching instances back as C-STORE
    sub-operations over the same association (PS3.4 Annex C.4.3), each on the presentation
    context negotiated for its own SOP Class, with pending responses carrying the
    remaining/completed/failed/warning counts. The SCU dispatches incoming C-STORE-RQ
    messages to SCUConfig.OnCStore and acknowledges each one.
    • CGetResponse.Instances supplies the instances to transfer
    • SCUConfig.OnCStore receives them on the requesting side
    • qrscp retains received datasets and serves them, making it a working
      in-memory query/retrieve server
  • C-MOVE sub-operations — the SCP now opens an association to the move destination and
    sends the matching instances there as C-STORE sub-operations (PS3.4 Annex C.4.2),
    reporting progress back to the requestor. This completes query/retrieve: C-FIND,
    C-GET, and C-MOVE all work as both SCU and SCP.
    • CMoveResponse.Instances supplies the instances to move
    • QueryRetrieveHandler.OnMoveInstances returns them from a handler; the older
      OnMove, which could not transfer anything, is deprecated but still honored
    • SCPConfig.MoveDestinations and SCPConfig.ResolveMoveDestination resolve a
      destination AE title to an address; an unresolvable title is answered with
      StatusMoveDestUnknown
    • qrscp -move-dest AETITLE=host:port configures destinations from the CLI
  • Sequence writing in filewriterDataElement.Items holds nested
    SequenceItem values, closing the read → write → read round trip. Items are written
    with explicit lengths and implicit-style item headers as PS3.5 Section 7.5 requires.
  • Raw DICOM data sets without a file meta headerReadDICOMFile required the
    128-byte preamble and DICM prefix, so a raw stream, which is what modalities produce and
    what travels on the network, could not be read despite the README listing it as
    supported. The reader now detects which form the stream is and falls back to implicit VR
    little endian per PS3.5 Section 10.1, recording the outcome in DICOMFile.HasPreamble.
  • DICOMFile.MetaElements — the group-0002 elements as they appeared in the file,
    for callers that need to display the header verbatim.
  • Interoperability testing against pynetdicom and dcmtkscripts/interop-test.sh
    plus a CI job. Exercises C-ECHO and C-STORE in both directions and C-GET
    sub-operations, using pydicom's CT_small.dcm as the fixture and pydicom as the
    verifier rather than this library's own reader. Fails when no third-party peer is
    available, so a broken install cannot pass by skipping.

Fixed

  • The CLI parsed files with a second, broken parsershow, info, convert, and
    codify used a parser in cli/helpers.go separate from filereader, which received
    none of this cycle's fixes. It read the file in 64 KiB chunks and parsed each
    independently, so an element straddling a boundary desynchronized the stream: on a
    268 KB file where pydicom reports 258 elements it printed roughly 38 and ended with an
    invented element whose VR was two arbitrary bytes. It also never descended into
    sequences, and classified SQ and UT as short-form VRs. The CLI now uses filereader,
    reports 269 elements for the same file, and indents sequence contents by nesting depth.
  • ItemTag was 0xFFFE0000, not 0xFFFEE000 (critical) — the constant was missing
    a digit and decoded as (FFFE,0000). Sequence parsing, added in 1.2.0, therefore failed
    on every real DICOM file containing a sequence, rejecting the correct item tag as
    unexpected. The unit tests passed because they built their fixtures with the same wrong
    constant.
  • tag.FromBytes and tag.ToBytes transposed group and element — both treated the
    4-byte tag as a single uint32 rather than two consecutive 16-bit values. Undetected
    because the only test case was PatientName (0010,0010), where group equals element, and
    because the two functions were each other's inverse.
  • Sequences were lost over the networkEncodeDataset skipped sequence elements,
    and storescu built its dataset from elem.Value, which is nil for a sequence. An
    instance sent to a peer arrived with its sequence present but empty.
  • An empty data set sent no PDU at allSendPData looped over the payload, so a
    zero-length data set produced nothing after the command had already announced one,
    leaving the peer blocked until the DIMSE timeout. Reachable with any keyless C-FIND or
    C-GET identifier.
  • QueryRetrieveHandler.OnGet results are now transferred rather than only counted.

Install

go install github.com/amrshadid/go-dicom@v1.3.0

Or download a binary below and place it on your PATH:

Platform File
Linux x86-64 dicom-linux-amd64
Linux ARM64 dicom-linux-arm64
macOS Intel dicom-macos-amd64
macOS Apple Silicon dicom-macos-arm64
Windows x86-64 dicom-windows-amd64.exe

Checksums are in SHA256SUMS:

sha256sum -c SHA256SUMS

Full changelog