suyashkumar / dicom

⚡High Performance DICOM Medical Image Parser in Go.
MIT License
950 stars 138 forks source link

Failed to parse DICOM file with TransferSyntaxUID JPEG 2000 (Lossless only) (1.2.840.10008.1.2.4.90) #207

Open favadi opened 3 years ago

favadi commented 3 years ago

I have a DICOM file, that embed JPEG 2000 (Lossless only) image, could not be parsed by suyashkumar/dicom but can be view as normal by Horos.

It can be reproducible with following codes:

package dicom

import (
    "testing"
)

func TestMyDICOMFile(t *testing.T) {
    const dicomFilePath = "<path-to-file>.dcm"
    dataset, err := ParseFile(dicomFilePath, nil)
    if err != nil {
        t.Fatal(err)
    }
    t.Log(dataset)
}

The error:

=== RUN   TestMyDICOMFile
2021/06/23 15:15:23 error reading value  unexpected EOF
2021/06/23 15:15:23 error reading value  unexpected EOF
2021/06/23 15:15:23 error reading subitem,  unexpected EOF
2021/06/23 15:15:23 error reading value  unexpected EOF
2021/06/23 15:15:23 error reading value  unexpected EOF
2021/06/23 15:15:23 error reading subitem,  unexpected EOF
2021/06/23 15:15:23 error reading value  unexpected EOF
2021/06/23 15:15:23 error reading value  unexpected EOF
2021/06/23 15:15:23 error reading subitem,  unexpected EOF
2021/06/23 15:15:23 error reading value  unexpected EOF

Examining the file with dcmdump command:

        (0009,1010) SQ (Sequence with undefined length #=1)     # u/l, 1 Unknown Tag & Data
          (fffe,e000) na (Item with undefined length #=19)        # u/l, 1 Item
            (0028,0002) US 1                                        #   2, 1 SamplesPerPixel
            (0028,0004) CS [MONOCHROME2]                            #  12, 1 PhotometricInterpretation
            (0028,0006) US 0                                        #   2, 1 PlanarConfiguration
            (0028,0010) US 128                                      #   2, 1 Rows
            (0028,0011) US 128                                      #   2, 1 Columns
            (0028,0100) US 16                                       #   2, 1 BitsAllocated
            (0028,0101) US 12                                       #   2, 1 BitsStored
            (0028,0102) US 11                                       #   2, 1 HighBit
            (0028,0103) US 0                                        #   2, 1 PixelRepresentation
            (0028,0107) US 2675                                     #   2, 1 LargestImagePixelValue
            (0028,1052) DS [-1024]                                  #   6, 1 RescaleIntercept
            (0028,1053) DS [1]                                      #   2, 1 RescaleSlope
            (0029,0010) LO [GEIIS]                                  #   6, 1 PrivateCreator
            (0029,1010) UL 0                                        #   4, 1 Unknown Tag & Data
            (0029,1012) UL 0                                        #   4, 1 Unknown Tag & Data
            (0029,1014) UL 1                                        #   4, 1 Unknown Tag & Data
            (7fd1,0010) LO [GEIIS]                                  #   6, 1 PrivateCreator
            (7fd1,1010) UL 26                                       #   4, 1 Unknown Tag & Data
            (7fe0,0010) OW                                      ... # 10132, 1 PixelData

Debugging shows that the error happens when parser try to read the pixel data in https://github.com/suyashkumar/dicom/blob/afbab016d495fe23b0b85099acdc5bfcf591e50b/read.go#L164.

The parser expects that there is 32768 bytes of pixel data, as according to the header.

totalBytes = Rows * Columns * BitsAllocated / 8 * SamplesPerPixel
                  = 128    * 128          *                   16 / 8 * 1
                  = 32768

The error happens when the parser ignores the VL of PixelData (10132) and tries to read 32768 bytes of pixel data.

Questions:

suyashkumar commented 5 months ago

Hey! This may be a duplicate of #85. The tl;dr is that for JPEG LS, yes there's a special processing that's needed since Go std lib doesn't support it.

That said, if it's jpeg ls data that should be encapsulated pixel data, so not sure why it's dispatching to readNativeFrames. Are you sure this is a JPEG-LS image?