changeset 3904:c62f84c7eda9 transcoding

fixing incorrect behavior in MemoryBufferTranscoder
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 07 May 2020 17:21:20 +0200
parents d1273d7cc200
children 061f3d031b5d
files Core/DicomNetworking/DicomStoreUserConnection.cpp Core/DicomParsing/DcmtkTranscoder.cpp Core/DicomParsing/DcmtkTranscoder.h Core/DicomParsing/IDicomTranscoder.h Core/DicomParsing/MemoryBufferTranscoder.cpp Core/DicomParsing/MemoryBufferTranscoder.h OrthancServer/ServerContext.cpp OrthancServer/ServerContext.h
diffstat 8 files changed, 95 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/Core/DicomNetworking/DicomStoreUserConnection.cpp	Thu May 07 16:43:08 2020 +0200
+++ b/Core/DicomNetworking/DicomStoreUserConnection.cpp	Thu May 07 17:21:20 2020 +0200
@@ -495,7 +495,7 @@
 
       bool hasSopInstanceUidChanged;
       
-      if (transcoder.HasInplaceTranscode())
+      if (transcoder.HasInplaceTranscode(inputSyntax, uncompressedSyntaxes))
       {
         if (transcoder.InplaceTranscode(hasSopInstanceUidChanged, *dicom, uncompressedSyntaxes, false))
         {
--- a/Core/DicomParsing/DcmtkTranscoder.cpp	Thu May 07 16:43:08 2020 +0200
+++ b/Core/DicomParsing/DcmtkTranscoder.cpp	Thu May 07 17:21:20 2020 +0200
@@ -339,4 +339,36 @@
       return true;
     }
   }
+
+
+  bool DcmtkTranscoder::IsSupported(DicomTransferSyntax syntax)
+  {
+    if (syntax == DicomTransferSyntax_LittleEndianImplicit ||
+        syntax == DicomTransferSyntax_LittleEndianExplicit ||
+        syntax == DicomTransferSyntax_BigEndianExplicit ||
+        syntax == DicomTransferSyntax_DeflatedLittleEndianExplicit)
+    {
+      return true;
+    }
+
+#if ORTHANC_ENABLE_DCMTK_JPEG == 1
+    if (syntax == DicomTransferSyntax_JPEGProcess1 ||
+        syntax == DicomTransferSyntax_JPEGProcess2_4 ||
+        syntax == DicomTransferSyntax_JPEGProcess14 ||
+        syntax == DicomTransferSyntax_JPEGProcess14SV1)
+    {
+      return true;
+    }
+#endif
+
+#if ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS == 1
+    if (syntax == DicomTransferSyntax_JPEGLSLossless ||
+        syntax == DicomTransferSyntax_JPEGLSLossy)
+    {
+      return true;
+    }
+#endif
+    
+    return false;
+  }
 }
--- a/Core/DicomParsing/DcmtkTranscoder.h	Thu May 07 16:43:08 2020 +0200
+++ b/Core/DicomParsing/DcmtkTranscoder.h	Thu May 07 17:21:20 2020 +0200
@@ -69,7 +69,8 @@
                                              const std::set<DicomTransferSyntax>& allowedSyntaxes,
                                              bool allowNewSopInstanceUid) ORTHANC_OVERRIDE;
 
-    virtual bool HasInplaceTranscode() const
+    virtual bool HasInplaceTranscode(DicomTransferSyntax inputSyntax,
+                                     const std::set<DicomTransferSyntax>& outputSyntaxes) const
     {
       return true;
     }
@@ -85,5 +86,7 @@
                                    size_t size,
                                    const std::set<DicomTransferSyntax>& allowedSyntaxes,
                                    bool allowNewSopInstanceUid) ORTHANC_OVERRIDE;
+
+    static bool IsSupported(DicomTransferSyntax syntax);
   };
 }
--- a/Core/DicomParsing/IDicomTranscoder.h	Thu May 07 16:43:08 2020 +0200
+++ b/Core/DicomParsing/IDicomTranscoder.h	Thu May 07 17:21:20 2020 +0200
@@ -73,7 +73,8 @@
                                              const std::set<DicomTransferSyntax>& allowedSyntaxes,
                                              bool allowNewSopInstanceUid) = 0;
     
-    virtual bool HasInplaceTranscode() const = 0;
+    virtual bool HasInplaceTranscode(DicomTransferSyntax inputSyntax,
+                                     const std::set<DicomTransferSyntax>& outputSyntaxes) const = 0;
 
     /**
      * In-place transcoding. This method is preferred for C-STORE.
--- a/Core/DicomParsing/MemoryBufferTranscoder.cpp	Thu May 07 16:43:08 2020 +0200
+++ b/Core/DicomParsing/MemoryBufferTranscoder.cpp	Thu May 07 17:21:20 2020 +0200
@@ -111,13 +111,54 @@
   }
 
 
+  bool MemoryBufferTranscoder::HasInplaceTranscode(
+    DicomTransferSyntax inputSyntax,
+    const std::set<DicomTransferSyntax>& outputSyntaxes) const
+  {
+    /**
+     * Inplace transcoding is only possible if DCMTK is enabled, and
+     * if DCMTK supports all the requested transfer
+     * syntaxes. Otherwise, one has to call the "buffer-to-buffer"
+     * transcoder.
+     **/
+    
+#if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1
+    if (useDcmtk_)
+    {
+      if (!DcmtkTranscoder::IsSupported(inputSyntax))
+      {
+        return false;
+      }
+      
+      for (std::set<DicomTransferSyntax>::const_iterator
+             it = outputSyntaxes.begin(); it != outputSyntaxes.end(); ++it)
+      {
+        if (!DcmtkTranscoder::IsSupported(*it))
+        {
+          return false;
+        }
+      }
+
+      return true;
+    }
+    else
+#endif
+    {
+      return false;
+    }
+  }
+    
+
   bool MemoryBufferTranscoder::InplaceTranscode(bool& hasSopInstanceUidChanged,
                                                 DcmFileFormat& dicom,
                                                 const std::set<DicomTransferSyntax>& allowedSyntaxes,
                                                 bool allowNewSopInstanceUid)
   {
 #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1
-    if (useDcmtk_)
+    DicomTransferSyntax inputSyntax;
+    if (useDcmtk_ &&
+        FromDcmtkBridge::LookupOrthancTransferSyntax(inputSyntax, dicom) &&
+        HasInplaceTranscode(inputSyntax, allowedSyntaxes))
     {
       return dcmtk_.InplaceTranscode(hasSopInstanceUidChanged, dicom, allowedSyntaxes, allowNewSopInstanceUid);
     }
--- a/Core/DicomParsing/MemoryBufferTranscoder.h	Thu May 07 16:43:08 2020 +0200
+++ b/Core/DicomParsing/MemoryBufferTranscoder.h	Thu May 07 17:21:20 2020 +0200
@@ -88,10 +88,9 @@
                                              const std::set<DicomTransferSyntax>& allowedSyntaxes,
                                              bool allowNewSopInstanceUid) ORTHANC_OVERRIDE;
 
-    virtual bool HasInplaceTranscode() const ORTHANC_OVERRIDE
-    {
-      return useDcmtk_;
-    }
+    virtual bool HasInplaceTranscode(
+      DicomTransferSyntax inputSyntax,
+      const std::set<DicomTransferSyntax>& outputSyntaxes) const ORTHANC_OVERRIDE;
     
     virtual bool InplaceTranscode(bool& hasSopInstanceUidChanged /* out */,
                                   DcmFileFormat& dicom,
--- a/OrthancServer/ServerContext.cpp	Thu May 07 16:43:08 2020 +0200
+++ b/OrthancServer/ServerContext.cpp	Thu May 07 17:21:20 2020 +0200
@@ -1161,6 +1161,13 @@
                                 const std::set<DicomTransferSyntax>& allowedSyntaxes,
                                 bool allowNewSopInstanceUid)
   {
+    DicomTransferSyntax inputSyntax;
+    if (!FromDcmtkBridge::LookupOrthancTransferSyntax(inputSyntax, dicom.GetDcmtkObject()))
+    {
+      throw OrthancException(ErrorCode_BadFileFormat,
+                             "Cannot determine the source transfer syntax during transcoding");
+    }
+
     IDicomTranscoder* transcoder = dcmtkTranscoder_.get();
     
 #if ORTHANC_ENABLE_PLUGINS == 1
@@ -1174,7 +1181,7 @@
     {
       throw OrthancException(ErrorCode_InternalError);
     }
-    else if (transcoder->HasInplaceTranscode())
+    else if (transcoder->HasInplaceTranscode(inputSyntax, allowedSyntaxes))
     {
       if (transcoder->InplaceTranscode(hasSopInstanceUidChanged, dicom.GetDcmtkObject(),
                                        allowedSyntaxes, allowNewSopInstanceUid))
--- a/OrthancServer/ServerContext.h	Thu May 07 16:43:08 2020 +0200
+++ b/OrthancServer/ServerContext.h	Thu May 07 17:21:20 2020 +0200
@@ -463,10 +463,11 @@
                               const std::string& moveOriginatorAet,
                               uint16_t moveOriginatorId);
 
-    // This method can be used even if "TranscodingEnabled" is set to "false"
+    // This method can be used even if the global option
+    // "TranscodingEnabled" is set to "false"
     bool Transcode(std::string& target,
                    bool& hasSopInstanceUidChanged,
-                   ParsedDicomFile& dicom, // Possibly modified
+                   ParsedDicomFile& dicom, // Can possibly be modified
                    const std::set<DicomTransferSyntax>& allowedSyntaxes,
                    bool allowNewSopInstanceUid);
   };