# HG changeset patch # User Sebastien Jodogne # Date 1550740872 -3600 # Node ID 9b0e67161600a3c83d47f1d592ab9b80385fe5b2 # Parent 5cd4c672d63c983261263105a49cfb29fb903494 More tolerance wrt. invalid DICOM files that must be returned by Orthanc C-FIND SCP diff -r 5cd4c672d63c -r 9b0e67161600 Core/DicomNetworking/DicomFindAnswers.cpp --- a/Core/DicomNetworking/DicomFindAnswers.cpp Wed Feb 20 17:21:39 2019 +0100 +++ b/Core/DicomNetworking/DicomFindAnswers.cpp Thu Feb 21 10:21:12 2019 +0100 @@ -119,7 +119,10 @@ void DicomFindAnswers::Add(const DicomMap& map) { - AddAnswerInternal(new ParsedDicomFile(map, encoding_)); + // We use the permissive mode to be tolerant wrt. invalid DICOM + // files that contain some tags with out-of-range values (such + // tags are removed from the answers) + AddAnswerInternal(new ParsedDicomFile(map, encoding_, true /* permissive */)); } diff -r 5cd4c672d63c -r 9b0e67161600 Core/DicomParsing/ParsedDicomFile.cpp --- a/Core/DicomParsing/ParsedDicomFile.cpp Wed Feb 20 17:21:39 2019 +0100 +++ b/Core/DicomParsing/ParsedDicomFile.cpp Thu Feb 21 10:21:12 2019 +0100 @@ -956,7 +956,8 @@ void ParsedDicomFile::CreateFromDicomMap(const DicomMap& source, - Encoding defaultEncoding) + Encoding defaultEncoding, + bool permissive) { pimpl_->file_.reset(new DcmFileFormat); @@ -998,24 +999,35 @@ if (it->first != DICOM_TAG_SPECIFIC_CHARACTER_SET && !it->second->IsNull()) { - ReplacePlainString(it->first, it->second->GetContent()); + try + { + ReplacePlainString(it->first, it->second->GetContent()); + } + catch (OrthancException&) + { + if (!permissive) + { + throw; + } + } } } } ParsedDicomFile::ParsedDicomFile(const DicomMap& map, - Encoding defaultEncoding) : + Encoding defaultEncoding, + bool permissive) : pimpl_(new PImpl) { - CreateFromDicomMap(map, defaultEncoding); + CreateFromDicomMap(map, defaultEncoding, permissive); } ParsedDicomFile::ParsedDicomFile(const DicomMap& map) : pimpl_(new PImpl) { - CreateFromDicomMap(map, GetDefaultDicomEncoding()); + CreateFromDicomMap(map, GetDefaultDicomEncoding(), false /* be strict by default */); } diff -r 5cd4c672d63c -r 9b0e67161600 Core/DicomParsing/ParsedDicomFile.h --- a/Core/DicomParsing/ParsedDicomFile.h Wed Feb 20 17:21:39 2019 +0100 +++ b/Core/DicomParsing/ParsedDicomFile.h Thu Feb 21 10:21:12 2019 +0100 @@ -81,7 +81,8 @@ bool keepSopInstanceUid); void CreateFromDicomMap(const DicomMap& source, - Encoding defaultEncoding); + Encoding defaultEncoding, + bool permissive); void RemovePrivateTagsInternal(const std::set* toKeep); @@ -97,7 +98,8 @@ ParsedDicomFile(bool createIdentifiers); // Create a minimal DICOM instance ParsedDicomFile(const DicomMap& map, - Encoding defaultEncoding); + Encoding defaultEncoding, + bool permissive); ParsedDicomFile(const DicomMap& map); diff -r 5cd4c672d63c -r 9b0e67161600 NEWS --- a/NEWS Wed Feb 20 17:21:39 2019 +0100 +++ b/NEWS Thu Feb 21 10:21:12 2019 +0100 @@ -9,6 +9,7 @@ * Basic support for character sets with code extensions (ISO 2022 escape sequences) * Fix issue #134 (/patient/modify gives 500, should really be 400) * Support of SOP classes: BreastProjectionXRayImageStorageForProcessing/Presentation +* More tolerance wrt. invalid DICOM files that must be returned by Orthanc C-FIND SCP Version 1.5.4 (2019-02-08) diff -r 5cd4c672d63c -r 9b0e67161600 UnitTestsSources/FromDcmtkTests.cpp --- a/UnitTestsSources/FromDcmtkTests.cpp Wed Feb 20 17:21:39 2019 +0100 +++ b/UnitTestsSources/FromDcmtkTests.cpp Thu Feb 21 10:21:12 2019 +0100 @@ -1126,7 +1126,7 @@ { DicomMap m; - ParsedDicomFile dicom(m, Encoding_Latin4); + ParsedDicomFile dicom(m, Encoding_Latin4, false); ASSERT_EQ(1u, dicom.GetDcmtkObject().getDataset()->card()); CheckEncoding(dicom, Encoding_Latin4); } @@ -1142,7 +1142,7 @@ { DicomMap m; m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, "ISO_IR 148", false); - ParsedDicomFile dicom(m, Encoding_Latin1); + ParsedDicomFile dicom(m, Encoding_Latin1, false); ASSERT_EQ(1u, dicom.GetDcmtkObject().getDataset()->card()); CheckEncoding(dicom, Encoding_Latin5); } @@ -1192,7 +1192,7 @@ DicomMap m; m.SetValue(DICOM_TAG_PATIENT_NAME, testEncodingsExpected[i], false); - ParsedDicomFile dicom(m, testEncodings[i]); + ParsedDicomFile dicom(m, testEncodings[i], false); const char* encoded = NULL; ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->findAndGetString(DCM_PatientName, encoded).good()); @@ -1212,7 +1212,7 @@ m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, GetDicomSpecificCharacterSet(testEncodings[i]), false); m.SetValue(DICOM_TAG_PATIENT_NAME, testEncodingsExpected[i], false); - ParsedDicomFile dicom(m, testEncodings[i]); + ParsedDicomFile dicom(m, testEncodings[i], false); Json::Value v2; dicom.DatasetToJson(v2, DicomToJsonFormat_Human, DicomToJsonFlags_Default, 0); @@ -1237,7 +1237,7 @@ std::string tag; - ParsedDicomFile dicom(m, Encoding_Utf8); + ParsedDicomFile dicom(m, Encoding_Utf8, false); bool hasCodeExtensions; ASSERT_EQ(Encoding_Utf8, dicom.DetectEncoding(hasCodeExtensions)); ASSERT_FALSE(hasCodeExtensions); @@ -1288,7 +1288,7 @@ DicomMap m; m.SetValue(DICOM_TAG_PATIENT_NAME, "HELLO", false); - ParsedDicomFile d(m, Encoding_Latin3 /* default encoding */); + ParsedDicomFile d(m, Encoding_Latin3 /* default encoding */, false); bool hasCodeExtensions; ASSERT_EQ(Encoding_Latin3, d.DetectEncoding(hasCodeExtensions)); @@ -1301,7 +1301,7 @@ m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, "ISO_IR 13", false); m.SetValue(DICOM_TAG_PATIENT_NAME, "HELLO", false); - ParsedDicomFile d(m, Encoding_Latin3 /* default encoding */); + ParsedDicomFile d(m, Encoding_Latin3 /* default encoding */, false); bool hasCodeExtensions; ASSERT_EQ(Encoding_Japanese, d.DetectEncoding(hasCodeExtensions)); @@ -1314,7 +1314,7 @@ m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, "nope", false); m.SetValue(DICOM_TAG_PATIENT_NAME, "HELLO", false); - ASSERT_THROW(ParsedDicomFile d(m, Encoding_Latin3), OrthancException); + ASSERT_THROW(ParsedDicomFile d(m, Encoding_Latin3, false), OrthancException); } { @@ -1323,7 +1323,7 @@ m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, "ISO_IR 13", true); m.SetValue(DICOM_TAG_PATIENT_NAME, "HELLO", false); - ASSERT_THROW(ParsedDicomFile d(m, Encoding_Latin3), OrthancException); + ASSERT_THROW(ParsedDicomFile d(m, Encoding_Latin3, false), OrthancException); } { @@ -1333,7 +1333,7 @@ m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, "", false); m.SetValue(DICOM_TAG_PATIENT_NAME, "HELLO", false); - ParsedDicomFile d(m, Encoding_Latin3 /* default encoding */); + ParsedDicomFile d(m, Encoding_Latin3 /* default encoding */, false); bool hasCodeExtensions; ASSERT_EQ(Encoding_Latin3, d.DetectEncoding(hasCodeExtensions));