Skip to content

Commit

Permalink
Initial stab at deflate transfer syntax support
Browse files Browse the repository at this point in the history
  • Loading branch information
suyashkumar committed Jun 1, 2024
1 parent bb750f0 commit e6957b9
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 7 deletions.
10 changes: 7 additions & 3 deletions parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,16 @@ func NewParser(in io.Reader, bytesToRead int64, frameChannel chan *frame.Frame,
if err != nil {
debug.Log("WARN: could not find transfer syntax uid in metadata, proceeding with little endian implicit")
} else {
bo, implicit, err = uid.ParseTransferSyntaxUID(MustGetStrings(ts.Value)[0])
tsStr := MustGetStrings(ts.Value)[0]
bo, implicit, err = uid.ParseTransferSyntaxUID(tsStr)
if err != nil {
// TODO(suyashkumar): should we attempt to parse with LittleEndian
// Implicit here?
debug.Log("WARN: could not parse transfer syntax uid in metadata")
}
if tsStr == uid.DeflatedExplicitVRLittleEndian {
p.reader.rawReader.SetDeflate()
}
}
p.SetTransferSyntax(bo, implicit)

Expand Down Expand Up @@ -281,8 +285,8 @@ func SkipPixelData() ParseOption {
// a PixelData element will be added to the dataset with the
// PixelDataInfo.IntentionallyUnprocessed = true, and the raw bytes of the
// entire PixelData element stored in PixelDataInfo.UnprocessedValueData.
//
// In the future, we may be able to extend this functionality to support
//
// In the future, we may be able to extend this functionality to support
// on-demand processing of elements elsewhere in the library.
func SkipProcessingPixelDataValue() ParseOption {
return func(set *parseOptSet) {
Expand Down
17 changes: 17 additions & 0 deletions pkg/dicomio/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package dicomio

import (
"bufio"
"compress/flate"
"encoding/binary"
"errors"
"fmt"
Expand Down Expand Up @@ -71,7 +72,16 @@ type Reader interface {
// SetCodingSystem sets the charset.CodingSystem to be used when ReadString
// is called.
SetCodingSystem(cs charset.CodingSystem)
// ByteOrder returns the current byte order.
ByteOrder() binary.ByteOrder
// SetDeflate applies deflate decompression to the underlying reader for all
// subsequent reads. This should be set when working with a deflated
// transfer syntax. Right now this is expected to be called once when
// parsing the top level dicom data, and there is no facility to swap
// between deflate and non-deflate reading.
// This also sets the current limit to LimitReadUntilEOF, since the original
// limits (if any) will be based on uncompressed bytes.
SetDeflate()
}

type reader struct {
Expand Down Expand Up @@ -234,6 +244,13 @@ func (r *reader) SetTransferSyntax(bo binary.ByteOrder, implicit bool) {
r.implicit = implicit
}

func (r *reader) SetDeflate() {
r.in = bufio.NewReader(flate.NewReader(r.in))
// TODO(https://github.com/suyashkumar/dicom/issues/320): consider always
// having the top level limit read until EOF.
r.limit = LimitReadUntilEOF // needed because original limits may not apply to the deflated reader
}

func (r *reader) IsImplicit() bool { return r.implicit }

func (r *reader) SetCodingSystem(cs charset.CodingSystem) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/uid/uid.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func ParseTransferSyntaxUID(uid string) (bo binary.ByteOrder, implicit bool, err
case ImplicitVRLittleEndian:
return binary.LittleEndian, true, nil
case DeflatedExplicitVRLittleEndian:
fallthrough
return binary.LittleEndian, false, nil
case ExplicitVRLittleEndian:
return binary.LittleEndian, false, nil
case ExplicitVRBigEndian:
Expand Down
8 changes: 5 additions & 3 deletions testdata/data_details.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ be mentioned in one of them for brevity.
* Modality: CT
* Multiple frames
* Native pixel data
* [6.dcm](6.dcm)
* Deflated Little Endian Transfer Syntax (Explicit VR)
### Relevant Citations
#### For files 1.dcm, 2.dcm:
##### Data Citation:
Expand All @@ -58,6 +60,6 @@ Desai, S., Baghal, A., Wongsurawat, T., Al-Shukri, S., Gates, K., Farmer, P., Ru
#### TCIA Citation
Clark K, Vendt B, Smith K, Freymann J, Kirby J, Koppel P, Moore S, Phillips S, Maffitt D, Pringle M, Tarbox L, Prior F. The Cancer Imaging Archive (TCIA): Maintaining and Operating a Public Information Repository, Journal of Digital Imaging, Volume 26, Number 6, December, 2013, pp 1045-1057. DOI: 10.1007/s10278-013-9622-7

#### File 5.dcm
This file was sourced from [cornerstone](https://github.com/cornerstonejs/dicomParser/blob/master/testImages/encapsulated/multi-frame/CT0012.explicit_little_endian.dcm)
(which is MIT licensed, see the license reproduced in included_licenses.md)
#### File 5.dcm & 6.dcm
This file was sourced from cornerstone [5.dcm from here](https://github.com/cornerstonejs/dicomParser/blob/master/testImages/encapsulated/multi-frame/CT0012.explicit_little_endian.dcm), and [6.dcm from here](https://github.com/cornerstonejs/dicomParser/blob/7d2084349bf2bdaffe74021e27b286a6c295ca66/testImages/deflate/image_dfl).
(Cornerstone is MIT licensed, see the license reproduced in included_licenses.md).

0 comments on commit e6957b9

Please sign in to comment.