changeset 3819:1237bd0bbdb2 transcoding

update sop class/instance uid if transcoding
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 08 Apr 2020 17:00:33 +0200
parents 023b2a9f3aa1
children f89eac983c9b
files Core/DicomNetworking/DicomUserConnection.cpp UnitTestsSources/FromDcmtkTests.cpp
diffstat 2 files changed, 72 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/Core/DicomNetworking/DicomUserConnection.cpp	Tue Apr 07 17:35:44 2020 +0200
+++ b/Core/DicomNetworking/DicomUserConnection.cpp	Wed Apr 08 17:00:33 2020 +0200
@@ -240,6 +240,10 @@
                                       std::vector<const char*>& asFallback,
                                       const std::string& aet)
   {
+    // Presentation context IDs must be odd numbers, hence the
+    // increments by 2:
+    // http://dicom.nema.org/medical/dicom/2019e/output/chtml/part08/sect_9.3.2.2.html
+    
     Check(ASC_addPresentationContext(params, presentationContextId, 
                                      sopClass.c_str(), asPreferred, 1),
           aet, "initializing");
@@ -1177,6 +1181,28 @@
                              "Unable to negotiate a presentation context with AET " +
                              remoteAet_);
     }
+
+#if 0
+    // Manual loop over the accepted transfer syntaxes
+    LST_HEAD **l = &pimpl_->params_->DULparams.acceptedPresentationContext;
+    if (*l != NULL)
+    {
+      DUL_PRESENTATIONCONTEXT* pc = (DUL_PRESENTATIONCONTEXT*) LST_Head(l);
+      LST_Position(l, (LST_NODE*)pc);
+      while (pc)
+      {
+        if (pc->result == ASC_P_ACCEPTANCE)
+        {
+          printf("Accepted: %d [%s] [%s]\n", pc->presentationContextID, pc->abstractSyntax, pc->acceptedTransferSyntax);
+        }
+        else
+        {
+          printf("Rejected: %d [%s]\n", pc->presentationContextID, pc->abstractSyntax);
+        }
+        pc = (DUL_PRESENTATIONCONTEXT*) LST_Next(l);
+      }
+    }
+#endif
   }
 
   void DicomUserConnection::Close()
--- a/UnitTestsSources/FromDcmtkTests.cpp	Tue Apr 07 17:35:44 2020 +0200
+++ b/UnitTestsSources/FromDcmtkTests.cpp	Wed Apr 08 17:00:33 2020 +0200
@@ -1935,6 +1935,8 @@
     {
     }
 
+    virtual DcmFileFormat& GetDicom() = 0;
+
     virtual DicomTransferSyntax GetTransferSyntax() = 0;
 
     virtual std::string GetSopClassUid() = 0;
@@ -1948,6 +1950,8 @@
     virtual void GetCompressedFrame(std::string& target,
                                     unsigned int frame) = 0;
 
+    // NB: Transcoding can change the value of "GetSopInstanceUid()"
+    // and "GetTransferSyntax()" if lossy compression is applied
     virtual bool Transcode(std::string& target,
                            std::set<DicomTransferSyntax> syntaxes,
                            bool allowNewSopInstanceUid) = 0;
@@ -1967,6 +1971,23 @@
     uint16_t                          bitsStored_;
     unsigned int                      lossyQuality_;
 
+    static std::string GetStringTag(DcmDataset& dataset,
+                                    const DcmTagKey& tag)
+    {
+      const char* value = NULL;
+
+      if (!dataset.findAndGetString(tag, value).good() ||
+          value == NULL)
+      {
+        throw OrthancException(ErrorCode_BadFileFormat,
+                               "Missing SOP class/instance UID in DICOM instance");
+      }
+      else
+      {
+        return std::string(value);
+      }
+    }
+
     void Setup(DcmFileFormat* dicom)
     {
       lossyQuality_ = 90;
@@ -2007,20 +2028,8 @@
                                "Missing \"Bits Stored\" tag in DICOM instance");
       }      
 
-      const char* a = NULL;
-      const char* b = NULL;
-
-      if (!dataset.findAndGetString(DCM_SOPClassUID, a).good() ||
-          !dataset.findAndGetString(DCM_SOPInstanceUID, b).good() ||
-          a == NULL ||
-          b == NULL)
-      {
-        throw OrthancException(ErrorCode_BadFileFormat,
-                               "Missing SOP class/instance UID in DICOM instance");
-      }
-
-      sopClassUid_.assign(a);
-      sopInstanceUid_.assign(b);
+      sopClassUid_ = GetStringTag(dataset, DCM_SOPClassUID);
+      sopInstanceUid_ = GetStringTag(dataset, DCM_SOPInstanceUID);
     }
     
   public:
@@ -2058,6 +2067,12 @@
       return bitsStored_;
     }
 
+    virtual DcmFileFormat& GetDicom()
+    {
+      assert(dicom_ != NULL);
+      return *dicom_;
+    }
+
     virtual DicomTransferSyntax GetTransferSyntax() ORTHANC_OVERRIDE
     {
       return transferSyntax_;
@@ -2103,6 +2118,9 @@
                            std::set<DicomTransferSyntax> syntaxes,
                            bool allowNewSopInstanceUid) ORTHANC_OVERRIDE
     {
+      assert(dicom_ != NULL &&
+             dicom_->getDataset() != NULL);
+      
       if (syntaxes.find(GetTransferSyntax()) != syntaxes.end())
       {
         printf("NO TRANSCODING\n");
@@ -2119,16 +2137,19 @@
       if (syntaxes.find(DicomTransferSyntax_LittleEndianImplicit) != syntaxes.end() &&
           FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_LittleEndianImplicit, NULL))
       {
+        transferSyntax_ = DicomTransferSyntax_LittleEndianImplicit;
         return true;
       }
       else if (syntaxes.find(DicomTransferSyntax_LittleEndianExplicit) != syntaxes.end() &&
                FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_LittleEndianExplicit, NULL))
       {
+        transferSyntax_ = DicomTransferSyntax_LittleEndianExplicit;
         return true;
       }
       else if (syntaxes.find(DicomTransferSyntax_BigEndianExplicit) != syntaxes.end() &&
                FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_BigEndianExplicit, NULL))
       {
+        transferSyntax_ = DicomTransferSyntax_BigEndianExplicit;
         return true;
       }
       else if (syntaxes.find(DicomTransferSyntax_JPEGProcess1) != syntaxes.end() &&
@@ -2136,6 +2157,8 @@
                GetBitsStored() == 8 &&
                FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_JPEGProcess1, &rpLossy))
       {
+        transferSyntax_ = DicomTransferSyntax_JPEGProcess1;
+        sopInstanceUid_ = GetStringTag(*dicom_->getDataset(), DCM_SOPInstanceUID);
         return true;
       }
       else if (syntaxes.find(DicomTransferSyntax_JPEGProcess2_4) != syntaxes.end() &&
@@ -2143,6 +2166,8 @@
                GetBitsStored() <= 12 &&
                FromDcmtkBridge::Transcode(target, *dicom_, DicomTransferSyntax_JPEGProcess2_4, &rpLossy))
       {
+        transferSyntax_ = DicomTransferSyntax_JPEGProcess2_4;
+        sopInstanceUid_ = GetStringTag(*dicom_->getDataset(), DCM_SOPInstanceUID);
         return true;
       }
       else
@@ -2279,6 +2304,9 @@
   }
 
   {
+    std::string a = transcoder.GetSopInstanceUid();
+    DicomTransferSyntax b = transcoder.GetTransferSyntax();
+    
     std::set<DicomTransferSyntax> syntaxes;
     syntaxes.insert(DicomTransferSyntax_JPEGProcess2_4);
     //syntaxes.insert(DicomTransferSyntax_LittleEndianExplicit);
@@ -2289,6 +2317,10 @@
 
     if (ok)
     {
+      printf("[%s] => [%s]\n", a.c_str(), transcoder.GetSopInstanceUid().c_str());
+      printf("[%s] => [%s]\n", GetTransferSyntaxUid(b),
+             GetTransferSyntaxUid(transcoder.GetTransferSyntax()));
+      
       {
         char buf[1024];
         sprintf(buf, "/tmp/transcoded-%06d.dcm", count);