From 6c2dad58117ae68c397c9127f280862e49c10858 Mon Sep 17 00:00:00 2001 From: Suyash Kumar Date: Thu, 15 Jul 2021 21:05:05 -0400 Subject: [PATCH] Return a sentinel error for unsupported BitsAllocated (#210) This ensures that we return a recognizable sentinel error when we are trying to parse a file with an unexpected BitsAllocated. Previously, we would spin through the readNativeFrames loop without reading forward in the file, leading to an incorrect file offset when parsing the rest of the file which is not desirable. Longer term, we should aim to possibly support non-standard bitsAllocated (not supported by binary.ByteOrder), though we need to understand what exactly that would mean --- read.go | 10 ++++++++-- read_test.go | 13 +++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/read.go b/read.go index f9953355..7cf444cf 100644 --- a/read.go +++ b/read.go @@ -24,8 +24,12 @@ var ( // value length which is not allowed. ErrorOWRequiresEvenVL = errors.New("vr of OW requires even value length") // ErrorUnsupportedVR indicates that this VR is not supported. - ErrorUnsupportedVR = errors.New("unsupported VR") - errorUnableToParseFloat = errors.New("unable to parse float type") + ErrorUnsupportedVR = errors.New("unsupported VR") + // ErrorUnsupportedBitsAllocated indicates that the BitsAllocated in the + // NativeFrame PixelData is unsupported. In this situation, the rest of the + // dataset returned is still valid. + ErrorUnsupportedBitsAllocated = errors.New("unsupported BitsAllocated") + errorUnableToParseFloat = errors.New("unable to parse float type") ) func readTag(r dicomio.Reader) (*tag.Tag, error) { @@ -252,6 +256,8 @@ func readNativeFrames(d dicomio.Reader, parsedData *Dataset, fc chan<- *frame.Fr buf[(pixel*samplesPerPixel)+value] = int(bo.Uint16(pixelBuf)) } else if bitsAllocated == 32 { buf[(pixel*samplesPerPixel)+value] = int(bo.Uint32(pixelBuf)) + } else { + return nil, bytesRead, fmt.Errorf("unsupported BitsAllocated value of: %d : %w", bitsAllocated, ErrorUnsupportedBitsAllocated) } } currentFrame.NativeData.Data[pixel] = buf[pixel*samplesPerPixel : (pixel+1)*samplesPerPixel] diff --git a/read_test.go b/read_test.go index 4385c214..32db2532 100644 --- a/read_test.go +++ b/read_test.go @@ -344,6 +344,19 @@ func TestReadNativeFrames(t *testing.T) { expectedPixelData: nil, expectedError: ErrorElementNotFound, }, + { + Name: "unsupported BitsAllocated", + existingData: Dataset{Elements: []*Element{ + mustNewElement(tag.Rows, []int{5}), + mustNewElement(tag.Columns, []int{2}), + mustNewElement(tag.NumberOfFrames, []string{"1"}), + mustNewElement(tag.BitsAllocated, []int{1}), + mustNewElement(tag.SamplesPerPixel, []int{1}), + }}, + data: []uint16{1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + expectedPixelData: nil, + expectedError: ErrorUnsupportedBitsAllocated, + }, } for _, tc := range cases {