changeset 394:8f0e50452c26

Support of "/studies/.../rendered"
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 03 Mar 2020 10:41:21 +0100
parents 5af041432a60
children 93c57d07a0d1
files NEWS Plugin/Plugin.cpp Plugin/WadoRs.cpp Plugin/WadoRs.h Plugin/WadoRsRetrieveRendered.cpp
diffstat 5 files changed, 83 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Fri Feb 28 12:46:22 2020 +0100
+++ b/NEWS	Tue Mar 03 10:41:21 2020 +0100
@@ -5,7 +5,7 @@
 ------------
 
 * Support of "window", "viewport" and "quality" parameters in "Retrieve Rendered Transaction"
-* Support of "/studies/.../series/.../rendered"
+* Support of "/studies/.../rendered" and "/studies/.../series/.../rendered"
 * QIDO-RS: Allow to query against a list of multiple values separated by commas
 * WADO-RS "Retrieve Metadata": Configuration options "StudiesMetadata"
   and "SeriesMetadata", whose value can be "Full" (read all DICOM
@@ -35,7 +35,8 @@
 => Minimum SDK version: 1.5.4 <=
 
 * Web user interface to QIDO-RS, WADO-RS and STOW-RS client
-* First implementation of WADO-RS "Retrieve Rendered Transaction"
+* First implementation of WADO-RS "Retrieve Rendered Transaction", for
+  ".../instances/.../rendered" and ".../instances/.../frames/.../rendered"
 * WADO-RS and STOW-RS client now create Orthanc jobs
 * Support "Transfer-Encoding: chunked" to reduce memory consumption in STOW-RS
   (provided the SDK version is above 1.5.7)
--- a/Plugin/Plugin.cpp	Fri Feb 28 12:46:22 2020 +0100
+++ b/Plugin/Plugin.cpp	Tue Mar 03 10:41:21 2020 +0100
@@ -530,6 +530,7 @@
 
         OrthancPlugins::RegisterRestCallback<GetClientInformation>(root + "info", true);
 
+        OrthancPlugins::RegisterRestCallback<RetrieveStudyRendered>(root + "studies/([^/]*)/rendered", true);
         OrthancPlugins::RegisterRestCallback<RetrieveSeriesRendered>(root + "studies/([^/]*)/series/([^/]*)/rendered", true);
         OrthancPlugins::RegisterRestCallback<RetrieveInstanceRendered>(root + "studies/([^/]*)/series/([^/]*)/instances/([^/]*)/rendered", true);
         OrthancPlugins::RegisterRestCallback<RetrieveFrameRendered>(root + "studies/([^/]*)/series/([^/]*)/instances/([^/]*)/frames/([^/]*)/rendered", true);
--- a/Plugin/WadoRs.cpp	Fri Feb 28 12:46:22 2020 +0100
+++ b/Plugin/WadoRs.cpp	Tue Mar 03 10:41:21 2020 +0100
@@ -708,10 +708,10 @@
 
 
 
-static bool LocateStudy(OrthancPluginRestOutput* output,
-                        std::string& orthancId,
-                        std::string& studyInstanceUid,
-                        const OrthancPluginHttpRequest* request)
+bool LocateStudy(OrthancPluginRestOutput* output,
+                 std::string& orthancId,
+                 std::string& studyInstanceUid,
+                 const OrthancPluginHttpRequest* request)
 {
   OrthancPluginContext* context = OrthancPlugins::GetGlobalContext();
 
--- a/Plugin/WadoRs.h	Fri Feb 28 12:46:22 2020 +0100
+++ b/Plugin/WadoRs.h	Tue Mar 03 10:41:21 2020 +0100
@@ -24,6 +24,11 @@
 #include "Configuration.h"
 
 
+bool LocateStudy(OrthancPluginRestOutput* output,
+                 std::string& uri,
+                 std::string& studyInstanceUid,
+                 const OrthancPluginHttpRequest* request);
+
 bool LocateSeries(OrthancPluginRestOutput* output,
                   std::string& uri,
                   std::string& studyInstanceUid,
@@ -80,3 +85,7 @@
 void RetrieveSeriesRendered(OrthancPluginRestOutput* output,
                             const char* url,
                             const OrthancPluginHttpRequest* request);
+
+void RetrieveStudyRendered(OrthancPluginRestOutput* output,
+                           const char* url,
+                           const OrthancPluginHttpRequest* request);
--- a/Plugin/WadoRsRetrieveRendered.cpp	Fri Feb 28 12:46:22 2020 +0100
+++ b/Plugin/WadoRsRetrieveRendered.cpp	Tue Mar 03 10:41:21 2020 +0100
@@ -911,16 +911,77 @@
           series[INSTANCES].type() == Json::arrayValue &&
           series[INSTANCES].size() > 0)
       {
-        Json::Value::ArrayIndex i = series[INSTANCES].size() / 2;
-        if (series[INSTANCES][i].type() == Json::stringValue)
+        std::set<std::string> ids;
+        for (Json::Value::ArrayIndex i = 0; i < series[INSTANCES].size(); i++)
         {
-          std::string instanceId = series[INSTANCES][i].asString();
-          AnswerFrameRendered(output, instanceId, 1 /* first frame */, request);
-          return;  // Success
+          if (series[INSTANCES][i].type() != Json::stringValue)
+          {
+            throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+          }
+          else
+          {
+            ids.insert(series[INSTANCES][i].asString());
+          }
         }
+
+        // Retrieve the first instance in alphanumeric order, in order
+        // to always return the same instance
+        std::string instanceId = *ids.begin();
+        AnswerFrameRendered(output, instanceId, 1 /* first frame */, request);
+        return;  // Success
       }
     }
 
     throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem, "Inexistent series");
   }
 }
+
+
+void RetrieveStudyRendered(OrthancPluginRestOutput* output,
+                           const char* url,
+                           const OrthancPluginHttpRequest* request)
+{
+  static const char* const ID = "ID";
+  
+  assert(request->groupsCount == 1);
+
+  if (request->method != OrthancPluginHttpMethod_Get)
+  {
+    OrthancPluginSendMethodNotAllowed(OrthancPlugins::GetGlobalContext(), output, "GET");
+  }
+  else
+  {
+    std::string orthancId, studyInstanceUid;
+    if (LocateStudy(output, orthancId, studyInstanceUid, request))
+    {
+      Json::Value instances;
+      if (OrthancPlugins::RestApiGet(instances, "/studies/" + orthancId + "/instances", false) &&
+          instances.type() == Json::arrayValue &&
+          instances.size() > 0)
+      {
+        std::set<std::string> ids;
+        for (Json::Value::ArrayIndex i = 0; i < instances.size(); i++)
+        {
+          if (instances[i].type() != Json::objectValue ||
+              !instances[i].isMember(ID) ||
+              instances[i][ID].type() != Json::stringValue)
+          {
+            throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+          }
+          else
+          {
+            ids.insert(instances[i][ID].asString());
+          }
+        }
+
+        // Retrieve the first instance in alphanumeric order, in order
+        // to always return the same instance
+        std::string instanceId = *ids.begin();
+        AnswerFrameRendered(output, instanceId, 1 /* first frame */, request);
+        return;  // Success
+      }
+    }
+
+    throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem, "Inexistent study");
+  }
+}