changeset 4007:884b55ce01f6

Private tags returned by C-FIND SCP
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 06 Jun 2020 14:50:21 +0200
parents 55710d73780f
children 2d4427ca4be9 914b15dedae3
files Core/DicomNetworking/DicomControlUserConnection.cpp Core/DicomNetworking/DicomFindAnswers.cpp Core/DicomParsing/FromDcmtkBridge.cpp Core/DicomParsing/ParsedDicomFile.cpp Core/DicomParsing/ParsedDicomFile.h NEWS OrthancServer/DicomInstanceToStore.cpp OrthancServer/OrthancFindRequestHandler.cpp UnitTestsSources/FromDcmtkTests.cpp
diffstat 9 files changed, 60 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/Core/DicomNetworking/DicomControlUserConnection.cpp	Sat Jun 06 11:21:39 2020 +0200
+++ b/Core/DicomNetworking/DicomControlUserConnection.cpp	Sat Jun 06 14:50:21 2020 +0200
@@ -215,11 +215,13 @@
           }
         }
 
-        return new ParsedDicomFile(*fix, GetDefaultDicomEncoding(), false /* be strict */);
+        return new ParsedDicomFile(*fix, GetDefaultDicomEncoding(),
+                                   false /* be strict */, "" /* no private creator */);
       }
 
       default:
-        return new ParsedDicomFile(fields, GetDefaultDicomEncoding(), false /* be strict */);
+        return new ParsedDicomFile(fields, GetDefaultDicomEncoding(),
+                                   false /* be strict */, "" /* no private creator */);
     }
   }
 
@@ -475,9 +477,8 @@
     }
     else
     {
-      query.reset(new ParsedDicomFile(originalFields,
-                                      GetDefaultDicomEncoding(),
-                                      false /* be strict */));
+      query.reset(new ParsedDicomFile(originalFields, GetDefaultDicomEncoding(),
+                                      false /* be strict */, "" /* no private creator */));
     }
     
     DcmDataset* dataset = query->GetDcmtkObject().getDataset();
--- a/Core/DicomNetworking/DicomFindAnswers.cpp	Sat Jun 06 11:21:39 2020 +0200
+++ b/Core/DicomNetworking/DicomFindAnswers.cpp	Sat Jun 06 14:50:21 2020 +0200
@@ -122,7 +122,8 @@
     // 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 */));
+    AddAnswerInternal(new ParsedDicomFile(map, encoding_, true /* permissive */,
+                                          "" /* no private creator */));
   }
 
 
--- a/Core/DicomParsing/FromDcmtkBridge.cpp	Sat Jun 06 11:21:39 2020 +0200
+++ b/Core/DicomParsing/FromDcmtkBridge.cpp	Sat Jun 06 14:50:21 2020 +0200
@@ -1717,10 +1717,17 @@
 
       case Json::arrayValue:
       {
-        DcmTag key(tag.GetGroup(), tag.GetElement());
+        const char* p = NULL;
+        if (!privateCreator.empty())
+        {
+          p = privateCreator.c_str();
+        }
+        
+        DcmTag key(tag.GetGroup(), tag.GetElement(), p);
         if (key.getEVR() != EVR_SQ)
         {
-          throw OrthancException(ErrorCode_BadParameterType, "Bad Parameter type for tag " + tag.Format());
+          throw OrthancException(ErrorCode_BadParameterType,
+                                 "Bad Parameter type for tag " + tag.Format());
         }
 
         DcmSequenceOfItems* sequence = new DcmSequenceOfItems(key);
--- a/Core/DicomParsing/ParsedDicomFile.cpp	Sat Jun 06 11:21:39 2020 +0200
+++ b/Core/DicomParsing/ParsedDicomFile.cpp	Sat Jun 06 14:50:21 2020 +0200
@@ -1001,10 +1001,11 @@
 
   void ParsedDicomFile::CreateFromDicomMap(const DicomMap& source,
                                            Encoding defaultEncoding,
-                                           bool permissive)
+                                           bool permissive,
+                                           const std::string& privateCreator)
   {
     pimpl_->file_.reset(new DcmFileFormat);
-    pimpl_->frameIndex_.reset(NULL);
+    InvalidateCache();
 
     const DicomValue* tmp = source.TestAndGetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET);
 
@@ -1046,7 +1047,9 @@
       {
         try
         {
-          ReplacePlainString(it->first, it->second->GetContent());
+          // Same as "ReplacePlainString()", but with support for private creator
+          const std::string& utf8Value = it->second->GetContent();
+          Replace(it->first, utf8Value, false, DicomReplaceMode_InsertIfAbsent, privateCreator);
         }
         catch (OrthancException&)
         {
@@ -1062,10 +1065,11 @@
 
   ParsedDicomFile::ParsedDicomFile(const DicomMap& map,
                                    Encoding defaultEncoding,
-                                   bool permissive) :
+                                   bool permissive,
+                                   const std::string& privateCreator) :
     pimpl_(new PImpl)
   {
-    CreateFromDicomMap(map, defaultEncoding, permissive);
+    CreateFromDicomMap(map, defaultEncoding, permissive, privateCreator);
   }
 
 
--- a/Core/DicomParsing/ParsedDicomFile.h	Sat Jun 06 11:21:39 2020 +0200
+++ b/Core/DicomParsing/ParsedDicomFile.h	Sat Jun 06 14:50:21 2020 +0200
@@ -92,7 +92,8 @@
 
     void CreateFromDicomMap(const DicomMap& source,
                             Encoding defaultEncoding,
-                            bool permissive);
+                            bool permissive,
+                            const std::string& privateCreator);
 
     void RemovePrivateTagsInternal(const std::set<DicomTag>* toKeep);
 
@@ -111,7 +112,8 @@
 
     ParsedDicomFile(const DicomMap& map,
                     Encoding defaultEncoding,
-                    bool permissive);
+                    bool permissive,
+                    const std::string& privateCreator);
 
     ParsedDicomFile(const void* content,
                     size_t size);
--- a/NEWS	Sat Jun 06 11:21:39 2020 +0200
+++ b/NEWS	Sat Jun 06 14:50:21 2020 +0200
@@ -1,6 +1,8 @@
 Pending changes in the mainline
 ===============================
 
+* Private tags returned by C-FIND SCP (cf. option "DefaultPrivateCreator")
+
 
 Version 1.7.1 (2020-05-27)
 ==========================
--- a/OrthancServer/DicomInstanceToStore.cpp	Sat Jun 06 11:21:39 2020 +0200
+++ b/OrthancServer/DicomInstanceToStore.cpp	Sat Jun 06 14:50:21 2020 +0200
@@ -211,7 +211,8 @@
           {
             parsed_.TakeOwnership(new ParsedDicomFile(summary_.GetConstContent(),
                                                       GetDefaultDicomEncoding(),
-                                                      false /* be strict */));
+                                                      false /* be strict */,
+                                                      "" /* no private creator */));
           }                                
         }
 
--- a/OrthancServer/OrthancFindRequestHandler.cpp	Sat Jun 06 11:21:39 2020 +0200
+++ b/OrthancServer/OrthancFindRequestHandler.cpp	Sat Jun 06 14:50:21 2020 +0200
@@ -302,7 +302,8 @@
                         const Json::Value* dicomAsJson,
                         const DicomArray& query,
                         const std::list<DicomTag>& sequencesToReturn,
-                        const DicomMap* counters)
+                        const DicomMap* counters,
+                        const std::string& privateCreator)
   {
     DicomMap match;
 
@@ -371,7 +372,8 @@
     }
     else
     {
-      ParsedDicomFile dicom(result, GetDefaultDicomEncoding(), true /* be permissive, cf. issue #136 */);
+      ParsedDicomFile dicom(result, GetDefaultDicomEncoding(),
+                            true /* be permissive, cf. issue #136 */, privateCreator);
 
       for (std::list<DicomTag>::const_iterator tag = sequencesToReturn.begin();
            tag != sequencesToReturn.end(); ++tag)
@@ -394,8 +396,7 @@
             content.append(item);
           }
 
-          dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent,
-                        "" /* no private creator */);
+          dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, privateCreator);
         }
       }
 
@@ -484,6 +485,7 @@
     const DicomMap&             query_;
     DicomArray                  queryAsArray_;
     const std::list<DicomTag>&  sequencesToReturn_;
+    std::string                 privateCreator_;
 
   public:
     LookupVisitor(DicomFindAnswers&  answers,
@@ -499,6 +501,11 @@
       sequencesToReturn_(sequencesToReturn)
     {
       answers_.SetComplete(false);
+
+      {
+        OrthancConfiguration::ReaderLock lock;
+        privateCreator_ = lock.GetConfiguration().GetDefaultPrivateCreator();
+      }
     }
 
     virtual bool IsDicomAsJsonNeeded() const
@@ -540,7 +547,7 @@
       std::unique_ptr<DicomMap> counters(ComputeCounters(context_, instanceId, level_, query_));
 
       AddAnswer(answers_, mainDicomTags, dicomAsJson,
-                queryAsArray_, sequencesToReturn_, counters.get());
+                queryAsArray_, sequencesToReturn_, counters.get(), privateCreator_);
     }
   };
 
--- a/UnitTestsSources/FromDcmtkTests.cpp	Sat Jun 06 11:21:39 2020 +0200
+++ b/UnitTestsSources/FromDcmtkTests.cpp	Sat Jun 06 14:50:21 2020 +0200
@@ -1137,14 +1137,14 @@
 
   {
     DicomMap m;
-    ParsedDicomFile dicom(m, GetDefaultDicomEncoding(), false);
+    ParsedDicomFile dicom(m, GetDefaultDicomEncoding(), false, "" /* no private creator */);
     ASSERT_EQ(1u, dicom.GetDcmtkObject().getDataset()->card());
     CheckEncoding(dicom, Encoding_Ascii);
   }
 
   {
     DicomMap m;
-    ParsedDicomFile dicom(m, Encoding_Latin4, false);
+    ParsedDicomFile dicom(m, Encoding_Latin4, false, "" /* no private creator */);
     ASSERT_EQ(1u, dicom.GetDcmtkObject().getDataset()->card());
     CheckEncoding(dicom, Encoding_Latin4);
   }
@@ -1152,7 +1152,7 @@
   {
     DicomMap m;
     m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, "ISO_IR 148", false);
-    ParsedDicomFile dicom(m, GetDefaultDicomEncoding(), false);
+    ParsedDicomFile dicom(m, GetDefaultDicomEncoding(), false, "" /* no private creator */);
     ASSERT_EQ(1u, dicom.GetDcmtkObject().getDataset()->card());
     CheckEncoding(dicom, Encoding_Latin5);
   }
@@ -1160,7 +1160,7 @@
   {
     DicomMap m;
     m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, "ISO_IR 148", false);
-    ParsedDicomFile dicom(m, Encoding_Latin1, false);
+    ParsedDicomFile dicom(m, Encoding_Latin1, false, "" /* no private creator */);
     ASSERT_EQ(1u, dicom.GetDcmtkObject().getDataset()->card());
     CheckEncoding(dicom, Encoding_Latin5);
   }
@@ -1210,7 +1210,7 @@
         DicomMap m;
         m.SetValue(DICOM_TAG_PATIENT_NAME, testEncodingsExpected[i], false);
 
-        ParsedDicomFile dicom(m, testEncodings[i], false);
+        ParsedDicomFile dicom(m, testEncodings[i], false, "" /* no private creator */);
     
         const char* encoded = NULL;
         ASSERT_TRUE(dicom.GetDcmtkObject().getDataset()->findAndGetString(DCM_PatientName, encoded).good());
@@ -1230,7 +1230,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], false);
+        ParsedDicomFile dicom(m, testEncodings[i], false, "" /* no private creator */);
 
         Json::Value v2;
         dicom.DatasetToJson(v2, DicomToJsonFormat_Human, DicomToJsonFlags_Default, 0);
@@ -1255,7 +1255,7 @@
 
       std::string tag;
 
-      ParsedDicomFile dicom(m, Encoding_Utf8, false);
+      ParsedDicomFile dicom(m, Encoding_Utf8, false, "" /* no private creator */);
       bool hasCodeExtensions;
       ASSERT_EQ(Encoding_Utf8, dicom.DetectEncoding(hasCodeExtensions));
       ASSERT_FALSE(hasCodeExtensions);
@@ -1306,7 +1306,7 @@
     DicomMap m;
     m.SetValue(DICOM_TAG_PATIENT_NAME, "HELLO", false);
 
-    ParsedDicomFile d(m, Encoding_Latin3 /* default encoding */, false);
+    ParsedDicomFile d(m, Encoding_Latin3 /* default encoding */, false, "" /* no private creator */);
 
     bool hasCodeExtensions;
     ASSERT_EQ(Encoding_Latin3, d.DetectEncoding(hasCodeExtensions));
@@ -1319,7 +1319,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 */, false);
+    ParsedDicomFile d(m, Encoding_Latin3 /* default encoding */, false, "" /* no private creator */);
 
     bool hasCodeExtensions;
     ASSERT_EQ(Encoding_Japanese, d.DetectEncoding(hasCodeExtensions));
@@ -1332,7 +1332,8 @@
     m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, "nope", false);
     m.SetValue(DICOM_TAG_PATIENT_NAME, "HELLO", false);
 
-    ASSERT_THROW(ParsedDicomFile d(m, Encoding_Latin3, false), OrthancException);
+    ASSERT_THROW(ParsedDicomFile d(m, Encoding_Latin3, false, "" /* no private creator */),
+                 OrthancException);
   }
   
   {
@@ -1341,7 +1342,8 @@
     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, false), OrthancException);
+    ASSERT_THROW(ParsedDicomFile d(m, Encoding_Latin3, false, "" /* no private creator */),
+                 OrthancException);
   }
   
   {
@@ -1351,7 +1353,7 @@
     m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, "", false);
     m.SetValue(DICOM_TAG_PATIENT_NAME, "HELLO", false);
 
-    ParsedDicomFile d(m, Encoding_Latin3 /* default encoding */, false);
+    ParsedDicomFile d(m, Encoding_Latin3 /* default encoding */, false, "" /* no private creator */);
 
     bool hasCodeExtensions;
     ASSERT_EQ(Encoding_Latin3, d.DetectEncoding(hasCodeExtensions));