changeset 250:f2a7dba94df1

new class: DicomWebFormatter
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 26 Feb 2019 16:05:20 +0100
parents 8bcb07e58817
children 768634772ad7
files CMakeLists.txt Plugin/DicomWebFormatter.cpp Plugin/DicomWebFormatter.h Plugin/WadoRs.cpp
diffstat 4 files changed, 167 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Tue Feb 26 15:39:36 2019 +0100
+++ b/CMakeLists.txt	Tue Feb 26 16:05:20 2019 +0100
@@ -128,6 +128,7 @@
 
 add_library(OrthancDicomWeb SHARED ${CORE_SOURCES}
   ${CMAKE_SOURCE_DIR}/Plugin/DicomWebClient.cpp
+  ${CMAKE_SOURCE_DIR}/Plugin/DicomWebFormatter.cpp
   ${CMAKE_SOURCE_DIR}/Plugin/DicomWebServers.cpp
   ${CMAKE_SOURCE_DIR}/Plugin/Plugin.cpp
   ${CMAKE_SOURCE_DIR}/Plugin/QidoRs.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/DicomWebFormatter.cpp	Tue Feb 26 16:05:20 2019 +0100
@@ -0,0 +1,89 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "DicomWebFormatter.h"
+
+#include <Plugins/Samples/Common/OrthancPluginCppWrapper.h>
+
+
+namespace OrthancPlugins
+{
+  static std::string FormatTag(uint16_t group,
+                               uint16_t element)
+  {
+    char buf[16];
+    sprintf(buf, "%04x%04x", group, element);
+    return std::string(buf);
+  }
+
+
+  void DicomWebFormatter::Callback(OrthancPluginDicomWebNode *node,
+                                   OrthancPluginDicomWebSetBinaryNode setter,
+                                   uint32_t levelDepth,
+                                   const uint16_t *levelTagGroup,
+                                   const uint16_t *levelTagElement,
+                                   const uint32_t *levelIndex,
+                                   uint16_t tagGroup,
+                                   uint16_t tagElement,
+                                   OrthancPluginValueRepresentation vr)
+  {
+    std::string uri = GetSingleton().bulkRoot_;
+
+    for (size_t i = 0; i < levelDepth; i++)
+    {
+      uri += ("/" + FormatTag(levelTagGroup[i], levelTagElement[i]) + "/" +
+              boost::lexical_cast<std::string>(levelIndex[i] + 1));
+    }
+    
+    uri += "/" + FormatTag(tagGroup, tagElement);
+    
+    setter(node, OrthancPluginDicomWebBinaryMode_BulkDataUri, uri.c_str());
+  }
+
+
+  DicomWebFormatter::Locker::Locker(const std::string& bulkRoot) :
+    that_(GetSingleton()),
+    lock_(that_.mutex_)
+  {
+    that_.bulkRoot_ = bulkRoot;
+  }
+
+
+  void DicomWebFormatter::Locker::Apply(std::string& target,
+                                        OrthancPluginContext* context,
+                                        const void* data,
+                                        size_t size,
+                                        bool xml)
+  {
+    OrthancString s;
+
+    if (xml)
+    {
+      s.Assign(OrthancPluginEncodeDicomWebXml(context, data, size, Callback));
+    }
+    else
+    {
+      s.Assign(OrthancPluginEncodeDicomWebJson(context, data, size, Callback));
+    }
+
+    s.ToString(target);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugin/DicomWebFormatter.h	Tue Feb 26 16:05:20 2019 +0100
@@ -0,0 +1,70 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include <orthanc/OrthancCPlugin.h>
+
+#include <boost/thread/mutex.hpp>
+
+
+namespace OrthancPlugins
+{
+  class DicomWebFormatter : public boost::noncopyable
+  {
+  private:
+    boost::mutex  mutex_;
+    std::string   bulkRoot_;
+
+    static DicomWebFormatter& GetSingleton()
+    {
+      static DicomWebFormatter formatter;
+      return formatter;
+    }
+
+    static void Callback(OrthancPluginDicomWebNode *node,
+                         OrthancPluginDicomWebSetBinaryNode setter,
+                         uint32_t levelDepth,
+                         const uint16_t *levelTagGroup,
+                         const uint16_t *levelTagElement,
+                         const uint32_t *levelIndex,
+                         uint16_t tagGroup,
+                         uint16_t tagElement,
+                         OrthancPluginValueRepresentation vr);
+
+  public:
+    class Locker : public boost::noncopyable
+    {
+    private:
+      DicomWebFormatter&         that_;
+      boost::mutex::scoped_lock  lock_;
+
+    public:
+      Locker(const std::string& bulkRoot);
+
+      void Apply(std::string& target,
+                 OrthancPluginContext* context,
+                 const void* data,
+                 size_t size,
+                 bool xml);
+    };
+  };
+}
--- a/Plugin/WadoRs.cpp	Tue Feb 26 15:39:36 2019 +0100
+++ b/Plugin/WadoRs.cpp	Tue Feb 26 16:05:20 2019 +0100
@@ -22,6 +22,7 @@
 #include "Plugin.h"
 
 #include "Configuration.h"
+#include "DicomWebFormatter.h"
 
 #include <Core/ChunkedBuffer.h>
 #include <Core/Toolbox.h>
@@ -238,92 +239,6 @@
 }
 
 
-
-#include <boost/thread/mutex.hpp>
-
-class DicomWebFormatter : public boost::noncopyable
-{
-private:
-  boost::mutex  mutex_;
-  std::string   wadoBase_;
-
-  static DicomWebFormatter& GetSingleton()
-  {
-    static DicomWebFormatter  formatter;
-    return formatter;
-  }
-
-
-  static std::string FormatTag(uint16_t group,
-                               uint16_t element)
-  {
-    char buf[16];
-    sprintf(buf, "%04x%04x", group, element);
-    return std::string(buf);
-  }
-
-
-  static void Callback(OrthancPluginDicomWebNode *node,
-                       OrthancPluginDicomWebSetBinaryNode setter,
-                       uint32_t levelDepth,
-                       const uint16_t *levelTagGroup,
-                       const uint16_t *levelTagElement,
-                       const uint32_t *levelIndex,
-                       uint16_t tagGroup,
-                       uint16_t tagElement,
-                       OrthancPluginValueRepresentation vr)
-  {
-    std::string uri = GetSingleton().wadoBase_;
-    for (size_t i = 0; i < levelDepth; i++)
-    {
-      uri += ("/" + FormatTag(levelTagGroup[i], levelTagElement[i]) + "/" +
-              boost::lexical_cast<std::string>(levelIndex[i] + 1));
-    }
-
-    uri += "/" + FormatTag(tagGroup, tagElement);
-    
-    setter(node, OrthancPluginDicomWebBinaryMode_BulkDataUri, uri.c_str());
-  }
-
-
-public:
-  class Locker : public boost::noncopyable
-  {
-  private:
-    DicomWebFormatter&         that_;
-    boost::mutex::scoped_lock  lock_;
-
-  public:
-    Locker(const std::string& wadoBase) :
-      that_(GetSingleton()),
-      lock_(that_.mutex_)
-    {
-      that_.wadoBase_ = wadoBase;
-    }
-
-    void Apply(std::string& target,
-               OrthancPluginContext* context,
-               const void* data,
-               size_t size,
-               bool xml)
-    {
-      OrthancPlugins::OrthancString s;
-
-      if (xml)
-      {
-        s.Assign(OrthancPluginEncodeDicomWebXml(context, data, size, Callback));
-      }
-      else
-      {
-        s.Assign(OrthancPluginEncodeDicomWebJson(context, data, size, Callback));
-      }
-
-      s.ToString(target);
-    }
-  };
-};
-
-
 static bool GetDicomIdentifiers(std::string& studyInstanceUid,
                                 std::string& seriesInstanceUid,
                                 std::string& sopInstanceUid,
@@ -411,6 +326,11 @@
     std::string studyInstanceUid, seriesInstanceUid, sopInstanceUid;
     if (GetDicomIdentifiers(studyInstanceUid, seriesInstanceUid, sopInstanceUid, *it))
     {
+      const std::string bulkRoot = (wadoBase +
+                                    "studies/" + studyInstanceUid +
+                                    "/series/" + seriesInstanceUid + 
+                                    "/instances/" + sopInstanceUid + "/bulk");
+      
       OrthancPlugins::MemoryBuffer dicom;
       if (dicom.RestApiGet("/instances/" + *it + "/file", false))
       {
@@ -418,10 +338,7 @@
         
         {
           // TODO - Avoid a global mutex
-          DicomWebFormatter::Locker locker(wadoBase +
-                                           "studies/" + studyInstanceUid +
-                                           "/series/" + seriesInstanceUid + 
-                                           "/instances/" + sopInstanceUid + "/bulk");
+          OrthancPlugins::DicomWebFormatter::Locker locker(bulkRoot);
           locker.Apply(item, context, dicom.GetData(), dicom.GetSize(), isXml);
         }