diff --git a/mocks/pkg/dicomio/mock_reader.go b/mocks/pkg/dicomio/mock_reader.go index e7b239ce..9f060a4b 100644 --- a/mocks/pkg/dicomio/mock_reader.go +++ b/mocks/pkg/dicomio/mock_reader.go @@ -289,3 +289,17 @@ func (mr *MockReaderMockRecorder) SetCodingSystem(cs interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCodingSystem", reflect.TypeOf((*MockReader)(nil).SetCodingSystem), cs) } + +// ByteOrder indicates an expected call of GetByteOrder +func (mr *MockReaderMockRecorder) ByteOrder() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ByteOrder", reflect.TypeOf((*MockReader)(nil).ByteOrder)) +} + +// ByteOrder mocks base method +func (m *MockReader) ByteOrder() binary.ByteOrder { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ByteOrder") + ret0, _ := ret[0].(binary.ByteOrder) + return ret0 +} diff --git a/pkg/dicomio/reader.go b/pkg/dicomio/reader.go index 29af4ee0..4e6064a0 100644 --- a/pkg/dicomio/reader.go +++ b/pkg/dicomio/reader.go @@ -67,6 +67,7 @@ type Reader interface { // SetCodingSystem sets the charset.CodingSystem to be used when ReadString // is called. SetCodingSystem(cs charset.CodingSystem) + ByteOrder() binary.ByteOrder } type reader struct { @@ -234,3 +235,7 @@ func (r *reader) SetCodingSystem(cs charset.CodingSystem) { func (r *reader) Peek(n int) ([]byte, error) { return r.in.Peek(n) } + +func (r *reader) ByteOrder() binary.ByteOrder { + return r.bo +} diff --git a/read.go b/read.go index 14e7fbf0..b9958e21 100644 --- a/read.go +++ b/read.go @@ -212,6 +212,9 @@ func readNativeFrames(d dicomio.Reader, parsedData *Dataset, fc chan<- *frame.Fr // Parse the pixels: image.Frames = make([]frame.Frame, nFrames) + bo := d.ByteOrder() + bytesAllocated := bitsAllocated / 8 + pixelBuf := make([]byte, bytesAllocated) for frameIdx := 0; frameIdx < nFrames; frameIdx++ { // Init current frame currentFrame := frame.Frame{ @@ -226,24 +229,18 @@ func readNativeFrames(d dicomio.Reader, parsedData *Dataset, fc chan<- *frame.Fr buf := make([]int, int(pixelsPerFrame)*samplesPerPixel) for pixel := 0; pixel < int(pixelsPerFrame); pixel++ { for value := 0; value < samplesPerPixel; value++ { + _, err := io.ReadFull(d, pixelBuf) + if err != nil { + return nil, bytesRead, + fmt.Errorf("could not read uint%d from input: %w", bitsAllocated, err) + } + if bitsAllocated == 8 { - val, err := d.ReadUInt8() - if err != nil { - return nil, bytesRead, err - } - buf[(pixel*samplesPerPixel)+value] = int(val) + buf[(pixel*samplesPerPixel)+value] = int(pixelBuf[0]) } else if bitsAllocated == 16 { - val, err := d.ReadUInt16() - if err != nil { - return nil, bytesRead, err - } - buf[(pixel*samplesPerPixel)+value] = int(val) + buf[(pixel*samplesPerPixel)+value] = int(bo.Uint16(pixelBuf)) } else if bitsAllocated == 32 { - val, err := d.ReadUInt32() - if err != nil { - return nil, bytesRead, err - } - buf[(pixel*samplesPerPixel)+value] = int(val) + buf[(pixel*samplesPerPixel)+value] = int(bo.Uint32(pixelBuf)) } } currentFrame.NativeData.Data[pixel] = buf[pixel*samplesPerPixel : (pixel+1)*samplesPerPixel] @@ -254,7 +251,7 @@ func readNativeFrames(d dicomio.Reader, parsedData *Dataset, fc chan<- *frame.Fr } } - bytesRead = (bitsAllocated / 8) * samplesPerPixel * pixelsPerFrame * nFrames + bytesRead = bytesAllocated * samplesPerPixel * pixelsPerFrame * nFrames return &image, bytesRead, nil } diff --git a/read_test.go b/read_test.go index 8cba5b3d..34912731 100644 --- a/read_test.go +++ b/read_test.go @@ -4,7 +4,9 @@ import ( "bufio" "bytes" "encoding/binary" + "errors" "fmt" + "io" "math/rand" "strconv" "testing" @@ -249,6 +251,19 @@ func TestReadNativeFrames(t *testing.T) { }, expectedError: nil, }, + { + Name: "insufficient bytes, uint32", + existingData: Dataset{Elements: []*Element{ + mustNewElement(tag.Rows, []int{2}), + mustNewElement(tag.Columns, []int{2}), + mustNewElement(tag.NumberOfFrames, []string{"2"}), + mustNewElement(tag.BitsAllocated, []int{32}), + mustNewElement(tag.SamplesPerPixel, []int{2}), + }}, + data: []uint16{1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3}, + expectedPixelData: nil, + expectedError: io.ErrUnexpectedEOF, + }, { Name: "missing Columns", existingData: Dataset{Elements: []*Element{ @@ -278,7 +293,7 @@ func TestReadNativeFrames(t *testing.T) { } pixelData, _, err := readNativeFrames(r, &tc.existingData, nil) - if err != tc.expectedError { + if !errors.Is(err, tc.expectedError) { t.Errorf("TestReadNativeFrames(%v): did not get expected error. got: %v, want: %v", tc.data, err, tc.expectedError) }