changeset 1738:15a788a63846

DicomToJsonFlags_IncludeBinary
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 22 Oct 2015 09:28:08 +0200
parents ec66a16aa398
children df331354cea2
files CMakeLists.txt Core/DicomFormat/DicomValue.cpp Core/DicomFormat/DicomValue.h OrthancServer/FromDcmtkBridge.cpp OrthancServer/ServerEnumerations.h
diffstat 5 files changed, 179 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Thu Oct 22 07:52:24 2015 +0200
+++ b/CMakeLists.txt	Thu Oct 22 09:28:08 2015 +0200
@@ -96,6 +96,7 @@
   Core/DicomFormat/DicomImageInformation.cpp
   Core/DicomFormat/DicomIntegerPixelAccessor.cpp
   Core/DicomFormat/DicomInstanceHasher.cpp
+  Core/DicomFormat/DicomValue.cpp
   Core/Enumerations.cpp
   Core/FileStorage/FilesystemStorage.cpp
   Core/FileStorage/StorageAccessor.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Core/DicomFormat/DicomValue.cpp	Thu Oct 22 09:28:08 2015 +0200
@@ -0,0 +1,90 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * In addition, as a special exception, the copyright holders of this
+ * program give permission to link the code of its release with the
+ * OpenSSL project's "OpenSSL" library (or with modified versions of it
+ * that use the same license as the "OpenSSL" library), and distribute
+ * the linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s) with this exception, you may extend this exception to
+ * your version of the file(s), but you are not obligated to do so. If
+ * you do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source files
+ * in the program, then also delete it here.
+ * 
+ * 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "../PrecompiledHeaders.h"
+#include "DicomValue.h"
+
+#include "../OrthancException.h"
+#include "../Toolbox.h"
+
+namespace Orthanc
+{
+  DicomValue::DicomValue(const DicomValue& other) : 
+    type_(other.type_),
+    content_(other.content_)
+  {
+  }
+
+
+  DicomValue::DicomValue(const std::string& content,
+                         bool isBinary) :
+    type_(isBinary ? Type_Binary : Type_String),
+    content_(content)
+  {
+  }
+  
+  
+  DicomValue::DicomValue(const char* data,
+                         size_t size,
+                         bool isBinary) :
+    type_(isBinary ? Type_Binary : Type_String)
+  {
+    content_.assign(data, size);
+  }
+    
+  
+  const std::string& DicomValue::GetContent() const
+  {
+    if (type_ == Type_Null)
+    {
+      throw OrthancException(ErrorCode_BadParameterType);
+    }
+    else
+    {
+      return content_;
+    }
+  }
+
+
+  DicomValue* DicomValue::Clone() const
+  {
+    return new DicomValue(*this);
+  }
+
+  
+  void DicomValue::FormatDataUriScheme(std::string& target,
+                                       const std::string& mime) const
+  {
+    Toolbox::EncodeBase64(target, GetContent());
+    target.insert(0, "data:" + mime + ";base64,");
+  }
+}
--- a/Core/DicomFormat/DicomValue.h	Thu Oct 22 07:52:24 2015 +0200
+++ b/Core/DicomFormat/DicomValue.h	Thu Oct 22 09:28:08 2015 +0200
@@ -32,8 +32,6 @@
 
 #pragma once
 
-#include "../OrthancException.h"
-
 #include <string>
 #include <boost/noncopyable.hpp>
 
@@ -52,11 +50,7 @@
     Type         type_;
     std::string  content_;
 
-    DicomValue(const DicomValue& other) : 
-      type_(other.type_),
-      content_(other.content_)
-    {
-    }
+    DicomValue(const DicomValue& other);
 
   public:
     DicomValue() : type_(Type_Null)
@@ -64,31 +58,13 @@
     }
     
     DicomValue(const std::string& content,
-               bool isBinary) :
-      type_(isBinary ? Type_Binary : Type_String),
-      content_(content)
-    {
-    }
+               bool isBinary);
     
     DicomValue(const char* data,
                size_t size,
-               bool isBinary) :
-      type_(isBinary ? Type_Binary : Type_String)
-    {
-      content_.assign(data, size);
-    }
+               bool isBinary);
     
-    const std::string& GetContent() const
-    {
-      if (type_ == Type_Null)
-      {
-        throw OrthancException(ErrorCode_BadParameterType);
-      }
-      else
-      {
-        return content_;
-      }
-    }
+    const std::string& GetContent() const;
 
     bool IsNull() const
     {
@@ -100,9 +76,14 @@
       return type_ == Type_Binary;
     }
     
-    DicomValue* Clone() const
+    DicomValue* Clone() const;
+
+    void FormatDataUriScheme(std::string& target,
+                             const std::string& mime) const;
+
+    void FormatDataUriScheme(std::string& target) const
     {
-      return new DicomValue(*this);
+      FormatDataUriScheme(target, "application/octet-stream");
     }
   };
 }
--- a/OrthancServer/FromDcmtkBridge.cpp	Thu Oct 22 07:52:24 2015 +0200
+++ b/OrthancServer/FromDcmtkBridge.cpp	Thu Oct 22 09:28:08 2015 +0200
@@ -400,14 +400,28 @@
       {
 
         /**
-         * TODO.
+         * Deal with binary data (including PixelData).
          **/
 
         case EVR_OB:  // other byte
         case EVR_OF:  // other float
         case EVR_OW:  // other word
         case EVR_UN:  // unknown value representation
+        {
+          DicomTag tag(Convert(element.getTag()));
+
+          if ((tag == DICOM_TAG_PIXEL_DATA && flags & DicomToJsonFlags_IncludePixelData) ||
+              (tag != DICOM_TAG_PIXEL_DATA && flags & DicomToJsonFlags_IncludeBinary))
+          {
+            Uint8* data = NULL;
+            if (element.getUint8Array(data) == EC_Normal)
+            {
+              return new DicomValue(reinterpret_cast<const char*>(data), element.getLength(), true);
+            } 
+          }
+
           return new DicomValue;
+        }
     
           /**
            * String types, should never happen at this point because of
@@ -621,54 +635,82 @@
   static void LeafValueToJson(Json::Value& target,
                               const DicomValue& value,
                               DicomToJsonFormat format,
+                              DicomToJsonFlags flags,
                               unsigned int maxStringLength)
   {
+    Json::Value* targetValue = NULL;
+    Json::Value* targetType = NULL;
+
     switch (format)
     {
       case DicomToJsonFormat_Short:
       case DicomToJsonFormat_Simple:
       {
         assert(target.type() == Json::nullValue);
-
-        if (!value.IsNull() &&
-            (maxStringLength == 0 ||
-             value.GetContent().size() <= maxStringLength))
-        {
-          target = value.GetContent();
-        }
-
+        targetValue = &target;
         break;
       }      
 
       case DicomToJsonFormat_Full:
       {
         assert(target.type() == Json::objectValue);
-
-        if (value.IsNull())
-        {
-          target["Type"] = "Null";
-          target["Value"] = Json::nullValue;
-        }
-        else
-        {
-          if (maxStringLength == 0 ||
-              value.GetContent().size() <= maxStringLength)
-          {
-            target["Type"] = "String";
-            target["Value"] = value.GetContent();
-          }
-          else
-          {
-            target["Type"] = "TooLong";
-            target["Value"] = Json::nullValue;
-          }
-        }
+        target["Value"] = Json::nullValue;
+        target["Type"] = Json::nullValue;
+        targetType = &target["Type"];
+        targetValue = &target["Value"];
         break;
       }
 
       default:
         throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
+
+    assert(targetValue != NULL);
+    assert(targetValue->type() == Json::nullValue);
+    assert(targetType == NULL || targetType->type() == Json::nullValue);
+
+    if (value.IsNull())
+    {
+      if (targetType != NULL)
+      {
+        *targetType = "Null";
+      }
+    }
+    else if (value.IsBinary())
+    {
+      if (flags & DicomToJsonFlags_ConvertBinaryToAscii)
+      {
+        *targetValue = Toolbox::ConvertToAscii(value.GetContent());
+      }
+      else
+      {
+        std::string s;
+        value.FormatDataUriScheme(s);
+        *targetValue = s;
+      }
+
+      if (targetType != NULL)
+      {
+        *targetType = "Binary";
+      }
+    }
+    else if (maxStringLength == 0 ||
+             value.GetContent().size() <= maxStringLength)
+    {
+      *targetValue = value.GetContent();
+
+      if (targetType != NULL)
+      {
+        *targetType = "String";
+      }
+    }
+    else
+    {
+      if (targetType != NULL)
+      {
+        *targetType = "TooLong";
+      }
+    }
   }                              
 
 
@@ -698,7 +740,7 @@
     if (element.isLeaf())
     {
       std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(element, flags, encoding));
-      LeafValueToJson(target, *v, format, maxStringLength);
+      LeafValueToJson(target, *v, format, flags, maxStringLength);
     }
     else
     {
--- a/OrthancServer/ServerEnumerations.h	Thu Oct 22 07:52:24 2015 +0200
+++ b/OrthancServer/ServerEnumerations.h	Thu Oct 22 09:28:08 2015 +0200
@@ -110,11 +110,11 @@
 
   enum DicomToJsonFlags
   {
-    DicomToJsonFlags_IncludeBinary           = (1 << 0),
-    DicomToJsonFlags_IncludePrivateTags      = (1 << 1),
-    DicomToJsonFlags_IncludeUnknownTags      = (1 << 2),
-    DicomToJsonFlags_IncludePixelData        = (1 << 3),
-    DicomToJsonFlags_DataUriSchemeForBinary  = (1 << 4),
+    DicomToJsonFlags_IncludeBinary         = (1 << 0),
+    DicomToJsonFlags_IncludePrivateTags    = (1 << 1),
+    DicomToJsonFlags_IncludeUnknownTags    = (1 << 2),
+    DicomToJsonFlags_IncludePixelData      = (1 << 3),
+    DicomToJsonFlags_ConvertBinaryToAscii  = (1 << 4),
 
     // Some predefined combinations
     DicomToJsonFlags_None               = 0,