diff Framework/Enumerations.cpp @ 0:4a7a53257c7d

initial commit
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 22 Oct 2016 21:48:33 +0200
parents
children 7a88c614be04
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Enumerations.cpp	Sat Oct 22 21:48:33 2016 +0200
@@ -0,0 +1,184 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 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 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 "Enumerations.h"
+
+#include "Jpeg2000Reader.h"
+#include "Orthanc/Core/OrthancException.h"
+#include "Orthanc/Core/Toolbox.h"
+
+#include <string.h>
+#include <boost/algorithm/string/predicate.hpp>
+
+#define HEADER(s) (const void*) (s), sizeof(s)-1
+
+namespace OrthancWSI
+{
+  const char* EnumerationToString(ImageCompression compression)
+  {
+    switch (compression)
+    {
+      case ImageCompression_Unknown:
+        return "Unknown";
+
+      case ImageCompression_None:
+        return "Raw image";
+
+      case ImageCompression_Png:
+        return "PNG";
+
+      case ImageCompression_Jpeg:
+        return "JPEG";
+
+      case ImageCompression_Jpeg2000:
+        return "JPEG2000";
+
+      case ImageCompression_Tiff:
+        return "TIFF";
+
+      case ImageCompression_Dicom:
+        return "DICOM";
+
+      default:
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
+    }
+  }
+
+
+  static bool MatchHeader(const void* actual,
+                          size_t actualSize,
+                          const void* expected,
+                          size_t expectedSize)
+  {
+    if (actualSize < expectedSize)
+    {
+      return false;
+    }
+    else
+    {
+      return memcmp(actual, expected, expectedSize) == 0;
+    }
+  }
+
+
+  ImageCompression DetectFormatFromFile(const std::string& path)
+  {
+    std::string header;
+    Orthanc::Toolbox::ReadHeader(header, path, 256);
+
+    ImageCompression tmp = DetectFormatFromMemory(header.c_str(), header.size());
+    if (tmp != ImageCompression_Unknown)
+    {
+      return tmp;
+    }
+
+    // Cannot detect the format using the header, fallback to the use
+    // of the filename extension
+    
+    std::string lower;
+    Orthanc::Toolbox::ToLowerCase(lower, path);
+
+    if (boost::algorithm::ends_with(lower, ".jpeg") ||
+        boost::algorithm::ends_with(lower, ".jpg"))
+    {
+      return ImageCompression_Jpeg;
+    }
+
+    if (boost::algorithm::ends_with(lower, ".png"))
+    {
+      return ImageCompression_Png;
+    }
+
+    if (boost::algorithm::ends_with(lower, ".tiff") ||
+        boost::algorithm::ends_with(lower, ".tif"))
+    {
+      return ImageCompression_Tiff;
+    }
+
+    if (boost::algorithm::ends_with(lower, ".jp2") ||
+        boost::algorithm::ends_with(lower, ".j2k"))
+    {
+      return ImageCompression_Jpeg2000;
+    }
+
+    if (boost::algorithm::ends_with(lower, ".dcm"))
+    {
+      return ImageCompression_Dicom;
+    }
+
+    return ImageCompression_Unknown;
+  }
+
+
+  ImageCompression DetectFormatFromMemory(const void* buffer,
+                                          size_t size) 
+  {
+    if (MatchHeader(buffer, size, HEADER("\377\330\377")))
+    {
+      return ImageCompression_Jpeg;
+    }
+
+    if (MatchHeader(buffer, size, HEADER("\xff\x4f\xff\x51")) ||
+        MatchHeader(buffer, size, HEADER("\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a")))
+    {
+      return ImageCompression_Jpeg2000;
+    }
+
+    if (MatchHeader(buffer, size, HEADER("\211PNG\r\n\032\n")))
+    {
+      return ImageCompression_Png;
+    }
+
+    if (MatchHeader(buffer, size, HEADER("\115\115\000\052")) ||
+        MatchHeader(buffer, size, HEADER("\111\111\052\000")) ||
+        MatchHeader(buffer, size, HEADER("\115\115\000\053\000\010\000\000")) ||
+        MatchHeader(buffer, size, HEADER("\111\111\053\000\010\000\000\000")))
+    {
+      return ImageCompression_Tiff;
+    }
+
+    if (size >= 128 + 4 &&
+        MatchHeader(reinterpret_cast<const uint8_t*>(buffer) + 128, size - 128, HEADER("DICM")))
+    {
+      bool ok = true;
+      for (size_t i = 0; ok && i < 128; i++)
+      {
+        if (reinterpret_cast<const uint8_t*>(buffer)[i] != 0)
+        {
+          ok = false;
+        }
+      }
+
+      if (ok)
+      {
+        return ImageCompression_Dicom;
+      }
+    }        
+
+    Jpeg2000Format jpeg2000 = Jpeg2000Reader::DetectFormatFromMemory(buffer, size);
+    if (jpeg2000 == Jpeg2000Format_JP2 ||
+        jpeg2000 == Jpeg2000Format_J2K)
+    {
+      return ImageCompression_Jpeg2000;
+    }
+    
+    return ImageCompression_Unknown;
+  }
+}