Menu ▾ ▴

#555 Issues decoding JPEG-LS pixel data

3.1
open
None
5
2024-02-21
2024-02-12
XXX
No

I've found a couple of issues with decompressing JPEG-LS pixel data:

Decoding single sample pixel data with a JPEG-LS precision of 6 or 7 fails, but all other precisions in (2, 16) work.

./gdcmconv -i JLSL_08_07_0_1F.dcm -o out.dcm -w -V
Error: In .../GDCM/Source/MediaStorageAndFileFormat/gdcmJPEGLSCodec.cxx, line 220, function bool gdcm::JPEGLSCodec::DecodeByStreamsCommon(const char*, size_t, std::vector<unsigned char>&)
Could not decode JPEG-LS stream


Error: In .../GDCM/Source/MediaStorageAndFileFormat/gdcmImageChangeTransferSyntax.cxx, line 423, function bool gdcm::ImageChangeTransferSyntax::Change()
Error in getting buffer from input image.


Could not change the Transfer Syntax: ../JLSL_08_07_0_1F.dcm

If the dataset's Bits Allocated is 16, but the JPEG-LS precision (and Bits Stored) is <= 8 then the decompression fails due to a length check:

./gdcmconv -i JLSL_16_08_0_1F.dcm -o out.dcm -w -V
gdcmconv: /home/dean/Coding/src/GDCM/Source/MediaStorageAndFileFormat/gdcmBitmap.cxx:726: bool gdcm::Bitmap::TryJPEGLSCodec(char*, bool&) const: Assertion `len <= outbv->GetLength()' failed.
Aborted

JPEG-LS doesn't track signedness, so when Pixel Representation 1 and Bits Stored/precision is less than Bits Allocated the sign bit is lost on decompression and unsigned values are returned. Incorrect output is seen with gdcmconv -i JLSL_16_15_1_1F.dcm -o out.dcm -w

Attached are minimal test datasets with a JPEG-LS precision of 5, 6, 7 and 8-bits (the four JLSL_08_0X_0_1F.dcm files), a JPEG-LS precision/Bits Stored of 8 and a Bits Allocated of 16 (JLSL_16_08_0_1F.dcm) and a pair of signed Bits Allocated 16, with Bits Stored/precision 15 and 16 (JLSL_16_15_1_1F.dcm and JLSL_16_16_1_1F.dcm).

Thanks!

7 Attachments

Discussion

  • XXX

    XXX - 2024-02-12

    Forgot to mention, this is all with the current master on github (3.1.0?). I've also seen the same behaviour in v3.0.23.

     
  • Mihail Isakov

    Mihail Isakov - 2024-02-19

    ./gdcmconv -i JLSL_08_07_0_1F.dcm -o out.dcm -w -V

    will work if GDCM is compiled with the newer CharLS (GDCM_USE_SYSTEM_CHARLS), as well as the other JLSL_08_ files.

    Found charls version 2.4.1
    
    r@deb2:~/gdcm2/build/bin$ ./gdcmconv -i ~/Downloads/DICOM/bad_jpegls/JLSL_08_07_0_1F.dcm -o out.dcm -w -V
    r@deb2:~/gdcm2/build/bin$
    

    JLSL_16_08_0_1F.dcm seems to have wrong DICOM BitsAllocated, why it is 16, JPEGLS says bitsPerSample = 8. so the issue, not sure.

    I didn't look at 'sign' issue, BTW.

     
  • Mathieu Malaterre

    • assigned_to: Mathieu Malaterre
     
  • Mathieu Malaterre

    @scaramallion could you confirm what I see on my side:

    % for i in /tmp/555/*.dcm; do echo $i && dcmdjpls $i raw.dcm; done
    /tmp/555/JLSL_08_05_0_1F.dcm
    F: Codec received unsupported compression parameters: decompressing file: /tmp/555/JLSL_08_05_0_1F.dcm
    /tmp/555/JLSL_08_06_0_1F.dcm
    F: Invalid compressed image data: decompressing file: /tmp/555/JLSL_08_06_0_1F.dcm
    /tmp/555/JLSL_08_07_0_1F.dcm
    F: Invalid compressed image data: decompressing file: /tmp/555/JLSL_08_07_0_1F.dcm
    /tmp/555/JLSL_08_08_0_1F.dcm
    /tmp/555/JLSL_16_08_0_1F.dcm
    F: Image data mismatch between DICOM header and JPEG-LS bitstream: decompressing file: /tmp/555/JLSL_16_08_0_1F.dcm
    /tmp/555/JLSL_16_15_1_1F.dcm
    W: DcmItem: Length of element (7fe0,0010) is not a multiple of 2 (VR=OW)
    /tmp/555/JLSL_16_16_1_1F.dcm
    W: DcmItem: Length of element (7fe0,0010) is not a multiple of 2 (VR=OW)
    

    In other word, per DCMTK 3.6.9 only two files do not trigger a fatal error: JLSL_16_15_1_1F.dcm & JLSL_16_16_1_1F.dcm.

    Now if I compare GDCM vs DCMTK on JLSL_16_16_1_1F.dcm here is what I get:

    % gdcmconv --raw /tmp/555/JLSL_16_16_1_1F.dcm gdcm.dcm
    % gdcminfo --md5sum gdcm.dcm
    MediaStorage is 1.2.840.10008.5.1.4.1.1.2 [CT Image Storage]
    TransferSyntax is 1.2.840.10008.1.2.1 [Explicit VR Little Endian]
    NumberOfDimensions: 2
    Dimensions: (128,128,1)
    SamplesPerPixel    :1
    BitsAllocated      :16
    BitsStored         :16
    HighBit            :15
    PixelRepresentation:1
    ScalarType found   :INT16
    PhotometricInterpretation: MONOCHROME2
    PlanarConfiguration: 0
    TransferSyntax: 1.2.840.10008.1.2.1
    Origin: (-158.136,-179.036,-75.7)
    Spacing: (0.661468,0.661468,1)
    DirectionCosines: (1,0,0,0,1,0)
    Rescale Intercept/Slope: (-1024,1)
    Orientation Label: AXIAL
    md5sum: 45df16134454b381f79cc64eecdb072c
    

    lead to:

    % dcmdjpls /tmp/555/JLSL_16_16_1_1F.dcm dcmtk.dcm
    W: DcmItem: Length of element (7fe0,0010) is not a multiple of 2 (VR=OW)
    % gdcminfo --md5sum dcmtk.dcm
    MediaStorage is 1.2.840.10008.5.1.4.1.1.2 [CT Image Storage]
    TransferSyntax is 1.2.840.10008.1.2.1 [Explicit VR Little Endian]
    NumberOfDimensions: 2
    Dimensions: (128,128,1)
    SamplesPerPixel    :1
    BitsAllocated      :16
    BitsStored         :16
    HighBit            :15
    PixelRepresentation:1
    ScalarType found   :INT16
    PhotometricInterpretation: MONOCHROME2
    PlanarConfiguration: 0
    TransferSyntax: 1.2.840.10008.1.2.1
    Origin: (-158.136,-179.036,-75.7)
    Spacing: (0.661468,0.661468,1)
    DirectionCosines: (1,0,0,0,1,0)
    Rescale Intercept/Slope: (-1024,1)
    Orientation Label: AXIAL
    md5sum: 45df16134454b381f79cc64eecdb072c
    

    Could you rephrase your bug report and help me understand what you output you are expecting on JLSL_16_16_1_1F.dcm ? Thanks

     
  • Mathieu Malaterre

    Sorry I realized that JLSL_08_08_0_1F.dcm ought to work (per DCMTK). Here is what I see using gdcm from Debian/stable:

    % gdcmconv --raw /tmp/555/JLSL_08_08_0_1F.dcm gdcm.dcm
    % gdcminfo --md5sum gdcm.dcm
    MediaStorage is 1.2.840.10008.5.1.4.1.1.7 [Secondary Capture Image Storage]
    TransferSyntax is 1.2.840.10008.1.2.1 [Explicit VR Little Endian]
    NumberOfDimensions: 2
    Dimensions: (128,128,1)
    SamplesPerPixel    :1
    BitsAllocated      :8
    BitsStored         :8
    HighBit            :7
    PixelRepresentation:0
    ScalarType found   :UINT8
    PhotometricInterpretation: MONOCHROME2
    PlanarConfiguration: 0
    TransferSyntax: 1.2.840.10008.1.2.1
    Origin: (0,0,0)
    Spacing: (1,1,1)
    DirectionCosines: (1,0,0,0,1,0)
    Rescale Intercept/Slope: (0,1)
    Orientation Label: AXIAL
    md5sum: 56d2233ba12ad749f073b80e9a31d936
    
     

Log in to post a comment.