changeset 99:46ec13a1177c refactoring

use of ordered-slices
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 27 Nov 2015 21:39:41 +0100
parents 745cc19aa32b
children f5b1a9267da0
files NEWS Plugin/DecodedImageAdapter.cpp Plugin/DecodedImageAdapter.h Plugin/Plugin.cpp Plugin/SeriesInformationAdapter.cpp Plugin/ViewerPrefetchPolicy.cpp Plugin/ViewerToolbox.cpp WebApplication/viewer.js
diffstat 8 files changed, 63 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Fri Nov 27 18:30:46 2015 +0100
+++ b/NEWS	Fri Nov 27 21:39:41 2015 +0100
@@ -5,9 +5,10 @@
 
 * The GDCM decoder replaces the built-in Orthanc decoder
 
-TODO : Use "/series/ordered-slices"
 TODO : Support cine and multi-frame images
 TODO : Interpolation does not work, at least with Firefox
+TODO : Remove CacheBundle_InstanceInformation
+TODO : ViewerPrefetchPolicy::ApplyInstance => problem in prefetching, seems down
 
 
 Version 1.3 (2015-11-27)
--- a/Plugin/DecodedImageAdapter.cpp	Fri Nov 27 18:30:46 2015 +0100
+++ b/Plugin/DecodedImageAdapter.cpp	Fri Nov 27 21:39:41 2015 +0100
@@ -30,23 +30,29 @@
 #include <boost/lexical_cast.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 #include <json/writer.h>
+#include <boost/regex.hpp>
 
 namespace OrthancPlugins
 {
   bool DecodedImageAdapter::ParseUri(CompressionType& type,
                                      uint8_t& compressionLevel,
                                      std::string& instanceId,
+                                     unsigned int& frameIndex,
                                      const std::string& uri)
   {
-    size_t separator = uri.find('-');
-    if (separator == std::string::npos &&
-        separator >= 1)
+    boost::regex pattern("^([a-z0-9]+)-([a-z0-9-]+)_([0-9]+)$");
+
+    boost::cmatch what;
+    if (!regex_match(uri.c_str(), what, pattern))
     {
       return false;
     }
-  
-    std::string compression = uri.substr(0, separator);
-    instanceId = uri.substr(separator + 1);
+
+    printf("[%s] [%s] [%s]\n", what[1].str().c_str(), what[2].str().c_str(), what[3].str().c_str());
+
+    std::string compression(what[1]);
+    instanceId = what[2];
+    frameIndex = boost::lexical_cast<unsigned int>(what[3]);
 
     if (compression == "deflate")
     {
@@ -82,8 +88,9 @@
     CompressionType type;
     uint8_t level;
     std::string instanceId;
+    unsigned int frameIndex;
     
-    if (!ParseUri(type, level, instanceId, uri))
+    if (!ParseUri(type, level, instanceId, frameIndex, uri))
     {
       return false;
     }
@@ -99,7 +106,7 @@
       throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource);
     }
 
-    std::auto_ptr<OrthancImageWrapper> image(decoderCache_.Decode(context_, dicom.c_str(), dicom.size(), 0 /* TODO Frame */));
+    std::auto_ptr<OrthancImageWrapper> image(decoderCache_.Decode(context_, dicom.c_str(), dicom.size(), frameIndex));
 
     Json::Value json;
     if (GetCornerstoneMetadata(json, tags, *image))
--- a/Plugin/DecodedImageAdapter.h	Fri Nov 27 18:30:46 2015 +0100
+++ b/Plugin/DecodedImageAdapter.h	Fri Nov 27 21:39:41 2015 +0100
@@ -44,6 +44,7 @@
     static bool ParseUri(CompressionType& type,
                          uint8_t& compressionLevel,
                          std::string& instanceId,
+                         unsigned int& frameIndex,
                          const std::string& uri);
 
     static bool GetCornerstoneMetadata(Json::Value& result,
--- a/Plugin/Plugin.cpp	Fri Nov 27 18:30:46 2015 +0100
+++ b/Plugin/Plugin.cpp	Fri Nov 27 21:39:41 2015 +0100
@@ -30,6 +30,7 @@
 #include "InstanceInformationAdapter.h"
 #include "SeriesInformationAdapter.h"
 #include "../Orthanc/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h"
+#include "../Orthanc/Core/Toolbox.h"
 
 
 static OrthancPluginContext* context_ = NULL;
@@ -205,33 +206,34 @@
 
 
 #if ORTHANC_STANDALONE == 0
-static int32_t ServeWebViewer(OrthancPluginRestOutput* output,
-                              const char* url,
-                              const OrthancPluginHttpRequest* request)
+static OrthancPluginErrorCode ServeWebViewer(OrthancPluginRestOutput* output,
+                                             const char* url,
+                                             const OrthancPluginHttpRequest* request)
 {
   if (request->method != OrthancPluginHttpMethod_Get)
   {
     OrthancPluginSendMethodNotAllowed(context_, output, "GET");
-    return 0;
+    return OrthancPluginErrorCode_Success;
   }
 
   const std::string path = std::string(WEB_VIEWER_PATH) + std::string(request->groups[0]);
   const char* mime = OrthancPlugins::GetMimeType(path);
 
   std::string s;
-  if (OrthancPlugins::ReadFile(s, path))
+  try
   {
+    Orthanc::Toolbox::ReadFile(s, path);
     const char* resource = s.size() ? s.c_str() : NULL;
     OrthancPluginAnswerBuffer(context_, output, resource, s.size(), mime);
   }
-  else
+  catch (Orthanc::OrthancException&)
   {
     std::string s = "Inexistent file in served folder: " + path;
     OrthancPluginLogError(context_, s.c_str());
     OrthancPluginSendHttpStatusCode(context_, output, 404);
   }
 
-  return 0;
+  return OrthancPluginErrorCode_Success;
 }
 #endif
 
--- a/Plugin/SeriesInformationAdapter.cpp	Fri Nov 27 18:30:46 2015 +0100
+++ b/Plugin/SeriesInformationAdapter.cpp	Fri Nov 27 21:39:41 2015 +0100
@@ -25,6 +25,8 @@
 
 #include "../Orthanc/Core/OrthancException.h"
 
+#include <boost/regex.hpp>
+
 namespace OrthancPlugins
 {
   bool SeriesInformationAdapter::Create(std::string& content,
@@ -33,10 +35,11 @@
     std::string message = "Ordering instances of series: " + seriesId;
     OrthancPluginLogInfo(context_, message.c_str());
 
-    Json::Value series, study, patient;
+    Json::Value series, study, patient, ordered;
     if (!GetJsonFromOrthanc(series, context_, "/series/" + seriesId) ||
         !GetJsonFromOrthanc(study, context_, "/studies/" + series["ID"].asString() + "/module?simplify") ||
         !GetJsonFromOrthanc(patient, context_, "/studies/" + series["ID"].asString() + "/module-patient?simplify") ||
+        !GetJsonFromOrthanc(ordered, context_, "/series/" + series["ID"].asString() + "/ordered-slices") ||
         !series.isMember("Instances") ||
         series["Instances"].type() != Json::arrayValue)
     {
@@ -49,6 +52,25 @@
     result["StudyDescription"] = study["StudyDescription"].asString();
     result["PatientID"] = patient["PatientID"].asString();
     result["PatientName"] = patient["PatientName"].asString();
+    result["Type"] = ordered["Type"];
+    result["Slices"] = ordered["Slices"];
+
+    boost::regex pattern("^/instances/([a-f0-9-]+)/frames/([0-9]+)$");
+
+    for (Json::Value::ArrayIndex i = 0; i < result["Slices"].size(); i++)
+    {
+      boost::cmatch what;
+      if (regex_match(result["Slices"][i].asCString(), what, pattern))
+      {
+        result["Slices"][i] = std::string(what[1]) + "_" + std::string(what[2]);
+      }
+      else
+      {
+        return false;
+      }
+    }
+
+#if 0
     result["SortedInstances"] = Json::arrayValue;
 
     SeriesVolumeSorter sorter;
@@ -74,6 +96,10 @@
       result["SortedInstances"].append(sorter.GetInstance(i));
     }
 
+    std::cout << result.toStyledString();
+
+#endif
+
     content = result.toStyledString();
 
     return true;
--- a/Plugin/ViewerPrefetchPolicy.cpp	Fri Nov 27 18:30:46 2015 +0100
+++ b/Plugin/ViewerPrefetchPolicy.cpp	Fri Nov 27 21:39:41 2015 +0100
@@ -42,12 +42,12 @@
     Json::Value json;
     Json::Reader reader;
     if (!reader.parse(content, json) ||
-        !json.isMember("SortedInstances"))
+        !json.isMember("Slices"))
     {
       return;
     }
 
-    const Json::Value& instances = json["SortedInstances"];
+    const Json::Value& instances = json["Slices"];
     if (instances.type() != Json::arrayValue)
     {
       return;
@@ -76,6 +76,8 @@
     std::string compression = path.substr(0, separator + 1);
     std::string instanceId = path.substr(separator + 1);
 
+    instanceId = instanceId.substr(0, instanceId.find('_'));
+
     Json::Value instance;
     if (!GetJsonFromOrthanc(instance, context_, "/instances/" + instanceId) ||
         !instance.isMember("ParentSeries"))
@@ -92,12 +94,12 @@
     Json::Value series;
     Json::Reader reader;
     if (!reader.parse(tmp, series) ||
-        !series.isMember("SortedInstances"))
+        !series.isMember("Slices"))
     {
       return;
     }
 
-    const Json::Value& instances = series["SortedInstances"];
+    const Json::Value& instances = series["Slices"];
     if (instances.type() != Json::arrayValue)
     {
       return;
--- a/Plugin/ViewerToolbox.cpp	Fri Nov 27 18:30:46 2015 +0100
+++ b/Plugin/ViewerToolbox.cpp	Fri Nov 27 21:39:41 2015 +0100
@@ -329,7 +329,7 @@
     OrthancPluginErrorCode code = OrthancPluginCompressJpegImage
       (context, &tmp, Convert(accessor.GetFormat()), 
        accessor.GetWidth(), accessor.GetHeight(), accessor.GetPitch(),
-       accessor.GetBuffer(), quality);
+       accessor.GetConstBuffer(), quality);
 
     if (code != OrthancPluginErrorCode_Success)
     {
--- a/WebApplication/viewer.js	Fri Nov 27 18:30:46 2015 +0100
+++ b/WebApplication/viewer.js	Fri Nov 27 21:39:41 2015 +0100
@@ -361,8 +361,8 @@
     cache: false,
     async: false,
     success: function(volume) {
-      if (volume.SortedInstances.length != 0) {
-        instances = volume.SortedInstances;
+      if (volume.Slices.length != 0) {
+        instances = volume.Slices;
         $('#topright').html(volume.PatientID + '<br/>' +
                             volume.PatientName + '<br/>' +
                             volume.StudyDescription + '<br/>' +