|
29 | 29 | // ErrorUnsupportedBitsAllocated indicates that the BitsAllocated in the |
30 | 30 | // NativeFrame PixelData is unsupported. In this situation, the rest of the |
31 | 31 | // dataset returned is still valid. |
32 | | - ErrorUnsupportedBitsAllocated = errors.New("unsupported BitsAllocated") |
33 | | - errorUnableToParseFloat = errors.New("unable to parse float type") |
34 | | - ErrorExpectedEvenLength = errors.New("field length is not even, in violation of DICOM spec") |
| 32 | + ErrorUnsupportedBitsAllocated = errors.New("unsupported BitsAllocated") |
| 33 | + errorUnableToParseFloat = errors.New("unable to parse float type") |
| 34 | + ErrorExpectedEvenLength = errors.New("field length is not even, in violation of DICOM spec") |
| 35 | + ErrorExpectedDefinedLength = errors.New("unable to read field of undefined length") |
| 36 | + ErrorExpectedSequenceDelimitation = errors.New("expected to find sequence delimitation item (fffe,e0dd)") |
35 | 37 | ) |
36 | 38 |
|
37 | 39 | // reader is responsible for mid-level dicom parsing capabilities, like |
@@ -122,6 +124,9 @@ func (r *reader) readValue(t tag.Tag, vr string, vl uint32, isImplicit bool, d * |
122 | 124 | // TODO: if we keep consistent function signature, consider a static map of VR to func? |
123 | 125 | switch vrkind { |
124 | 126 | case tag.VRBytes: |
| 127 | + if vl == tag.VLUndefinedLength { |
| 128 | + return r.readUndefinedLengthByteValue() |
| 129 | + } |
125 | 130 | return r.readBytes(t, vr, vl) |
126 | 131 | case tag.VRString: |
127 | 132 | return r.readString(t, vr, vl) |
@@ -154,6 +159,34 @@ func (r *reader) readValue(t tag.Tag, vr string, vl uint32, isImplicit bool, d * |
154 | 159 | } |
155 | 160 | } |
156 | 161 |
|
| 162 | +// readUndefinedLengthByteValue reads a value of type OB or OW of undefined length. |
| 163 | +// see https://github.com/suyashkumar/dicom/issues/349 for details. |
| 164 | +// pixel data should not use this and instead use readPixelData. |
| 165 | +func (r *reader) readUndefinedLengthByteValue() (Value, error) { |
| 166 | + var allData []byte |
| 167 | + foundDelimeter := false |
| 168 | + |
| 169 | + for !r.rawReader.IsLimitExhausted() { |
| 170 | + data, terminated, err := r.readRawItem(false) |
| 171 | + if err != nil { |
| 172 | + return nil, fmt.Errorf("error reading undefined byte value: %w", err) |
| 173 | + } |
| 174 | + |
| 175 | + if terminated { |
| 176 | + foundDelimeter = true |
| 177 | + break |
| 178 | + } |
| 179 | + |
| 180 | + allData = append(allData, data...) |
| 181 | + } |
| 182 | + |
| 183 | + if !foundDelimeter { |
| 184 | + return nil, ErrorExpectedSequenceDelimitation |
| 185 | + } |
| 186 | + |
| 187 | + return &bytesValue{value: allData}, nil |
| 188 | +} |
| 189 | + |
157 | 190 | // readHeader reads the DICOM magic header and group two metadata elements. |
158 | 191 | // This should only be called once per DICOM at the start of parsing. |
159 | 192 | func (r *reader) readHeader() ([]*Element, error) { |
@@ -641,6 +674,10 @@ func (r *reader) readSequenceItem(t tag.Tag, vr string, vl uint32, d *Dataset) ( |
641 | 674 | } |
642 | 675 |
|
643 | 676 | func (r *reader) readBytes(t tag.Tag, vr string, vl uint32) (Value, error) { |
| 677 | + if vl == tag.VLUndefinedLength { |
| 678 | + return nil, ErrorExpectedDefinedLength |
| 679 | + } |
| 680 | + |
644 | 681 | // TODO: add special handling of PixelData |
645 | 682 | if vr == vrraw.OtherByte || vr == vrraw.Unknown { |
646 | 683 | data := make([]byte, vl) |
@@ -672,6 +709,10 @@ func (r *reader) readBytes(t tag.Tag, vr string, vl uint32) (Value, error) { |
672 | 709 | } |
673 | 710 |
|
674 | 711 | func (r *reader) readString(t tag.Tag, vr string, vl uint32) (Value, error) { |
| 712 | + if vl == tag.VLUndefinedLength { |
| 713 | + return nil, ErrorExpectedDefinedLength |
| 714 | + } |
| 715 | + |
675 | 716 | str, err := r.rawReader.ReadString(vl) |
676 | 717 | if err != nil { |
677 | 718 | return nil, fmt.Errorf("error reading string element (%v) value: %w", t, err) |
@@ -821,12 +862,11 @@ func (r *reader) readElement(d *Dataset, fc chan<- *frame.Frame) (*Element, erro |
821 | 862 | } |
822 | 863 |
|
823 | 864 | return &Element{Tag: *t, ValueRepresentation: tag.GetVRKind(*t, vr), RawValueRepresentation: vr, ValueLength: vl, Value: val}, nil |
824 | | - |
825 | 865 | } |
826 | 866 |
|
827 | 867 | // Read an Item object as raw bytes, useful when parsing encapsulated PixelData. |
828 | 868 | // This returns the read raw item, an indication if this is the end of the set |
829 | | -// of items, and a possible errorawReader. |
| 869 | +// of items, and a possible error. |
830 | 870 | func (r *reader) readRawItem(shouldSkip bool) ([]byte, bool, error) { |
831 | 871 | t, err := r.readTag() |
832 | 872 | if err != nil { |
|
0 commit comments