changeset 3935:09262122934c transcoding

Moved the GDCM sample plugin out of the Orthanc repository as a separate plugin
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 15 May 2020 15:48:15 +0200
parents 0b59e2706366
children 01d4667f5c44
files NEWS Plugins/Samples/GdcmDecoder/CMakeLists.txt Plugins/Samples/GdcmDecoder/GdcmConfiguration.cmake Plugins/Samples/GdcmDecoder/GdcmDecoderCache.cpp Plugins/Samples/GdcmDecoder/GdcmDecoderCache.h Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h Plugins/Samples/GdcmDecoder/Plugin.cpp Plugins/Samples/GdcmDecoder/README
diffstat 9 files changed, 1 insertions(+), 1286 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Fri May 15 15:15:58 2020 +0200
+++ b/NEWS	Fri May 15 15:48:15 2020 +0200
@@ -48,6 +48,7 @@
 Maintenance
 -----------
 
+* Moved the GDCM sample plugin out of the Orthanc repository as a separate plugin
 * Fix missing body in "OrthancPluginHttpPost()" and "OrthancPluginHttpPut()"
 * Fix issue #169 (TransferSyntaxUID change from Explicit to Implicit during C-STORE SCU)
 * Upgraded dependencies for static builds (notably on Windows and LSB):
--- a/Plugins/Samples/GdcmDecoder/CMakeLists.txt	Fri May 15 15:15:58 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-# Orthanc - A Lightweight, RESTful DICOM Store
-# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
-# Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2020 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/>.
-
-
-cmake_minimum_required(VERSION 2.8)
-
-project(GdcmDecoder)
-
-SET(PLUGIN_VERSION "mainline" CACHE STRING "Version of the plugin")
-
-
-# Parameters of the build
-set(STATIC_BUILD OFF CACHE BOOL "Static build of the third-party libraries (necessary for Windows)")
-set(STANDALONE_BUILD ON CACHE BOOL "Standalone build (all the resources are embedded, necessary for releases)")
-set(ALLOW_DOWNLOADS OFF CACHE BOOL "Allow CMake to download packages")
-
-# Advanced parameters to fine-tune linking against system libraries
-set(USE_SYSTEM_GDCM ON CACHE BOOL "Use the system version of Grassroot DICOM (GDCM)")
-set(USE_SYSTEM_ORTHANC_SDK ON CACHE BOOL "Use the system version of the Orthanc plugin SDK")
-
-# Setup the Orthanc framework
-set(ORTHANC_ROOT ${CMAKE_SOURCE_DIR}/../../..)
-
-set(ORTHANC_FRAMEWORK_PLUGIN ON)
-include(${ORTHANC_ROOT}/Resources/CMake/OrthancFrameworkParameters.cmake)
-
-set(ENABLE_LOCALE OFF CACHE INTERNAL "")      # Disable support for locales (notably in Boost)
-set(ENABLE_MODULE_IMAGES OFF CACHE INTERNAL "")
-set(ENABLE_MODULE_JOBS OFF CACHE INTERNAL "")
-
-include(${ORTHANC_ROOT}/Resources/CMake/OrthancFrameworkConfiguration.cmake)
-
-include(GdcmConfiguration.cmake)
-
-
-# Check that the Orthanc SDK headers are available
-if (STATIC_BUILD OR NOT USE_SYSTEM_ORTHANC_SDK)
-  #include_directories(${CMAKE_SOURCE_DIR}/Resources/Orthanc/Sdk-0.9.5)
-  include_directories(${CMAKE_SOURCE_DIR}/../../Include) # TODO => SYNC 0.9.5
-else ()
-  CHECK_INCLUDE_FILE_CXX(orthanc/OrthancCPlugin.h HAVE_ORTHANC_H)
-  if (NOT HAVE_ORTHANC_H)
-    message(FATAL_ERROR "Please install the headers of the Orthanc plugins SDK")
-  endif()
-endif()
-
-
-include_directories(${ORTHANC_ROOT})
-
-add_definitions(
-  -DPLUGIN_VERSION="${PLUGIN_VERSION}"
-  -DHAS_ORTHANC_EXCEPTION=1
-  -DORTHANC_ENABLE_LOGGING_PLUGIN=1
-  )
-
-add_library(GdcmDecoder SHARED
-  GdcmDecoderCache.cpp
-  GdcmImageDecoder.cpp
-  Plugin.cpp
-  ${CMAKE_SOURCE_DIR}/../Common/OrthancPluginCppWrapper.cpp
-  ${ORTHANC_CORE_SOURCES}
-  )
-
-target_link_libraries(GdcmDecoder ${GDCM_LIBRARIES})
-
-if (STATIC_BUILD OR NOT USE_SYSTEM_GDCM)
-  add_dependencies(GdcmDecoder GDCM)
-endif()
--- a/Plugins/Samples/GdcmDecoder/GdcmConfiguration.cmake	Fri May 15 15:15:58 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-# Orthanc - A Lightweight, RESTful DICOM Store
-# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
-# Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2020 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/>.
-
-
-if (STATIC_BUILD OR NOT USE_SYSTEM_GDCM)
-  if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD")
-    # If using gcc, build GDCM with the "-fPIC" argument to allow its
-    # embedding into the shared library containing the Orthanc plugin
-    set(AdditionalCFlags "-fPIC")
-    set(AdditionalCxxFlags ${AdditionalCFlags})
-  elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows" AND
-      CMAKE_COMPILER_IS_GNUCXX)
-    # Prevents error: "jump to label ‘err’ crosses initialization" of some variable
-    # within "Source/Common/gdcmCAPICryptographicMessageSyntax.cxx" if using MinGW
-    set(AdditionalCxxFlags "-fpermissive")
-  elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
-    # This definition is necessary to compile
-    # "Source/MediaStorageAndFileFormat/gdcmFileStreamer.cxx"
-    set(AdditionalCFlags "-Doff64_t=off_t") 
-    set(AdditionalCxxFlags ${AdditionalCFlags})
-  endif()
-  
-  set(Flags
-    "-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} ${AdditionalCFlags}"
-    "-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} ${AdditionalCxxFlags}"
-    -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG}
-    -DCMAKE_CXX_FLAGS_DEBUG=${CMAKE_CXX_FLAGS_DEBUG}
-    -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE}
-    -DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE}
-    -DCMAKE_C_FLAGS_MINSIZEREL=${CMAKE_C_FLAGS_MINSIZEREL}
-    -DCMAKE_CXX_FLAGS_MINSIZEREL=${CMAKE_CXX_FLAGS_MINSIZEREL} 
-    -DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO} 
-    -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}
-    )
-
-  if (CMAKE_TOOLCHAIN_FILE)
-    # Take absolute path to the toolchain
-    get_filename_component(TMP ${CMAKE_TOOLCHAIN_FILE} REALPATH BASE ${CMAKE_SOURCE_DIR})
-    list(APPEND Flags -DCMAKE_TOOLCHAIN_FILE=${TMP})
-  endif()
-
-  # Don't build manpages (since gdcm 2.8.4)
-  list(APPEND Flags -DGDCM_BUILD_DOCBOOK_MANPAGES=OFF)
-
-  if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase")
-    # Trick to disable the compilation of socket++ by gdcm, which is
-    # incompatible with LSB, but fortunately only required for DICOM
-    # Networking
-    list(APPEND Flags -DGDCM_USE_SYSTEM_SOCKETXX=ON)
-
-    # Detect the number of CPU cores to run "make" with as much
-    # parallelism as possible
-    include(ProcessorCount)
-    ProcessorCount(N)
-    if (NOT N EQUAL 0)
-      set(MAKE_PARALLEL -j${N})
-    endif()
-      
-    # For Linux Standard Base, avoid building incompatible target gdcmMEXD (*)
-    set(BUILD_COMMAND BUILD_COMMAND
-      ${CMAKE_MAKE_PROGRAM} ${MAKE_PARALLEL}
-      gdcmMSFF gdcmcharls gdcmDICT gdcmDSED gdcmIOD gdcmjpeg8
-      gdcmjpeg12 gdcmjpeg16 gdcmopenjp2 gdcmzlib gdcmCommon gdcmexpat)
-  endif()
-
-  include(ExternalProject)
-  externalproject_add(GDCM
-    URL "http://orthanc.osimis.io/ThirdPartyDownloads/gdcm-3.0.4.tar.gz"
-    URL_MD5 "f12dbded708356d5fa0b5ed37ccdb66e"
-    TIMEOUT 60
-    CMAKE_ARGS -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} ${Flags}
-    ${BUILD_COMMAND}    # Customize "make", only for Linux Standard Base (*)
-    INSTALL_COMMAND ""  # Skip the install step
-    )
-
-  if(MSVC)
-    set(Suffix ".lib")
-    set(Prefix "")
-  else()
-    set(Suffix ".a")
-    list(GET CMAKE_FIND_LIBRARY_PREFIXES 0 Prefix)
-  endif()
-
-  set(GDCM_LIBRARIES
-    # WARNING: The order of the libraries below *is* important!
-    ${Prefix}gdcmMSFF${Suffix}
-    ${Prefix}gdcmcharls${Suffix}
-    ${Prefix}gdcmDICT${Suffix}
-    ${Prefix}gdcmDSED${Suffix}
-    ${Prefix}gdcmIOD${Suffix}
-    ${Prefix}gdcmjpeg8${Suffix}
-    ${Prefix}gdcmjpeg12${Suffix}
-    ${Prefix}gdcmjpeg16${Suffix}
-    ${Prefix}gdcmopenjp2${Suffix}
-    ${Prefix}gdcmzlib${Suffix}
-    ${Prefix}gdcmCommon${Suffix}
-    ${Prefix}gdcmexpat${Suffix}
-
-    #${Prefix}socketxx${Suffix}
-    #${Prefix}gdcmMEXD${Suffix}  # DICOM Networking, unneeded by Orthanc plugins
-    #${Prefix}gdcmgetopt${Suffix}
-    #${Prefix}gdcmuuid${Suffix}
-    )
-
-  ExternalProject_Get_Property(GDCM binary_dir)
-  include_directories(${binary_dir}/Source/Common)
-  link_directories(${binary_dir}/bin)
-
-  ExternalProject_Get_Property(GDCM source_dir)
-  include_directories(
-    ${source_dir}/Source/Common
-    ${source_dir}/Source/MediaStorageAndFileFormat
-    ${source_dir}/Source/DataStructureAndEncodingDefinition
-    )
-
-else()
-  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)
-endif()
--- a/Plugins/Samples/GdcmDecoder/GdcmDecoderCache.cpp	Fri May 15 15:15:58 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., 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 <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "GdcmDecoderCache.h"
-
-#include "../../../Core/Compatibility.h"
-
-namespace OrthancPlugins
-{
-  std::string GdcmDecoderCache::ComputeMd5(const void* dicom,
-                                           size_t size)
-  {
-    std::string result;
-
-    char* md5 = OrthancPluginComputeMd5(OrthancPlugins::GetGlobalContext(), dicom, size);
-
-    if (md5 == NULL)
-    {
-      throw std::runtime_error("Cannot compute MD5 hash");
-    }
-
-    bool ok = false;
-    try
-    {
-      result.assign(md5);
-      ok = true;
-    }
-    catch (...)
-    {
-    }
-
-    OrthancPluginFreeString(OrthancPlugins::GetGlobalContext(), md5);
-
-    if (!ok)
-    {
-      throw std::runtime_error("Not enough memory");
-    }
-    else
-    {    
-      return result;
-    }
-  }
-
-
-  OrthancImage* GdcmDecoderCache::Decode(const void* dicom,
-                                         const uint32_t size,
-                                         uint32_t frameIndex)
-  {
-    std::string md5 = ComputeMd5(dicom, size);
-
-    // First check whether the previously decoded image is the same
-    // as this one
-    {
-      boost::mutex::scoped_lock lock(mutex_);
-
-      if (decoder_.get() != NULL &&
-          size_ == size &&
-          md5_ == md5)
-      {
-        // This is the same image: Reuse the previous decoding
-        return new OrthancImage(decoder_->Decode(frameIndex));
-      }
-    }
-
-    // This is not the same image
-    std::unique_ptr<GdcmImageDecoder> decoder(new GdcmImageDecoder(dicom, size));
-    std::unique_ptr<OrthancImage> image(new OrthancImage(decoder->Decode(frameIndex)));
-
-    {
-      // Cache the newly created decoder for further use
-      boost::mutex::scoped_lock lock(mutex_);
-      decoder_.reset(decoder.release());
-      size_ = size;
-      md5_ = md5;
-    }
-
-    return image.release();
-  }
-}
--- a/Plugins/Samples/GdcmDecoder/GdcmDecoderCache.h	Fri May 15 15:15:58 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., 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 <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../../Core/Compatibility.h"
-#include "GdcmImageDecoder.h"
-#include "../Common/OrthancPluginCppWrapper.h"
-
-#include <boost/thread.hpp>
-
-
-namespace OrthancPlugins
-{
-  class GdcmDecoderCache : public boost::noncopyable
-  {
-  private:
-    boost::mutex   mutex_;
-    std::unique_ptr<OrthancPlugins::GdcmImageDecoder>  decoder_;
-    size_t       size_;
-    std::string  md5_;
-
-    static std::string ComputeMd5(const void* dicom,
-                                  size_t size);
-
-  public:
-    GdcmDecoderCache() : size_(0)
-    {
-    }
-
-    OrthancImage* Decode(const void* dicom,
-                         const uint32_t size,
-                         uint32_t frameIndex);
-  };
-}
--- a/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp	Fri May 15 15:15:58 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,408 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., 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 <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "GdcmImageDecoder.h"
-
-#include "../../../Core/Compatibility.h"
-
-#include <gdcmImageReader.h>
-#include <gdcmImageApplyLookupTable.h>
-#include <gdcmImageChangePlanarConfiguration.h>
-#include <gdcmImageChangePhotometricInterpretation.h>
-#include <stdexcept>
-#include <boost/iostreams/stream.hpp>
-#include <boost/iostreams/device/array.hpp>
-
-
-namespace OrthancPlugins
-{
-  struct GdcmImageDecoder::PImpl
-  {
-    const void*           dicom_;
-    size_t                size_;
-
-    gdcm::ImageReader reader_;
-    std::unique_ptr<gdcm::ImageApplyLookupTable> lut_;
-    std::unique_ptr<gdcm::ImageChangePhotometricInterpretation> photometric_;
-    std::unique_ptr<gdcm::ImageChangePlanarConfiguration> interleaved_;
-    std::string decoded_;
-
-    PImpl(const void* dicom,
-          size_t size) :
-      dicom_(dicom),
-      size_(size)
-    {
-    }
-
-
-    const gdcm::DataSet& GetDataSet() const
-    {
-      return reader_.GetFile().GetDataSet();
-    }
-
-
-    const gdcm::Image& GetImage() const
-    {
-      if (interleaved_.get() != NULL)
-      {
-        return interleaved_->GetOutput();
-      }
-
-      if (lut_.get() != NULL)
-      {
-        return lut_->GetOutput();
-      }
-
-      if (photometric_.get() != NULL)
-      {
-        return photometric_->GetOutput();
-      }
-
-      return reader_.GetImage();
-    }
-
-
-    void Decode()
-    {
-      // Change photometric interpretation or apply LUT, if required
-      {
-        const gdcm::Image& image = GetImage();
-        if (image.GetPixelFormat().GetSamplesPerPixel() == 1 &&
-            image.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::PALETTE_COLOR)
-        {
-          lut_.reset(new gdcm::ImageApplyLookupTable());
-          lut_->SetInput(image);
-          if (!lut_->Apply())
-          {
-            throw std::runtime_error( "GDCM cannot apply the lookup table");
-          }
-        }
-        else if (image.GetPixelFormat().GetSamplesPerPixel() == 1)
-        {
-          if (image.GetPhotometricInterpretation() != gdcm::PhotometricInterpretation::MONOCHROME1 &&
-              image.GetPhotometricInterpretation() != gdcm::PhotometricInterpretation::MONOCHROME2)
-          {
-            photometric_.reset(new gdcm::ImageChangePhotometricInterpretation());
-            photometric_->SetInput(image);
-            photometric_->SetPhotometricInterpretation(gdcm::PhotometricInterpretation::MONOCHROME2);
-            if (!photometric_->Change() ||
-                GetImage().GetPhotometricInterpretation() != gdcm::PhotometricInterpretation::MONOCHROME2)
-            {
-              throw std::runtime_error("GDCM cannot change the photometric interpretation");
-            }
-          }      
-        }
-        else 
-        {
-          if (image.GetPixelFormat().GetSamplesPerPixel() == 3 &&
-              image.GetPhotometricInterpretation() != gdcm::PhotometricInterpretation::RGB &&
-              image.GetPhotometricInterpretation() != gdcm::PhotometricInterpretation::YBR_FULL &&
-              (image.GetTransferSyntax() != gdcm::TransferSyntax::JPEG2000Lossless ||
-               image.GetPhotometricInterpretation() != gdcm::PhotometricInterpretation::YBR_RCT))
-          {
-            photometric_.reset(new gdcm::ImageChangePhotometricInterpretation());
-            photometric_->SetInput(image);
-            photometric_->SetPhotometricInterpretation(gdcm::PhotometricInterpretation::RGB);
-            if (!photometric_->Change() ||
-                GetImage().GetPhotometricInterpretation() != gdcm::PhotometricInterpretation::RGB)
-            {
-              throw std::runtime_error("GDCM cannot change the photometric interpretation");
-            }
-          }
-        }
-      }
-
-      // Possibly convert planar configuration to interleaved
-      {
-        const gdcm::Image& image = GetImage();
-        if (image.GetPlanarConfiguration() != 0 && 
-            image.GetPixelFormat().GetSamplesPerPixel() != 1)
-        {
-          interleaved_.reset(new gdcm::ImageChangePlanarConfiguration());
-          interleaved_->SetInput(image);
-          if (!interleaved_->Change() ||
-              GetImage().GetPlanarConfiguration() != 0)
-          {
-            throw std::runtime_error("GDCM cannot change the planar configuration to interleaved");
-          }
-        }
-      }
-    }
-  };
-
-  GdcmImageDecoder::GdcmImageDecoder(const void* dicom,
-                                     size_t size) :
-    pimpl_(new PImpl(dicom, size))
-  {
-    // Setup a stream to the memory buffer
-    using namespace boost::iostreams;
-    basic_array_source<char> source(reinterpret_cast<const char*>(dicom), size);
-    stream<basic_array_source<char> > stream(source);
-
-    // Parse the DICOM instance using GDCM
-    pimpl_->reader_.SetStream(stream);
-    if (!pimpl_->reader_.Read())
-    {
-      throw std::runtime_error("Bad file format");
-    }
-
-    pimpl_->Decode();
-  }
-
-
-  OrthancPluginPixelFormat GdcmImageDecoder::GetFormat() const
-  {
-    const gdcm::Image& image = pimpl_->GetImage();
-
-    if (image.GetPixelFormat().GetSamplesPerPixel() == 1 &&
-        (image.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::MONOCHROME1 ||
-         image.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::MONOCHROME2))
-    {
-      switch (image.GetPixelFormat())
-      {
-        case gdcm::PixelFormat::UINT16:
-          return OrthancPluginPixelFormat_Grayscale16;
-
-        case gdcm::PixelFormat::INT16:
-          return OrthancPluginPixelFormat_SignedGrayscale16;
-
-        case gdcm::PixelFormat::UINT8:
-          return OrthancPluginPixelFormat_Grayscale8;
-
-        default:
-          throw std::runtime_error("Unsupported pixel format");
-      }
-    }
-    else if (image.GetPixelFormat().GetSamplesPerPixel() == 3 &&
-             (image.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::RGB ||
-              image.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::YBR_FULL ||
-              image.GetPhotometricInterpretation() == gdcm::PhotometricInterpretation::YBR_RCT))
-    {
-      switch (image.GetPixelFormat())
-      {
-        case gdcm::PixelFormat::UINT8:
-          return OrthancPluginPixelFormat_RGB24;
-
-        case gdcm::PixelFormat::UINT16:
-#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 3, 1)
-          return OrthancPluginPixelFormat_RGB48;
-#else
-          throw std::runtime_error("RGB48 pixel format is only supported if compiled against Orthanc SDK >= 1.3.1");
-#endif
-          
-        default:
-          break;
-      }      
-    }
-
-    throw std::runtime_error("Unsupported pixel format");
-  }
-
-
-  unsigned int GdcmImageDecoder::GetWidth() const
-  {
-    return pimpl_->GetImage().GetColumns();
-  }
-
-
-  unsigned int GdcmImageDecoder::GetHeight() const
-  {
-    return pimpl_->GetImage().GetRows();
-  }
-
-  
-  unsigned int GdcmImageDecoder::GetFramesCount() const
-  {
-    return pimpl_->GetImage().GetDimension(2);
-  }
-
-
-  size_t GdcmImageDecoder::GetBytesPerPixel(OrthancPluginPixelFormat format)
-  {
-    switch (format)
-    {
-      case OrthancPluginPixelFormat_Grayscale8:
-        return 1;
-
-      case OrthancPluginPixelFormat_Grayscale16:
-      case OrthancPluginPixelFormat_SignedGrayscale16:
-        return 2;
-
-      case OrthancPluginPixelFormat_RGB24:
-        return 3;
-
-#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 3, 1)
-      case OrthancPluginPixelFormat_RGB48:
-        return 6;
-#endif
-
-      default:
-        throw std::runtime_error("Unsupport pixel format");
-    }
-  }
-
-  static void ConvertYbrToRgb(uint8_t rgb[3],
-                              const uint8_t ybr[3])
-  {
-    // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2
-    // https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion
-    
-    // TODO - Check out the outcome of Mathieu's discussion about
-    // truncation of YCbCr-to-RGB conversion:
-    // https://groups.google.com/forum/#!msg/comp.protocols.dicom/JHuGeyWbTz8/ARoTWrJzAQAJ
-
-    const float Y  = ybr[0];
-    const float Cb = ybr[1];
-    const float Cr = ybr[2];
-
-    const float result[3] = {
-      Y                             + 1.402f    * (Cr - 128.0f),
-      Y - 0.344136f * (Cb - 128.0f) - 0.714136f * (Cr - 128.0f),
-      Y + 1.772f    * (Cb - 128.0f)
-    };
-
-    for (uint8_t i = 0; i < 3 ; i++)
-    {
-      if (result[i] < 0)
-      {
-        rgb[i] = 0;
-      }
-      else if (result[i] > 255)
-      {
-        rgb[i] = 255;
-      }
-      else
-      {
-        rgb[i] = static_cast<uint8_t>(result[i]);
-      }
-    }    
-  }
-
-  
-  static void FixPhotometricInterpretation(OrthancImage& image,
-                                           gdcm::PhotometricInterpretation interpretation)
-  {
-    switch (interpretation)
-    {
-      case gdcm::PhotometricInterpretation::MONOCHROME1:
-      case gdcm::PhotometricInterpretation::MONOCHROME2:
-      case gdcm::PhotometricInterpretation::RGB:
-        return;
-
-      case gdcm::PhotometricInterpretation::YBR_FULL:
-      {
-        // Fix for Osimis issue WVB-319: Some images are not loading in US_MF
-
-        uint32_t width = image.GetWidth();
-        uint32_t height = image.GetHeight();
-        uint32_t pitch = image.GetPitch();
-        uint8_t* buffer = reinterpret_cast<uint8_t*>(image.GetBuffer());
-        
-        if (image.GetPixelFormat() != OrthancPluginPixelFormat_RGB24 ||
-            pitch < 3 * width)
-        {
-          throw std::runtime_error("Internal error");
-        }
-
-        for (uint32_t y = 0; y < height; y++)
-        {
-          uint8_t* p = buffer + y * pitch;
-          for (uint32_t x = 0; x < width; x++, p += 3)
-          {
-            const uint8_t ybr[3] = { p[0], p[1], p[2] };
-            uint8_t rgb[3];
-            ConvertYbrToRgb(rgb, ybr);
-            p[0] = rgb[0];
-            p[1] = rgb[1];
-            p[2] = rgb[2];
-          }
-        }
-
-        return;
-      }
-
-      default:
-        throw std::runtime_error("Unsupported output photometric interpretation");
-    }    
-  }
-
-
-  OrthancPluginImage* GdcmImageDecoder::Decode(unsigned int frameIndex) const
-  {
-    unsigned int frames = GetFramesCount();
-    unsigned int width = GetWidth();
-    unsigned int height = GetHeight();
-    OrthancPluginPixelFormat format = GetFormat();
-    size_t bpp = GetBytesPerPixel(format);
-
-    if (frameIndex >= frames)
-    {
-      throw std::runtime_error("Inexistent frame index");
-    }
-
-    std::string& decoded = pimpl_->decoded_;
-    OrthancImage target(format, width, height);
-
-    if (width == 0 ||
-        height == 0)
-    {
-      return target.Release();
-    }
-
-    if (decoded.empty())
-    {
-      decoded.resize(pimpl_->GetImage().GetBufferLength());
-      if (!pimpl_->GetImage().GetBuffer(&decoded[0]))
-      {
-        throw std::runtime_error("Image not properly decoded to a memory buffer");
-      }
-    }
-
-    const void* sourceBuffer = &decoded[0];
-
-    if (target.GetPitch() == bpp * width &&
-        frames == 1)
-    {
-      assert(decoded.size() == target.GetPitch() * target.GetHeight());      
-      memcpy(target.GetBuffer(), sourceBuffer, decoded.size());
-    }
-    else 
-    {
-      size_t targetPitch = target.GetPitch();
-      size_t sourcePitch = width * bpp;
-
-      const uint8_t* a = (reinterpret_cast<const uint8_t*>(decoded.c_str()) +
-                          sourcePitch * height * frameIndex);
-      uint8_t* b = reinterpret_cast<uint8_t*>(target.GetBuffer());
-
-      for (uint32_t y = 0; y < height; y++)
-      {
-        memcpy(b, a, sourcePitch);
-        a += sourcePitch;
-        b += targetPitch;
-      }
-    }
-    
-    FixPhotometricInterpretation(target, pimpl_->GetImage().GetPhotometricInterpretation());
-                                 
-    return target.Release();
-  }
-}
--- a/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h	Fri May 15 15:15:58 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., 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 <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Common/OrthancPluginCppWrapper.h"
-
-#include <stdint.h>
-#include <boost/noncopyable.hpp>
-#include <boost/shared_ptr.hpp>
-
-
-namespace OrthancPlugins
-{
-  class GdcmImageDecoder : public boost::noncopyable
-  {
-  private:
-    struct PImpl;
-    boost::shared_ptr<PImpl> pimpl_;
-  
-  public:
-    GdcmImageDecoder(const void* dicom,
-                     size_t size);
-
-    OrthancPluginPixelFormat GetFormat() const;
-
-    unsigned int GetWidth() const;
-
-    unsigned int GetHeight() const;
-
-    unsigned int GetFramesCount() const;
-
-    static size_t GetBytesPerPixel(OrthancPluginPixelFormat format);
-
-    OrthancPluginImage* Decode(unsigned int frameIndex) const;
-  };
-}
--- a/Plugins/Samples/GdcmDecoder/Plugin.cpp	Fri May 15 15:15:58 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,443 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., 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 <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../../../Core/Compatibility.h"
-#include "../../../Core/DicomFormat/DicomMap.h"
-#include "../../../Core/MultiThreading/Semaphore.h"
-#include "../../../Core/Toolbox.h"
-#include "GdcmDecoderCache.h"
-
-#include <gdcmImageChangeTransferSyntax.h>
-#include <gdcmImageReader.h>
-#include <gdcmImageWriter.h>
-#include <gdcmUIDGenerator.h>
-#include <gdcmAttribute.h>
-
-
-static OrthancPlugins::GdcmDecoderCache  cache_;
-static bool restrictTransferSyntaxes_ = false;
-static std::set<std::string> enabledTransferSyntaxes_;
-static bool hasThrottling_ = false;
-static std::unique_ptr<Orthanc::Semaphore> throttlingSemaphore_;
-
-static bool ExtractTransferSyntax(std::string& transferSyntax,
-                                  const void* dicom,
-                                  const uint32_t size)
-{
-  Orthanc::DicomMap header;
-  if (!Orthanc::DicomMap::ParseDicomMetaInformation(header, reinterpret_cast<const char*>(dicom), size))
-  {
-    return false;
-  }
-
-  const Orthanc::DicomValue* tag = header.TestAndGetValue(0x0002, 0x0010);
-  if (tag == NULL ||
-      tag->IsNull() ||
-      tag->IsBinary())
-  {
-    return false;
-  }
-  else
-  {
-    // Stripping spaces should not be required, as this is a UI value
-    // representation whose stripping is supported by the Orthanc
-    // core, but let's be careful...
-    transferSyntax = Orthanc::Toolbox::StripSpaces(tag->GetContent());
-    return true;
-  }
-}
-
-
-static bool IsTransferSyntaxEnabled(const void* dicom,
-                                    const uint32_t size)
-{
-  std::string formattedSize;
-
-  {
-    char tmp[16];
-    sprintf(tmp, "%0.1fMB", static_cast<float>(size) / (1024.0f * 1024.0f));
-    formattedSize.assign(tmp);
-  }
-
-  if (!restrictTransferSyntaxes_)
-  {
-    LOG(INFO) << "Decoding one DICOM instance of " << formattedSize << " using GDCM";
-    return true;
-  }
-
-  std::string transferSyntax;
-  if (!ExtractTransferSyntax(transferSyntax, dicom, size))
-  {
-    LOG(INFO) << "Cannot extract the transfer syntax of this instance of "
-              << formattedSize << ", will use GDCM to decode it";
-    return true;
-  }
-  else if (enabledTransferSyntaxes_.find(transferSyntax) != enabledTransferSyntaxes_.end())
-  {
-    // Decoding for this transfer syntax is enabled
-    LOG(INFO) << "Using GDCM to decode this instance of " << formattedSize
-              << " with transfer syntax " << transferSyntax;
-    return true;
-  }
-  else
-  {
-    LOG(INFO) << "Won't use GDCM to decode this instance of " << formattedSize
-              << ", as its transfer syntax " << transferSyntax << " is disabled";
-    return false;
-  }
-}
-
-
-static OrthancPluginErrorCode DecodeImageCallback(OrthancPluginImage** target,
-                                                  const void* dicom,
-                                                  const uint32_t size,
-                                                  uint32_t frameIndex)
-{
-  try
-  {
-    std::unique_ptr<Orthanc::Semaphore::Locker> locker;
-    
-    if (hasThrottling_)
-    {
-      if (throttlingSemaphore_.get() == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-      else
-      {
-        locker.reset(new Orthanc::Semaphore::Locker(*throttlingSemaphore_));
-      }
-    }
-
-    if (!IsTransferSyntaxEnabled(dicom, size))
-    {
-      *target = NULL;
-      return OrthancPluginErrorCode_Success;
-    }
-
-    std::unique_ptr<OrthancPlugins::OrthancImage> image;
-
-#if 0
-    // Do not use the cache
-    OrthancPlugins::GdcmImageDecoder decoder(dicom, size);
-    image.reset(new OrthancPlugins::OrthancImage(decoder.Decode(frameIndex)));
-#else
-    image.reset(cache_.Decode(dicom, size, frameIndex));
-#endif
-
-    *target = image->Release();
-
-    return OrthancPluginErrorCode_Success;
-  }
-  catch (Orthanc::OrthancException& e)
-  {
-    *target = NULL;
-
-    LOG(WARNING) << "Cannot decode image using GDCM: " << e.What();
-    return OrthancPluginErrorCode_Plugin;
-  }
-  catch (std::runtime_error& e)
-  {
-    *target = NULL;
-
-    LOG(WARNING) << "Cannot decode image using GDCM: " << e.what();
-    return OrthancPluginErrorCode_Plugin;
-  }
-  catch (...)
-  {
-    *target = NULL;
-
-    LOG(WARNING) << "Native exception while decoding image using GDCM";
-    return OrthancPluginErrorCode_Plugin;
-  }
-}
-
-
-OrthancPluginErrorCode TranscoderCallback(
-  OrthancPluginMemoryBuffer* transcoded /* out */,
-  uint8_t*                   hasSopInstanceUidChanged /* out */,
-  const void*                buffer,
-  uint64_t                   size,
-  const char* const*         allowedSyntaxes,
-  uint32_t                   countSyntaxes,
-  uint8_t                    allowNewSopInstanceUid)
-{
-  try
-  {
-    std::unique_ptr<Orthanc::Semaphore::Locker> locker;
-    
-    if (hasThrottling_)
-    {
-      if (throttlingSemaphore_.get() == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-      else
-      {
-        locker.reset(new Orthanc::Semaphore::Locker(*throttlingSemaphore_));
-      }
-    }
-
-    std::string dicom(reinterpret_cast<const char*>(buffer), size);
-    std::stringstream stream(dicom);
-
-    gdcm::ImageReader reader;
-    reader.SetStream(stream);
-    if (!reader.Read())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
-                                      "GDCM cannot decode the image");
-    }
-
-    // First check that transcoding is mandatory
-    for (uint32_t i = 0; i < countSyntaxes; i++)
-    {
-      gdcm::TransferSyntax syntax(gdcm::TransferSyntax::GetTSType(allowedSyntaxes[i]));
-      if (syntax.IsValid() &&
-          reader.GetImage().GetTransferSyntax() == syntax)
-      {
-        // Same transfer syntax as in the source, return a copy of the
-        // source buffer
-        OrthancPlugins::MemoryBuffer orthancBuffer(buffer, size);
-        *transcoded = orthancBuffer.Release();
-        *hasSopInstanceUidChanged = false;
-        return OrthancPluginErrorCode_Success;
-      }
-    }
-
-    for (uint32_t i = 0; i < countSyntaxes; i++)
-    {
-      gdcm::TransferSyntax syntax(gdcm::TransferSyntax::GetTSType(allowedSyntaxes[i]));
-      if (syntax.IsValid())
-      {
-        gdcm::ImageChangeTransferSyntax change;
-        change.SetTransferSyntax(syntax);
-        change.SetInput(reader.GetImage());
-
-        if (change.Change())
-        {
-          if (syntax == gdcm::TransferSyntax::JPEGBaselineProcess1 ||
-              syntax == gdcm::TransferSyntax::JPEGExtendedProcess2_4 ||
-              syntax == gdcm::TransferSyntax::JPEGLSNearLossless ||
-              syntax == gdcm::TransferSyntax::JPEG2000 ||
-              syntax == gdcm::TransferSyntax::JPEG2000Part2)
-          {
-            // In the case of a lossy compression, generate new SOP instance UID
-            gdcm::UIDGenerator generator;
-            std::string uid = generator.Generate();
-            if (uid.size() == 0)
-            {
-              throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
-                                              "GDCM cannot generate a UID");
-            }
-
-            gdcm::Attribute<0x0008,0x0018> sopInstanceUid;
-            sopInstanceUid.SetValue(uid);
-            reader.GetFile().GetDataSet().Replace(sopInstanceUid.GetAsDataElement());
-            *hasSopInstanceUidChanged = 1;
-          }
-          else
-          {
-            *hasSopInstanceUidChanged = 0;
-          }
-      
-          // GDCM was able to change the transfer syntax, serialize it
-          // to the output buffer
-          gdcm::ImageWriter writer;
-          writer.SetImage(change.GetOutput());
-          writer.SetFile(reader.GetFile());
-
-          std::stringstream ss;
-          writer.SetStream(ss);
-          if (writer.Write())
-          {
-            std::string s = ss.str();
-            OrthancPlugins::MemoryBuffer orthancBuffer(s.empty() ? NULL : s.c_str(), s.size());
-            *transcoded = orthancBuffer.Release();
-
-            return OrthancPluginErrorCode_Success;
-          }
-          else
-          {
-            throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
-                                            "GDCM cannot serialize the image");
-          }
-        }
-      }
-    }
-    
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-  }
-  catch (Orthanc::OrthancException& e)
-  {
-    LOG(INFO) << "Cannot transcode image using GDCM: " << e.What();
-    return OrthancPluginErrorCode_Plugin;
-  }
-  catch (std::runtime_error& e)
-  {
-    LOG(INFO) << "Cannot transcode image using GDCM: " << e.what();
-    return OrthancPluginErrorCode_Plugin;
-  }
-  catch (...)
-  {
-    LOG(INFO) << "Native exception while decoding image using GDCM";
-    return OrthancPluginErrorCode_Plugin;
-  }
-}
-
-
-/**
- * We force the redefinition of the "ORTHANC_PLUGINS_API" macro, that
- * was left empty with gcc until Orthanc SDK 1.5.7 (no "default"
- * visibility). This causes the version script, if run from "Holy
- * Build Box", to make private the 4 global functions of the plugin.
- **/
-
-#undef ORTHANC_PLUGINS_API
-
-#ifdef WIN32
-#  define ORTHANC_PLUGINS_API __declspec(dllexport)
-#elif __GNUC__ >= 4
-#  define ORTHANC_PLUGINS_API __attribute__ ((visibility ("default")))
-#else
-#  define ORTHANC_PLUGINS_API
-#endif
-
-
-extern "C"
-{
-  ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context)
-  {
-    static const char* const KEY_GDCM = "Gdcm";
-    static const char* const KEY_ENABLE_GDCM = "Enable";
-    static const char* const KEY_THROTTLING = "Throttling";
-    static const char* const KEY_RESTRICT_TRANSFER_SYNTAXES = "RestrictTransferSyntaxes";
-
-    try
-    {
-      OrthancPlugins::SetGlobalContext(context);
-      Orthanc::Logging::Initialize(context);
-      LOG(INFO) << "Initializing the decoder/transcoder of medical images using GDCM";
-
-      /* Check the version of the Orthanc core */
-      if (!OrthancPlugins::CheckMinimalOrthancVersion(0, 9, 5))
-      {
-        LOG(ERROR) << "Your version of Orthanc (" << std::string(context->orthancVersion)
-                   << ") must be above 0.9.5 to run this plugin";
-        return -1;
-      }
-
-      OrthancPluginSetDescription(context, "Decoder/transcoder of medical images using GDCM.");
-
-      OrthancPlugins::OrthancConfiguration global;
-
-      bool enabled = true;
-      hasThrottling_ = false;
-    
-      if (global.IsSection(KEY_GDCM))
-      {
-        OrthancPlugins::OrthancConfiguration config;
-        global.GetSection(config, KEY_GDCM);
-
-        enabled = config.GetBooleanValue(KEY_ENABLE_GDCM, true);
-
-        if (enabled &&
-            config.LookupSetOfStrings(enabledTransferSyntaxes_, KEY_RESTRICT_TRANSFER_SYNTAXES, false))
-        {
-          restrictTransferSyntaxes_ = true;
-        
-          for (std::set<std::string>::const_iterator it = enabledTransferSyntaxes_.begin();
-               it != enabledTransferSyntaxes_.end(); ++it)
-          {
-            LOG(WARNING) << "Orthanc will use GDCM to decode transfer syntax: " << *it;
-          }
-        }
-
-        unsigned int throttling;
-        if (enabled &&
-            config.LookupUnsignedIntegerValue(throttling, KEY_THROTTLING))
-        {
-          if (throttling == 0)
-          {
-            LOG(ERROR) << "Bad value for option \"" << KEY_THROTTLING
-                       << "\": Must be a strictly positive integer";
-            return -1;
-          }
-          else
-          {
-            LOG(WARNING) << "Throttling GDCM to " << throttling << " concurrent thread(s)";
-            hasThrottling_ = true;
-            throttlingSemaphore_.reset(new Orthanc::Semaphore(throttling));
-          }
-        }
-      }
-
-      if (enabled)
-      {
-        if (!hasThrottling_)
-        {
-          LOG(WARNING) << "GDCM throttling is disabled";
-        }
-
-        OrthancPluginRegisterDecodeImageCallback(context, DecodeImageCallback);
-
-        if (OrthancPlugins::CheckMinimalOrthancVersion(1, 7, 0))
-        {
-          OrthancPluginRegisterTranscoderCallback(context, TranscoderCallback);
-        }
-        else
-        {
-          LOG(WARNING) << "Your version of Orthanc (" << std::string(context->orthancVersion)
-                       << ") must be above 1.7.0 to benefit from transcoding";
-        }
-      }
-      else
-      {
-        LOG(WARNING) << "The decoder/transcoder of medical images using GDCM is disabled";
-      }
-    
-      return 0;
-    }
-    catch (Orthanc::OrthancException& e)
-    {
-      LOG(ERROR) << "Exception while initializing the GDCM plugin: " << e.What();
-      return -1;
-    }
-  }
-
-
-  ORTHANC_PLUGINS_API void OrthancPluginFinalize()
-  {
-    LOG(INFO) << "Finalizing the decoder/transcoder of medical images using GDCM";
-  }
-
-
-  ORTHANC_PLUGINS_API const char* OrthancPluginGetName()
-  {
-    return "gdcm";
-  }
-
-
-  ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion()
-  {
-    return PLUGIN_VERSION;
-  }
-}
--- a/Plugins/Samples/GdcmDecoder/README	Fri May 15 15:15:58 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-This sample shows how to replace the decoder of DICOM images that is
-built in Orthanc, by the GDCM library.
-
-A production-ready version of this sample, is available in the
-offical Web viewer plugin:
-http://www.orthanc-server.com/static.php?page=web-viewer