changeset 3868:d5be23fc0106 transcoding

better negotiation of transfer syntaxes
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 28 Apr 2020 08:43:48 +0200
parents e1c2bc9a5cc1
children c23ef85c7d9c
files Core/DicomNetworking/DicomStoreUserConnection.cpp Core/DicomNetworking/DicomStoreUserConnection.h UnitTestsSources/FromDcmtkTests.cpp
diffstat 3 files changed, 77 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/Core/DicomNetworking/DicomStoreUserConnection.cpp	Mon Apr 27 18:34:20 2020 +0200
+++ b/Core/DicomNetworking/DicomStoreUserConnection.cpp	Tue Apr 28 08:43:48 2020 +0200
@@ -48,8 +48,28 @@
   bool DicomStoreUserConnection::ProposeStorageClass(const std::string& sopClassUid,
                                                      const std::set<DicomTransferSyntax>& syntaxes)
   {
+    // Default transfer syntax for DICOM
+    const bool addLittleEndianImplicit = (
+      proposeUncompressedSyntaxes_ &&
+      syntaxes.find(DicomTransferSyntax_LittleEndianImplicit) == syntaxes.end());
+    
+    const bool addLittleEndianExplicit = (
+      proposeUncompressedSyntaxes_ &&
+      syntaxes.find(DicomTransferSyntax_LittleEndianExplicit) == syntaxes.end());
+    
+    const bool addBigEndianExplicit = (
+      proposeUncompressedSyntaxes_ &&
+      proposeRetiredBigEndian_ &&
+      syntaxes.find(DicomTransferSyntax_BigEndianExplicit) == syntaxes.end());
+    
     size_t requiredCount = syntaxes.size();
-    if (proposeUncompressedSyntaxes_)
+    if (addLittleEndianImplicit)
+    {
+      requiredCount += 1;
+    }
+      
+    if (addLittleEndianExplicit ||
+        addBigEndianExplicit)
     {
       requiredCount += 1;
     }
@@ -58,40 +78,41 @@
     {
       return false;  // Not enough room
     }
-      
-    for (std::set<DicomTransferSyntax>::const_iterator
-           it = syntaxes.begin(); it != syntaxes.end(); ++it)
+    else
     {
-      association_->ProposePresentationContext(sopClassUid, *it);
-    }
-
-    if (proposeUncompressedSyntaxes_)
-    {
-      std::set<DicomTransferSyntax> uncompressed;
-        
-      if (syntaxes.find(DicomTransferSyntax_LittleEndianImplicit) == syntaxes.end())
+      for (std::set<DicomTransferSyntax>::const_iterator
+             it = syntaxes.begin(); it != syntaxes.end(); ++it)
       {
-        uncompressed.insert(DicomTransferSyntax_LittleEndianImplicit);
+        association_->ProposePresentationContext(sopClassUid, *it);
       }
-        
-      if (syntaxes.find(DicomTransferSyntax_LittleEndianExplicit) == syntaxes.end())
+
+      if (addLittleEndianImplicit)
       {
-        uncompressed.insert(DicomTransferSyntax_LittleEndianExplicit);
-      }
-        
-      if (proposeRetiredBigEndian_ &&
-          syntaxes.find(DicomTransferSyntax_BigEndianExplicit) == syntaxes.end())
-      {
-        uncompressed.insert(DicomTransferSyntax_BigEndianExplicit);
+        std::set<DicomTransferSyntax> uncompressed;
+        uncompressed.insert(DicomTransferSyntax_LittleEndianImplicit);
+        association_->ProposePresentationContext(sopClassUid, uncompressed);
       }
 
-      if (!uncompressed.empty())
+      if (addLittleEndianExplicit ||
+          addBigEndianExplicit)
       {
+        std::set<DicomTransferSyntax> uncompressed;
+
+        if (addLittleEndianExplicit)
+        {
+          uncompressed.insert(DicomTransferSyntax_LittleEndianExplicit);
+        }
+
+        if (addBigEndianExplicit)
+        {
+          uncompressed.insert(DicomTransferSyntax_BigEndianExplicit);
+        }
+
         association_->ProposePresentationContext(sopClassUid, uncompressed);
       }
-    }      
 
-    return true;
+      return true;
+    }
   }
 
 
@@ -144,8 +165,8 @@
   }
     
 
-  void DicomStoreUserConnection::PrepareStorageClass(const std::string& sopClassUid,
-                                                     DicomTransferSyntax syntax)
+  void DicomStoreUserConnection::RegisterStorageClass(const std::string& sopClassUid,
+                                                      DicomTransferSyntax syntax)
   {
     StorageClasses::iterator found = storageClasses_.find(sopClassUid);
 
@@ -211,7 +232,7 @@
     }
     
     association_->ClearPresentationContexts();
-    PrepareStorageClass(sopClassUid, transferSyntax);
+    RegisterStorageClass(sopClassUid, transferSyntax);
 
       
     /**
@@ -239,7 +260,7 @@
       
     /**
      * Step 3: Propose all the previously spotted SOP classes, as
-     * registered through the "PrepareStorageClass()" method.
+     * registered through the "RegisterStorageClass()" method.
      **/
       
     for (StorageClasses::const_iterator it = storageClasses_.begin();
@@ -262,8 +283,9 @@
 
     if (proposeCommonClasses_)
     {
+      // The method "ProposeStorageClass()" will automatically add
+      // "LittleEndianImplicit"
       std::set<DicomTransferSyntax> ts;
-      ts.insert(DicomTransferSyntax_LittleEndianImplicit);
         
       for (int i = 0; i < numberOfDcmShortSCUStorageSOPClassUIDs; i++)
       {
--- a/Core/DicomNetworking/DicomStoreUserConnection.h	Mon Apr 27 18:34:20 2020 +0200
+++ b/Core/DicomNetworking/DicomStoreUserConnection.h	Tue Apr 28 08:43:48 2020 +0200
@@ -125,8 +125,8 @@
       return proposeRetiredBigEndian_;
     }      
 
-    void PrepareStorageClass(const std::string& sopClassUid,
-                             DicomTransferSyntax syntax);
+    void RegisterStorageClass(const std::string& sopClassUid,
+                              DicomTransferSyntax syntax);
 
     // Should only be used if transcoding
     // TODO => to private
--- a/UnitTestsSources/FromDcmtkTests.cpp	Mon Apr 27 18:34:20 2020 +0200
+++ b/UnitTestsSources/FromDcmtkTests.cpp	Tue Apr 28 08:43:48 2020 +0200
@@ -2520,9 +2520,9 @@
   params.SetRemotePort(2000);
 
   DicomStoreUserConnection assoc(params);
-  assoc.PrepareStorageClass(UID_MRImageStorage, DicomTransferSyntax_JPEGProcess1);
-  assoc.PrepareStorageClass(UID_MRImageStorage, DicomTransferSyntax_JPEGProcess2_4);
-  //assoc.PrepareStorageClass(UID_MRImageStorage, DicomTransferSyntax_LittleEndianExplicit);
+  assoc.RegisterStorageClass(UID_MRImageStorage, DicomTransferSyntax_JPEGProcess1);
+  assoc.RegisterStorageClass(UID_MRImageStorage, DicomTransferSyntax_JPEGProcess2_4);
+  //assoc.RegisterStorageClass(UID_MRImageStorage, DicomTransferSyntax_LittleEndianExplicit);
 
   //assoc.SetUncompressedSyntaxesProposed(false);  // Necessary for transcoding
   //assoc.SetCommonClassesProposed(false);
@@ -2530,4 +2530,24 @@
   TestTranscode(assoc, UID_MRImageStorage, DicomTransferSyntax_LittleEndianExplicit);
 }
 
+
+TEST(Toto, DISABLED_Store2)
+{
+  DicomAssociationParameters params;
+  params.SetLocalApplicationEntityTitle("ORTHANC");
+  params.SetRemoteApplicationEntityTitle("STORESCP");
+  params.SetRemotePort(2000);
+
+  DicomStoreUserConnection assoc(params);
+  //assoc.SetCommonClassesProposed(false);
+  assoc.SetRetiredBigEndianProposed(true);
+
+  std::string s;
+  Orthanc::SystemToolbox::ReadFile(s, "/tmp/i/" + std::string(GetTransferSyntaxUid(DicomTransferSyntax_BigEndianExplicit)) +".dcm");
+
+  std::string c, i;
+  assoc.Store(c, i, s.c_str(), s.size());
+  printf("[%s] [%s]\n", c.c_str(), i.c_str());
+}
+
 #endif