# HG changeset patch # User Sebastien Jodogne # Date 1448625294 -3600 # Node ID 323dd64029335532bb50be1426743501c012e86f # Parent b1a6f49b21dddb1062ed40b1a61bc42d70248949 removal of an old sample diff -r b1a6f49b21dd -r 323dd6402933 Plugins/Samples/GdcmDecoding/CMakeLists.txt --- a/Plugins/Samples/GdcmDecoding/CMakeLists.txt Fri Nov 27 12:53:32 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -project(GdcmDecoding) - -SET(ALLOW_DOWNLOADS OFF CACHE BOOL "Allow CMake to download packages") -SET(STATIC_BUILD OFF CACHE BOOL "Static build of the third-party libraries (necessary for Windows)") - -SET(USE_SYSTEM_BOOST ON CACHE BOOL "Use the system version of Boost") -SET(USE_SYSTEM_JSONCPP ON CACHE BOOL "Use the system version of JsonCpp") - -set(SAMPLES_ROOT ${CMAKE_SOURCE_DIR}/..) -include(${CMAKE_SOURCE_DIR}/../Common/OrthancPlugins.cmake) - -include(${ORTHANC_ROOT}/Resources/CMake/BoostConfiguration.cmake) -include(${ORTHANC_ROOT}/Resources/CMake/JsonCppConfiguration.cmake) - -find_package(GDCM REQUIRED) -if (GDCM_FOUND) - include(${GDCM_USE_FILE}) - set(GDCM_LIBRARIES gdcmCommon gdcmMSFF) -else(GDCM_FOUND) - message(FATAL_ERROR "Cannot find GDCM, did you set GDCM_DIR?") -endif(GDCM_FOUND) - -add_library(GdcmDecoding SHARED - Plugin.cpp - OrthancContext.cpp - - # Sources from Orthanc - ${GOOGLE_LOG_SOURCES} - ${ORTHANC_ROOT}/Core/ChunkedBuffer.cpp - ${ORTHANC_ROOT}/Core/Enumerations.cpp - ${ORTHANC_ROOT}/Core/Images/ImageAccessor.cpp - ${ORTHANC_ROOT}/Core/Images/ImageBuffer.cpp - ${ORTHANC_ROOT}/Core/Images/ImageProcessing.cpp - ${ORTHANC_ROOT}/Core/Toolbox.cpp - ${ORTHANC_ROOT}/Resources/ThirdParty/base64/base64.cpp - ${ORTHANC_ROOT}/Resources/ThirdParty/md5/md5.c - ${JSONCPP_SOURCES} - ${THIRD_PARTY_SOURCES} - ) - -target_link_libraries(GdcmDecoding ${GDCM_LIBRARIES}) diff -r b1a6f49b21dd -r 323dd6402933 Plugins/Samples/GdcmDecoding/OrthancContext.cpp --- a/Plugins/Samples/GdcmDecoding/OrthancContext.cpp Fri Nov 27 12:53:32 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/** - * 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. - * - * 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 . - **/ - - -#include "OrthancContext.h" - -#include - - -void OrthancContext::Check() -{ - if (context_ == NULL) - { - throw std::runtime_error("The Orthanc plugin context is not initialized"); - } -} - - -OrthancContext& OrthancContext::GetInstance() -{ - static OrthancContext instance; - return instance; -} - - -void OrthancContext::ExtractGetArguments(Arguments& arguments, - const OrthancPluginHttpRequest& request) -{ - Check(); - arguments.clear(); - - for (uint32_t i = 0; i < request.getCount; i++) - { - arguments[request.getKeys[i]] = request.getValues[i]; - } -} - - -void OrthancContext::LogError(const std::string& s) -{ - Check(); - OrthancPluginLogError(context_, s.c_str()); -} - - -void OrthancContext::LogWarning(const std::string& s) -{ - Check(); - OrthancPluginLogWarning(context_, s.c_str()); -} - - -void OrthancContext::LogInfo(const std::string& s) -{ - Check(); - OrthancPluginLogInfo(context_, s.c_str()); -} - - -void OrthancContext::Register(const std::string& uri, - OrthancPluginRestCallback callback) -{ - Check(); - OrthancPluginRegisterRestCallback(context_, uri.c_str(), callback); -} - - -void OrthancContext::GetDicomForInstance(std::string& result, - const std::string& instanceId) -{ - Check(); - OrthancPluginMemoryBuffer buffer; - - if (OrthancPluginGetDicomForInstance(context_, &buffer, instanceId.c_str())) - { - throw std::runtime_error("No DICOM instance with Orthanc ID: " + instanceId); - } - - if (buffer.size == 0) - { - result.clear(); - } - else - { - result.assign(reinterpret_cast(buffer.data), buffer.size); - } - - OrthancPluginFreeMemoryBuffer(context_, &buffer); -} - - -void OrthancContext::CompressAndAnswerPngImage(OrthancPluginRestOutput* output, - const Orthanc::ImageAccessor& accessor) -{ - Check(); - - OrthancPluginPixelFormat format; - switch (accessor.GetFormat()) - { - case Orthanc::PixelFormat_Grayscale8: - format = OrthancPluginPixelFormat_Grayscale8; - break; - - case Orthanc::PixelFormat_Grayscale16: - format = OrthancPluginPixelFormat_Grayscale16; - break; - - case Orthanc::PixelFormat_SignedGrayscale16: - format = OrthancPluginPixelFormat_SignedGrayscale16; - break; - - case Orthanc::PixelFormat_RGB24: - format = OrthancPluginPixelFormat_RGB24; - break; - - case Orthanc::PixelFormat_RGBA32: - format = OrthancPluginPixelFormat_RGBA32; - break; - - default: - throw std::runtime_error("Unsupported pixel format"); - } - - OrthancPluginCompressAndAnswerPngImage(context_, output, format, accessor.GetWidth(), - accessor.GetHeight(), accessor.GetPitch(), accessor.GetConstBuffer()); -} - - - -void OrthancContext::Redirect(OrthancPluginRestOutput* output, - const std::string& s) -{ - Check(); - OrthancPluginRedirect(context_, output, s.c_str()); -} diff -r b1a6f49b21dd -r 323dd6402933 Plugins/Samples/GdcmDecoding/OrthancContext.h --- a/Plugins/Samples/GdcmDecoding/OrthancContext.h Fri Nov 27 12:53:32 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/** - * 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. - * - * 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 . - **/ - - -#pragma once - -#include - -#include "../../../Core/Images/ImageBuffer.h" - -#include -#include -#include - - -class OrthancContext : public boost::noncopyable -{ -private: - OrthancPluginContext* context_; - - OrthancContext() : context_(NULL) - { - } - - void Check(); - -public: - typedef std::map Arguments; - - static OrthancContext& GetInstance(); - - void Initialize(OrthancPluginContext* context) - { - context_ = context; - } - - void Finalize() - { - context_ = NULL; - } - - void ExtractGetArguments(Arguments& arguments, - const OrthancPluginHttpRequest& request); - - void LogError(const std::string& s); - - void LogWarning(const std::string& s); - - void LogInfo(const std::string& s); - - void Register(const std::string& uri, - OrthancPluginRestCallback callback); - - void GetDicomForInstance(std::string& result, - const std::string& instanceId); - - void CompressAndAnswerPngImage(OrthancPluginRestOutput* output, - const Orthanc::ImageAccessor& accessor); - - void Redirect(OrthancPluginRestOutput* output, - const std::string& s); -}; diff -r b1a6f49b21dd -r 323dd6402933 Plugins/Samples/GdcmDecoding/Plugin.cpp --- a/Plugins/Samples/GdcmDecoding/Plugin.cpp Fri Nov 27 12:53:32 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,264 +0,0 @@ -/** - * 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. - * - * 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 . - **/ - - -#include -#include -#include -#include -#include - -#include "OrthancContext.h" -#include "../../../Core/Images/ImageProcessing.h" - -#include -#include -#include - - -static void AnswerUnsupportedImage(OrthancPluginRestOutput* output) -{ - OrthancContext::GetInstance().Redirect(output, "/app/images/unsupported.png"); -} - - -static bool GetOrthancPixelFormat(Orthanc::PixelFormat& format, - const gdcm::Image& image) -{ - if (image.GetPlanarConfiguration() != 0 && - image.GetPixelFormat().GetSamplesPerPixel() != 1) - { - OrthancContext::GetInstance().LogError("Planar configurations are not supported"); - return false; - } - - if (image.GetPixelFormat().GetSamplesPerPixel() == 1) - { - switch (image.GetPixelFormat().GetScalarType()) - { - case gdcm::PixelFormat::UINT8: - format = Orthanc::PixelFormat_Grayscale8; - return true; - - case gdcm::PixelFormat::UINT16: - format = Orthanc::PixelFormat_Grayscale16; - return true; - - case gdcm::PixelFormat::INT16: - format = Orthanc::PixelFormat_SignedGrayscale16; - return true; - - default: - return false; - } - } - else if (image.GetPixelFormat().GetSamplesPerPixel() == 3 && - image.GetPixelFormat().GetScalarType() == gdcm::PixelFormat::UINT8) - { - format = Orthanc::PixelFormat_RGB24; - return true; - } - else if (image.GetPixelFormat().GetSamplesPerPixel() == 4 && - image.GetPixelFormat().GetScalarType() == gdcm::PixelFormat::UINT8) - { - format = Orthanc::PixelFormat_RGBA32; - return true; - } - - return false; -} - - -ORTHANC_PLUGINS_API OrthancPluginErrorCode DecodeImage(OrthancPluginRestOutput* output, - const char* url, - const OrthancPluginHttpRequest* request) -{ - std::string instance(request->groups[0]); - std::string outputFormat(request->groups[1]); - OrthancContext::GetInstance().LogWarning("Using GDCM to decode instance " + instance); - - // Download the request DICOM instance from Orthanc into a memory buffer - std::string dicom; - OrthancContext::GetInstance().GetDicomForInstance(dicom, instance); - - // Prepare a memory stream over the DICOM instance - std::stringstream stream(dicom); - - // Parse the DICOM instance using GDCM - gdcm::ImageReader imageReader; - imageReader.SetStream(stream); - if (!imageReader.Read()) - { - OrthancContext::GetInstance().LogError("GDCM cannot extract an image from this DICOM instance"); - AnswerUnsupportedImage(output); - return OrthancPluginErrorCode_Success; - } - - gdcm::Image& image = imageReader.GetImage(); - - - // Log information about the decoded image - char tmp[1024]; - sprintf(tmp, "Image format: %dx%d %s with %d color channel(s)", image.GetRows(), image.GetColumns(), - image.GetPixelFormat().GetScalarTypeAsString(), image.GetPixelFormat().GetSamplesPerPixel()); - OrthancContext::GetInstance().LogWarning(tmp); - - - // Convert planar configuration - gdcm::ImageChangePlanarConfiguration planar; - if (image.GetPlanarConfiguration() != 0 && - image.GetPixelFormat().GetSamplesPerPixel() != 1) - { - OrthancContext::GetInstance().LogWarning("Converting planar configuration to interleaved"); - planar.SetInput(imageReader.GetImage()); - planar.Change(); - image = planar.GetOutput(); - } - - - // Create a read-only accessor to the bitmap decoded by GDCM - Orthanc::PixelFormat format; - if (!GetOrthancPixelFormat(format, image)) - { - OrthancContext::GetInstance().LogError("This sample plugin does not support this image format"); - AnswerUnsupportedImage(output); - return OrthancPluginErrorCode_Success; - } - - Orthanc::ImageAccessor decodedImage; - std::vector decodedBuffer(image.GetBufferLength()); - - if (decodedBuffer.size()) - { - image.GetBuffer(&decodedBuffer[0]); - unsigned int pitch = image.GetColumns() * ::Orthanc::GetBytesPerPixel(format); - decodedImage.AssignWritable(format, image.GetColumns(), image.GetRows(), pitch, &decodedBuffer[0]); - } - else - { - // Empty image - decodedImage.AssignWritable(format, 0, 0, 0, NULL); - } - - - // Convert the pixel format from GDCM to the format requested by the REST query - Orthanc::ImageBuffer converted; - converted.SetWidth(decodedImage.GetWidth()); - converted.SetHeight(decodedImage.GetHeight()); - - if (outputFormat == "preview") - { - if (format == Orthanc::PixelFormat_RGB24 || - format == Orthanc::PixelFormat_RGBA32) - { - // Do not rescale color image - converted.SetFormat(Orthanc::PixelFormat_RGB24); - } - else - { - converted.SetFormat(Orthanc::PixelFormat_Grayscale8); - - // Rescale the image to the [0,255] range - int64_t a, b; - Orthanc::ImageProcessing::GetMinMaxValue(a, b, decodedImage); - - float offset = -a; - float scaling = 255.0f / static_cast(b - a); - Orthanc::ImageProcessing::ShiftScale(decodedImage, offset, scaling); - } - } - else - { - if (format == Orthanc::PixelFormat_RGB24 || - format == Orthanc::PixelFormat_RGBA32) - { - // Do not convert color images to grayscale values (this is Orthanc convention) - AnswerUnsupportedImage(output); - return OrthancPluginErrorCode_Success; - } - - if (outputFormat == "image-uint8") - { - converted.SetFormat(Orthanc::PixelFormat_Grayscale8); - } - else if (outputFormat == "image-uint16") - { - converted.SetFormat(Orthanc::PixelFormat_Grayscale16); - } - else if (outputFormat == "image-int16") - { - converted.SetFormat(Orthanc::PixelFormat_SignedGrayscale16); - } - else - { - OrthancContext::GetInstance().LogError("Unknown output format: " + outputFormat); - AnswerUnsupportedImage(output); - return OrthancPluginErrorCode_Success; - } - } - - Orthanc::ImageAccessor convertedAccessor(converted.GetAccessor()); - Orthanc::ImageProcessing::Convert(convertedAccessor, decodedImage); - - // Compress the converted image as a PNG file - OrthancContext::GetInstance().CompressAndAnswerPngImage(output, convertedAccessor); - - return OrthancPluginErrorCode_Success; // Success -} - - -extern "C" -{ - ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) - { - OrthancContext::GetInstance().Initialize(context); - OrthancContext::GetInstance().LogWarning("Initializing GDCM decoding"); - - // Check the version of the Orthanc core - if (OrthancPluginCheckVersion(context) == 0) - { - OrthancContext::GetInstance().LogError( - "Your version of Orthanc (" + std::string(context->orthancVersion) + - ") must be above " + boost::lexical_cast(ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER) + - "." + boost::lexical_cast(ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER) + - "." + boost::lexical_cast(ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER) + - " to run this plugin"); - return -1; - } - - OrthancContext::GetInstance().Register("/instances/([^/]+)/(preview|image-uint8|image-uint16|image-int16)", DecodeImage); - return 0; - } - - ORTHANC_PLUGINS_API void OrthancPluginFinalize() - { - OrthancContext::GetInstance().LogWarning("Finalizing GDCM decoding"); - OrthancContext::GetInstance().Finalize(); - } - - ORTHANC_PLUGINS_API const char* OrthancPluginGetName() - { - return "gdcm-decoding"; - } - - ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() - { - return "1.0"; - } -}