Skip to content

BUG: DCMTK reader wrongly rejects file with preamble#4501

Merged
thewtex merged 3 commits intoInsightSoftwareConsortium:masterfrom
thewtex:4801-dcmtk-preamble
Mar 14, 2024
Merged

BUG: DCMTK reader wrongly rejects file with preamble#4501
thewtex merged 3 commits intoInsightSoftwareConsortium:masterfrom
thewtex:4801-dcmtk-preamble

Conversation

@thewtex
Copy link
Copy Markdown
Member

@thewtex thewtex commented Mar 11, 2024

A previous optimization didn't take into account the preamble of a dicom file. This adds a check.

Fixes #4108

@github-actions github-actions Bot added type:Bug Inconsistencies or issues which will cause an incorrect result under some or all circumstances area:IO Issues affecting the IO module labels Mar 11, 2024
@thewtex thewtex force-pushed the 4801-dcmtk-preamble branch from c8850bb to 0c9fd3d Compare March 11, 2024 02:07
@thewtex thewtex requested review from jhlegarreta and pieper March 11, 2024 02:10
Comment thread Modules/IO/DCMTK/src/itkDCMTKImageIO.cxx Outdated
Comment thread Modules/IO/DCMTK/src/itkDCMTKImageIO.cxx Outdated
@thewtex
Copy link
Copy Markdown
Member Author

thewtex commented Mar 11, 2024

Great suggestions, @N-Dekker , added.

@thewtex thewtex force-pushed the 4801-dcmtk-preamble branch from 0c9fd3d to 4606503 Compare March 11, 2024 19:09
@thewtex thewtex requested a review from fedorov March 11, 2024 19:40
@N-Dekker
Copy link
Copy Markdown
Contributor

Fixes #4801

Are you sure it's issue 4801? I cannot find it 🤷

Copy link
Copy Markdown
Member

@jhlegarreta jhlegarreta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can a minimal test be added if an appropriate dataset can be found, please?

@thewtex
Copy link
Copy Markdown
Member Author

thewtex commented Mar 11, 2024

@pieper do you have a test file?

@issakomi
Copy link
Copy Markdown
Member

issakomi commented Mar 12, 2024

Can a minimal test be added if an appropriate dataset can be found, please?

Almost every DICOM file has the "preamble". There are old ACR-NEMA files without preamble / prefix / header (0x0002 group).
Strictly speaking, the preamble consists of 128 (zero) bytes at the beginning (reserved), and the subsequent 4 bytes "DICM" are called the prefix.
https://dicom.nema.org/medical/dicom/current/output/chtml/part10/chapter_7.html

Here is one without preamble and prefix, starts with the header (0x0002 group), specially for testing purposes. Most DICOM viewers can open it. It is also 'dciodvfy' clean.
https://data.kitware.com/#item/65efb5f18353a45974ec399b

Edit:
Here is one tiny and 'dciodvfy' clean file with correct preamble/prefix, just for simplicity, if a dedicated test is required. But again, every modern DICOM file should have this
https://data.kitware.com/#item/65efb9518353a45974ec399e

@issakomi
Copy link
Copy Markdown
Member

Fixes #4801

Are you sure it's issue 4801? I cannot find it 🤷

#4108

pieper and others added 2 commits March 12, 2024 14:57
A previous optimization didn't take into account the preamble
of a dicom file. This adds a check.

Fixes InsightSoftwareConsortium#4108.
Both GDCM and DCMTK.

Related to InsightSoftwareConsortium#4108.

From @issakomi:

> Almost every DICOM file has the "preamble". There are old ACR-NEMA files without preamble / prefix / header (0x0002 group).
> Strictly speaking, the preamble consists of 128 (zero) bytes at the beginning (reserved), and the subsequent 4 bytes "DICM" are called the prefix.
> https://dicom.nema.org/medical/dicom/current/output/chtml/part10/chapter_7.html
>
> Here is one without preamble and prefix, starts with the header (0x0002 group), specially for testing purposes. Most DICOM viewers can open it. It is also 'dciodvfy' clean.
> https://data.kitware.com/#item/65efb5f18353a45974ec399b
>
> Here is one tiny and 'dciodvfy' clean file with correct preamble/prefix, just for simplicity, if a dedicated test is required. But again, every modern DICOM file should have this
> https://data.kitware.com/#item/65efb9518353a45974ec399e
@thewtex
Copy link
Copy Markdown
Member Author

thewtex commented Mar 12, 2024

@issakomi awesome, thank you! I added tests accordingly for both GDCM, DCMTK.

@thewtex thewtex force-pushed the 4801-dcmtk-preamble branch from 4606503 to 8427bbe Compare March 12, 2024 19:24
@github-actions github-actions Bot added the type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots label Mar 12, 2024
@issakomi
Copy link
Copy Markdown
Member

issakomi commented Mar 13, 2024

Please give me some time for more test. I am not sure that we have tested DCMTKIO CanReadFile. It seems to reject no_preamble.dcm. The name of the PR is a little bit not precise. The DCMTKIO reader doesn't reject files with preamble. DCMTKIO CanReadFile returns false for usual and valid files with preamble, but it is usually not invoked at all, only if a user calls it explicitly.

@issakomi
Copy link
Copy Markdown
Member

issakomi commented Mar 13, 2024

Here is test with CanReadFile and readers for both DCMTKIO and GDCMIO.


r@deb2:~/tmp/test11/build$ ./test ../data/preamble.dcm 

DCMTKIO CanReadFile(../data/preamble.dcm): false

GDCMIO CanReadFile(../data/preamble.dcm): true

Failure for DCMTK CanReadFile with preamble will be fixed by this PR


r@deb2:~/tmp/test11/build$ ./test ../data/no_preamble.dcm 

DCMTKIO CanReadFile(../data/no_preamble.dcm): false

GDCMIO CanReadFile(../data/no_preamble.dcm): false

Not sure that it is important, no_preamble.dcm is synthetic, but both readers work with it.


r@deb2:~/tmp/test11/build$ ./test ../data/SIEMENS_GBS_III-16-ACR_NEMA_1.acr 
No DICOM magic number found, but the file appears to be DICOM without a preamble.
Proceeding without caution.
DCMTKIO CanReadFile(../data/SIEMENS_GBS_III-16-ACR_NEMA_1.acr): false
DCMTKIO reader failed
ITK ERROR: DCMTKImageIO(0x564451eb2bf0): Missing Image Data in ../data/SIEMENS_GBS_III-16-ACR_NEMA_1.acr
No DICOM magic number found, but the file appears to be DICOM without a preamble.
Proceeding without caution.
GDCMIO CanReadFile(../data/SIEMENS_GBS_III-16-ACR_NEMA_1.acr): true

SIEMENS_GBS_III-16-ACR_NEMA_1.acr is real ACR-NEMA file, DCMTKIO reader fails (and CanReadFile too).


#include "itkImage.h"
#include "itkDCMTKImageIO.h"
#include "itkGDCMImageIO.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include <iostream>

int main(int argc, char ** argv)
{
  if (argc < 2)
  {
    std::cout << "Filename is required" << std::endl;
  }
  {
    using ImageType = itk::Image<short, 2>;
    using ImageIOType = itk::DCMTKImageIO;
    auto io = ImageIOType::New();

    ////////////////////////////////////////////////////////////////////////
    //
    // Bug https://github.com/InsightSoftwareConsortium/ITK/issues/4108
    //
    try
    {
      const bool r = io->CanReadFile(argv[1]);
      std::cout << "\nDCMTKIO CanReadFile(" << argv[1] << "): " << (r ? "true" : "false") << std::endl;
    }
    catch (const itk::ExceptionObject & e)
    {
      std::cout << e.GetDescription() << std::endl;
    }
    //
    //
    ////////////////////////////////////////////////////////////////////////

    itk::ImageFileReader<ImageType>::Pointer reader = itk::ImageFileReader<ImageType>::New();
    reader->SetImageIO(io);
    reader->SetFileName(argv[1]);
    try
    {
      reader->Update();
    }
    catch (const itk::ExceptionObject & e)
    {
      std::cout << "DCMTKIO reader failed\n" << e.GetDescription() << std::endl;
    }
  }
  //
  {
    using ImageType = itk::Image<short, 2>;
    using ImageIOType = itk::GDCMImageIO;
    auto io = ImageIOType::New();

    ////////////////////////////////////////////////////////////////////////
    //
    //
    try
    {
      const bool r = io->CanReadFile(argv[1]);
      std::cout << "\nGDCMIO CanReadFile(" << argv[1] << "): " << (r ? "true" : "false") << std::endl;
    }
    catch (const itk::ExceptionObject & e)
    {
      std::cout << e.GetDescription() << std::endl;
    }
    //
    //
    ////////////////////////////////////////////////////////////////////////

    itk::ImageFileReader<ImageType>::Pointer reader = itk::ImageFileReader<ImageType>::New();
    reader->SetImageIO(io);
    reader->SetFileName(argv[1]);
    try
    {
      reader->Update();
    }
    catch (const itk::ExceptionObject & e)
    {
      std::cout << "GDCMIO reader failed\n" << e.GetDescription() << std::endl;
    }
  }
  return 0;
}

Edit: updated image type to short, but it doesn't change anything, just for correctness (ACR-NEMA test file is 16 bits allocated)

Copy link
Copy Markdown
Member

@issakomi issakomi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved for clarity. Despite of issues reported above, the PR is a step in the right direction.

Testing coverage for InsightSoftwareConsortium#4108. We are re-using the test coverage of
CanReadFile in the no-preamble test to ensure that files with a
preamble are also evaluated correctly.
@thewtex
Copy link
Copy Markdown
Member Author

thewtex commented Mar 13, 2024

@issakomi thank you for helping us progress forward in the right direction on this!!

I added a few more tests that improve our coverage based on your remarks.

@thewtex
Copy link
Copy Markdown
Member Author

thewtex commented Mar 13, 2024

/azp run ITK.macOS

@thewtex thewtex merged commit be79ceb into InsightSoftwareConsortium:master Mar 14, 2024
@thewtex thewtex deleted the 4801-dcmtk-preamble branch March 14, 2024 14:53
@N-Dekker N-Dekker mentioned this pull request Mar 18, 2024
7 tasks
hjmjohnson pushed a commit to hjmjohnson/ITK that referenced this pull request May 6, 2026
…cmtk-preamble

BUG: DCMTK reader wrongly rejects file with preamble
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:IO Issues affecting the IO module type:Bug Inconsistencies or issues which will cause an incorrect result under some or all circumstances type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DCMTK reader fails for valid files

5 participants