changeset 4511:1ec156a0da38

ServerContext::ReadDicomUntilPixelData()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 11 Feb 2021 19:06:29 +0100
parents a3635a01a945
children cff7fdfc83a4
files OrthancServer/Sources/ServerContext.cpp OrthancServer/Sources/ServerContext.h
diffstat 2 files changed, 60 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/Sources/ServerContext.cpp	Thu Feb 11 17:51:04 2021 +0100
+++ b/OrthancServer/Sources/ServerContext.cpp	Thu Feb 11 19:06:29 2021 +0100
@@ -584,7 +584,7 @@
       attachments.push_back(dicomInfo);
 
       FileInfo jsonInfo;
-      if (true /* TODO - !area_.HasReadRange() || !hasPixelDataOffset */)
+      if (true /* TODO - !area_.HasReadRange() || !hasPixelDataOffset || compression != CompressionType_DicomAsJson */)
       {
         jsonInfo = accessor.Write(dicomAsJson.toStyledString(), 
                                   FileContentType_DicomAsJson, compression, storeMD5_);
@@ -807,8 +807,8 @@
   }
 
 
-  void ServerContext::ReadDicomAsJsonInternal(std::string& result,
-                                              const std::string& instancePublicId)
+  void ServerContext::ReadDicomAsJson(std::string& result,
+                                      const std::string& instancePublicId)
   {
     FileInfo attachment;
     if (index_.LookupAttachment(attachment, instancePublicId, FileContentType_DicomAsJson))
@@ -843,23 +843,6 @@
   }
 
 
-  void ServerContext::ReadDicomAsJson(std::string& result,
-                                      const std::string& instancePublicId,
-                                      const std::set<DicomTag>& ignoreTagLength)
-  {
-    if (ignoreTagLength.empty())
-    {
-      ReadDicomAsJsonInternal(result, instancePublicId);
-    }
-    else
-    {
-      Json::Value tmp;
-      ReadDicomAsJson(tmp, instancePublicId, ignoreTagLength);
-      result = tmp.toStyledString();
-    }
-  }
-
-
   void ServerContext::ReadDicomAsJson(Json::Value& result,
                                       const std::string& instancePublicId,
                                       const std::set<DicomTag>& ignoreTagLength)
@@ -867,7 +850,7 @@
     if (ignoreTagLength.empty())
     {
       std::string tmp;
-      ReadDicomAsJsonInternal(tmp, instancePublicId);
+      ReadDicomAsJson(tmp, instancePublicId);
 
       if (!Toolbox::ReadJson(result, tmp))
       {
@@ -887,6 +870,14 @@
   }
 
 
+  void ServerContext::ReadDicomAsJson(Json::Value& result,
+                                      const std::string& instancePublicId)
+  {
+    std::set<DicomTag> ignoreTagLength;
+    ReadDicomAsJson(result, instancePublicId, ignoreTagLength);
+  }
+
+
   void ServerContext::ReadDicom(std::string& dicom,
                                 const std::string& instancePublicId)
   {
@@ -894,6 +885,47 @@
   }
     
 
+  bool ServerContext::ReadDicomUntilPixelData(std::string& dicom,
+                                              const std::string& instancePublicId)
+  {
+    if (!area_.HasReadRange())
+    {
+      return false;
+    }
+    
+    FileInfo attachment;
+    if (!index_.LookupAttachment(attachment, instancePublicId, FileContentType_Dicom))
+    {
+      throw OrthancException(ErrorCode_InternalError,
+                             "Unable to read the DICOM file of instance " + instancePublicId);
+    }
+
+    std::string s;
+
+    if (attachment.GetCompressionType() == CompressionType_None &&
+        index_.LookupMetadata(s, instancePublicId, ResourceType_Instance,
+                              MetadataType_Instance_PixelDataOffset) &&
+        !s.empty())
+    {
+      try
+      {
+        uint64_t pixelDataOffset = boost::lexical_cast<uint64_t>(s);
+
+        std::unique_ptr<IMemoryBuffer> buffer(
+          area_.ReadRange(attachment.GetUuid(), attachment.GetContentType(), 0, pixelDataOffset));
+        buffer->MoveToString(dicom);
+        return true;   // Success
+      }
+      catch (boost::bad_lexical_cast&)
+      {
+        LOG(ERROR) << "Metadata \"PixelDataOffset\" is corrupted for instance: " << instancePublicId;
+      }
+    }
+
+    return false;
+  }
+  
+
   void ServerContext::ReadAttachment(std::string& result,
                                      const std::string& instancePublicId,
                                      FileContentType content,
--- a/OrthancServer/Sources/ServerContext.h	Thu Feb 11 17:51:04 2021 +0100
+++ b/OrthancServer/Sources/ServerContext.h	Thu Feb 11 19:06:29 2021 +0100
@@ -159,9 +159,6 @@
     static void SaveJobsThread(ServerContext* that,
                                unsigned int sleepDelay);
 
-    void ReadDicomAsJsonInternal(std::string& result,
-                                 const std::string& instancePublicId);
-
     void SaveJobsEngine();
 
     virtual void SignalJobSubmitted(const std::string& jobId) ORTHANC_OVERRIDE;
@@ -316,36 +313,27 @@
                                      CompressionType compression);
 
     void ReadDicomAsJson(std::string& result,
-                         const std::string& instancePublicId,
-                         const std::set<DicomTag>& ignoreTagLength);
+                         const std::string& instancePublicId);
 
     void ReadDicomAsJson(Json::Value& result,
                          const std::string& instancePublicId,
                          const std::set<DicomTag>& ignoreTagLength);
 
-    void ReadDicomAsJson(std::string& result,
-                         const std::string& instancePublicId)
-    {
-      std::set<DicomTag> ignoreTagLength;
-      ReadDicomAsJson(result, instancePublicId, ignoreTagLength);
-    }
-
     void ReadDicomAsJson(Json::Value& result,
-                         const std::string& instancePublicId)
-    {
-      std::set<DicomTag> ignoreTagLength;
-      ReadDicomAsJson(result, instancePublicId, ignoreTagLength);
-    }
+                         const std::string& instancePublicId);
 
     void ReadDicom(std::string& dicom,
                    const std::string& instancePublicId);
     
-    // TODO CACHING MECHANISM AT THIS POINT
+    bool ReadDicomUntilPixelData(std::string& dicom,
+                                 const std::string& instancePublicId);
+
+    // This method is for low-level operations on "/instances/.../attachments/..."
     void ReadAttachment(std::string& result,
                         const std::string& instancePublicId,
                         FileContentType content,
                         bool uncompressIfNeeded);
-    
+
     void SetStoreMD5ForAttachments(bool storeMD5);
 
     bool IsStoreMD5ForAttachments() const