Encountering undefined Behavior when writing DICOM images

Hello everyone,

I am currently encountering undefined behavior when trying to write a DICOM series with headers taken from another series. I use only the gdcmIO and loop through all files to read the header with ReadImageInformation() and modify the slope and intercept of the header because it appears to be faster than the regular series reader.

    // Sorting input DICOM files with gdcm IO 
	std::cout << "Sorting all DICOM files with gdcm IO...:";
	NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
	nameGenerator->SetInputDirectory(inputDICOMDir);
	FileNamesContainer fileNames = nameGenerator->GetInputFileNames();

	// MetaDataDictionary Array
	std::vector<itk::MetaDataDictionary*> fullMetaDataDictionaryArray;
	std::vector<itk::MetaDataDictionary> allDictionaries;

	std::cout << "Reading all Headers with gdcm IO...:";

	// DICOM IO for Single file
	ImageIOType::Pointer dcmIOsingleFiles = ImageIOType::New();

	// Read files one by one
	// Read all headers of all DICOM files in fileNames
	for (std::string filename : fileNames) {
		dcmIOsingleFiles->SetFileName(filename);
		dcmIOsingleFiles->ReadImageInformation();

		// Slope and Intercept fix
		itk::MetaDataDictionary& sliceDictionary = dcmIOsingleFiles->GetMetaDataDictionary();
		itk::EncapsulateMetaData<std::string>(sliceDictionary, DICOMTag_slope, "1");
		itk::EncapsulateMetaData<std::string>(sliceDictionary, DICOMTag_intercept, "0");

		allDictionaries.push_back(sliceDictionary);
	}

Now, I prepare the vector for providing it to the writer, where all pointers to the itk::MetaDataDictionarys are stored. Everything works fine, till i reach the Update() call of the writer, where the program just closes without any further info. Both vectors are not empty either, I checked them before. Also they don’t go out of scope, so that should not be an issue i suppose?

    for (int dictonary = 0; dictonary < allDictionaries.size(); dictonary++)
	{
		fullMetaDataDictionaryArray.push_back(&allDictionaries[dictonary]);
	}

	// Write Series
	Series4DWriterType::Pointer seriesWriter = Series4DWriterType::New();
	seriesWriter->SetInput(reader->GetOutput());
	seriesWriter->SetImageIO(dcmIOsingleFiles);
	seriesWriter->SetFileNames(namesGenerator->GetFileNames());
	seriesWriter->SetMetaDataDictionaryArray(&fullMetaDataDictionaryArray);

	try {
		seriesWriter->Update();
	}
	catch (const itk::ExceptionObject& err) {
		std::cerr << "ExceptionObject caught!" << std::endl;
		std::cerr << err << std::endl;
		return EXIT_FAILURE;
	}

Can anybody tell me what the problem may be? Am I using the header reading of the GDCM object wrong? Should i stick to read the series via a regular series reader and transfer the header?

I am using ITK 5.2.1 with Visual Studio 2019.

Thank you so much in advance, as usual. :slight_smile:

Have you tried also catching std::runtime_error? An example here:

Problem might be reading too. Have you called reader->Update();? Does that go smoothly?

1 Like

Thank you for the rapid response.

Yes, i update the reader explicitly:

    ReaderType::Pointer reader = ReaderType::New();
	reader->SetFileName(inputFilename);
	std::cout << "Reading input data: <" << inputFilename << ">...";
	try {
		reader->Update();
	}
	catch (const itk::ExceptionObject& excp) {
		std::cerr << "Exception thrown while reading the image" << std::endl;
		std::cerr << excp << std::endl;
		return EXIT_FAILURE;
	}

This works perfectly without any issues and errors.

I just added the runtimer_error exception block but still, without any error the program closes…

   try {
   	seriesWriter->Update();
   }
   catch (const itk::ExceptionObject& err) {
   	std::cerr << "ExceptionObject caught!" << std::endl;
   	std::cerr << err << std::endl;
   	return EXIT_FAILURE;
   }
   catch (std::runtime_error& err)
   {
   	std::cerr << err.what();
   	return EXIT_FAILURE;
   }
   catch (...)
   {
   	std::cerr << "Unknown error has occurred" << std::endl;
   	return EXIT_FAILURE;
   }

Maybe something else to check?
Thanks again!

Search for std::terminate() and exit() function invocations in GDCM code :smiley:. Or step through the code using a debugger.

1 Like

Ok, I’ll see if i find something. :smiley:
And report back if I do…

Thanks :slight_smile:

@dzenanz, and anyone curious, analyzing it with the debugger prompted following error:

HEAP CORRUPTION DETECTED: after Normal block (#133158230) at 0x000001A80A036040.
CRT detected that the application wrote to memory after end of heap buffer.

Apparently dcmIOsingleFiles is the problem. If I create and use another ImageIO besides this one, I do not get any error or crash…