diff Core/DicomParsing/IDicomTranscoder.cpp @ 3945:0b3256c3ee14 transcoding

simplified IDicomTranscoder
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 19 May 2020 11:24:00 +0200
parents aae045f802f4
children 1f33ed7f82e6
line wrap: on
line diff
--- a/Core/DicomParsing/IDicomTranscoder.cpp	Tue May 19 10:17:06 2020 +0200
+++ b/Core/DicomParsing/IDicomTranscoder.cpp	Tue May 19 11:24:00 2020 +0200
@@ -44,28 +44,50 @@
 {
   void IDicomTranscoder::DicomImage::Parse()
   {
-    if (parsed_.get() != NULL ||
-        buffer_.get() == NULL)
+    if (parsed_.get() != NULL)
     {
+      // Already parsed
       throw OrthancException(ErrorCode_BadSequenceOfCalls);
     }
-    else
+    else if (buffer_.get() != NULL)
     {
-      parsed_.reset(FromDcmtkBridge::LoadFromMemoryBuffer(
-                      buffer_->empty() ? NULL : buffer_->c_str(), buffer_->size()));
-
+      if (isExternalBuffer_)
+      {
+        throw OrthancException(ErrorCode_InternalError);
+      }
+      else
+      {
+        parsed_.reset(FromDcmtkBridge::LoadFromMemoryBuffer(
+                        buffer_->empty() ? NULL : buffer_->c_str(), buffer_->size()));
+        
+        if (parsed_.get() == NULL)
+        {
+          throw OrthancException(ErrorCode_BadFileFormat);
+        }      
+      }
+    }
+    else if (isExternalBuffer_)
+    {
+      parsed_.reset(FromDcmtkBridge::LoadFromMemoryBuffer(externalBuffer_, externalSize_));
+      
       if (parsed_.get() == NULL)
       {
         throw OrthancException(ErrorCode_BadFileFormat);
       }      
     }
+    else
+    {
+      // No buffer is available
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
   }
   
   
   void IDicomTranscoder::DicomImage::Serialize()
   {
     if (parsed_.get() == NULL ||
-        buffer_.get() != NULL)
+        buffer_.get() != NULL ||
+        isExternalBuffer_)
     {
       throw OrthancException(ErrorCode_BadSequenceOfCalls);
     }
@@ -81,10 +103,17 @@
   }
 
   
+  IDicomTranscoder::DicomImage::DicomImage() :
+    isExternalBuffer_(false)
+  {
+  }
+
+
   void IDicomTranscoder::DicomImage::Clear()
   {
     parsed_.reset(NULL);
     buffer_.reset(NULL);
+    isExternalBuffer_ = false;
   }
 
   
@@ -100,14 +129,14 @@
     {
       throw OrthancException(ErrorCode_NullPointer);
     }
+    else if (parsed->getDataset() == NULL)
+    {
+      throw OrthancException(ErrorCode_InternalError);
+    }
     else if (parsed_.get() != NULL)
     {
       throw OrthancException(ErrorCode_BadSequenceOfCalls);
     }
-    else if (parsed->getDataset() == NULL)
-    {
-      throw OrthancException(ErrorCode_InternalError);
-    }
     else
     {
       parsed_.reset(parsed);
@@ -123,7 +152,8 @@
 
   void IDicomTranscoder::DicomImage::AcquireBuffer(std::string& buffer /* will be swapped */)
   {
-    if (buffer_.get() != NULL)
+    if (buffer_.get() != NULL ||
+        isExternalBuffer_)
     {
       throw OrthancException(ErrorCode_BadSequenceOfCalls);
     }
@@ -137,36 +167,69 @@
 
   void IDicomTranscoder::DicomImage::AcquireBuffer(DicomImage& other)
   {
-    if (buffer_.get() != NULL)
+    if (buffer_.get() != NULL ||
+        isExternalBuffer_)
     {
       throw OrthancException(ErrorCode_BadSequenceOfCalls);
     }
-    else if (other.buffer_.get() == NULL)
+    else if (other.isExternalBuffer_)
     {
-      buffer_.reset(NULL);
+      assert(other.buffer_.get() == NULL);
+      isExternalBuffer_ = true;
+      externalBuffer_ = other.externalBuffer_;
+      externalSize_ = other.externalSize_;
+    }
+    else if (other.buffer_.get() != NULL)
+    {
+      buffer_.reset(other.buffer_.release());
     }
     else
     {
-      buffer_.reset(other.buffer_.release());
+      buffer_.reset(NULL);
     }    
   }
 
   
+  void IDicomTranscoder::DicomImage::SetExternalBuffer(const void* buffer,
+                                                       size_t size)
+  {
+    if (buffer_.get() != NULL ||
+        isExternalBuffer_)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      isExternalBuffer_ = true;
+      externalBuffer_ = buffer;
+      externalSize_ = size;
+    }
+  }
+
+
+  void IDicomTranscoder::DicomImage::SetExternalBuffer(const std::string& buffer)
+  {
+    SetExternalBuffer(buffer.empty() ? NULL : buffer.c_str(), buffer.size());
+  }
+
+
   DcmFileFormat& IDicomTranscoder::DicomImage::GetParsed()
   {
     if (parsed_.get() != NULL)
     {
       return *parsed_;
     }
-    else if (buffer_.get() != NULL)
+    else if (buffer_.get() != NULL ||
+             isExternalBuffer_)
     {
       Parse();
       return *parsed_;
     }
     else
     {
-      throw OrthancException(ErrorCode_BadSequenceOfCalls,
-                             "AcquireParsed() or AcquireBuffer() should have been called");
+      throw OrthancException(
+        ErrorCode_BadSequenceOfCalls,
+        "AcquireParsed(), AcquireBuffer() or SetExternalBuffer() should have been called");
     }
   }
   
@@ -178,7 +241,8 @@
       buffer_.reset(NULL);
       return parsed_.release();
     }
-    else if (buffer_.get() != NULL)
+    else if (buffer_.get() != NULL ||
+             isExternalBuffer_)
     {
       Parse();
       buffer_.reset(NULL);
@@ -186,102 +250,55 @@
     }
     else
     {
-      throw OrthancException(ErrorCode_BadSequenceOfCalls,
-                             "AcquireParsed() or AcquireBuffer() should have been called");
+      throw OrthancException(
+        ErrorCode_BadSequenceOfCalls,
+        "AcquireParsed(), AcquireBuffer() or SetExternalBuffer() should have been called");
     }
   }
 
+
+  ParsedDicomFile* IDicomTranscoder::DicomImage::ReleaseAsParsedDicomFile()
+  {
+    return ParsedDicomFile::AcquireDcmtkObject(ReleaseParsed());
+  }
+
   
   const void* IDicomTranscoder::DicomImage::GetBufferData()
   {
-    if (buffer_.get() == NULL)
+    if (isExternalBuffer_)
     {
-      Serialize();
+      assert(buffer_.get() == NULL);
+      return externalBuffer_;
     }
+    else
+    {    
+      if (buffer_.get() == NULL)
+      {
+        Serialize();
+      }
 
-    assert(buffer_.get() != NULL);
-    return buffer_->empty() ? NULL : buffer_->c_str();
+      assert(buffer_.get() != NULL);
+      return buffer_->empty() ? NULL : buffer_->c_str();
+    }
   }
 
   
   size_t IDicomTranscoder::DicomImage::GetBufferSize()
   {
-    if (buffer_.get() == NULL)
+    if (isExternalBuffer_)
     {
-      Serialize();
-    }
-
-    assert(buffer_.get() != NULL);
-    return buffer_->size();
-  }
-
-
-  IDicomTranscoder::TranscodedDicom::TranscodedDicom(bool hasSopInstanceUidChanged) :
-    external_(NULL),
-    hasSopInstanceUidChanged_(hasSopInstanceUidChanged)
-  {
-  }
-  
-
-  IDicomTranscoder::TranscodedDicom*
-  IDicomTranscoder::TranscodedDicom::CreateFromExternal(DcmFileFormat& dicom,
-                                                        bool hasSopInstanceUidChanged)
-  {
-    std::unique_ptr<TranscodedDicom> transcoded(new TranscodedDicom(hasSopInstanceUidChanged));
-    transcoded->external_ = &dicom;
-    return transcoded.release();
-  }        
-
-  
-  IDicomTranscoder::TranscodedDicom*
-  IDicomTranscoder::TranscodedDicom::CreateFromInternal(DcmFileFormat* dicom,
-                                                        bool hasSopInstanceUidChanged)
-  {
-    if (dicom == NULL)
-    {
-      throw OrthancException(ErrorCode_NullPointer);
+      assert(buffer_.get() == NULL);
+      return externalSize_;
     }
     else
-    {
-      std::unique_ptr<TranscodedDicom> transcoded(new TranscodedDicom(hasSopInstanceUidChanged));
-      transcoded->internal_.reset(dicom);
-      return transcoded.release();
+    {    
+      if (buffer_.get() == NULL)
+      {
+        Serialize();
+      }
+
+      assert(buffer_.get() != NULL);
+      return buffer_->size();
     }
   }
-
-  
-  DcmFileFormat& IDicomTranscoder::TranscodedDicom::GetDicom() const
-  {
-    if (internal_.get() != NULL)
-    {
-      return *internal_.get();
-    }
-    else if (external_ != NULL)
-    {
-      return *external_;
-    }
-    else
-    {
-      // Probably results from a call to "ReleaseDicom()"
-      throw OrthancException(ErrorCode_BadSequenceOfCalls);
-    }
-  }
-
-
-  DcmFileFormat* IDicomTranscoder::TranscodedDicom::ReleaseDicom()
-  {
-    if (internal_.get() != NULL)
-    {
-      return internal_.release();
-    }
-    else if (external_ != NULL)
-    {
-      return new DcmFileFormat(*external_);  // Clone
-    }
-    else
-    {
-      // Probably results from a call to "ReleaseDicom()"
-      throw OrthancException(ErrorCode_BadSequenceOfCalls);      
-    }        
-  }
 }