Skip to content

Commit

Permalink
write errors on deflated transfer syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
suyashkumar committed Jun 1, 2024
1 parent 005ec03 commit 0d5d36a
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 37 deletions.
6 changes: 5 additions & 1 deletion write.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ var (
ErrorUnexpectedValueType = errors.New("Unexpected ValueType")
// ErrorUnsupportedBitsPerSample indicates that the BitsPerSample in this
// Dataset is not supported when unpacking native PixelData.
ErrorUnsupportedBitsPerSample = errors.New("unsupported BitsPerSample value")
ErrorUnsupportedBitsPerSample = errors.New("unsupported BitsPerSample value")
errorDeflatedTransferSyntaxUnsupported = errors.New("deflated explicit vr little endian transfer syntax not yet support on write (https://github.com/suyashkumar/dicom/issues/323)")
)

// Writer is a struct that allows element-by element writing to a DICOM writer.
Expand Down Expand Up @@ -261,6 +262,9 @@ func writeMetaElem(w dicomio.Writer, t tag.Tag, ds *Dataset, tagsUsed *map[tag.T
if err != nil {
return err
}
if elem.Tag == tag.TransferSyntaxUID && MustGetStrings(elem.Value)[0] == uid.DeflatedExplicitVRLittleEndian {
return errorDeflatedTransferSyntaxUnsupported
}
err = writeElement(w, elem, optSet)
if err != nil {
return err
Expand Down
88 changes: 52 additions & 36 deletions write_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dicom
import (
"bytes"
"encoding/binary"
"errors"
"os"
"testing"

Expand All @@ -27,13 +28,13 @@ import (
// Write implementation (e.g. it kinda goes both ways and covers Parse too).
func TestWrite(t *testing.T) {
cases := []struct {
name string
dataset Dataset
extraElems []*Element
expectedError error
opts []WriteOption
parseOpts []ParseOption
cmpOpts []cmp.Option
name string
dataset Dataset
extraElems []*Element
wantError error
opts []WriteOption
parseOpts []ParseOption
cmpOpts []cmp.Option
}{
{
name: "basic types",
Expand All @@ -58,7 +59,7 @@ func TestWrite(t *testing.T) {
},
},
}},
expectedError: nil,
wantError: nil,
},
{
name: "private tag",
Expand All @@ -70,7 +71,7 @@ func TestWrite(t *testing.T) {
mustNewElement(tag.TransferSyntaxUID, []string{uid.ExplicitVRLittleEndian}),
mustNewPrivateElement(tag.Tag{0x0003, 0x0010}, vrraw.ShortText, []string{"some data"}),
}},
expectedError: nil,
wantError: nil,
},
{
name: "sequence (2 Items with 2 values each)",
Expand Down Expand Up @@ -120,7 +121,7 @@ func TestWrite(t *testing.T) {
},
}),
}},
expectedError: nil,
wantError: nil,
},
{
name: "sequence (2 Items with 2 values each) - skip vr verification",
Expand Down Expand Up @@ -170,8 +171,8 @@ func TestWrite(t *testing.T) {
},
}),
}},
expectedError: nil,
opts: []WriteOption{SkipVRVerification()},
wantError: nil,
opts: []WriteOption{SkipVRVerification()},
},
{
name: "nested sequences",
Expand Down Expand Up @@ -207,7 +208,7 @@ func TestWrite(t *testing.T) {
},
}),
}},
expectedError: nil,
wantError: nil,
},
{
name: "nested sequences - without VR verification",
Expand Down Expand Up @@ -243,8 +244,8 @@ func TestWrite(t *testing.T) {
},
}),
}},
expectedError: nil,
opts: []WriteOption{SkipVRVerification()},
wantError: nil,
opts: []WriteOption{SkipVRVerification()},
},
{
name: "without transfer syntax",
Expand All @@ -255,7 +256,7 @@ func TestWrite(t *testing.T) {
mustNewElement(tag.Rows, []int{128}),
mustNewElement(tag.FloatingPointValue, []float64{128.10}),
}},
expectedError: ErrorElementNotFound,
wantError: ErrorElementNotFound,
},
{
name: "without transfer syntax with DefaultMissingTransferSyntax",
Expand All @@ -267,9 +268,9 @@ func TestWrite(t *testing.T) {
mustNewElement(tag.FloatingPointValue, []float64{128.10}),
}},
// This gets inserted if DefaultMissingTransferSyntax is provided:
extraElems: []*Element{mustNewElement(tag.TransferSyntaxUID, []string{uid.ImplicitVRLittleEndian})},
expectedError: nil,
opts: []WriteOption{DefaultMissingTransferSyntax()},
extraElems: []*Element{mustNewElement(tag.TransferSyntaxUID, []string{uid.ImplicitVRLittleEndian})},
wantError: nil,
opts: []WriteOption{DefaultMissingTransferSyntax()},
},
{
name: "native PixelData: 8bit",
Expand Down Expand Up @@ -299,7 +300,7 @@ func TestWrite(t *testing.T) {
mustNewElement(tag.FloatingPointValue, []float64{128.10}),
mustNewElement(tag.DimensionIndexPointer, []int{32, 36950}),
}},
expectedError: nil,
wantError: nil,
},
{
name: "native PixelData: 16bit",
Expand Down Expand Up @@ -327,7 +328,7 @@ func TestWrite(t *testing.T) {
},
}),
}},
expectedError: nil,
wantError: nil,
},
{
name: "native PixelData: 32bit",
Expand Down Expand Up @@ -355,7 +356,7 @@ func TestWrite(t *testing.T) {
},
}),
}},
expectedError: nil,
wantError: nil,
},
{
name: "native PixelData: 2 SamplesPerPixel, 2 frames",
Expand Down Expand Up @@ -392,7 +393,7 @@ func TestWrite(t *testing.T) {
},
}),
}},
expectedError: nil,
wantError: nil,
},
{
name: "encapsulated PixelData",
Expand All @@ -419,7 +420,7 @@ func TestWrite(t *testing.T) {
mustNewElement(tag.FloatingPointValue, []float64{128.10}),
mustNewElement(tag.DimensionIndexPointer, []int{32, 36950}),
}},
expectedError: nil,
wantError: nil,
},
{
name: "encapsulated PixelData: multiframe",
Expand All @@ -444,7 +445,7 @@ func TestWrite(t *testing.T) {
mustNewElement(tag.FloatingPointValue, []float64{128.10}),
mustNewElement(tag.DimensionIndexPointer, []int{32, 36950}),
}},
expectedError: nil,
wantError: nil,
},
{
name: "native_PixelData_2samples_2frames_BigEndian",
Expand Down Expand Up @@ -481,7 +482,7 @@ func TestWrite(t *testing.T) {
},
}),
}},
expectedError: nil,
wantError: nil,
},
{
name: "native_PixelData_odd_bytes",
Expand Down Expand Up @@ -509,7 +510,7 @@ func TestWrite(t *testing.T) {
},
}),
}},
expectedError: nil,
wantError: nil,
},
{
name: "PixelData with IntentionallyUnprocessed=true",
Expand All @@ -526,8 +527,8 @@ func TestWrite(t *testing.T) {
IsEncapsulated: false,
}),
}},
parseOpts: []ParseOption{SkipProcessingPixelDataValue()},
expectedError: nil,
parseOpts: []ParseOption{SkipProcessingPixelDataValue()},
wantError: nil,
},
{
name: "Native PixelData with IntentionallySkipped=true",
Expand All @@ -542,8 +543,8 @@ func TestWrite(t *testing.T) {
IsEncapsulated: false,
}),
}},
parseOpts: []ParseOption{SkipPixelData()},
expectedError: nil,
parseOpts: []ParseOption{SkipPixelData()},
wantError: nil,
},
{
name: "Encapsulated PixelData with IntentionallySkipped=true",
Expand All @@ -558,8 +559,23 @@ func TestWrite(t *testing.T) {
IsEncapsulated: true,
})),
}},
parseOpts: []ParseOption{SkipPixelData()},
expectedError: nil,
parseOpts: []ParseOption{SkipPixelData()},
wantError: nil,
},
{
name: "deflated transfer syntax returns error",
dataset: Dataset{Elements: []*Element{
mustNewElement(tag.MediaStorageSOPClassUID, []string{"1.2.840.10008.5.1.4.1.1.1.2"}),
mustNewElement(tag.MediaStorageSOPInstanceUID, []string{"1.2.3.4.5.6.7"}),
mustNewElement(tag.TransferSyntaxUID, []string{uid.DeflatedExplicitVRLittleEndian}),
mustNewElement(tag.BitsAllocated, []int{8}),
mustNewElement(tag.FloatingPointValue, []float64{128.10}),
setUndefinedLength(mustNewElement(tag.PixelData, PixelDataInfo{
IntentionallySkipped: true,
IsEncapsulated: true,
})),
}},
parseOpts: []ParseOption{SkipPixelData()}, wantError: errorDeflatedTransferSyntaxUnsupported,
},
}
for _, tc := range cases {
Expand All @@ -568,12 +584,12 @@ func TestWrite(t *testing.T) {
if err != nil {
t.Fatalf("Unexpected error when creating tempfile: %v", err)
}
if err = Write(file, tc.dataset, tc.opts...); err != tc.expectedError {
t.Fatalf("Write(%v): unexpected error. got: %v, want: %v", tc.dataset, err, tc.expectedError)
if err = Write(file, tc.dataset, tc.opts...); errors.Is(err, tc.wantError) {
t.Fatalf("Write(%v): unexpected error. got: %v, want: %v", tc.dataset, err, tc.wantError)
}
file.Close()
// If we expect an error, we do not need to continue to check the value of the written data, so we continue to the next test case.
if tc.expectedError != nil {
if tc.wantError != nil {
return
}
// Read the data back in and check for equality to the tc.dataset:
Expand Down

0 comments on commit 0d5d36a

Please sign in to comment.