changeset 212:5412adf19980

resort to OrthancFramework
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 01 Jun 2018 17:48:47 +0200
parents 64eac89a1de3
children f753a7e15a73
files Applications/IBasicApplication.cpp Applications/Samples/BasicPetCtFusionApplication.h Applications/Samples/LayoutPetCtFusionApplication.h Applications/Samples/SingleFrameApplication.h Applications/Samples/SingleVolumeApplication.h Applications/Samples/SynchronizedSeriesApplication.h Applications/Sdl/SdlEngine.cpp Applications/Sdl/SdlSurface.cpp Applications/Sdl/SdlWindow.cpp Framework/Layers/ColorFrameRenderer.cpp Framework/Layers/FrameRenderer.cpp Framework/Layers/GrayscaleFrameRenderer.cpp Framework/Layers/LayerSourceBase.cpp Framework/Layers/OrthancFrameLayerSource.cpp Framework/Layers/RenderStyle.cpp Framework/Layers/SeriesFrameRendererFactory.cpp Framework/Layers/SingleFrameRendererFactory.cpp Framework/StoneEnumerations.cpp Framework/Toolbox/CoordinateSystem3D.cpp Framework/Toolbox/CoordinateSystem3D.h Framework/Toolbox/DicomFrameConverter.cpp Framework/Toolbox/DicomFrameConverter.h Framework/Toolbox/DicomStructureSet.cpp Framework/Toolbox/DicomStructureSet.h Framework/Toolbox/DownloadStack.cpp Framework/Toolbox/FiniteProjectiveCamera.cpp Framework/Toolbox/GeometryToolbox.cpp Framework/Toolbox/ISeriesLoader.h Framework/Toolbox/IWebService.h Framework/Toolbox/ImageGeometry.cpp Framework/Toolbox/ImageGeometry.h Framework/Toolbox/LinearAlgebra.cpp Framework/Toolbox/LinearAlgebra.h Framework/Toolbox/MessagingToolbox.cpp Framework/Toolbox/MessagingToolbox.h Framework/Toolbox/ObserversRegistry.h Framework/Toolbox/OrientedBoundingBox.cpp Framework/Toolbox/OrthancSlicesLoader.cpp Framework/Toolbox/ParallelSlices.cpp Framework/Toolbox/ParallelSlicesCursor.cpp Framework/Toolbox/ShearWarpProjectiveTransform.cpp Framework/Toolbox/Slice.cpp Framework/Toolbox/Slice.h Framework/Toolbox/SlicesSorter.cpp Framework/Toolbox/SubpixelReader.h Framework/Toolbox/SubvoxelReader.h Framework/Toolbox/ViewportGeometry.cpp Framework/Viewport/CairoContext.cpp Framework/Viewport/CairoFont.cpp Framework/Viewport/CairoSurface.cpp Framework/Viewport/CairoSurface.h Framework/Viewport/IViewport.h Framework/Viewport/WidgetViewport.cpp Framework/Volumes/ImageBuffer3D.cpp Framework/Volumes/ImageBuffer3D.h Framework/Volumes/StructureSetLoader.cpp Framework/Volumes/VolumeReslicer.cpp Framework/Widgets/CairoWidget.cpp Framework/Widgets/EmptyWidget.cpp Framework/Widgets/LayerWidget.cpp Framework/Widgets/LayoutWidget.cpp Framework/Widgets/WidgetBase.cpp Framework/dev.h Platforms/Generic/CMakeLists.txt Platforms/Generic/IOracleCommand.h Platforms/Generic/Oracle.cpp Platforms/Generic/WebServiceGetCommand.cpp Platforms/Generic/WebServiceGetCommand.h Platforms/Generic/WebServicePostCommand.cpp Platforms/Generic/WebServicePostCommand.h Resources/CMake/OrthancStoneConfiguration.cmake Resources/CMake/OrthancStoneParameters.cmake Resources/CMake/Version.cmake Resources/Orthanc/Core/Cache/ICachePageProvider.h Resources/Orthanc/Core/Cache/LeastRecentlyUsedIndex.h Resources/Orthanc/Core/Cache/MemoryCache.cpp Resources/Orthanc/Core/Cache/MemoryCache.h Resources/Orthanc/Core/Cache/SharedArchive.cpp Resources/Orthanc/Core/Cache/SharedArchive.h Resources/Orthanc/Core/ChunkedBuffer.cpp Resources/Orthanc/Core/ChunkedBuffer.h Resources/Orthanc/Core/Compression/DeflateBaseCompressor.cpp Resources/Orthanc/Core/Compression/DeflateBaseCompressor.h Resources/Orthanc/Core/Compression/GzipCompressor.cpp Resources/Orthanc/Core/Compression/GzipCompressor.h Resources/Orthanc/Core/Compression/HierarchicalZipWriter.cpp Resources/Orthanc/Core/Compression/HierarchicalZipWriter.h Resources/Orthanc/Core/Compression/IBufferCompressor.h Resources/Orthanc/Core/Compression/ZipWriter.cpp Resources/Orthanc/Core/Compression/ZipWriter.h Resources/Orthanc/Core/Compression/ZlibCompressor.cpp Resources/Orthanc/Core/Compression/ZlibCompressor.h Resources/Orthanc/Core/DicomFormat/DicomArray.cpp Resources/Orthanc/Core/DicomFormat/DicomArray.h Resources/Orthanc/Core/DicomFormat/DicomElement.h Resources/Orthanc/Core/DicomFormat/DicomImageInformation.cpp Resources/Orthanc/Core/DicomFormat/DicomImageInformation.h Resources/Orthanc/Core/DicomFormat/DicomInstanceHasher.cpp Resources/Orthanc/Core/DicomFormat/DicomInstanceHasher.h Resources/Orthanc/Core/DicomFormat/DicomIntegerPixelAccessor.cpp Resources/Orthanc/Core/DicomFormat/DicomIntegerPixelAccessor.h Resources/Orthanc/Core/DicomFormat/DicomMap.cpp Resources/Orthanc/Core/DicomFormat/DicomMap.h Resources/Orthanc/Core/DicomFormat/DicomTag.cpp Resources/Orthanc/Core/DicomFormat/DicomTag.h Resources/Orthanc/Core/DicomFormat/DicomValue.cpp Resources/Orthanc/Core/DicomFormat/DicomValue.h Resources/Orthanc/Core/Endianness.h Resources/Orthanc/Core/Enumerations.cpp Resources/Orthanc/Core/Enumerations.h Resources/Orthanc/Core/FileStorage/FileInfo.h Resources/Orthanc/Core/FileStorage/FilesystemStorage.cpp Resources/Orthanc/Core/FileStorage/FilesystemStorage.h Resources/Orthanc/Core/FileStorage/IStorageArea.h Resources/Orthanc/Core/FileStorage/StorageAccessor.cpp Resources/Orthanc/Core/FileStorage/StorageAccessor.h Resources/Orthanc/Core/HttpClient.cpp Resources/Orthanc/Core/HttpClient.h Resources/Orthanc/Core/ICommand.h Resources/Orthanc/Core/IDynamicObject.h Resources/Orthanc/Core/Images/Font.cpp Resources/Orthanc/Core/Images/Font.h Resources/Orthanc/Core/Images/FontRegistry.cpp Resources/Orthanc/Core/Images/FontRegistry.h Resources/Orthanc/Core/Images/IImageWriter.cpp Resources/Orthanc/Core/Images/IImageWriter.h Resources/Orthanc/Core/Images/Image.cpp Resources/Orthanc/Core/Images/Image.h Resources/Orthanc/Core/Images/ImageAccessor.cpp Resources/Orthanc/Core/Images/ImageAccessor.h Resources/Orthanc/Core/Images/ImageBuffer.cpp Resources/Orthanc/Core/Images/ImageBuffer.h Resources/Orthanc/Core/Images/ImageProcessing.cpp Resources/Orthanc/Core/Images/ImageProcessing.h Resources/Orthanc/Core/Images/ImageTraits.h Resources/Orthanc/Core/Images/JpegErrorManager.cpp Resources/Orthanc/Core/Images/JpegErrorManager.h Resources/Orthanc/Core/Images/JpegReader.cpp Resources/Orthanc/Core/Images/JpegReader.h Resources/Orthanc/Core/Images/JpegWriter.cpp Resources/Orthanc/Core/Images/JpegWriter.h Resources/Orthanc/Core/Images/PixelTraits.h Resources/Orthanc/Core/Images/PngReader.cpp Resources/Orthanc/Core/Images/PngReader.h Resources/Orthanc/Core/Images/PngWriter.cpp Resources/Orthanc/Core/Images/PngWriter.h Resources/Orthanc/Core/Logging.cpp Resources/Orthanc/Core/Logging.h Resources/Orthanc/Core/MultiThreading/BagOfTasks.h Resources/Orthanc/Core/MultiThreading/BagOfTasksProcessor.cpp Resources/Orthanc/Core/MultiThreading/BagOfTasksProcessor.h Resources/Orthanc/Core/MultiThreading/ILockable.h Resources/Orthanc/Core/MultiThreading/IRunnableBySteps.h Resources/Orthanc/Core/MultiThreading/Mutex.cpp Resources/Orthanc/Core/MultiThreading/Mutex.h Resources/Orthanc/Core/MultiThreading/ReaderWriterLock.cpp Resources/Orthanc/Core/MultiThreading/ReaderWriterLock.h Resources/Orthanc/Core/MultiThreading/RunnableWorkersPool.cpp Resources/Orthanc/Core/MultiThreading/RunnableWorkersPool.h Resources/Orthanc/Core/MultiThreading/Semaphore.cpp Resources/Orthanc/Core/MultiThreading/Semaphore.h Resources/Orthanc/Core/MultiThreading/SharedMessageQueue.cpp Resources/Orthanc/Core/MultiThreading/SharedMessageQueue.h Resources/Orthanc/Core/OrthancException.h Resources/Orthanc/Core/PrecompiledHeaders.cpp Resources/Orthanc/Core/PrecompiledHeaders.h Resources/Orthanc/Core/SharedLibrary.cpp Resources/Orthanc/Core/SharedLibrary.h Resources/Orthanc/Core/SystemToolbox.cpp Resources/Orthanc/Core/SystemToolbox.h Resources/Orthanc/Core/TemporaryFile.cpp Resources/Orthanc/Core/TemporaryFile.h Resources/Orthanc/Core/Toolbox.cpp Resources/Orthanc/Core/Toolbox.h Resources/Orthanc/Core/WebServiceParameters.cpp Resources/Orthanc/Core/WebServiceParameters.h Resources/Orthanc/DownloadOrthancFramework.cmake Resources/Orthanc/LinuxStandardBaseToolchain.cmake Resources/Orthanc/MinGW-W64-Toolchain32.cmake Resources/Orthanc/MinGW-W64-Toolchain64.cmake Resources/Orthanc/MinGWToolchain.cmake Resources/Orthanc/NEWS Resources/Orthanc/Plugins/Samples/Common/DicomDatasetReader.cpp Resources/Orthanc/Plugins/Samples/Common/DicomDatasetReader.h Resources/Orthanc/Plugins/Samples/Common/DicomPath.cpp Resources/Orthanc/Plugins/Samples/Common/DicomPath.h Resources/Orthanc/Plugins/Samples/Common/DicomTag.h Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.cpp Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.h Resources/Orthanc/Plugins/Samples/Common/IDicomDataset.h Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.cpp Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.h Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.cpp Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.h Resources/Orthanc/Plugins/Samples/Common/OrthancPluginException.h Resources/Orthanc/Resources/CMake/AutoGeneratedCode.cmake Resources/Orthanc/Resources/CMake/BoostConfiguration.cmake Resources/Orthanc/Resources/CMake/Compiler.cmake Resources/Orthanc/Resources/CMake/DownloadPackage.cmake Resources/Orthanc/Resources/CMake/GoogleTestConfiguration.cmake Resources/Orthanc/Resources/CMake/JsonCppConfiguration.cmake Resources/Orthanc/Resources/CMake/LibCurlConfiguration.cmake Resources/Orthanc/Resources/CMake/LibJpegConfiguration.cmake Resources/Orthanc/Resources/CMake/LibPngConfiguration.cmake Resources/Orthanc/Resources/CMake/OpenSslConfiguration.cmake Resources/Orthanc/Resources/CMake/OrthancFrameworkConfiguration.cmake Resources/Orthanc/Resources/CMake/OrthancFrameworkParameters.cmake Resources/Orthanc/Resources/CMake/UuidConfiguration.cmake Resources/Orthanc/Resources/CMake/ZlibConfiguration.cmake Resources/Orthanc/Resources/EmbedResources.py Resources/Orthanc/Resources/LinuxStandardBaseToolchain.cmake Resources/Orthanc/Resources/MinGW-W64-Toolchain32.cmake Resources/Orthanc/Resources/MinGW-W64-Toolchain64.cmake Resources/Orthanc/Resources/MinGWToolchain.cmake Resources/Orthanc/Resources/Patches/boost-1.66.0-linux-standard-base.patch Resources/Orthanc/Resources/Patches/curl-7.57.0-cmake.patch Resources/Orthanc/Resources/Patches/dcmtk-3.6.2-linux-standard-base.patch Resources/Orthanc/Resources/ThirdParty/VisualStudio/stdint.h Resources/Orthanc/Resources/ThirdParty/base64/base64.cpp Resources/Orthanc/Resources/ThirdParty/base64/base64.h Resources/Orthanc/Resources/ThirdParty/md5/md5.c Resources/Orthanc/Resources/ThirdParty/md5/md5.h Resources/Orthanc/Resources/ThirdParty/minizip/NOTES Resources/Orthanc/Resources/ThirdParty/minizip/crypt.h Resources/Orthanc/Resources/ThirdParty/minizip/ioapi.c Resources/Orthanc/Resources/ThirdParty/minizip/ioapi.h Resources/Orthanc/Resources/ThirdParty/minizip/zip.c Resources/Orthanc/Resources/ThirdParty/minizip/zip.h Resources/Orthanc/Resources/ThirdParty/patch/NOTES.txt Resources/Orthanc/Resources/ThirdParty/patch/msys-1.0.dll Resources/Orthanc/Resources/ThirdParty/patch/patch.exe Resources/Orthanc/Resources/ThirdParty/patch/patch.exe.manifest Resources/Orthanc/Resources/WindowsResources.py Resources/Orthanc/Resources/WindowsResources.rc Resources/SyncOrthancFolder.py UnitTestsSources/UnitTestsMain.cpp
diffstat 236 files changed, 631 insertions(+), 30688 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/IBasicApplication.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Applications/IBasicApplication.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -24,9 +24,9 @@
 #include "../Framework/Toolbox/MessagingToolbox.h"
 #include "Sdl/SdlEngine.h"
 
-#include "../Resources/Orthanc/Core/Logging.h"
-#include "../Resources/Orthanc/Core/HttpClient.h"
-#include "../Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.h"
+#include <Core/Logging.h>
+#include <Core/HttpClient.h>
+#include <Plugins/Samples/Common/OrthancHttpConnection.h>
 
 namespace OrthancStone
 {
--- a/Applications/Samples/BasicPetCtFusionApplication.h	Mon May 21 09:02:03 2018 +0200
+++ b/Applications/Samples/BasicPetCtFusionApplication.h	Fri Jun 01 17:48:47 2018 +0200
@@ -23,7 +23,7 @@
 
 #include "SampleInteractor.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
+#include <Core/Logging.h>
 
 namespace OrthancStone
 {
--- a/Applications/Samples/LayoutPetCtFusionApplication.h	Mon May 21 09:02:03 2018 +0200
+++ b/Applications/Samples/LayoutPetCtFusionApplication.h	Fri Jun 01 17:48:47 2018 +0200
@@ -27,7 +27,7 @@
 #include "../../Framework/Layers/DicomStructureSetRendererFactory.h"
 #include "../../Framework/Widgets/LayoutWidget.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
+#include <Core/Logging.h>
 
 namespace OrthancStone
 {
--- a/Applications/Samples/SingleFrameApplication.h	Mon May 21 09:02:03 2018 +0200
+++ b/Applications/Samples/SingleFrameApplication.h	Fri Jun 01 17:48:47 2018 +0200
@@ -26,7 +26,7 @@
 #include "../../Framework/Layers/OrthancFrameLayerSource.h"
 #include "../../Framework/Widgets/LayerWidget.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
+#include <Core/Logging.h>
 
 namespace OrthancStone
 {
--- a/Applications/Samples/SingleVolumeApplication.h	Mon May 21 09:02:03 2018 +0200
+++ b/Applications/Samples/SingleVolumeApplication.h	Fri Jun 01 17:48:47 2018 +0200
@@ -27,10 +27,10 @@
 #include "../../Framework/Layers/LineMeasureTracker.h"
 #include "../../Framework/Layers/CircleMeasureTracker.h"
 
-#include "../../Resources/Orthanc/Core/Toolbox.h"
-#include "../../Resources/Orthanc/Core/Logging.h"
+#include <Core/Toolbox.h>
+#include <Core/Logging.h>
 
-#include "../../Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.h"   // TODO REMOVE
+#include <Plugins/Samples/Common/OrthancHttpConnection.h>   // TODO REMOVE
 #include "../../Framework/Layers/DicomStructureSetRendererFactory.h"   // TODO REMOVE
 #include "../../Framework/Toolbox/MessagingToolbox.h"   // TODO REMOVE
 
--- a/Applications/Samples/SynchronizedSeriesApplication.h	Mon May 21 09:02:03 2018 +0200
+++ b/Applications/Samples/SynchronizedSeriesApplication.h	Fri Jun 01 17:48:47 2018 +0200
@@ -27,7 +27,8 @@
 #include "../../Framework/Layers/SeriesFrameRendererFactory.h"
 #include "../../Framework/Layers/SiblingSliceLocationFactory.h"
 #include "../../Framework/Widgets/LayoutWidget.h"
-#include "../../Resources/Orthanc/Core/Logging.h"
+
+#include <Core/Logging.h>
 
 namespace OrthancStone
 {
--- a/Applications/Sdl/SdlEngine.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Applications/Sdl/SdlEngine.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -23,7 +23,7 @@
 
 #if ORTHANC_ENABLE_SDL == 1
 
-#include "../../Resources/Orthanc/Core/Logging.h"
+#include <Core/Logging.h>
 
 #include <SDL.h>
 
--- a/Applications/Sdl/SdlSurface.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Applications/Sdl/SdlSurface.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -23,8 +23,8 @@
 
 #if ORTHANC_ENABLE_SDL == 1
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Applications/Sdl/SdlWindow.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Applications/Sdl/SdlWindow.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -23,8 +23,8 @@
 
 #if ORTHANC_ENABLE_SDL == 1
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Layers/ColorFrameRenderer.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Layers/ColorFrameRenderer.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,8 +21,8 @@
 
 #include "ColorFrameRenderer.h"
 
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
+#include <Core/OrthancException.h>
+#include <Core/Images/ImageProcessing.h>
 
 namespace OrthancStone
 {
--- a/Framework/Layers/FrameRenderer.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Layers/FrameRenderer.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -24,7 +24,7 @@
 #include "GrayscaleFrameRenderer.h"
 #include "ColorFrameRenderer.h"
 
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Layers/GrayscaleFrameRenderer.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Layers/GrayscaleFrameRenderer.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,7 +21,7 @@
 
 #include "GrayscaleFrameRenderer.h"
 
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Layers/LayerSourceBase.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Layers/LayerSourceBase.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,7 +21,7 @@
 
 #include "LayerSourceBase.h"
 
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Layers/OrthancFrameLayerSource.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Layers/OrthancFrameLayerSource.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -24,8 +24,8 @@
 #include "FrameRenderer.h"
 #include "../Toolbox/DicomFrameConverter.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
 
 #include <boost/lexical_cast.hpp>
 
--- a/Framework/Layers/RenderStyle.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Layers/RenderStyle.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,7 +21,7 @@
 
 #include "RenderStyle.h"
 
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Layers/SeriesFrameRendererFactory.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Layers/SeriesFrameRendererFactory.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -23,9 +23,9 @@
 
 #include "FrameRenderer.h"
 
-#include "../../Resources/Orthanc/OrthancException.h"
-#include "../../Resources/Orthanc/Logging.h"
-#include "../../Resources/Orthanc/Toolbox.h"
+#include <OrthancException.h>
+#include <Logging.h>
+#include <Toolbox.h>
 #include <Plugins/Samples/Common/OrthancPluginException.h>
 #include <Plugins/Samples/Common/DicomDatasetReader.h>
 
--- a/Framework/Layers/SingleFrameRendererFactory.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Layers/SingleFrameRendererFactory.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -25,7 +25,7 @@
 #include "../Toolbox/MessagingToolbox.h"
 #include "../Toolbox/DicomFrameConverter.h"
 
-#include "../../Resources/Orthanc/OrthancException.h"
+#include <OrthancException.h>
 #include <Plugins/Samples/Common/FullOrthancDataset.h>
 #include <Plugins/Samples/Common/DicomDatasetReader.h>
 
--- a/Framework/StoneEnumerations.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/StoneEnumerations.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,9 +21,9 @@
 
 #include "StoneEnumerations.h"
 
-#include "../Resources/Orthanc/Core/Logging.h"
-#include "../Resources/Orthanc/Core/OrthancException.h"
-#include "../Resources/Orthanc/Core/Toolbox.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
+#include <Core/Toolbox.h>
 
 namespace OrthancStone
 {  
--- a/Framework/Toolbox/CoordinateSystem3D.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/CoordinateSystem3D.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -24,9 +24,9 @@
 #include "LinearAlgebra.h"
 #include "GeometryToolbox.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/Toolbox.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Logging.h>
+#include <Core/Toolbox.h>
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Toolbox/CoordinateSystem3D.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/CoordinateSystem3D.h	Fri Jun 01 17:48:47 2018 +0200
@@ -23,7 +23,7 @@
 
 #include "LinearAlgebra.h"
 
-#include "../../Resources/Orthanc/Plugins/Samples/Common/IDicomDataset.h"
+#include <Plugins/Samples/Common/IDicomDataset.h>
 
 namespace OrthancStone
 {
--- a/Framework/Toolbox/DicomFrameConverter.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/DicomFrameConverter.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -23,10 +23,10 @@
 
 #include "LinearAlgebra.h"
 
-#include "../../Resources/Orthanc/Core/Images/Image.h"
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-#include "../../Resources/Orthanc/Core/Toolbox.h"
+#include <Core/Images/Image.h>
+#include <Core/Images/ImageProcessing.h>
+#include <Core/OrthancException.h>
+#include <Core/Toolbox.h>
 
 namespace OrthancStone
 {
--- a/Framework/Toolbox/DicomFrameConverter.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/DicomFrameConverter.h	Fri Jun 01 17:48:47 2018 +0200
@@ -21,8 +21,8 @@
 
 #pragma once
 
-#include "../../Resources/Orthanc/Core/DicomFormat/DicomMap.h"
-#include "../../Resources/Orthanc/Core/Images/ImageAccessor.h"
+#include <Core/DicomFormat/DicomMap.h>
+#include <Core/Images/ImageAccessor.h>
 
 #include <memory>
 
--- a/Framework/Toolbox/DicomStructureSet.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/DicomStructureSet.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -24,10 +24,10 @@
 #include "../Toolbox/GeometryToolbox.h"
 #include "../Toolbox/MessagingToolbox.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-#include "../../Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.h"
-#include "../../Resources/Orthanc/Plugins/Samples/Common/DicomDatasetReader.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
+#include <Plugins/Samples/Common/FullOrthancDataset.h>
+#include <Plugins/Samples/Common/DicomDatasetReader.h>
 
 #include <limits>
 #include <stdio.h>
--- a/Framework/Toolbox/DicomStructureSet.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/DicomStructureSet.h	Fri Jun 01 17:48:47 2018 +0200
@@ -24,7 +24,7 @@
 #include "CoordinateSystem3D.h"
 #include "Extent2D.h"
 
-#include "../../Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.h"
+#include <Plugins/Samples/Common/FullOrthancDataset.h>
 
 #include <list>
 
--- a/Framework/Toolbox/DownloadStack.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/DownloadStack.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,7 +21,7 @@
 
 #include "DownloadStack.h"
 
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/OrthancException.h>
 
 #include <cassert>
 
--- a/Framework/Toolbox/FiniteProjectiveCamera.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/FiniteProjectiveCamera.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -24,10 +24,10 @@
 #include "GeometryToolbox.h"
 #include "SubpixelReader.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-#include "../../Resources/Orthanc/Core/Images/Image.h"
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
+#include <Core/Images/Image.h>
+#include <Core/Images/ImageProcessing.h>
 
 namespace OrthancStone
 {
--- a/Framework/Toolbox/GeometryToolbox.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/GeometryToolbox.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,8 +21,8 @@
 
 #include "GeometryToolbox.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
 
 #include <cassert>
 
--- a/Framework/Toolbox/ISeriesLoader.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/ISeriesLoader.h	Fri Jun 01 17:48:47 2018 +0200
@@ -23,8 +23,8 @@
 
 #include "ParallelSlices.h"
 
-#include "../../Resources/Orthanc/Images/ImageAccessor.h"
-#include "../../Resources/Orthanc/Plugins/Samples/Common/IDicomDataset.h"
+#include <Images/ImageAccessor.h>
+#include <Plugins/Samples/Common/IDicomDataset.h>
 
 namespace OrthancStone
 {
--- a/Framework/Toolbox/IWebService.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/IWebService.h	Fri Jun 01 17:48:47 2018 +0200
@@ -21,7 +21,7 @@
 
 #pragma once
 
-#include "../../Resources/Orthanc/Core/IDynamicObject.h"
+#include <Core/IDynamicObject.h>
 
 #include <string>
 
--- a/Framework/Toolbox/ImageGeometry.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/ImageGeometry.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -24,8 +24,8 @@
 #include "Extent2D.h"
 #include "SubpixelReader.h"
 
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
-#include "../../Resources/Orthanc/Core/Logging.h"
+#include <Core/Images/ImageProcessing.h>
+#include <Core/Logging.h>
 
 
 namespace OrthancStone
--- a/Framework/Toolbox/ImageGeometry.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/ImageGeometry.h	Fri Jun 01 17:48:47 2018 +0200
@@ -24,7 +24,7 @@
 #include "../StoneEnumerations.h"
 #include "LinearAlgebra.h"
 
-#include "../../Resources/Orthanc/Core/Images/ImageAccessor.h"
+#include <Core/Images/ImageAccessor.h>
 
 
 namespace OrthancStone
--- a/Framework/Toolbox/LinearAlgebra.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/LinearAlgebra.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,9 +21,9 @@
 
 #include "LinearAlgebra.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-#include "../../Resources/Orthanc/Core/Toolbox.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
+#include <Core/Toolbox.h>
 
 #include <stdio.h>
 #include <boost/lexical_cast.hpp>
--- a/Framework/Toolbox/LinearAlgebra.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/LinearAlgebra.h	Fri Jun 01 17:48:47 2018 +0200
@@ -28,7 +28,7 @@
 #  include <boost/serialization/array_wrapper.hpp>
 #endif
 
-#include "../../Resources/Orthanc/Core/DicomFormat/DicomMap.h"
+#include <Core/DicomFormat/DicomMap.h>
 
 #include <boost/numeric/ublas/matrix.hpp>
 #include <boost/numeric/ublas/vector.hpp>
--- a/Framework/Toolbox/MessagingToolbox.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/MessagingToolbox.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,13 +21,13 @@
 
 #include "MessagingToolbox.h"
 
-#include "../../Resources/Orthanc/Core/Images/Image.h"
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
-#include "../../Resources/Orthanc/Core/Images/JpegReader.h"
-#include "../../Resources/Orthanc/Core/Images/PngReader.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-#include "../../Resources/Orthanc/Core/Toolbox.h"
-#include "../../Resources/Orthanc/Core/Logging.h"
+#include <Core/Images/Image.h>
+#include <Core/Images/ImageProcessing.h>
+#include <Core/Images/JpegReader.h>
+#include <Core/Images/PngReader.h>
+#include <Core/OrthancException.h>
+#include <Core/Toolbox.h>
+#include <Core/Logging.h>
 
 #include <boost/lexical_cast.hpp>
 #include <json/reader.h>
--- a/Framework/Toolbox/MessagingToolbox.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/MessagingToolbox.h	Fri Jun 01 17:48:47 2018 +0200
@@ -23,10 +23,10 @@
 
 #include "../StoneEnumerations.h"
 
-#include "../../Resources/Orthanc/Core/DicomFormat/DicomMap.h"
-#include "../../Resources/Orthanc/Core/Images/ImageAccessor.h"
-#include "../../Resources/Orthanc/Plugins/Samples/Common/IDicomDataset.h"
-#include "../../Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.h"
+#include <Core/DicomFormat/DicomMap.h>
+#include <Core/Images/ImageAccessor.h>
+#include <Plugins/Samples/Common/IDicomDataset.h>
+#include <Plugins/Samples/Common/IOrthancConnection.h>
 
 #include <json/value.h>
 
--- a/Framework/Toolbox/ObserversRegistry.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/ObserversRegistry.h	Fri Jun 01 17:48:47 2018 +0200
@@ -21,7 +21,7 @@
 
 #pragma once
 
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/OrthancException.h>
 
 #include <boost/noncopyable.hpp>
 #include <set>
--- a/Framework/Toolbox/OrientedBoundingBox.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/OrientedBoundingBox.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -23,7 +23,7 @@
 
 #include "GeometryToolbox.h"
 
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/OrthancException.h>
 
 #include <cassert>
 
--- a/Framework/Toolbox/OrthancSlicesLoader.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/OrthancSlicesLoader.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -23,16 +23,16 @@
 
 #include "MessagingToolbox.h"
 
-#include "../../Resources/Orthanc/Core/Compression/GzipCompressor.h"
-#include "../../Resources/Orthanc/Core/Endianness.h"
-#include "../../Resources/Orthanc/Core/Images/Image.h"
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
-#include "../../Resources/Orthanc/Core/Images/JpegReader.h"
-#include "../../Resources/Orthanc/Core/Images/PngReader.h"
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-#include "../../Resources/Orthanc/Core/Toolbox.h"
-#include "../../Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.h"
+#include <Core/Compression/GzipCompressor.h>
+#include <Core/Endianness.h>
+#include <Core/Images/Image.h>
+#include <Core/Images/ImageProcessing.h>
+#include <Core/Images/JpegReader.h>
+#include <Core/Images/PngReader.h>
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
+#include <Core/Toolbox.h>
+#include <Plugins/Samples/Common/FullOrthancDataset.h>
 
 #include <boost/lexical_cast.hpp>
 
--- a/Framework/Toolbox/ParallelSlices.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/ParallelSlices.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -23,8 +23,8 @@
 
 #include "GeometryToolbox.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Toolbox/ParallelSlicesCursor.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/ParallelSlicesCursor.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,7 +21,7 @@
 
 #include "ParallelSlicesCursor.h"
 
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Toolbox/ShearWarpProjectiveTransform.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/ShearWarpProjectiveTransform.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -26,10 +26,10 @@
 #include "FiniteProjectiveCamera.h"
 #include "GeometryToolbox.h"
 
-#include "../../Resources/Orthanc/Core/Images/PixelTraits.h"
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-#include "../../Resources/Orthanc/Core/Logging.h"
+#include <Core/Images/PixelTraits.h>
+#include <Core/Images/ImageProcessing.h>
+#include <Core/OrthancException.h>
+#include <Core/Logging.h>
 
 #include <boost/numeric/ublas/matrix_proxy.hpp>
 #include <boost/math/special_functions/round.hpp>
--- a/Framework/Toolbox/Slice.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/Slice.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -24,9 +24,9 @@
 #include "../StoneEnumerations.h"
 #include "GeometryToolbox.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-#include "../../Resources/Orthanc/Core/Toolbox.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
+#include <Core/Toolbox.h>
 
 #include <boost/lexical_cast.hpp>
 
--- a/Framework/Toolbox/Slice.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/Slice.h	Fri Jun 01 17:48:47 2018 +0200
@@ -24,7 +24,7 @@
 #include "CoordinateSystem3D.h"
 #include "DicomFrameConverter.h"
 
-#include "../../Resources/Orthanc/Core/DicomFormat/DicomImageInformation.h"
+#include <Core/DicomFormat/DicomImageInformation.h>
 
 namespace OrthancStone
 {
--- a/Framework/Toolbox/SlicesSorter.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/SlicesSorter.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -23,7 +23,7 @@
 
 #include "GeometryToolbox.h"
 
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Toolbox/SubpixelReader.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/SubpixelReader.h	Fri Jun 01 17:48:47 2018 +0200
@@ -24,7 +24,7 @@
 #include "../StoneEnumerations.h"
 #include "GeometryToolbox.h"
 
-#include "../../Resources/Orthanc/Core/Images/ImageTraits.h"
+#include <Core/Images/ImageTraits.h>
 
 #include <boost/noncopyable.hpp>
 #include <cmath>
--- a/Framework/Toolbox/SubvoxelReader.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/SubvoxelReader.h	Fri Jun 01 17:48:47 2018 +0200
@@ -24,7 +24,7 @@
 #include "../Volumes/ImageBuffer3D.h"
 #include "GeometryToolbox.h"
 
-#include "../../Resources/Orthanc/Core/Images/ImageTraits.h"
+#include <Core/Images/ImageTraits.h>
 
 #include <boost/noncopyable.hpp>
 #include <cmath>
--- a/Framework/Toolbox/ViewportGeometry.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Toolbox/ViewportGeometry.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,8 +21,8 @@
 
 #include "ViewportGeometry.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
 
 #include <boost/math/special_functions/round.hpp>
 
--- a/Framework/Viewport/CairoContext.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Viewport/CairoContext.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,8 +21,8 @@
 
 #include "CairoContext.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Viewport/CairoFont.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Viewport/CairoFont.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,8 +21,8 @@
 
 #include "CairoFont.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Viewport/CairoSurface.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Viewport/CairoSurface.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,9 +21,9 @@
 
 #include "CairoSurface.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
+#include <Core/Images/ImageProcessing.h>
 
 namespace OrthancStone
 {
--- a/Framework/Viewport/CairoSurface.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Viewport/CairoSurface.h	Fri Jun 01 17:48:47 2018 +0200
@@ -21,7 +21,7 @@
 
 #pragma once
 
-#include "../../Resources/Orthanc/Core/Images/ImageAccessor.h"
+#include <Core/Images/ImageAccessor.h>
 
 #include <boost/noncopyable.hpp>
 #include <cairo.h>
--- a/Framework/Viewport/IViewport.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Viewport/IViewport.h	Fri Jun 01 17:48:47 2018 +0200
@@ -24,7 +24,7 @@
 #include "IStatusBar.h"
 #include "../StoneEnumerations.h"
 
-#include "../../Resources/Orthanc/Core/Images/ImageAccessor.h"
+#include <Core/Images/ImageAccessor.h>
 
 namespace OrthancStone
 {
--- a/Framework/Viewport/WidgetViewport.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Viewport/WidgetViewport.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,8 +21,8 @@
 
 #include "WidgetViewport.h"
 
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Images/ImageProcessing.h>
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Volumes/ImageBuffer3D.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Volumes/ImageBuffer3D.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,9 +21,9 @@
 
 #include "ImageBuffer3D.h"
 
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Images/ImageProcessing.h>
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
 
 #include <string.h>
 
--- a/Framework/Volumes/ImageBuffer3D.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Volumes/ImageBuffer3D.h	Fri Jun 01 17:48:47 2018 +0200
@@ -27,7 +27,7 @@
 #include "../Toolbox/DicomFrameConverter.h"
 #include "../Toolbox/ParallelSlices.h"
 
-#include "../../Resources/Orthanc/Core/Images/Image.h"
+#include <Core/Images/Image.h>
 
 namespace OrthancStone
 {
--- a/Framework/Volumes/StructureSetLoader.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Volumes/StructureSetLoader.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -23,7 +23,7 @@
 
 #include "../Toolbox/MessagingToolbox.h"
 
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Volumes/VolumeReslicer.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Volumes/VolumeReslicer.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -24,9 +24,9 @@
 #include "../Toolbox/GeometryToolbox.h"
 #include "../Toolbox/SubvoxelReader.h"
 
-#include "../../Resources/Orthanc/Core/Images/ImageTraits.h"
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Images/ImageTraits.h>
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
 
 #include <boost/math/special_functions/round.hpp>
 
--- a/Framework/Widgets/CairoWidget.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Widgets/CairoWidget.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,8 +21,8 @@
 
 #include "CairoWidget.h"
 
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Images/ImageProcessing.h>
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Widgets/EmptyWidget.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Widgets/EmptyWidget.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,8 +21,8 @@
 
 #include "EmptyWidget.h"
 
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Images/ImageProcessing.h>
+#include <Core/OrthancException.h>
 
 namespace OrthancStone
 {
--- a/Framework/Widgets/LayerWidget.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Widgets/LayerWidget.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -24,7 +24,7 @@
 #include "../Layers/SliceOutlineRenderer.h"
 #include "../Toolbox/GeometryToolbox.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
+#include <Core/Logging.h>
 
 static const double THIN_SLICE_THICKNESS = 100.0 * std::numeric_limits<double>::epsilon();
 
--- a/Framework/Widgets/LayoutWidget.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Widgets/LayoutWidget.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,8 +21,8 @@
 
 #include "LayoutWidget.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Logging.h>
+#include <Core/OrthancException.h>
 
 #include <boost/math/special_functions/round.hpp>
 
--- a/Framework/Widgets/WidgetBase.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/Widgets/WidgetBase.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,9 +21,9 @@
 
 #include "WidgetBase.h"
 
-#include "../../Resources/Orthanc/Core/OrthancException.h"
-#include "../../Resources/Orthanc/Core/Images/ImageProcessing.h"
-#include "../../Resources/Orthanc/Core/Logging.h"
+#include <Core/OrthancException.h>
+#include <Core/Images/ImageProcessing.h>
+#include <Core/Logging.h>
 
 namespace OrthancStone
 {
--- a/Framework/dev.h	Mon May 21 09:02:03 2018 +0200
+++ b/Framework/dev.h	Fri Jun 01 17:48:47 2018 +0200
@@ -32,8 +32,8 @@
 #include "Volumes/ImageBuffer3D.h"
 #include "Volumes/SlicedVolumeBase.h"
 
-#include "../Resources/Orthanc/Core/Logging.h"
-#include "../Resources/Orthanc/Core/Images/ImageProcessing.h"
+#include <Core/Logging.h>
+#include <Core/Images/ImageProcessing.h>
 
 #include <boost/math/special_functions/round.hpp>
 
--- a/Platforms/Generic/CMakeLists.txt	Mon May 21 09:02:03 2018 +0200
+++ b/Platforms/Generic/CMakeLists.txt	Fri Jun 01 17:48:47 2018 +0200
@@ -3,6 +3,25 @@
 
 
 #####################################################################
+## Configuration for Orthanc
+#####################################################################
+
+include(../../Resources/CMake/Version.cmake)
+
+if (ORTHANC_STONE_VERSION STREQUAL "mainline")
+  set(ORTHANC_FRAMEWORK_VERSION "mainline")
+  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "hg")
+else()
+  set(ORTHANC_FRAMEWORK_VERSION "1.3.2")
+  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "web")
+endif()
+
+set(ORTHANC_FRAMEWORK_SOURCE "${ORTHANC_FRAMEWORK_DEFAULT_SOURCE}" CACHE STRING "Source of the Orthanc source code (can be \"hg\", \"archive\", \"web\" or \"path\")")
+set(ORTHANC_FRAMEWORK_ARCHIVE "" CACHE STRING "Path to the Orthanc archive, if ORTHANC_FRAMEWORK_SOURCE is \"archive\"")
+set(ORTHANC_FRAMEWORK_ROOT "" CACHE STRING "Path to the Orthanc source directory, if ORTHANC_FRAMEWORK_SOURCE is \"path\"")
+
+
+#####################################################################
 ## Build a static library containing the Orthanc Stone framework
 #####################################################################
 
--- a/Platforms/Generic/IOracleCommand.h	Mon May 21 09:02:03 2018 +0200
+++ b/Platforms/Generic/IOracleCommand.h	Fri Jun 01 17:48:47 2018 +0200
@@ -21,7 +21,7 @@
 
 #pragma once
 
-#include "../../Resources/Orthanc/Core/IDynamicObject.h"
+#include <Core/IDynamicObject.h>
 
 namespace OrthancStone
 {
--- a/Platforms/Generic/Oracle.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Platforms/Generic/Oracle.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,9 +21,9 @@
 
 #include "Oracle.h"
 
-#include "../../Resources/Orthanc/Core/Logging.h"
-#include "../../Resources/Orthanc/Core/MultiThreading/SharedMessageQueue.h"
-#include "../../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/Logging.h>
+#include <Core/MultiThreading/SharedMessageQueue.h>
+#include <Core/OrthancException.h>
 
 #include <vector>
 #include <stdio.h>
--- a/Platforms/Generic/WebServiceGetCommand.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Platforms/Generic/WebServiceGetCommand.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,7 +21,7 @@
 
 #include "WebServiceGetCommand.h"
 
-#include "../../Resources/Orthanc/Core/HttpClient.h"
+#include <Core/HttpClient.h>
 
 namespace OrthancStone
 {
--- a/Platforms/Generic/WebServiceGetCommand.h	Mon May 21 09:02:03 2018 +0200
+++ b/Platforms/Generic/WebServiceGetCommand.h	Fri Jun 01 17:48:47 2018 +0200
@@ -25,7 +25,7 @@
 
 #include "../../Framework/Toolbox/IWebService.h"
 
-#include "../../Resources/Orthanc/Core/WebServiceParameters.h"
+#include <Core/WebServiceParameters.h>
 
 #include <memory>
 
--- a/Platforms/Generic/WebServicePostCommand.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/Platforms/Generic/WebServicePostCommand.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -21,7 +21,7 @@
 
 #include "WebServicePostCommand.h"
 
-#include "../../Resources/Orthanc/Core/HttpClient.h"
+#include <Core/HttpClient.h>
 
 namespace OrthancStone
 {
--- a/Platforms/Generic/WebServicePostCommand.h	Mon May 21 09:02:03 2018 +0200
+++ b/Platforms/Generic/WebServicePostCommand.h	Fri Jun 01 17:48:47 2018 +0200
@@ -25,7 +25,7 @@
 
 #include "../../Framework/Toolbox/IWebService.h"
 
-#include "../../Resources/Orthanc/Core/WebServiceParameters.h"
+#include <Core/WebServiceParameters.h>
 
 #include <memory>
 
--- a/Resources/CMake/OrthancStoneConfiguration.cmake	Mon May 21 09:02:03 2018 +0200
+++ b/Resources/CMake/OrthancStoneConfiguration.cmake	Fri Jun 01 17:48:47 2018 +0200
@@ -22,11 +22,8 @@
 ## Configure the Orthanc Framework
 #####################################################################
 
-SET(ENABLE_JPEG ON)
-SET(ENABLE_PNG ON)
-SET(ENABLE_ZLIB ON)
-
 include(${ORTHANC_ROOT}/Resources/CMake/OrthancFrameworkConfiguration.cmake)
+include_directories(${ORTHANC_ROOT})
 
 
 #####################################################################
--- a/Resources/CMake/OrthancStoneParameters.cmake	Mon May 21 09:02:03 2018 +0200
+++ b/Resources/CMake/OrthancStoneParameters.cmake	Fri Jun 01 17:48:47 2018 +0200
@@ -22,10 +22,15 @@
 ## Import the parameters of the Orthanc Framework
 #####################################################################
 
-set(ORTHANC_STONE_ROOT ${CMAKE_CURRENT_LIST_DIR}/../..)
-set(ORTHANC_ROOT ${ORTHANC_STONE_ROOT}/Resources/Orthanc)
+include(${CMAKE_CURRENT_LIST_DIR}/../../Resources/Orthanc/DownloadOrthancFramework.cmake)
+include(${ORTHANC_ROOT}/Resources/CMake/OrthancFrameworkParameters.cmake)
 
-include(${ORTHANC_ROOT}/Resources/CMake/OrthancFrameworkParameters.cmake)
+set(ENABLE_LOCALE OFF)         # Disable support for locales (notably in Boost)
+set(ENABLE_GOOGLE_TEST ON)
+set(ENABLE_SQLITE OFF)
+SET(ENABLE_JPEG ON)
+SET(ENABLE_PNG ON)
+SET(ENABLE_ZLIB ON)
 
 
 #####################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/CMake/Version.cmake	Fri Jun 01 17:48:47 2018 +0200
@@ -0,0 +1,5 @@
+set(ORTHANC_STONE_VERSION "mainline")
+
+add_definitions(
+  -DORTHANC_STONE_VERSION="${ORTHANC_WSI_VERSION}"
+  )
--- a/Resources/Orthanc/Core/Cache/ICachePageProvider.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <string>
-#include "../IDynamicObject.h"
-
-namespace Orthanc
-{
-  class ICachePageProvider
-  {
-  public:
-    virtual ~ICachePageProvider()
-    {
-    }
-
-    virtual IDynamicObject* Provide(const std::string& id) = 0;
-  };
-}
--- a/Resources/Orthanc/Core/Cache/LeastRecentlyUsedIndex.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,347 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <list>
-#include <map>
-#include <boost/noncopyable.hpp>
-#include <cassert>
-
-#include "../OrthancException.h"
-#include "../Toolbox.h"
-
-namespace Orthanc
-{
-  /**
-   * This class implements the index of a cache with least recently
-   * used (LRU) recycling policy. All the items of the cache index
-   * can be associated with a payload.
-   * Reference: http://stackoverflow.com/a/2504317
-   **/
-  template <typename T, typename Payload = NullType>
-  class LeastRecentlyUsedIndex : public boost::noncopyable
-  {
-  private:
-    typedef std::list< std::pair<T, Payload> >  Queue;
-    typedef std::map<T, typename Queue::iterator>  Index;
-
-    Index  index_;
-    Queue  queue_;
-
-    /**
-     * Internal method for debug builds to check whether the internal
-     * data structures are not corrupted.
-     **/
-    void CheckInvariants() const;
-
-  public:
-    /**
-     * Add a new element to the cache index, and make it the most
-     * recent element.
-     * \param id The ID of the element.
-     * \param payload The payload of the element.
-     **/
-    void Add(T id, Payload payload = Payload());
-
-    void AddOrMakeMostRecent(T id, Payload payload = Payload());
-
-    /**
-     * When accessing an element of the cache, this method tags the
-     * element as the most recently used.
-     * \param id The most recently accessed item.
-     **/
-    void MakeMostRecent(T id);
-
-    void MakeMostRecent(T id, Payload updatedPayload);
-
-    /**
-     * Remove an element from the cache index.
-     * \param id The item to remove.
-     **/
-    Payload Invalidate(T id);
-
-    /**
-     * Get the oldest element in the cache and remove it.
-     * \return The oldest item.
-     **/
-    T RemoveOldest();
-
-    /**
-     * Get the oldest element in the cache, remove it and return the
-     * associated payload.
-     * \param payload Where to store the associated payload.
-     * \return The oldest item.
-     **/
-    T RemoveOldest(Payload& payload);
-
-    /**
-     * Check whether an element is contained in the cache.
-     * \param id The item.
-     * \return \c true iff the item is indexed by the cache.
-     **/
-    bool Contains(T id) const
-    {
-      return index_.find(id) != index_.end();
-    }
-
-    bool Contains(T id, Payload& payload) const
-    {
-      typename Index::const_iterator it = index_.find(id);
-      if (it == index_.end())
-      {
-        return false;
-      }
-      else
-      {
-        payload = it->second->second;
-        return true;
-      }
-    }
-
-    /**
-     * Return the number of elements in the cache.
-     * \return The number of elements.
-     **/
-    size_t GetSize() const
-    {
-      assert(index_.size() == queue_.size());
-      return queue_.size();
-    }
-
-    /**
-     * Check whether the cache index is empty.
-     * \return \c true iff the cache is empty.
-     **/
-    bool IsEmpty() const
-    {
-      return index_.empty();
-    }
-
-    const T& GetOldest() const;
-    
-    const Payload& GetOldestPayload() const;
-  };
-
-
-
-
-  /******************************************************************
-   ** Implementation of the template
-   ******************************************************************/
-
-  template <typename T, typename Payload>
-  void LeastRecentlyUsedIndex<T, Payload>::CheckInvariants() const
-  {
-#ifndef NDEBUG
-    assert(index_.size() == queue_.size());
-
-    for (typename Index::const_iterator 
-           it = index_.begin(); it != index_.end(); it++)
-    {
-      assert(it->second != queue_.end());
-      assert(it->second->first == it->first);
-    }
-#endif
-  }
-
-
-  template <typename T, typename Payload>
-  void LeastRecentlyUsedIndex<T, Payload>::Add(T id, Payload payload)
-  {
-    if (Contains(id))
-    {
-      throw OrthancException(ErrorCode_BadSequenceOfCalls);
-    }
-
-    queue_.push_front(std::make_pair(id, payload));
-    index_[id] = queue_.begin();
-
-    CheckInvariants();
-  }
-
-
-  template <typename T, typename Payload>
-  void LeastRecentlyUsedIndex<T, Payload>::MakeMostRecent(T id)
-  {
-    if (!Contains(id))
-    {
-      throw OrthancException(ErrorCode_InexistentItem);
-    }
-
-    typename Index::iterator it = index_.find(id);
-    assert(it != index_.end());
-
-    std::pair<T, Payload> item = *(it->second);
-    
-    queue_.erase(it->second);
-    queue_.push_front(item);
-    index_[id] = queue_.begin();
-
-    CheckInvariants();
-  }
-
-
-  template <typename T, typename Payload>
-  void LeastRecentlyUsedIndex<T, Payload>::AddOrMakeMostRecent(T id, Payload payload)
-  {
-    typename Index::iterator it = index_.find(id);
-
-    if (it != index_.end())
-    {
-      // Already existing. Make it most recent.
-      std::pair<T, Payload> item = *(it->second);
-      item.second = payload;
-      queue_.erase(it->second);
-      queue_.push_front(item);
-    }
-    else
-    {
-      // New item
-      queue_.push_front(std::make_pair(id, payload));
-    }
-
-    index_[id] = queue_.begin();
-
-    CheckInvariants();
-  }
-
-
-  template <typename T, typename Payload>
-  void LeastRecentlyUsedIndex<T, Payload>::MakeMostRecent(T id, Payload updatedPayload)
-  {
-    if (!Contains(id))
-    {
-      throw OrthancException(ErrorCode_InexistentItem);
-    }
-
-    typename Index::iterator it = index_.find(id);
-    assert(it != index_.end());
-
-    std::pair<T, Payload> item = *(it->second);
-    item.second = updatedPayload;
-    
-    queue_.erase(it->second);
-    queue_.push_front(item);
-    index_[id] = queue_.begin();
-
-    CheckInvariants();
-  }
-
-
-  template <typename T, typename Payload>
-  Payload LeastRecentlyUsedIndex<T, Payload>::Invalidate(T id)
-  {
-    if (!Contains(id))
-    {
-      throw OrthancException(ErrorCode_InexistentItem);
-    }
-
-    typename Index::iterator it = index_.find(id);
-    assert(it != index_.end());
-
-    Payload payload = it->second->second;
-    queue_.erase(it->second);
-    index_.erase(it);
-
-    CheckInvariants();
-    return payload;
-  }
-
-
-  template <typename T, typename Payload>
-  T LeastRecentlyUsedIndex<T, Payload>::RemoveOldest(Payload& payload)
-  {
-    if (IsEmpty())
-    {
-      throw OrthancException(ErrorCode_BadSequenceOfCalls);
-    }
-
-    std::pair<T, Payload> item = queue_.back();
-    T oldest = item.first;
-    payload = item.second;
-
-    queue_.pop_back();
-    assert(index_.find(oldest) != index_.end());
-    index_.erase(oldest);
-
-    CheckInvariants();
-
-    return oldest;
-  }
-
-
-  template <typename T, typename Payload>
-  T LeastRecentlyUsedIndex<T, Payload>::RemoveOldest()
-  {
-    if (IsEmpty())
-    {
-      throw OrthancException(ErrorCode_BadSequenceOfCalls);
-    }
-
-    std::pair<T, Payload> item = queue_.back();
-    T oldest = item.first;
-
-    queue_.pop_back();
-    assert(index_.find(oldest) != index_.end());
-    index_.erase(oldest);
-
-    CheckInvariants();
-
-    return oldest;
-  }
-
-
-  template <typename T, typename Payload>
-  const T& LeastRecentlyUsedIndex<T, Payload>::GetOldest() const
-  {
-    if (IsEmpty())
-    {
-      throw OrthancException(ErrorCode_BadSequenceOfCalls);
-    }
-
-    return queue_.back().first;
-  }
-
-
-  template <typename T, typename Payload>
-  const Payload& LeastRecentlyUsedIndex<T, Payload>::GetOldestPayload() const
-  {
-    if (IsEmpty())
-    {
-      throw OrthancException(ErrorCode_BadSequenceOfCalls);
-    }
-
-    return queue_.back().second;
-  }
-}
--- a/Resources/Orthanc/Core/Cache/MemoryCache.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +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-2018 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.
- *
- * 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 "MemoryCache.h"
-
-#include "../Logging.h"
-
-namespace Orthanc
-{
-  MemoryCache::Page& MemoryCache::Load(const std::string& id)
-  {
-    // Reuse the cache entry if it already exists
-    Page* p = NULL;
-    if (index_.Contains(id, p))
-    {
-      VLOG(1) << "Reusing a cache page";
-      assert(p != NULL);
-      index_.MakeMostRecent(id);
-      return *p;
-    }
-
-    // The id is not in the cache yet. Make some room if the cache
-    // is full.
-    if (index_.GetSize() == cacheSize_)
-    {
-      VLOG(1) << "Dropping the oldest cache page";
-      index_.RemoveOldest(p);
-      delete p;
-    }
-
-    // Create a new cache page
-    std::auto_ptr<Page> result(new Page);
-    result->id_ = id;
-    result->content_.reset(provider_.Provide(id));
-
-    // Add the newly create page to the cache
-    VLOG(1) << "Registering new data in a cache page";
-    p = result.release();
-    index_.Add(id, p);
-    return *p;
-  }
-
-  MemoryCache::MemoryCache(ICachePageProvider& provider,
-                           size_t cacheSize) : 
-    provider_(provider),
-    cacheSize_(cacheSize)
-  {
-  }
-
-  void MemoryCache::Invalidate(const std::string& id)
-  {
-    if (index_.Contains(id))
-    {
-      VLOG(1) << "Invalidating a cache page";
-      index_.Invalidate(id);
-    }
-  }
-
-  MemoryCache::~MemoryCache()
-  {
-    while (!index_.IsEmpty())
-    {
-      Page* element = NULL;
-      index_.RemoveOldest(element);
-      assert(element != NULL);
-      delete element;
-    }
-  }
-
-  IDynamicObject& MemoryCache::Access(const std::string& id)
-  {
-    return *Load(id).content_;
-  }
-}
--- a/Resources/Orthanc/Core/Cache/MemoryCache.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <memory>
-#include "LeastRecentlyUsedIndex.h"
-#include "ICachePageProvider.h"
-
-namespace Orthanc
-{
-  /**
-   * WARNING: This class is NOT thread-safe.
-   **/
-  class MemoryCache
-  {
-  private:
-    struct Page
-    {
-      std::string id_;
-      std::auto_ptr<IDynamicObject> content_;
-    };
-
-    ICachePageProvider& provider_;
-    size_t cacheSize_;
-    LeastRecentlyUsedIndex<std::string, Page*>  index_;
-
-    Page& Load(const std::string& id);
-
-  public:
-    MemoryCache(ICachePageProvider& provider,
-                size_t cacheSize);
-
-    ~MemoryCache();
-
-    IDynamicObject& Access(const std::string& id);
-
-    void Invalidate(const std::string& id);
-  };
-}
--- a/Resources/Orthanc/Core/Cache/SharedArchive.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +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-2018 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.
- *
- * 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 "SharedArchive.h"
-
-#include "../Toolbox.h"
-
-
-namespace Orthanc
-{
-  void SharedArchive::RemoveInternal(const std::string& id)
-  {
-    Archive::iterator it = archive_.find(id);
-
-    if (it != archive_.end())
-    {
-      delete it->second;
-      archive_.erase(it);
-    }
-  }
-
-
-  SharedArchive::Accessor::Accessor(SharedArchive& that,
-                                    const std::string& id) :
-    lock_(that.mutex_)
-  {
-    Archive::iterator it = that.archive_.find(id);
-
-    if (it == that.archive_.end())
-    {
-      throw OrthancException(ErrorCode_InexistentItem);
-    }
-    else
-    {
-      that.lru_.MakeMostRecent(id);
-      item_ = it->second;
-    }
-  }
-
-
-  SharedArchive::SharedArchive(size_t maxSize) : 
-    maxSize_(maxSize)
-  {
-    if (maxSize == 0)
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  SharedArchive::~SharedArchive()
-  {
-    for (Archive::iterator it = archive_.begin();
-         it != archive_.end(); ++it)
-    {
-      delete it->second;
-    }
-  }
-
-
-  std::string SharedArchive::Add(IDynamicObject* obj)
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-
-    if (archive_.size() == maxSize_)
-    {
-      // The quota has been reached, remove the oldest element
-      std::string oldest = lru_.RemoveOldest();
-      RemoveInternal(oldest);
-    }
-
-    std::string id = Toolbox::GenerateUuid();
-    RemoveInternal(id);  // Should never be useful because of UUID
-    archive_[id] = obj;
-    lru_.Add(id);
-
-    return id;
-  }
-
-
-  void SharedArchive::Remove(const std::string& id)
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-    RemoveInternal(id);      
-    lru_.Invalidate(id);
-  }
-
-
-  void SharedArchive::List(std::list<std::string>& items)
-  {
-    items.clear();
-
-    boost::mutex::scoped_lock lock(mutex_);
-
-    for (Archive::const_iterator it = archive_.begin();
-         it != archive_.end(); ++it)
-    {
-      items.push_back(it->first);
-    }
-  }
-}
-
-
--- a/Resources/Orthanc/Core/Cache/SharedArchive.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_SANDBOXED)
-#  error The macro ORTHANC_SANDBOXED must be defined
-#endif
-
-#if ORTHANC_SANDBOXED == 1
-#  error The class SharedArchive cannot be used in sandboxed environments
-#endif
-
-#include "LeastRecentlyUsedIndex.h"
-#include "../IDynamicObject.h"
-
-#include <map>
-#include <boost/thread.hpp>
-
-namespace Orthanc
-{
-  class SharedArchive : public boost::noncopyable
-  {
-  private:
-    typedef std::map<std::string, IDynamicObject*>  Archive;
-
-    size_t         maxSize_;
-    boost::mutex   mutex_;
-    Archive        archive_;
-    Orthanc::LeastRecentlyUsedIndex<std::string> lru_;
-
-    void RemoveInternal(const std::string& id);
-
-  public:
-    class Accessor : public boost::noncopyable
-    {
-    private:
-      boost::mutex::scoped_lock  lock_;
-      IDynamicObject*            item_;
-
-    public:
-      Accessor(SharedArchive& that,
-               const std::string& id);
-
-      IDynamicObject& GetItem() const
-      {
-        return *item_;
-      }      
-    };
-
-
-    SharedArchive(size_t maxSize);
-
-    ~SharedArchive();
-
-    std::string Add(IDynamicObject* obj);  // Takes the ownership
-
-    void Remove(const std::string& id);
-
-    void List(std::list<std::string>& items);
-  };
-}
-
-
--- a/Resources/Orthanc/Core/ChunkedBuffer.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +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-2018 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.
- *
- * 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 "ChunkedBuffer.h"
-
-#include <cassert>
-#include <string.h>
-
-
-namespace Orthanc
-{
-  void ChunkedBuffer::Clear()
-  {
-    numBytes_ = 0;
-
-    for (Chunks::iterator it = chunks_.begin(); 
-         it != chunks_.end(); ++it)
-    {
-      delete *it;
-    }
-  }
-
-
-  void ChunkedBuffer::AddChunk(const void* chunkData,
-                               size_t chunkSize)
-  {
-    if (chunkSize == 0)
-    {
-      return;
-    }
-    else
-    {
-      assert(chunkData != NULL);
-      chunks_.push_back(new std::string(reinterpret_cast<const char*>(chunkData), chunkSize));
-      numBytes_ += chunkSize;
-    }
-  }
-
-
-  void ChunkedBuffer::AddChunk(const std::string& chunk)
-  {
-    if (chunk.size() > 0)
-    {
-      AddChunk(&chunk[0], chunk.size());
-    }
-  }
-
-
-  void ChunkedBuffer::Flatten(std::string& result)
-  {
-    result.resize(numBytes_);
-
-    size_t pos = 0;
-    for (Chunks::iterator it = chunks_.begin(); 
-         it != chunks_.end(); ++it)
-    {
-      assert(*it != NULL);
-
-      size_t s = (*it)->size();
-      if (s != 0)
-      {
-        memcpy(&result[pos], (*it)->c_str(), s);
-        pos += s;
-      }
-
-      delete *it;
-    }
-
-    chunks_.clear();
-    numBytes_ = 0;
-  }
-}
--- a/Resources/Orthanc/Core/ChunkedBuffer.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <list>
-#include <string>
-
-namespace Orthanc
-{
-  class ChunkedBuffer
-  {
-  private:
-    typedef std::list<std::string*>  Chunks;
-    size_t numBytes_;
-    Chunks chunks_;
-  
-    void Clear();
-
-  public:
-    ChunkedBuffer() : numBytes_(0)
-    {
-    }
-
-    ~ChunkedBuffer()
-    {
-      Clear();
-    }
-
-    size_t GetNumBytes() const
-    {
-      return numBytes_;
-    }
-
-    void AddChunk(const void* chunkData,
-                  size_t chunkSize);
-
-    void AddChunk(const std::string& chunk);
-
-    void Flatten(std::string& result);
-  };
-}
--- a/Resources/Orthanc/Core/Compression/DeflateBaseCompressor.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +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-2018 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.
- *
- * 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 "DeflateBaseCompressor.h"
-
-#include "../OrthancException.h"
-#include "../Logging.h"
-
-#include <string.h>
-
-namespace Orthanc
-{
-  void DeflateBaseCompressor::SetCompressionLevel(uint8_t level)
-  {
-    if (level >= 10)
-    {
-      LOG(ERROR) << "Zlib compression level must be between 0 (no compression) and 9 (highest compression)";
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    compressionLevel_ = level;
-  }
-
-
-  uint64_t DeflateBaseCompressor::ReadUncompressedSizePrefix(const void* compressed,
-                                                             size_t compressedSize)
-  {
-    if (compressedSize == 0)
-    {
-      return 0;
-    }
-
-    if (compressedSize < sizeof(uint64_t))
-    {
-      LOG(ERROR) << "The compressed buffer is ill-formed";
-      throw OrthancException(ErrorCode_CorruptedFile);
-    }
-
-    uint64_t size;
-    memcpy(&size, compressed, sizeof(uint64_t));
-
-    return size;
-  }
-
-}
--- a/Resources/Orthanc/Core/Compression/DeflateBaseCompressor.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "IBufferCompressor.h"
-
-#if !defined(ORTHANC_ENABLE_ZLIB)
-#  error The macro ORTHANC_ENABLE_ZLIB must be defined
-#endif
-
-#if ORTHANC_ENABLE_ZLIB != 1
-#  error ZLIB support must be enabled to include this file
-#endif
-
-
-#include <stdint.h>
-
-namespace Orthanc
-{
-  class DeflateBaseCompressor : public IBufferCompressor
-  {
-  private:
-    uint8_t compressionLevel_;
-    bool    prefixWithUncompressedSize_;
-
-  protected:
-    uint64_t ReadUncompressedSizePrefix(const void* compressed,
-                                        size_t compressedSize);
-
-  public:
-    DeflateBaseCompressor() : 
-      compressionLevel_(6),
-      prefixWithUncompressedSize_(false)
-    {
-    }
-
-    void SetCompressionLevel(uint8_t level);
-    
-    void SetPrefixWithUncompressedSize(bool prefix)
-    {
-      prefixWithUncompressedSize_ = prefix;
-    }
-
-    bool HasPrefixWithUncompressedSize() const
-    {
-      return prefixWithUncompressedSize_;
-    }
-
-    uint8_t GetCompressionLevel() const
-    {
-      return compressionLevel_;
-    }
-  };
-}
--- a/Resources/Orthanc/Core/Compression/GzipCompressor.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +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-2018 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.
- *
- * 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 "GzipCompressor.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <zlib.h>
-
-#include "../OrthancException.h"
-#include "../Logging.h"
-
-namespace Orthanc
-{
-  uint64_t GzipCompressor::GuessUncompressedSize(const void* compressed,
-                                                 size_t compressedSize)
-  {
-    /**
-     * "Is there a way to find out the size of the original file which
-     * is inside a GZIP file? [...] There is no truly reliable way,
-     * other than gunzipping the stream. You do not need to save the
-     * result of the decompression, so you can determine the size by
-     * simply reading and decoding the entire file without taking up
-     * space with the decompressed result.
-     *
-     * There is an unreliable way to determine the uncompressed size,
-     * which is to look at the last four bytes of the gzip file, which
-     * is the uncompressed length of that entry modulo 232 in little
-     * endian order.
-     * 
-     * It is unreliable because a) the uncompressed data may be longer
-     * than 2^32 bytes, and b) the gzip file may consist of multiple
-     * gzip streams, in which case you would find the length of only
-     * the last of those streams.
-     * 
-     * If you are in control of the source of the gzip files, you know
-     * that they consist of single gzip streams, and you know that
-     * they are less than 2^32 bytes uncompressed, then and only then
-     * can you use those last four bytes with confidence."
-     *
-     * http://stackoverflow.com/a/9727599/881731
-     **/
-
-    if (compressedSize < 4)
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-
-    const uint8_t* p = reinterpret_cast<const uint8_t*>(compressed) + compressedSize - 4;
-
-    return ((static_cast<uint32_t>(p[0]) << 0) +
-            (static_cast<uint32_t>(p[1]) << 8) +
-            (static_cast<uint32_t>(p[2]) << 16) +
-            (static_cast<uint32_t>(p[3]) << 24));            
-  }
-
-
-
-  void GzipCompressor::Compress(std::string& compressed,
-                                const void* uncompressed,
-                                size_t uncompressedSize)
-  {
-    uLongf compressedSize = compressBound(uncompressedSize) + 1024 /* security margin */;
-    if (compressedSize == 0)
-    {
-      compressedSize = 1;
-    }
-
-    uint8_t* target;
-    if (HasPrefixWithUncompressedSize())
-    {
-      compressed.resize(compressedSize + sizeof(uint64_t));
-      target = reinterpret_cast<uint8_t*>(&compressed[0]) + sizeof(uint64_t);
-    }
-    else
-    {
-      compressed.resize(compressedSize);
-      target = reinterpret_cast<uint8_t*>(&compressed[0]);
-    }
-
-    z_stream stream;
-    memset(&stream, 0, sizeof(stream));
-
-    stream.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(uncompressed));
-    stream.next_out = reinterpret_cast<Bytef*>(target);
-
-    stream.avail_in = static_cast<uInt>(uncompressedSize);
-    stream.avail_out = static_cast<uInt>(compressedSize);
-
-    // Ensure no overflow (if the buffer is too large for the current archicture)
-    if (static_cast<size_t>(stream.avail_in) != uncompressedSize ||
-        static_cast<size_t>(stream.avail_out) != compressedSize)
-    {
-      throw OrthancException(ErrorCode_NotEnoughMemory);
-    }
-    
-    // Initialize the compression engine
-    int error = deflateInit2(&stream, 
-                             GetCompressionLevel(), 
-                             Z_DEFLATED,
-                             MAX_WBITS + 16,      // ask for gzip output
-                             8,                   // default memory level
-                             Z_DEFAULT_STRATEGY);
-
-    if (error != Z_OK)
-    {
-      // Cannot initialize zlib
-      compressed.clear();
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-    // Compress the input buffer
-    error = deflate(&stream, Z_FINISH);
-
-    if (error != Z_STREAM_END)
-    {
-      deflateEnd(&stream);
-      compressed.clear();
-
-      switch (error)
-      {
-      case Z_MEM_ERROR:
-        throw OrthancException(ErrorCode_NotEnoughMemory);
-
-      default:
-        throw OrthancException(ErrorCode_InternalError);
-      }  
-    }
-
-    size_t size = stream.total_out;
-
-    if (deflateEnd(&stream) != Z_OK)
-    {
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-    // The compression was successful
-    if (HasPrefixWithUncompressedSize())
-    {
-      uint64_t s = static_cast<uint64_t>(uncompressedSize);
-      memcpy(&compressed[0], &s, sizeof(uint64_t));
-      compressed.resize(size + sizeof(uint64_t));
-    }
-    else
-    {
-      compressed.resize(size);
-    }
-  }
-
-
-  void GzipCompressor::Uncompress(std::string& uncompressed,
-                                  const void* compressed,
-                                  size_t compressedSize)
-  {
-    uint64_t uncompressedSize;
-    const uint8_t* source = reinterpret_cast<const uint8_t*>(compressed);
-
-    if (HasPrefixWithUncompressedSize())
-    {
-      uncompressedSize = ReadUncompressedSizePrefix(compressed, compressedSize);
-      source += sizeof(uint64_t);
-      compressedSize -= sizeof(uint64_t);
-    }
-    else
-    {
-      uncompressedSize = GuessUncompressedSize(compressed, compressedSize);
-    }
-
-    try
-    {
-      uncompressed.resize(static_cast<size_t>(uncompressedSize));
-    }
-    catch (...)
-    {
-      throw OrthancException(ErrorCode_NotEnoughMemory);
-    }
-
-    z_stream stream;
-    memset(&stream, 0, sizeof(stream));
-
-    char dummy = '\0';  // zlib does not like NULL output buffers (even if the uncompressed data is empty)
-    stream.next_in = const_cast<Bytef*>(source);
-    stream.next_out = reinterpret_cast<Bytef*>(uncompressedSize == 0 ? &dummy : &uncompressed[0]);
-
-    stream.avail_in = static_cast<uInt>(compressedSize);
-    stream.avail_out = static_cast<uInt>(uncompressedSize);
-
-    // Ensure no overflow (if the buffer is too large for the current archicture)
-    if (static_cast<size_t>(stream.avail_in) != compressedSize ||
-        static_cast<size_t>(stream.avail_out) != uncompressedSize)
-    {
-      throw OrthancException(ErrorCode_NotEnoughMemory);
-    }
-
-    // Initialize the compression engine
-    int error = inflateInit2(&stream, 
-                             MAX_WBITS + 16);  // this is a gzip input
-
-    if (error != Z_OK)
-    {
-      // Cannot initialize zlib
-      uncompressed.clear();
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-    // Uncompress the input buffer
-    error = inflate(&stream, Z_FINISH);
-
-    if (error != Z_STREAM_END)
-    {
-      inflateEnd(&stream);
-      uncompressed.clear();
-
-      switch (error)
-      {
-        case Z_MEM_ERROR:
-          throw OrthancException(ErrorCode_NotEnoughMemory);
-          
-        case Z_BUF_ERROR:
-        case Z_NEED_DICT:
-          throw OrthancException(ErrorCode_BadFileFormat);
-          
-        default:
-          throw OrthancException(ErrorCode_InternalError);
-      }
-    }
-
-    size_t size = stream.total_out;
-
-    if (inflateEnd(&stream) != Z_OK)
-    {
-      uncompressed.clear();
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-    if (size != uncompressedSize)
-    {
-      uncompressed.clear();
-
-      // The uncompressed size was not that properly guess, presumably
-      // because of a file size over 4GB. Should fallback to
-      // stream-based decompression.
-      LOG(ERROR) << "The uncompressed size of a gzip-encoded buffer was not properly guessed";
-      throw OrthancException(ErrorCode_NotImplemented);
-    }
-  }
-}
--- a/Resources/Orthanc/Core/Compression/GzipCompressor.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "DeflateBaseCompressor.h"
-
-namespace Orthanc
-{
-  class GzipCompressor : public DeflateBaseCompressor
-  {
-  private:
-    uint64_t GuessUncompressedSize(const void* compressed,
-                                   size_t compressedSize);
-
-  public:
-    GzipCompressor()
-    {
-      SetPrefixWithUncompressedSize(false);
-    }
-
-    virtual void Compress(std::string& compressed,
-                          const void* uncompressed,
-                          size_t uncompressedSize);
-
-    virtual void Uncompress(std::string& uncompressed,
-                            const void* compressed,
-                            size_t compressedSize);
-  };
-}
--- a/Resources/Orthanc/Core/Compression/HierarchicalZipWriter.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +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-2018 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.
- *
- * 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 "HierarchicalZipWriter.h"
-
-#include "../Toolbox.h"
-#include "../OrthancException.h"
-
-#include <boost/lexical_cast.hpp>
-
-namespace Orthanc
-{
-  std::string HierarchicalZipWriter::Index::KeepAlphanumeric(const std::string& source)
-  {
-    std::string result;
-
-    bool lastSpace = false;
-
-    result.reserve(source.size());
-    for (size_t i = 0; i < source.size(); i++)
-    {
-      char c = source[i];
-      if (c == '^')
-        c = ' ';
-
-      if (c <= 127 && 
-          c >= 0)
-      {
-        if (isspace(c)) 
-        {
-          if (!lastSpace)
-          {
-            lastSpace = true;
-            result.push_back(' ');
-          }
-        }
-        else if (isalnum(c) || 
-                 c == '.' || 
-                 c == '_')
-        {
-          result.push_back(c);
-          lastSpace = false;
-        }
-      }
-    }
-
-    return Toolbox::StripSpaces(result);
-  }
-
-  std::string HierarchicalZipWriter::Index::GetCurrentDirectoryPath() const
-  {
-    std::string result;
-
-    Stack::const_iterator it = stack_.begin();
-    ++it;  // Skip the root node (to avoid absolute paths)
-
-    while (it != stack_.end())
-    {
-      result += (*it)->name_ + "/";
-      ++it;
-    }
-
-    return result;
-  }
-
-  std::string HierarchicalZipWriter::Index::EnsureUniqueFilename(const char* filename)
-  {
-    std::string standardized = KeepAlphanumeric(filename);
-
-    Directory& d = *stack_.back();
-    Directory::Content::iterator it = d.content_.find(standardized);
-
-    if (it == d.content_.end())
-    {
-      d.content_[standardized] = 1;
-      return standardized;
-    }
-    else
-    {
-      it->second++;
-      return standardized + "-" + boost::lexical_cast<std::string>(it->second);
-    }    
-  }
-
-  HierarchicalZipWriter::Index::Index()
-  {
-    stack_.push_back(new Directory);
-  }
-
-  HierarchicalZipWriter::Index::~Index()
-  {
-    for (Stack::iterator it = stack_.begin(); it != stack_.end(); ++it)
-    {
-      delete *it;
-    }
-  }
-
-  std::string HierarchicalZipWriter::Index::OpenFile(const char* name)
-  {
-    return GetCurrentDirectoryPath() + EnsureUniqueFilename(name);
-  }
-
-  void HierarchicalZipWriter::Index::OpenDirectory(const char* name)
-  {
-    std::string d = EnsureUniqueFilename(name);
-
-    // Push the new directory onto the stack
-    stack_.push_back(new Directory);
-    stack_.back()->name_ = d;
-  }
-
-  void HierarchicalZipWriter::Index::CloseDirectory()
-  {
-    if (IsRoot())
-    {
-      // Cannot close the root node
-      throw OrthancException(ErrorCode_BadSequenceOfCalls);
-    }
-
-    delete stack_.back();
-    stack_.pop_back();
-  }
-
-
-  HierarchicalZipWriter::HierarchicalZipWriter(const char* path)
-  {
-    writer_.SetOutputPath(path);
-    writer_.Open();
-  }
-
-  HierarchicalZipWriter::~HierarchicalZipWriter()
-  {
-    writer_.Close();
-  }
-
-  void HierarchicalZipWriter::OpenFile(const char* name)
-  {
-    std::string p = indexer_.OpenFile(name);
-    writer_.OpenFile(p.c_str());
-  }
-
-  void HierarchicalZipWriter::OpenDirectory(const char* name)
-  {
-    indexer_.OpenDirectory(name);
-  }
-
-  void HierarchicalZipWriter::CloseDirectory()
-  {
-    indexer_.CloseDirectory();
-  }
-}
--- a/Resources/Orthanc/Core/Compression/HierarchicalZipWriter.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "ZipWriter.h"
-
-#include <map>
-#include <list>
-#include <boost/lexical_cast.hpp>
-
-#if ORTHANC_BUILD_UNIT_TESTS == 1
-#  include <gtest/gtest_prod.h>
-#endif
-
-namespace Orthanc
-{
-  class HierarchicalZipWriter
-  {
-#if ORTHANC_BUILD_UNIT_TESTS == 1
-    FRIEND_TEST(HierarchicalZipWriter, Index);
-    FRIEND_TEST(HierarchicalZipWriter, Filenames);
-#endif
-
-  private:
-    class Index
-    {
-    private:
-      struct Directory
-      {
-        typedef std::map<std::string, unsigned int>  Content;
-
-        std::string name_;
-        Content  content_;
-      };
-
-      typedef std::list<Directory*> Stack;
-  
-      Stack stack_;
-
-      std::string EnsureUniqueFilename(const char* filename);
-
-    public:
-      Index();
-
-      ~Index();
-
-      bool IsRoot() const
-      {
-        return stack_.size() == 1;
-      }
-
-      std::string OpenFile(const char* name);
-
-      void OpenDirectory(const char* name);
-
-      void CloseDirectory();
-
-      std::string GetCurrentDirectoryPath() const;
-
-      static std::string KeepAlphanumeric(const std::string& source);
-    };
-
-    Index indexer_;
-    ZipWriter writer_;
-
-  public:
-    HierarchicalZipWriter(const char* path);
-
-    ~HierarchicalZipWriter();
-
-    void SetZip64(bool isZip64)
-    {
-      writer_.SetZip64(isZip64);
-    }
-
-    bool IsZip64() const
-    {
-      return writer_.IsZip64();
-    }
-
-    void SetCompressionLevel(uint8_t level)
-    {
-      writer_.SetCompressionLevel(level);
-    }
-
-    uint8_t GetCompressionLevel() const
-    {
-      return writer_.GetCompressionLevel();
-    }
-
-    void SetAppendToExisting(bool append)
-    {
-      writer_.SetAppendToExisting(append);
-    }
-    
-    bool IsAppendToExisting() const
-    {
-      return writer_.IsAppendToExisting();
-    }
-    
-    void OpenFile(const char* name);
-
-    void OpenDirectory(const char* name);
-
-    void CloseDirectory();
-
-    std::string GetCurrentDirectoryPath() const
-    {
-      return indexer_.GetCurrentDirectoryPath();
-    }
-
-    void Write(const char* data, size_t length)
-    {
-      writer_.Write(data, length);
-    }
-
-    void Write(const std::string& data)
-    {
-      writer_.Write(data);
-    }
-  };
-}
--- a/Resources/Orthanc/Core/Compression/IBufferCompressor.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <string>
-#include <boost/noncopyable.hpp>
-
-namespace Orthanc
-{
-  class IBufferCompressor : public boost::noncopyable
-  {
-  public:
-    virtual ~IBufferCompressor()
-    {
-    }
-
-    virtual void Compress(std::string& compressed,
-                          const void* uncompressed,
-                          size_t uncompressedSize) = 0;
-
-    virtual void Uncompress(std::string& uncompressed,
-                            const void* compressed,
-                            size_t compressedSize) = 0;
-
-    static void Compress(std::string& compressed,
-                         IBufferCompressor& compressor,
-                         const std::string& uncompressed)
-    {
-      compressor.Compress(compressed, 
-                          uncompressed.size() == 0 ? NULL : uncompressed.c_str(), 
-                          uncompressed.size());
-    }
-
-    static void Uncompress(std::string& uncompressed,
-                           IBufferCompressor& compressor,
-                           const std::string& compressed)
-    {
-      compressor.Uncompress(uncompressed, 
-                            compressed.size() == 0 ? NULL : compressed.c_str(), 
-                            compressed.size());
-    }
-  };
-}
--- a/Resources/Orthanc/Core/Compression/ZipWriter.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +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-2018 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.
- *
- * 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"
-
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-
-#include "ZipWriter.h"
-
-#include <limits>
-#include <boost/filesystem.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-
-#include "../../Resources/ThirdParty/minizip/zip.h"
-#include "../OrthancException.h"
-#include "../Logging.h"
-
-
-static void PrepareFileInfo(zip_fileinfo& zfi)
-{
-  memset(&zfi, 0, sizeof(zfi));
-
-  using namespace boost::posix_time;
-  ptime now = second_clock::local_time();
-
-  boost::gregorian::date today = now.date();
-  ptime midnight(today);
-
-  time_duration sinceMidnight = now - midnight;
-  zfi.tmz_date.tm_sec = sinceMidnight.seconds();  // seconds after the minute - [0,59]
-  zfi.tmz_date.tm_min = sinceMidnight.minutes();  // minutes after the hour - [0,59]
-  zfi.tmz_date.tm_hour = sinceMidnight.hours();  // hours since midnight - [0,23]
-
-  // http://www.boost.org/doc/libs/1_35_0/doc/html/boost/gregorian/greg_day.html
-  zfi.tmz_date.tm_mday = today.day();  // day of the month - [1,31]
-
-  // http://www.boost.org/doc/libs/1_35_0/doc/html/boost/gregorian/greg_month.html
-  zfi.tmz_date.tm_mon = today.month() - 1;  // months since January - [0,11]
-
-  // http://www.boost.org/doc/libs/1_35_0/doc/html/boost/gregorian/greg_year.html
-  zfi.tmz_date.tm_year = today.year();  // years - [1980..2044]
-}
-
-
-
-namespace Orthanc
-{
-  struct ZipWriter::PImpl
-  {
-    zipFile file_;
-
-    PImpl() : file_(NULL)
-    {
-    }
-  };
-
-  ZipWriter::ZipWriter() :
-    pimpl_(new PImpl),
-    isZip64_(false),
-    hasFileInZip_(false),
-    append_(false),
-    compressionLevel_(6)
-  {
-  }
-
-  ZipWriter::~ZipWriter()
-  {
-    Close();
-  }
-
-  void ZipWriter::Close()
-  {
-    if (IsOpen())
-    {
-      zipClose(pimpl_->file_, "Created by Orthanc");
-      pimpl_->file_ = NULL;
-      hasFileInZip_ = false;
-    }
-  }
-
-  bool ZipWriter::IsOpen() const
-  {
-    return pimpl_->file_ != NULL;
-  }
-
-  void ZipWriter::Open()
-  {
-    if (IsOpen())
-    {
-      return;
-    }
-
-    if (path_.size() == 0)
-    {
-      LOG(ERROR) << "Please call SetOutputPath() before creating the file";
-      throw OrthancException(ErrorCode_BadSequenceOfCalls);
-    }
-
-    hasFileInZip_ = false;
-
-    int mode = APPEND_STATUS_CREATE;
-    if (append_ && 
-        boost::filesystem::exists(path_))
-    {
-      mode = APPEND_STATUS_ADDINZIP;
-    }
-
-    if (isZip64_)
-    {
-      pimpl_->file_ = zipOpen64(path_.c_str(), mode);
-    }
-    else
-    {
-      pimpl_->file_ = zipOpen(path_.c_str(), mode);
-    }
-
-    if (!pimpl_->file_)
-    {
-      throw OrthancException(ErrorCode_CannotWriteFile);
-    }
-  }
-
-  void ZipWriter::SetOutputPath(const char* path)
-  {
-    Close();
-    path_ = path;
-  }
-
-  void ZipWriter::SetZip64(bool isZip64)
-  {
-    Close();
-    isZip64_ = isZip64;
-  }
-
-  void ZipWriter::SetCompressionLevel(uint8_t level)
-  {
-    if (level >= 10)
-    {
-      LOG(ERROR) << "ZIP compression level must be between 0 (no compression) and 9 (highest compression)";
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    Close();
-    compressionLevel_ = level;
-  }
-
-  void ZipWriter::OpenFile(const char* path)
-  {
-    Open();
-
-    zip_fileinfo zfi;
-    PrepareFileInfo(zfi);
-
-    int result;
-
-    if (isZip64_)
-    {
-      result = zipOpenNewFileInZip64(pimpl_->file_, path,
-                                     &zfi,
-                                     NULL,   0,
-                                     NULL,   0,
-                                     "",  // Comment
-                                     Z_DEFLATED,
-                                     compressionLevel_, 1);
-    }
-    else
-    {
-      result = zipOpenNewFileInZip(pimpl_->file_, path,
-                                   &zfi,
-                                   NULL,   0,
-                                   NULL,   0,
-                                   "",  // Comment
-                                   Z_DEFLATED,
-                                   compressionLevel_);
-    }
-
-    if (result != 0)
-    {
-      throw OrthancException(ErrorCode_CannotWriteFile);
-    }
-
-    hasFileInZip_ = true;
-  }
-
-
-  void ZipWriter::Write(const std::string& data)
-  {
-    if (data.size())
-    {
-      Write(&data[0], data.size());
-    }
-  }
-
-
-  void ZipWriter::Write(const char* data, size_t length)
-  {
-    if (!hasFileInZip_)
-    {
-      LOG(ERROR) << "Call first OpenFile()";
-      throw OrthancException(ErrorCode_BadSequenceOfCalls);
-    }
-
-    const size_t maxBytesInAStep = std::numeric_limits<int32_t>::max();
-
-    while (length > 0)
-    {
-      int bytes = static_cast<int32_t>(length <= maxBytesInAStep ? length : maxBytesInAStep);
-
-      if (zipWriteInFileInZip(pimpl_->file_, data, bytes))
-      {
-        throw OrthancException(ErrorCode_CannotWriteFile);
-      }
-      
-      data += bytes;
-      length -= bytes;
-    }
-  }
-
-
-  void ZipWriter::SetAppendToExisting(bool append)
-  {
-    Close();
-    append_ = append;
-  }
-    
-
-}
--- a/Resources/Orthanc/Core/Compression/ZipWriter.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_ENABLE_ZLIB)
-#  error The macro ORTHANC_ENABLE_ZLIB must be defined
-#endif
-
-#if ORTHANC_ENABLE_ZLIB != 1
-#  error ZLIB support must be enabled to include this file
-#endif
-
-
-#include <stdint.h>
-#include <string>
-#include <boost/shared_ptr.hpp>
-
-namespace Orthanc
-{
-  class ZipWriter
-  {
-  private:
-    struct PImpl;
-    boost::shared_ptr<PImpl> pimpl_;
-
-    bool isZip64_;
-    bool hasFileInZip_;
-    bool append_;
-    uint8_t compressionLevel_;
-    std::string path_;
-
-  public:
-    ZipWriter();
-
-    ~ZipWriter();
-
-    void SetZip64(bool isZip64);
-
-    bool IsZip64() const
-    {
-      return isZip64_;
-    }
-
-    void SetCompressionLevel(uint8_t level);
-
-    uint8_t GetCompressionLevel() const
-    {
-      return compressionLevel_;
-    }
-
-    void SetAppendToExisting(bool append);
-    
-    bool IsAppendToExisting() const
-    {
-      return append_;
-    }
-    
-    void Open();
-
-    void Close();
-
-    bool IsOpen() const;
-
-    void SetOutputPath(const char* path);
-
-    const std::string& GetOutputPath() const
-    {
-      return path_;
-    }
-
-    void OpenFile(const char* path);
-
-    void Write(const char* data, size_t length);
-
-    void Write(const std::string& data);
-  };
-}
--- a/Resources/Orthanc/Core/Compression/ZlibCompressor.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +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-2018 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.
- *
- * 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 "ZlibCompressor.h"
-
-#include "../OrthancException.h"
-#include "../Logging.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <zlib.h>
-
-namespace Orthanc
-{
-  void ZlibCompressor::Compress(std::string& compressed,
-                                const void* uncompressed,
-                                size_t uncompressedSize)
-  {
-    if (uncompressedSize == 0)
-    {
-      compressed.clear();
-      return;
-    }
-
-    uLongf compressedSize = compressBound(uncompressedSize) + 1024 /* security margin */;
-    if (compressedSize == 0)
-    {
-      compressedSize = 1;
-    }
-
-    uint8_t* target;
-    if (HasPrefixWithUncompressedSize())
-    {
-      compressed.resize(compressedSize + sizeof(uint64_t));
-      target = reinterpret_cast<uint8_t*>(&compressed[0]) + sizeof(uint64_t);
-    }
-    else
-    {
-      compressed.resize(compressedSize);
-      target = reinterpret_cast<uint8_t*>(&compressed[0]);
-    }
-
-    int error = compress2(target,
-                          &compressedSize,
-                          const_cast<Bytef *>(static_cast<const Bytef *>(uncompressed)), 
-                          uncompressedSize,
-                          GetCompressionLevel());
-
-    if (error != Z_OK)
-    {
-      compressed.clear();
-
-      switch (error)
-      {
-      case Z_MEM_ERROR:
-        throw OrthancException(ErrorCode_NotEnoughMemory);
-
-      default:
-        throw OrthancException(ErrorCode_InternalError);
-      }  
-    }
-
-    // The compression was successful
-    if (HasPrefixWithUncompressedSize())
-    {
-      uint64_t s = static_cast<uint64_t>(uncompressedSize);
-      memcpy(&compressed[0], &s, sizeof(uint64_t));
-      compressed.resize(compressedSize + sizeof(uint64_t));
-    }
-    else
-    {
-      compressed.resize(compressedSize);
-    }
-  }
-
-
-  void ZlibCompressor::Uncompress(std::string& uncompressed,
-                                  const void* compressed,
-                                  size_t compressedSize)
-  {
-    if (compressedSize == 0)
-    {
-      uncompressed.clear();
-      return;
-    }
-
-    if (!HasPrefixWithUncompressedSize())
-    {
-      LOG(ERROR) << "Cannot guess the uncompressed size of a zlib-encoded buffer";
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-    uint64_t uncompressedSize = ReadUncompressedSizePrefix(compressed, compressedSize);
-    
-    try
-    {
-      uncompressed.resize(static_cast<size_t>(uncompressedSize));
-    }
-    catch (...)
-    {
-      throw OrthancException(ErrorCode_NotEnoughMemory);
-    }
-
-    uLongf tmp = static_cast<uLongf>(uncompressedSize);
-    int error = uncompress
-      (reinterpret_cast<uint8_t*>(&uncompressed[0]), 
-       &tmp,
-       reinterpret_cast<const uint8_t*>(compressed) + sizeof(uint64_t),
-       compressedSize - sizeof(uint64_t));
-
-    if (error != Z_OK)
-    {
-      uncompressed.clear();
-
-      switch (error)
-      {
-      case Z_DATA_ERROR:
-        throw OrthancException(ErrorCode_CorruptedFile);
-
-      case Z_MEM_ERROR:
-        throw OrthancException(ErrorCode_NotEnoughMemory);
-
-      default:
-        throw OrthancException(ErrorCode_InternalError);
-      }  
-    }
-  }
-}
--- a/Resources/Orthanc/Core/Compression/ZlibCompressor.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "DeflateBaseCompressor.h"
-
-namespace Orthanc
-{
-  class ZlibCompressor : public DeflateBaseCompressor
-  {
-  public:
-    ZlibCompressor()
-    {
-      SetPrefixWithUncompressedSize(true);
-    }
-
-    virtual void Compress(std::string& compressed,
-                          const void* uncompressed,
-                          size_t uncompressedSize);
-
-    virtual void Uncompress(std::string& uncompressed,
-                            const void* compressed,
-                            size_t compressedSize);
-  };
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomArray.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +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-2018 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.
- *
- * 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 "DicomArray.h"
-
-#include <stdio.h>
-
-namespace Orthanc
-{
-  DicomArray::DicomArray(const DicomMap& map)
-  {
-    elements_.reserve(map.map_.size());
-    
-    for (DicomMap::Map::const_iterator it = 
-           map.map_.begin(); it != map.map_.end(); ++it)
-    {
-      elements_.push_back(new DicomElement(it->first, *it->second));
-    }
-  }
-
-
-  DicomArray::~DicomArray()
-  {
-    for (size_t i = 0; i < elements_.size(); i++)
-    {
-      delete elements_[i];
-    }
-  }
-
-
-  void DicomArray::Print(FILE* fp) const
-  {
-    for (size_t  i = 0; i < elements_.size(); i++)
-    {
-      DicomTag t = elements_[i]->GetTag();
-      const DicomValue& v = elements_[i]->GetValue();
-      std::string s = v.IsNull() ? "(null)" : v.GetContent();
-      printf("0x%04x 0x%04x [%s]\n", t.GetGroup(), t.GetElement(), s.c_str());
-    }
-  }
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomArray.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "DicomElement.h"
-#include "DicomMap.h"
-
-#include <vector>
-
-namespace Orthanc
-{
-  class DicomArray : public boost::noncopyable
-  {
-  private:
-    typedef std::vector<DicomElement*>  Elements;
-
-    Elements  elements_;
-
-  public:
-    explicit DicomArray(const DicomMap& map);
-
-    ~DicomArray();
-
-    size_t GetSize() const
-    {
-      return elements_.size();
-    }
-
-    const DicomElement& GetElement(size_t i) const
-    {
-      return *elements_[i];
-    }
-
-    void Print(FILE* fp) const;
-  };
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomElement.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "DicomValue.h"
-#include "DicomTag.h"
-
-namespace Orthanc
-{
-  class DicomElement : public boost::noncopyable
-  {
-  private:
-    DicomTag tag_;
-    DicomValue* value_;
-
-  public:
-    DicomElement(uint16_t group,
-                 uint16_t element,
-                 const DicomValue& value) :
-      tag_(group, element),
-      value_(value.Clone())
-    {
-    }
-
-    DicomElement(const DicomTag& tag,
-                 const DicomValue& value) :
-      tag_(tag),
-      value_(value.Clone())
-    {
-    }
-
-    ~DicomElement()
-    {
-      delete value_;
-    }
-
-    const DicomTag& GetTag() const
-    {
-      return tag_;
-    }
-
-    const DicomValue& GetValue() const
-    {
-      return *value_;
-    }
-
-    uint16_t GetTagGroup() const
-    {
-      return tag_.GetGroup();
-    }
-
-    uint16_t GetTagElement() const
-    {
-      return tag_.GetElement();
-    }
-
-    bool operator< (const DicomElement& other) const
-    {
-      return GetTag() < other.GetTag();
-    }
-  };
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomImageInformation.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +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-2018 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.
- *
- * 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"
-
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-
-#include "DicomImageInformation.h"
-
-#include "../OrthancException.h"
-#include "../Toolbox.h"
-#include <boost/lexical_cast.hpp>
-#include <limits>
-#include <cassert>
-#include <stdio.h>
-
-namespace Orthanc
-{
-  DicomImageInformation::DicomImageInformation(const DicomMap& values)
-  {
-    unsigned int pixelRepresentation;
-    unsigned int planarConfiguration = 0;
-
-    try
-    {
-      std::string p = values.GetValue(DICOM_TAG_PHOTOMETRIC_INTERPRETATION).GetContent();
-      Toolbox::ToUpperCase(p);
-
-      if (p == "RGB")
-      {
-        photometric_ = PhotometricInterpretation_RGB;
-      }
-      else if (p == "MONOCHROME1")
-      {
-        photometric_ = PhotometricInterpretation_Monochrome1;
-      }
-      else if (p == "MONOCHROME2")
-      {
-        photometric_ = PhotometricInterpretation_Monochrome2;
-      }
-      else if (p == "PALETTE COLOR")
-      {
-        photometric_ = PhotometricInterpretation_Palette;
-      }
-      else if (p == "HSV")
-      {
-        photometric_ = PhotometricInterpretation_HSV;
-      }
-      else if (p == "ARGB")
-      {
-        photometric_ = PhotometricInterpretation_ARGB;
-      }
-      else if (p == "CMYK")
-      {
-        photometric_ = PhotometricInterpretation_CMYK;
-      }
-      else if (p == "YBR_FULL")
-      {
-        photometric_ = PhotometricInterpretation_YBRFull;
-      }
-      else if (p == "YBR_FULL_422")
-      {
-        photometric_ = PhotometricInterpretation_YBRFull422;
-      }
-      else if (p == "YBR_PARTIAL_420")
-      {
-        photometric_ = PhotometricInterpretation_YBRPartial420;
-      }
-      else if (p == "YBR_PARTIAL_422")
-      {
-        photometric_ = PhotometricInterpretation_YBRPartial422;
-      }
-      else if (p == "YBR_ICT")
-      {
-        photometric_ = PhotometricInterpretation_YBR_ICT;
-      }
-      else if (p == "YBR_RCT")
-      {
-        photometric_ = PhotometricInterpretation_YBR_RCT;
-      }
-      else
-      {
-        photometric_ = PhotometricInterpretation_Unknown;
-      }
-
-      width_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_COLUMNS).GetContent());
-      height_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_ROWS).GetContent());
-      bitsAllocated_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_BITS_ALLOCATED).GetContent());
-
-      try
-      {
-        samplesPerPixel_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_SAMPLES_PER_PIXEL).GetContent());
-      }
-      catch (OrthancException&)
-      {
-        samplesPerPixel_ = 1;  // Assume 1 color channel
-      }
-
-      try
-      {
-        bitsStored_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_BITS_STORED).GetContent());
-      }
-      catch (OrthancException&)
-      {
-        bitsStored_ = bitsAllocated_;
-      }
-
-      try
-      {
-        highBit_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_HIGH_BIT).GetContent());
-      }
-      catch (OrthancException&)
-      {
-        highBit_ = bitsStored_ - 1;
-      }
-
-      try
-      {
-        pixelRepresentation = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_PIXEL_REPRESENTATION).GetContent());
-      }
-      catch (OrthancException&)
-      {
-        pixelRepresentation = 0;  // Assume unsigned pixels
-      }
-
-      if (samplesPerPixel_ > 1)
-      {
-        // The "Planar Configuration" is only set when "Samples per Pixels" is greater than 1
-        // http://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.7.6.3.1.3
-        try
-        {
-          planarConfiguration = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_PLANAR_CONFIGURATION).GetContent());
-        }
-        catch (OrthancException&)
-        {
-          planarConfiguration = 0;  // Assume interleaved color channels
-        }
-      }
-    }
-    catch (boost::bad_lexical_cast&)
-    {
-      throw OrthancException(ErrorCode_NotImplemented);
-    }
-    catch (OrthancException&)
-    {
-      throw OrthancException(ErrorCode_NotImplemented);
-    }
-
-    if (values.HasTag(DICOM_TAG_NUMBER_OF_FRAMES))
-    {
-      try
-      {
-        numberOfFrames_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_NUMBER_OF_FRAMES).GetContent());
-      }
-      catch (boost::bad_lexical_cast&)
-      {
-        throw OrthancException(ErrorCode_NotImplemented);
-      }
-    }
-    else
-    {
-      numberOfFrames_ = 1;
-    }
-
-    if ((bitsAllocated_ != 8 && bitsAllocated_ != 16 && 
-         bitsAllocated_ != 24 && bitsAllocated_ != 32) ||
-        numberOfFrames_ == 0 ||
-        (planarConfiguration != 0 && planarConfiguration != 1))
-    {
-      throw OrthancException(ErrorCode_NotImplemented);
-    }
-
-    if (samplesPerPixel_ == 0)
-    {
-      throw OrthancException(ErrorCode_NotImplemented);
-    }
-
-    bytesPerValue_ = bitsAllocated_ / 8;
-
-    isPlanar_ = (planarConfiguration != 0 ? true : false);
-    isSigned_ = (pixelRepresentation != 0 ? true : false);
-  }
-
-
-  bool DicomImageInformation::ExtractPixelFormat(PixelFormat& format,
-                                                 bool ignorePhotometricInterpretation) const
-  {
-    if (photometric_ == PhotometricInterpretation_Palette)
-    {
-      if (GetBitsStored() == 8 && GetChannelCount() == 1 && !IsSigned())
-      {
-        format = PixelFormat_RGB24;
-        return true;
-      }
-
-      if (GetBitsStored() == 16 && GetChannelCount() == 1 && !IsSigned())
-      {
-        format = PixelFormat_RGB48;
-        return true;
-      }
-    }
-    
-    if (ignorePhotometricInterpretation ||
-        photometric_ == PhotometricInterpretation_Monochrome1 ||
-        photometric_ == PhotometricInterpretation_Monochrome2)
-    {
-      if (GetBitsStored() == 8 && GetChannelCount() == 1 && !IsSigned())
-      {
-        format = PixelFormat_Grayscale8;
-        return true;
-      }
-      
-      if (GetBitsAllocated() == 16 && GetChannelCount() == 1 && !IsSigned())
-      {
-        format = PixelFormat_Grayscale16;
-        return true;
-      }
-
-      if (GetBitsAllocated() == 16 && GetChannelCount() == 1 && IsSigned())
-      {
-        format = PixelFormat_SignedGrayscale16;
-        return true;
-      }
-    }
-
-    if (GetBitsStored() == 8 && 
-        GetChannelCount() == 3 && 
-        !IsSigned() &&
-        (ignorePhotometricInterpretation || photometric_ == PhotometricInterpretation_RGB))
-    {
-      format = PixelFormat_RGB24;
-      return true;
-    }
-
-    return false;
-  }
-
-
-  size_t DicomImageInformation::GetFrameSize() const
-  {
-    return (GetHeight() * 
-            GetWidth() * 
-            GetBytesPerValue() * 
-            GetChannelCount());
-  }
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomImageInformation.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "DicomMap.h"
-
-#include <stdint.h>
-
-namespace Orthanc
-{
-  class DicomImageInformation
-  {
-  private:
-    unsigned int width_;
-    unsigned int height_;
-    unsigned int samplesPerPixel_;
-    unsigned int numberOfFrames_;
-
-    bool isPlanar_;
-    bool isSigned_;
-    size_t bytesPerValue_;
-
-    unsigned int bitsAllocated_;
-    unsigned int bitsStored_;
-    unsigned int highBit_;
-
-    PhotometricInterpretation  photometric_;
-
-  public:
-    explicit DicomImageInformation(const DicomMap& values);
-
-    unsigned int GetWidth() const
-    {
-      return width_;
-    }
-
-    unsigned int GetHeight() const
-    {
-      return height_;
-    }
-
-    unsigned int GetNumberOfFrames() const
-    {
-      return numberOfFrames_;
-    }
-
-    unsigned int GetChannelCount() const
-    {
-      return samplesPerPixel_;
-    }
-
-    unsigned int GetBitsStored() const
-    {
-      return bitsStored_;
-    }
-
-    size_t GetBytesPerValue() const
-    {
-      return bytesPerValue_;
-    }
-
-    bool IsSigned() const
-    {
-      return isSigned_;
-    }
-
-    unsigned int GetBitsAllocated() const
-    {
-      return bitsAllocated_;
-    }
-
-    unsigned int GetHighBit() const
-    {
-      return highBit_;
-    }
-
-    bool IsPlanar() const
-    {
-      return isPlanar_;
-    }
-
-    unsigned int GetShift() const
-    {
-      return highBit_ + 1 - bitsStored_;
-    }
-
-    PhotometricInterpretation GetPhotometricInterpretation() const
-    {
-      return photometric_;
-    }
-
-    bool ExtractPixelFormat(PixelFormat& format,
-                            bool ignorePhotometricInterpretation) const;
-
-    size_t GetFrameSize() const;
-  };
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomInstanceHasher.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +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-2018 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.
- *
- * 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 "DicomInstanceHasher.h"
-
-#include "../OrthancException.h"
-#include "../Toolbox.h"
-
-namespace Orthanc
-{
-  void DicomInstanceHasher::Setup(const std::string& patientId,
-                                  const std::string& studyUid,
-                                  const std::string& seriesUid,
-                                  const std::string& instanceUid)
-  {
-    patientId_ = patientId;
-    studyUid_ = studyUid;
-    seriesUid_ = seriesUid;
-    instanceUid_ = instanceUid;
-
-    if (studyUid_.size() == 0 ||
-        seriesUid_.size() == 0 ||
-        instanceUid_.size() == 0)
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-  }
-
-  DicomInstanceHasher::DicomInstanceHasher(const DicomMap& instance)
-  {
-    const DicomValue* patientId = instance.TestAndGetValue(DICOM_TAG_PATIENT_ID);
-
-    Setup(patientId == NULL ? "" : patientId->GetContent(),
-          instance.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).GetContent(),
-          instance.GetValue(DICOM_TAG_SERIES_INSTANCE_UID).GetContent(),
-          instance.GetValue(DICOM_TAG_SOP_INSTANCE_UID).GetContent());
-  }
-
-  const std::string& DicomInstanceHasher::HashPatient()
-  {
-    if (patientHash_.size() == 0)
-    {
-      Toolbox::ComputeSHA1(patientHash_, patientId_);
-    }
-
-    return patientHash_;
-  }
-
-  const std::string& DicomInstanceHasher::HashStudy()
-  {
-    if (studyHash_.size() == 0)
-    {
-      Toolbox::ComputeSHA1(studyHash_, patientId_ + "|" + studyUid_);
-    }
-
-    return studyHash_;
-  }
-
-  const std::string& DicomInstanceHasher::HashSeries()
-  {
-    if (seriesHash_.size() == 0)
-    {
-      Toolbox::ComputeSHA1(seriesHash_, patientId_ + "|" + studyUid_ + "|" + seriesUid_);
-    }
-
-    return seriesHash_;
-  }
-
-  const std::string& DicomInstanceHasher::HashInstance()
-  {
-    if (instanceHash_.size() == 0)
-    {
-      Toolbox::ComputeSHA1(instanceHash_, patientId_ + "|" + studyUid_ + "|" + seriesUid_ + "|" + instanceUid_);
-    }
-
-    return instanceHash_;
-  }
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomInstanceHasher.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "DicomMap.h"
-
-namespace Orthanc
-{
-  /**
-   * This class implements the hashing mechanism that is used to
-   * convert DICOM unique identifiers to Orthanc identifiers. Any
-   * Orthanc identifier for a DICOM resource corresponds to the SHA-1
-   * hash of the DICOM identifiers. 
-
-   * \note SHA-1 hash is used because it is less sensitive to
-   * collision attacks than MD5. <a
-   * href="http://en.wikipedia.org/wiki/SHA-256#Comparison_of_SHA_functions">[Reference]</a>
-   **/
-  class DicomInstanceHasher
-  {
-  private:
-    std::string patientId_;
-    std::string studyUid_;
-    std::string seriesUid_;
-    std::string instanceUid_;
-
-    std::string patientHash_;
-    std::string studyHash_;
-    std::string seriesHash_;
-    std::string instanceHash_;
-
-    void Setup(const std::string& patientId,
-               const std::string& studyUid,
-               const std::string& seriesUid,
-               const std::string& instanceUid);
-
-  public:
-    DicomInstanceHasher(const DicomMap& instance);
-
-    DicomInstanceHasher(const std::string& patientId,
-                        const std::string& studyUid,
-                        const std::string& seriesUid,
-                        const std::string& instanceUid)
-    {
-      Setup(patientId, studyUid, seriesUid, instanceUid);
-    }
-
-    const std::string& GetPatientId() const
-    {
-      return patientId_;
-    }
-
-    const std::string& GetStudyUid() const
-    {
-      return studyUid_;
-    }
-
-    const std::string& GetSeriesUid() const
-    {
-      return seriesUid_;
-    }
-
-    const std::string& GetInstanceUid() const
-    {
-      return instanceUid_;
-    }
-
-    const std::string& HashPatient();
-
-    const std::string& HashStudy();
-
-    const std::string& HashSeries();
-
-    const std::string& HashInstance();
-  };
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomIntegerPixelAccessor.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,204 +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-2018 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.
- *
- * 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"
-
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-
-#include "DicomIntegerPixelAccessor.h"
-
-#include "../OrthancException.h"
-#include <boost/lexical_cast.hpp>
-#include <limits>
-#include <cassert>
-#include <stdio.h>
-
-namespace Orthanc
-{
-  DicomIntegerPixelAccessor::DicomIntegerPixelAccessor(const DicomMap& values,
-                                                       const void* pixelData,
-                                                       size_t size) :
-    information_(values),
-    pixelData_(pixelData),
-    size_(size)
-  {
-    if (information_.GetBitsAllocated() > 32 ||
-        information_.GetBitsStored() >= 32)
-    {
-      // Not available, as the accessor internally uses int32_t values
-      throw OrthancException(ErrorCode_NotImplemented);
-    }
-
-    frame_ = 0;
-    frameOffset_ = information_.GetFrameSize();
-
-    if (information_.GetNumberOfFrames() * frameOffset_ > size)
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-
-    if (information_.IsSigned())
-    {
-      // Pixels are signed
-      mask_ = (1 << (information_.GetBitsStored() - 1)) - 1;
-      signMask_ = (1 << (information_.GetBitsStored() - 1));
-    }
-    else
-    {
-      // Pixels are unsigned
-      mask_ = (1 << information_.GetBitsStored()) - 1;
-      signMask_ = 0;
-    }
-
-    if (information_.IsPlanar())
-    {
-      /**
-       * Each color plane shall be sent contiguously. For RGB images,
-       * this means the order of the pixel values sent is R1, R2, R3,
-       * ..., G1, G2, G3, ..., B1, B2, B3, etc.
-       **/
-      rowOffset_ = information_.GetWidth() * information_.GetBytesPerValue();
-    }
-    else
-    {
-      /**
-       * The sample values for the first pixel are followed by the
-       * sample values for the second pixel, etc. For RGB images, this
-       * means the order of the pixel values sent shall be R1, G1, B1,
-       * R2, G2, B2, ..., etc.
-       **/
-      rowOffset_ = information_.GetWidth() * information_.GetBytesPerValue() * information_.GetChannelCount();
-    }
-  }
-
-
-  void DicomIntegerPixelAccessor::GetExtremeValues(int32_t& min, 
-                                                   int32_t& max) const
-  {
-    if (information_.GetHeight() == 0 || information_.GetWidth() == 0)
-    {
-      min = max = 0;
-      return;
-    }
-
-    min = std::numeric_limits<int32_t>::max();
-    max = std::numeric_limits<int32_t>::min();
-    
-    for (unsigned int y = 0; y < information_.GetHeight(); y++)
-    {
-      for (unsigned int x = 0; x < information_.GetWidth(); x++)
-      {
-        for (unsigned int c = 0; c < information_.GetChannelCount(); c++)
-        {
-          int32_t v = GetValue(x, y);
-          if (v < min)
-            min = v;
-          if (v > max)
-            max = v;
-        }
-      }
-    }
-  }
-
-
-  int32_t DicomIntegerPixelAccessor::GetValue(unsigned int x, 
-                                              unsigned int y,
-                                              unsigned int channel) const
-  {
-    assert(x < information_.GetWidth() && 
-           y < information_.GetHeight() && 
-           channel < information_.GetChannelCount());
-    
-    const uint8_t* pixel = reinterpret_cast<const uint8_t*>(pixelData_) + 
-      y * rowOffset_ + frame_ * frameOffset_;
-
-    // http://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.7.6.3.1.3
-    if (information_.IsPlanar())
-    {
-      /**
-       * Each color plane shall be sent contiguously. For RGB images,
-       * this means the order of the pixel values sent is R1, R2, R3,
-       * ..., G1, G2, G3, ..., B1, B2, B3, etc.
-       **/
-      assert(frameOffset_ % information_.GetChannelCount() == 0);
-      pixel += channel * frameOffset_ / information_.GetChannelCount() + x * information_.GetBytesPerValue();
-    }
-    else
-    {
-      /**
-       * The sample values for the first pixel are followed by the
-       * sample values for the second pixel, etc. For RGB images, this
-       * means the order of the pixel values sent shall be R1, G1, B1,
-       * R2, G2, B2, ..., etc.
-       **/
-      pixel += channel * information_.GetBytesPerValue() + x * information_.GetChannelCount() * information_.GetBytesPerValue();
-    }
-
-    uint32_t v;
-    v = pixel[0];
-    if (information_.GetBytesPerValue() >= 2)
-      v = v + (static_cast<uint32_t>(pixel[1]) << 8);
-    if (information_.GetBytesPerValue() >= 3)
-      v = v + (static_cast<uint32_t>(pixel[2]) << 16);
-    if (information_.GetBytesPerValue() >= 4)
-      v = v + (static_cast<uint32_t>(pixel[3]) << 24);
-
-    v = v >> information_.GetShift();
-
-    if (v & signMask_)
-    {
-      // Signed value
-      // http://en.wikipedia.org/wiki/Two%27s_complement#Subtraction_from_2N
-      return -static_cast<int32_t>(mask_) + static_cast<int32_t>(v & mask_) - 1;
-    }
-    else
-    {
-      // Unsigned value
-      return static_cast<int32_t>(v & mask_);
-    }
-  }
-
-
-  void DicomIntegerPixelAccessor::SetCurrentFrame(unsigned int frame)
-  {
-    if (frame >= information_.GetNumberOfFrames())
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    frame_ = frame;
-  }
-
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomIntegerPixelAccessor.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "DicomMap.h"
-
-#include "DicomImageInformation.h"
-
-#include <stdint.h>
-
-namespace Orthanc
-{
-  class DicomIntegerPixelAccessor
-  {
-  private:
-    DicomImageInformation information_;
-
-    uint32_t signMask_;
-    uint32_t mask_;
-
-    const void* pixelData_;
-    size_t size_;
-    unsigned int frame_;
-    size_t frameOffset_;
-    size_t rowOffset_;
-
-  public:
-    DicomIntegerPixelAccessor(const DicomMap& values,
-                              const void* pixelData,
-                              size_t size);
-
-    const DicomImageInformation GetInformation() const
-    {
-      return information_;
-    }
-
-    unsigned int GetCurrentFrame() const
-    {
-      return frame_;
-    }
-
-    void SetCurrentFrame(unsigned int frame);
-
-    void GetExtremeValues(int32_t& min, 
-                          int32_t& max) const;
-
-    int32_t GetValue(unsigned int x, unsigned int y, unsigned int channel = 0) const;
-
-    const void* GetPixelData() const
-    {
-      return pixelData_;
-    }
-
-    size_t GetSize() const
-    {
-      return size_;
-    }
-  };
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomMap.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,975 +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-2018 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.
- *
- * 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 "DicomMap.h"
-
-#include <stdio.h>
-#include <memory>
-
-#include "../Endianness.h"
-#include "../Logging.h"
-#include "../OrthancException.h"
-
-
-namespace Orthanc
-{
-  static DicomTag patientTags[] =
-  {
-    //DicomTag(0x0010, 0x1010), // PatientAge
-    //DicomTag(0x0010, 0x1040)  // PatientAddress
-    DicomTag(0x0010, 0x0010),   // PatientName
-    DicomTag(0x0010, 0x0030),   // PatientBirthDate
-    DicomTag(0x0010, 0x0040),   // PatientSex
-    DicomTag(0x0010, 0x1000),   // OtherPatientIDs
-    DICOM_TAG_PATIENT_ID
-  };
-
-  static DicomTag studyTags[] =
-  {
-    //DicomTag(0x0010, 0x1020), // PatientSize
-    //DicomTag(0x0010, 0x1030)  // PatientWeight
-    DICOM_TAG_STUDY_DATE,
-    DicomTag(0x0008, 0x0030),   // StudyTime
-    DicomTag(0x0020, 0x0010),   // StudyID
-    DICOM_TAG_STUDY_DESCRIPTION,
-    DICOM_TAG_ACCESSION_NUMBER,
-    DICOM_TAG_STUDY_INSTANCE_UID,
-    DICOM_TAG_REQUESTED_PROCEDURE_DESCRIPTION,   // New in db v6
-    DICOM_TAG_INSTITUTION_NAME,                  // New in db v6
-    DICOM_TAG_REQUESTING_PHYSICIAN,              // New in db v6
-    DICOM_TAG_REFERRING_PHYSICIAN_NAME           // New in db v6
-  };
-
-  static DicomTag seriesTags[] =
-  {
-    //DicomTag(0x0010, 0x1080), // MilitaryRank
-    DicomTag(0x0008, 0x0021),   // SeriesDate
-    DicomTag(0x0008, 0x0031),   // SeriesTime
-    DICOM_TAG_MODALITY,
-    DicomTag(0x0008, 0x0070),   // Manufacturer
-    DicomTag(0x0008, 0x1010),   // StationName
-    DICOM_TAG_SERIES_DESCRIPTION,
-    DicomTag(0x0018, 0x0015),   // BodyPartExamined
-    DicomTag(0x0018, 0x0024),   // SequenceName
-    DicomTag(0x0018, 0x1030),   // ProtocolName
-    DicomTag(0x0020, 0x0011),   // SeriesNumber
-    DICOM_TAG_CARDIAC_NUMBER_OF_IMAGES,
-    DICOM_TAG_IMAGES_IN_ACQUISITION,
-    DICOM_TAG_NUMBER_OF_TEMPORAL_POSITIONS,
-    DICOM_TAG_NUMBER_OF_SLICES,
-    DICOM_TAG_NUMBER_OF_TIME_SLICES,
-    DICOM_TAG_SERIES_INSTANCE_UID,
-    DICOM_TAG_IMAGE_ORIENTATION_PATIENT,                  // New in db v6
-    DICOM_TAG_SERIES_TYPE,                                // New in db v6
-    DICOM_TAG_OPERATOR_NAME,                              // New in db v6
-    DICOM_TAG_PERFORMED_PROCEDURE_STEP_DESCRIPTION,       // New in db v6
-    DICOM_TAG_ACQUISITION_DEVICE_PROCESSING_DESCRIPTION,  // New in db v6
-    DICOM_TAG_CONTRAST_BOLUS_AGENT                        // New in db v6
-  };
-
-  static DicomTag instanceTags[] =
-  {
-    DicomTag(0x0008, 0x0012),   // InstanceCreationDate
-    DicomTag(0x0008, 0x0013),   // InstanceCreationTime
-    DicomTag(0x0020, 0x0012),   // AcquisitionNumber
-    DICOM_TAG_IMAGE_INDEX,
-    DICOM_TAG_INSTANCE_NUMBER,
-    DICOM_TAG_NUMBER_OF_FRAMES,
-    DICOM_TAG_TEMPORAL_POSITION_IDENTIFIER,
-    DICOM_TAG_SOP_INSTANCE_UID,
-    DICOM_TAG_IMAGE_POSITION_PATIENT,    // New in db v6
-    DICOM_TAG_IMAGE_COMMENTS             // New in db v6
-  };
-
-
-  void DicomMap::LoadMainDicomTags(const DicomTag*& tags,
-                                   size_t& size,
-                                   ResourceType level)
-  {
-    switch (level)
-    {
-      case ResourceType_Patient:
-        tags = patientTags;
-        size = sizeof(patientTags) / sizeof(DicomTag);
-        break;
-
-      case ResourceType_Study:
-        tags = studyTags;
-        size = sizeof(studyTags) / sizeof(DicomTag);
-        break;
-
-      case ResourceType_Series:
-        tags = seriesTags;
-        size = sizeof(seriesTags) / sizeof(DicomTag);
-        break;
-
-      case ResourceType_Instance:
-        tags = instanceTags;
-        size = sizeof(instanceTags) / sizeof(DicomTag);
-        break;
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  void DicomMap::SetValue(uint16_t group, 
-                          uint16_t element, 
-                          DicomValue* value)
-  {
-    DicomTag tag(group, element);
-    Map::iterator it = map_.find(tag);
-
-    if (it != map_.end())
-    {
-      delete it->second;
-      it->second = value;
-    }
-    else
-    {
-      map_.insert(std::make_pair(tag, value));
-    }
-  }
-
-  void DicomMap::SetValue(DicomTag tag, 
-                          DicomValue* value)
-  {
-    SetValue(tag.GetGroup(), tag.GetElement(), value);
-  }
-
-
-
-
-  void DicomMap::Clear()
-  {
-    for (Map::iterator it = map_.begin(); it != map_.end(); ++it)
-    {
-      delete it->second;
-    }
-
-    map_.clear();
-  }
-
-
-  void DicomMap::ExtractTags(DicomMap& result,
-                             const DicomTag* tags,
-                             size_t count) const
-  {
-    result.Clear();
-
-    for (unsigned int i = 0; i < count; i++)
-    {
-      Map::const_iterator it = map_.find(tags[i]);
-      if (it != map_.end())
-      {
-        result.SetValue(it->first, it->second->Clone());
-      }
-    }
-  }
-
-
-  void DicomMap::ExtractPatientInformation(DicomMap& result) const
-  {
-    ExtractTags(result, patientTags, sizeof(patientTags) / sizeof(DicomTag));
-  }
-
-  void DicomMap::ExtractStudyInformation(DicomMap& result) const
-  {
-    ExtractTags(result, studyTags, sizeof(studyTags) / sizeof(DicomTag));
-  }
-
-  void DicomMap::ExtractSeriesInformation(DicomMap& result) const
-  {
-    ExtractTags(result, seriesTags, sizeof(seriesTags) / sizeof(DicomTag));
-  }
-
-  void DicomMap::ExtractInstanceInformation(DicomMap& result) const
-  {
-    ExtractTags(result, instanceTags, sizeof(instanceTags) / sizeof(DicomTag));
-  }
-
-
-
-  DicomMap* DicomMap::Clone() const
-  {
-    std::auto_ptr<DicomMap> result(new DicomMap);
-
-    for (Map::const_iterator it = map_.begin(); it != map_.end(); ++it)
-    {
-      result->map_.insert(std::make_pair(it->first, it->second->Clone()));
-    }
-
-    return result.release();
-  }
-
-
-  void DicomMap::Assign(const DicomMap& other)
-  {
-    Clear();
-
-    for (Map::const_iterator it = other.map_.begin(); it != other.map_.end(); ++it)
-    {
-      map_.insert(std::make_pair(it->first, it->second->Clone()));
-    }
-  }
-
-
-  const DicomValue& DicomMap::GetValue(const DicomTag& tag) const
-  {
-    const DicomValue* value = TestAndGetValue(tag);
-
-    if (value)
-    {
-      return *value;
-    }
-    else
-    {
-      throw OrthancException(ErrorCode_InexistentTag);
-    }
-  }
-
-
-  const DicomValue* DicomMap::TestAndGetValue(const DicomTag& tag) const
-  {
-    Map::const_iterator it = map_.find(tag);
-
-    if (it == map_.end())
-    {
-      return NULL;
-    }
-    else
-    {
-      return it->second;
-    }
-  }
-
-
-  void DicomMap::Remove(const DicomTag& tag) 
-  {
-    Map::iterator it = map_.find(tag);
-    if (it != map_.end())
-    {
-      delete it->second;
-      map_.erase(it);
-    }
-  }
-
-
-  static void SetupFindTemplate(DicomMap& result,
-                                const DicomTag* tags,
-                                size_t count) 
-  {
-    result.Clear();
-
-    for (size_t i = 0; i < count; i++)
-    {
-      result.SetValue(tags[i], "", false);
-    }
-  }
-
-  void DicomMap::SetupFindPatientTemplate(DicomMap& result)
-  {
-    SetupFindTemplate(result, patientTags, sizeof(patientTags) / sizeof(DicomTag));
-  }
-
-  void DicomMap::SetupFindStudyTemplate(DicomMap& result)
-  {
-    SetupFindTemplate(result, studyTags, sizeof(studyTags) / sizeof(DicomTag));
-    result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false);
-    result.SetValue(DICOM_TAG_PATIENT_ID, "", false);
-
-    // These main DICOM tags are only indirectly related to the
-    // General Study Module, remove them
-    result.Remove(DICOM_TAG_INSTITUTION_NAME);
-    result.Remove(DICOM_TAG_REQUESTING_PHYSICIAN);
-    result.Remove(DICOM_TAG_REQUESTED_PROCEDURE_DESCRIPTION);
-  }
-
-  void DicomMap::SetupFindSeriesTemplate(DicomMap& result)
-  {
-    SetupFindTemplate(result, seriesTags, sizeof(seriesTags) / sizeof(DicomTag));
-    result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false);
-    result.SetValue(DICOM_TAG_PATIENT_ID, "", false);
-    result.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "", false);
-
-    // These tags are considered as "main" by Orthanc, but are not in the Series module
-    result.Remove(DicomTag(0x0008, 0x0070));  // Manufacturer
-    result.Remove(DicomTag(0x0008, 0x1010));  // Station name
-    result.Remove(DicomTag(0x0018, 0x0024));  // Sequence name
-    result.Remove(DICOM_TAG_CARDIAC_NUMBER_OF_IMAGES);
-    result.Remove(DICOM_TAG_IMAGES_IN_ACQUISITION);
-    result.Remove(DICOM_TAG_NUMBER_OF_SLICES);
-    result.Remove(DICOM_TAG_NUMBER_OF_TEMPORAL_POSITIONS);
-    result.Remove(DICOM_TAG_NUMBER_OF_TIME_SLICES);
-    result.Remove(DICOM_TAG_IMAGE_ORIENTATION_PATIENT);
-    result.Remove(DICOM_TAG_SERIES_TYPE);
-    result.Remove(DICOM_TAG_ACQUISITION_DEVICE_PROCESSING_DESCRIPTION);
-    result.Remove(DICOM_TAG_CONTRAST_BOLUS_AGENT);
-  }
-
-  void DicomMap::SetupFindInstanceTemplate(DicomMap& result)
-  {
-    SetupFindTemplate(result, instanceTags, sizeof(instanceTags) / sizeof(DicomTag));
-    result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false);
-    result.SetValue(DICOM_TAG_PATIENT_ID, "", false);
-    result.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "", false);
-    result.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, "", false);
-  }
-
-
-  void DicomMap::CopyTagIfExists(const DicomMap& source,
-                                 const DicomTag& tag)
-  {
-    if (source.HasTag(tag))
-    {
-      SetValue(tag, source.GetValue(tag));
-    }
-  }
-
-
-  bool DicomMap::IsMainDicomTag(const DicomTag& tag, ResourceType level)
-  {
-    DicomTag *tags = NULL;
-    size_t size;
-
-    switch (level)
-    {
-      case ResourceType_Patient:
-        tags = patientTags;
-        size = sizeof(patientTags) / sizeof(DicomTag);
-        break;
-
-      case ResourceType_Study:
-        tags = studyTags;
-        size = sizeof(studyTags) / sizeof(DicomTag);
-        break;
-
-      case ResourceType_Series:
-        tags = seriesTags;
-        size = sizeof(seriesTags) / sizeof(DicomTag);
-        break;
-
-      case ResourceType_Instance:
-        tags = instanceTags;
-        size = sizeof(instanceTags) / sizeof(DicomTag);
-        break;
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    for (size_t i = 0; i < size; i++)
-    {
-      if (tags[i] == tag)
-      {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  bool DicomMap::IsMainDicomTag(const DicomTag& tag)
-  {
-    return (IsMainDicomTag(tag, ResourceType_Patient) ||
-            IsMainDicomTag(tag, ResourceType_Study) ||
-            IsMainDicomTag(tag, ResourceType_Series) ||
-            IsMainDicomTag(tag, ResourceType_Instance));
-  }
-
-
-  void DicomMap::GetMainDicomTagsInternal(std::set<DicomTag>& result, ResourceType level)
-  {
-    DicomTag *tags = NULL;
-    size_t size;
-
-    switch (level)
-    {
-      case ResourceType_Patient:
-        tags = patientTags;
-        size = sizeof(patientTags) / sizeof(DicomTag);
-        break;
-
-      case ResourceType_Study:
-        tags = studyTags;
-        size = sizeof(studyTags) / sizeof(DicomTag);
-        break;
-
-      case ResourceType_Series:
-        tags = seriesTags;
-        size = sizeof(seriesTags) / sizeof(DicomTag);
-        break;
-
-      case ResourceType_Instance:
-        tags = instanceTags;
-        size = sizeof(instanceTags) / sizeof(DicomTag);
-        break;
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    for (size_t i = 0; i < size; i++)
-    {
-      result.insert(tags[i]);
-    }
-  }
-
-
-  void DicomMap::GetMainDicomTags(std::set<DicomTag>& result, ResourceType level)
-  {
-    result.clear();
-    GetMainDicomTagsInternal(result, level);
-  }
-
-
-  void DicomMap::GetMainDicomTags(std::set<DicomTag>& result)
-  {
-    result.clear();
-    GetMainDicomTagsInternal(result, ResourceType_Patient);
-    GetMainDicomTagsInternal(result, ResourceType_Study);
-    GetMainDicomTagsInternal(result, ResourceType_Series);
-    GetMainDicomTagsInternal(result, ResourceType_Instance);
-  }
-
-
-  void DicomMap::GetTags(std::set<DicomTag>& tags) const
-  {
-    tags.clear();
-
-    for (Map::const_iterator it = map_.begin();
-         it != map_.end(); ++it)
-    {
-      tags.insert(it->first);
-    }
-  }
-
-
-  static uint16_t ReadUnsignedInteger16(const char* dicom)
-  {
-    return le16toh(*reinterpret_cast<const uint16_t*>(dicom));
-  }
-
-
-  static uint32_t ReadUnsignedInteger32(const char* dicom)
-  {
-    return le32toh(*reinterpret_cast<const uint32_t*>(dicom));
-  }
-
-
-  static bool ValidateTag(const ValueRepresentation& vr,
-                          const std::string& value)
-  {
-    switch (vr)
-    {
-      case ValueRepresentation_ApplicationEntity:
-        return value.size() <= 16;
-
-      case ValueRepresentation_AgeString:
-        return (value.size() == 4 &&
-                isdigit(value[0]) &&
-                isdigit(value[1]) &&
-                isdigit(value[2]) &&
-                (value[3] == 'D' || value[3] == 'W' || value[3] == 'M' || value[3] == 'Y'));
-
-      case ValueRepresentation_AttributeTag:
-        return value.size() == 4;
-
-      case ValueRepresentation_CodeString:
-        return value.size() <= 16;
-
-      case ValueRepresentation_Date:
-        return value.size() <= 18;
-
-      case ValueRepresentation_DecimalString:
-        return value.size() <= 16;
-
-      case ValueRepresentation_DateTime:
-        return value.size() <= 54;
-
-      case ValueRepresentation_FloatingPointSingle:
-        return value.size() == 4;
-
-      case ValueRepresentation_FloatingPointDouble:
-        return value.size() == 8;
-
-      case ValueRepresentation_IntegerString:
-        return value.size() <= 12;
-
-      case ValueRepresentation_LongString:
-        return value.size() <= 64;
-
-      case ValueRepresentation_LongText:
-        return value.size() <= 10240;
-
-      case ValueRepresentation_OtherByte:
-        return true;
-      
-      case ValueRepresentation_OtherDouble:
-        return value.size() <= (static_cast<uint64_t>(1) << 32) - 8;
-
-      case ValueRepresentation_OtherFloat:
-        return value.size() <= (static_cast<uint64_t>(1) << 32) - 4;
-
-      case ValueRepresentation_OtherLong:
-        return true;
-
-      case ValueRepresentation_OtherWord:
-        return true;
-
-      case ValueRepresentation_PersonName:
-        return true;
-
-      case ValueRepresentation_ShortString:
-        return value.size() <= 16;
-
-      case ValueRepresentation_SignedLong:
-        return value.size() == 4;
-
-      case ValueRepresentation_Sequence:
-        return true;
-
-      case ValueRepresentation_SignedShort:
-        return value.size() == 2;
-
-      case ValueRepresentation_ShortText:
-        return value.size() <= 1024;
-
-      case ValueRepresentation_Time:
-        return value.size() <= 28;
-
-      case ValueRepresentation_UnlimitedCharacters:
-        return value.size() <= (static_cast<uint64_t>(1) << 32) - 2;
-
-      case ValueRepresentation_UniqueIdentifier:
-        return value.size() <= 64;
-
-      case ValueRepresentation_UnsignedLong:
-        return value.size() == 4;
-
-      case ValueRepresentation_Unknown:
-        return true;
-
-      case ValueRepresentation_UniversalResource:
-        return value.size() <= (static_cast<uint64_t>(1) << 32) - 2;
-
-      case ValueRepresentation_UnsignedShort:
-        return value.size() == 2;
-
-      case ValueRepresentation_UnlimitedText:
-        return value.size() <= (static_cast<uint64_t>(1) << 32) - 2;
-
-      default:
-        // Assume unsupported tags are OK
-        return true;
-    }
-  }
-
-
-  static void RemoveTagPadding(std::string& value,
-                               const ValueRepresentation& vr)
-  {
-    /**
-     * Remove padding from character strings, if need be. For the time
-     * being, only the UI VR is supported.
-     * http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_6.2.html
-     **/
-
-    switch (vr)
-    {
-      case ValueRepresentation_UniqueIdentifier:
-      {
-        /**
-         * "Values with a VR of UI shall be padded with a single
-         * trailing NULL (00H) character when necessary to achieve even
-         * length."
-         **/
-
-        if (!value.empty() &&
-            value[value.size() - 1] == '\0')
-        {
-          value.resize(value.size() - 1);
-        }
-
-        break;
-      }
-
-      /**
-       * TODO implement other VR
-       **/
-
-      default:
-        // No padding is applicable to this VR
-        break;
-    }
-  }
-
-
-  static bool ReadNextTag(DicomTag& tag,
-                          ValueRepresentation& vr,
-                          std::string& value,
-                          const char* dicom,
-                          size_t size,
-                          size_t& position)
-  {
-    /**
-     * http://dicom.nema.org/medical/dicom/current/output/chtml/part05/chapter_7.html#sect_7.1.2
-     * This function reads a data element with Explicit VR encoded using Little-Endian.
-     **/
-
-    if (position + 6 > size)
-    {
-      return false;
-    }
-
-    tag = DicomTag(ReadUnsignedInteger16(dicom + position),
-                   ReadUnsignedInteger16(dicom + position + 2));
-
-    vr = StringToValueRepresentation(std::string(dicom + position + 4, 2), true);
-    if (vr == ValueRepresentation_NotSupported)
-    {
-      return false;
-    }
-
-    if (vr == ValueRepresentation_OtherByte ||
-        vr == ValueRepresentation_OtherDouble ||
-        vr == ValueRepresentation_OtherFloat ||
-        vr == ValueRepresentation_OtherLong ||
-        vr == ValueRepresentation_OtherWord ||
-        vr == ValueRepresentation_Sequence ||
-        vr == ValueRepresentation_UnlimitedCharacters ||
-        vr == ValueRepresentation_UniversalResource ||
-        vr == ValueRepresentation_UnlimitedText ||
-        vr == ValueRepresentation_Unknown)    // Note that "UN" should never appear in the Meta Information
-    {
-      if (position + 12 > size)
-      {
-        return false;
-      }
-
-      uint32_t length = ReadUnsignedInteger32(dicom + position + 8);
-
-      if (position + 12 + length > size)
-      {
-        return false;
-      }
-
-      value.assign(dicom + position + 12, length);
-      position += (12 + length);
-    }
-    else
-    {
-      if (position + 8 > size)
-      {
-        return false;
-      }
-
-      uint16_t length = ReadUnsignedInteger16(dicom + position + 6);
-
-      if (position + 8 + length > size)
-      {
-        return false;
-      }
-
-      value.assign(dicom + position + 8, length);
-      position += (8 + length);
-    }
-
-    if (!ValidateTag(vr, value))
-    {
-      return false;
-    }
-
-    RemoveTagPadding(value, vr);
-
-    return true;
-  }
-
-
-  bool DicomMap::ParseDicomMetaInformation(DicomMap& result,
-                                           const char* dicom,
-                                           size_t size)
-  {
-    /**
-     * http://dicom.nema.org/medical/dicom/current/output/chtml/part10/chapter_7.html
-     * According to Table 7.1-1, besides the "DICM" DICOM prefix, the
-     * file preamble (i.e. dicom[0..127]) should not be taken into
-     * account to determine whether the file is or is not a DICOM file.
-     **/
-
-    if (size < 132 ||
-        dicom[128] != 'D' ||
-        dicom[129] != 'I' ||
-        dicom[130] != 'C' ||
-        dicom[131] != 'M')
-    {
-      return false;
-    }
-
-
-    /**
-     * The DICOM File Meta Information must be encoded using the
-     * Explicit VR Little Endian Transfer Syntax
-     * (UID=1.2.840.10008.1.2.1).
-     **/
-
-    result.Clear();
-
-    // First, we read the "File Meta Information Group Length" tag
-    // (0002,0000) to know where to stop reading the meta header
-    size_t position = 132;
-
-    DicomTag tag(0x0000, 0x0000);  // Dummy initialization
-    ValueRepresentation vr;
-    std::string value;
-    if (!ReadNextTag(tag, vr, value, dicom, size, position) ||
-        tag.GetGroup() != 0x0002 ||
-        tag.GetElement() != 0x0000 ||
-        vr != ValueRepresentation_UnsignedLong ||
-        value.size() != 4)
-    {
-      return false;
-    }
-
-    size_t stopPosition = position + ReadUnsignedInteger32(value.c_str());
-    if (stopPosition > size)
-    {
-      return false;
-    }
-
-    while (position < stopPosition)
-    {
-      if (ReadNextTag(tag, vr, value, dicom, size, position))
-      {
-        result.SetValue(tag, value, IsBinaryValueRepresentation(vr));
-      }
-      else
-      {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-
-  static std::string ValueAsString(const DicomMap& summary,
-                                   const DicomTag& tag)
-  {
-    const DicomValue& value = summary.GetValue(tag);
-    if (value.IsNull())
-    {
-      return "(null)";
-    }
-    else
-    {
-      return value.GetContent();
-    }
-  }
-
-
-  void DicomMap::LogMissingTagsForStore() const
-  {
-    std::string s, t;
-
-    if (HasTag(DICOM_TAG_PATIENT_ID))
-    {
-      if (t.size() > 0)
-        t += ", ";
-      t += "PatientID=" + ValueAsString(*this, DICOM_TAG_PATIENT_ID);
-    }
-    else
-    {
-      if (s.size() > 0)
-        s += ", ";
-      s += "PatientID";
-    }
-
-    if (HasTag(DICOM_TAG_STUDY_INSTANCE_UID))
-    {
-      if (t.size() > 0)
-        t += ", ";
-      t += "StudyInstanceUID=" + ValueAsString(*this, DICOM_TAG_STUDY_INSTANCE_UID);
-    }
-    else
-    {
-      if (s.size() > 0)
-        s += ", ";
-      s += "StudyInstanceUID";
-    }
-
-    if (HasTag(DICOM_TAG_SERIES_INSTANCE_UID))
-    {
-      if (t.size() > 0)
-        t += ", ";
-      t += "SeriesInstanceUID=" + ValueAsString(*this, DICOM_TAG_SERIES_INSTANCE_UID);
-    }
-    else
-    {
-      if (s.size() > 0)
-        s += ", ";
-      s += "SeriesInstanceUID";
-    }
-
-    if (HasTag(DICOM_TAG_SOP_INSTANCE_UID))
-    {
-      if (t.size() > 0)
-        t += ", ";
-      t += "SOPInstanceUID=" + ValueAsString(*this, DICOM_TAG_SOP_INSTANCE_UID);
-    }
-    else
-    {
-      if (s.size() > 0)
-        s += ", ";
-      s += "SOPInstanceUID";
-    }
-
-    if (t.size() == 0)
-    {
-      LOG(ERROR) << "Store has failed because all the required tags (" << s << ") are missing (is it a DICOMDIR file?)";
-    }
-    else
-    {
-      LOG(ERROR) << "Store has failed because required tags (" << s << ") are missing for the following instance: " << t;
-    }
-  }
-
-
-  bool DicomMap::CopyToString(std::string& result,
-                              const DicomTag& tag,
-                              bool allowBinary) const
-  {
-    const DicomValue* value = TestAndGetValue(tag);
-
-    if (value == NULL)
-    {
-      return false;
-    }
-    else
-    {
-      return value->CopyToString(result, allowBinary);
-    }
-  }
-    
-  bool DicomMap::ParseInteger32(int32_t& result,
-                                const DicomTag& tag) const
-  {
-    const DicomValue* value = TestAndGetValue(tag);
-
-    if (value == NULL)
-    {
-      return false;
-    }
-    else
-    {
-      return value->ParseInteger32(result);
-    }
-  }
-
-  bool DicomMap::ParseInteger64(int64_t& result,
-                                const DicomTag& tag) const
-  {
-    const DicomValue* value = TestAndGetValue(tag);
-
-    if (value == NULL)
-    {
-      return false;
-    }
-    else
-    {
-      return value->ParseInteger64(result);
-    }
-  }
-
-  bool DicomMap::ParseUnsignedInteger32(uint32_t& result,
-                                        const DicomTag& tag) const
-  {
-    const DicomValue* value = TestAndGetValue(tag);
-
-    if (value == NULL)
-    {
-      return false;
-    }
-    else
-    {
-      return value->ParseUnsignedInteger32(result);
-    }
-  }
-
-  bool DicomMap::ParseUnsignedInteger64(uint64_t& result,
-                                        const DicomTag& tag) const
-  {
-    const DicomValue* value = TestAndGetValue(tag);
-
-    if (value == NULL)
-    {
-      return false;
-    }
-    else
-    {
-      return value->ParseUnsignedInteger64(result);
-    }
-  }
-
-  bool DicomMap::ParseFloat(float& result,
-                            const DicomTag& tag) const
-  {
-    const DicomValue* value = TestAndGetValue(tag);
-
-    if (value == NULL)
-    {
-      return false;
-    }
-    else
-    {
-      return value->ParseFloat(result);
-    }
-  }
-
-  bool DicomMap::ParseDouble(double& result,
-                             const DicomTag& tag) const
-  {
-    const DicomValue* value = TestAndGetValue(tag);
-
-    if (value == NULL)
-    {
-      return false;
-    }
-    else
-    {
-      return value->ParseDouble(result);
-    }
-  }
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomMap.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "DicomTag.h"
-#include "DicomValue.h"
-#include "../Enumerations.h"
-
-#include <set>
-#include <map>
-#include <json/json.h>
-
-namespace Orthanc
-{
-  class DicomMap : public boost::noncopyable
-  {
-  private:
-    friend class DicomArray;
-    friend class FromDcmtkBridge;
-    friend class ParsedDicomFile;
-
-    typedef std::map<DicomTag, DicomValue*>  Map;
-
-    Map map_;
-
-    // Warning: This takes the ownership of "value"
-    void SetValue(uint16_t group, 
-                  uint16_t element, 
-                  DicomValue* value);
-
-    void SetValue(DicomTag tag, 
-                  DicomValue* value);
-
-    void ExtractTags(DicomMap& source,
-                     const DicomTag* tags,
-                     size_t count) const;
-   
-    static void GetMainDicomTagsInternal(std::set<DicomTag>& result, ResourceType level);
-
-  public:
-    DicomMap()
-    {
-    }
-
-    ~DicomMap()
-    {
-      Clear();
-    }
-
-    size_t GetSize() const
-    {
-      return map_.size();
-    }
-    
-    DicomMap* Clone() const;
-
-    void Assign(const DicomMap& other);
-
-    void Clear();
-
-    void SetValue(uint16_t group, 
-                  uint16_t element, 
-                  const DicomValue& value)
-    {
-      SetValue(group, element, value.Clone());
-    }
-
-    void SetValue(const DicomTag& tag,
-                  const DicomValue& value)
-    {
-      SetValue(tag, value.Clone());
-    }
-
-    void SetValue(const DicomTag& tag,
-                  const std::string& str,
-                  bool isBinary)
-    {
-      SetValue(tag, new DicomValue(str, isBinary));
-    }
-
-    void SetValue(uint16_t group, 
-                  uint16_t element, 
-                  const std::string& str,
-                  bool isBinary)
-    {
-      SetValue(group, element, new DicomValue(str, isBinary));
-    }
-
-    bool HasTag(uint16_t group, uint16_t element) const
-    {
-      return HasTag(DicomTag(group, element));
-    }
-
-    bool HasTag(const DicomTag& tag) const
-    {
-      return map_.find(tag) != map_.end();
-    }
-
-    const DicomValue& GetValue(uint16_t group, uint16_t element) const
-    {
-      return GetValue(DicomTag(group, element));
-    }
-
-    const DicomValue& GetValue(const DicomTag& tag) const;
-
-    // DO NOT delete the returned value!
-    const DicomValue* TestAndGetValue(uint16_t group, uint16_t element) const
-    {
-      return TestAndGetValue(DicomTag(group, element));
-    }       
-
-    // DO NOT delete the returned value!
-    const DicomValue* TestAndGetValue(const DicomTag& tag) const;
-
-    void Remove(const DicomTag& tag);
-
-    void ExtractPatientInformation(DicomMap& result) const;
-
-    void ExtractStudyInformation(DicomMap& result) const;
-
-    void ExtractSeriesInformation(DicomMap& result) const;
-
-    void ExtractInstanceInformation(DicomMap& result) const;
-
-    static void SetupFindPatientTemplate(DicomMap& result);
-
-    static void SetupFindStudyTemplate(DicomMap& result);
-
-    static void SetupFindSeriesTemplate(DicomMap& result);
-
-    static void SetupFindInstanceTemplate(DicomMap& result);
-
-    void CopyTagIfExists(const DicomMap& source,
-                         const DicomTag& tag);
-
-    static bool IsMainDicomTag(const DicomTag& tag, ResourceType level);
-
-    static bool IsMainDicomTag(const DicomTag& tag);
-
-    static void GetMainDicomTags(std::set<DicomTag>& result, ResourceType level);
-
-    static void GetMainDicomTags(std::set<DicomTag>& result);
-
-    void GetTags(std::set<DicomTag>& tags) const;
-
-    static void LoadMainDicomTags(const DicomTag*& tags,
-                                  size_t& size,
-                                  ResourceType level);
-
-    static bool ParseDicomMetaInformation(DicomMap& result,
-                                          const char* dicom,
-                                          size_t size);
-
-    void LogMissingTagsForStore() const;
-
-    bool CopyToString(std::string& result,
-                      const DicomTag& tag,
-                      bool allowBinary) const;
-    
-    bool ParseInteger32(int32_t& result,
-                        const DicomTag& tag) const;
-
-    bool ParseInteger64(int64_t& result,
-                        const DicomTag& tag) const;                                
-
-    bool ParseUnsignedInteger32(uint32_t& result,
-                                const DicomTag& tag) const;
-
-    bool ParseUnsignedInteger64(uint64_t& result,
-                                const DicomTag& tag) const;                                
-
-    bool ParseFloat(float& result,
-                    const DicomTag& tag) const;                                
-
-    bool ParseDouble(double& result,
-                     const DicomTag& tag) const;                                
-  };
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomTag.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,253 +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-2018 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.
- *
- * 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 "DicomTag.h"
-
-#include "../OrthancException.h"
-
-#include <iostream>
-#include <iomanip>
-#include <stdio.h>
-
-namespace Orthanc
-{
-  bool DicomTag::operator< (const DicomTag& other) const
-  {
-    if (group_ < other.group_)
-      return true;
-
-    if (group_ > other.group_)
-      return false;
-
-    return element_ < other.element_;
-  }
-
-
-  std::ostream& operator<< (std::ostream& o, const DicomTag& tag)
-  {
-    using namespace std;
-    ios_base::fmtflags state = o.flags();
-    o.flags(ios::right | ios::hex);
-    o << "(" << setfill('0') << setw(4) << tag.GetGroup()
-      << "," << setw(4) << tag.GetElement() << ")";
-    o.flags(state);
-    return o;
-  }
-
-
-  std::string DicomTag::Format() const
-  {
-    char b[16];
-    sprintf(b, "%04x,%04x", group_, element_);
-    return std::string(b);
-  }
-
-
-  const char* DicomTag::GetMainTagsName() const
-  {
-    if (*this == DICOM_TAG_ACCESSION_NUMBER)
-      return "AccessionNumber";
-
-    if (*this == DICOM_TAG_SOP_INSTANCE_UID)
-      return "SOPInstanceUID";
-
-    if (*this == DICOM_TAG_PATIENT_ID)
-      return "PatientID";
-
-    if (*this == DICOM_TAG_SERIES_INSTANCE_UID)
-      return "SeriesInstanceUID";
-
-    if (*this == DICOM_TAG_STUDY_INSTANCE_UID)
-      return "StudyInstanceUID"; 
-
-    if (*this == DICOM_TAG_PIXEL_DATA)
-      return "PixelData";
-
-    if (*this == DICOM_TAG_IMAGE_INDEX)
-      return "ImageIndex";
-
-    if (*this == DICOM_TAG_INSTANCE_NUMBER)
-      return "InstanceNumber";
-
-    if (*this == DICOM_TAG_NUMBER_OF_SLICES)
-      return "NumberOfSlices";
-
-    if (*this == DICOM_TAG_NUMBER_OF_FRAMES)
-      return "NumberOfFrames";
-
-    if (*this == DICOM_TAG_CARDIAC_NUMBER_OF_IMAGES)
-      return "CardiacNumberOfImages";
-
-    if (*this == DICOM_TAG_IMAGES_IN_ACQUISITION)
-      return "ImagesInAcquisition";
-
-    if (*this == DICOM_TAG_PATIENT_NAME)
-      return "PatientName";
-
-    if (*this == DICOM_TAG_IMAGE_POSITION_PATIENT)
-      return "ImagePositionPatient";
-
-    if (*this == DICOM_TAG_IMAGE_ORIENTATION_PATIENT)
-      return "ImageOrientationPatient";
-
-    return "";
-  }
-
-
-  void DicomTag::AddTagsForModule(std::set<DicomTag>& target,
-                                  DicomModule module)
-  {
-    // REFERENCE: 11_03pu.pdf, DICOM PS 3.3 2011 - Information Object Definitions
-
-    switch (module)
-    {
-      case DicomModule_Patient:
-        // This is Table C.7-1 "Patient Module Attributes" (p. 373)
-        target.insert(DicomTag(0x0010, 0x0010));   // Patient's name
-        target.insert(DicomTag(0x0010, 0x0020));   // Patient ID
-        target.insert(DicomTag(0x0010, 0x0030));   // Patient's birth date
-        target.insert(DicomTag(0x0010, 0x0040));   // Patient's sex
-        target.insert(DicomTag(0x0008, 0x1120));   // Referenced patient sequence
-        target.insert(DicomTag(0x0010, 0x0032));   // Patient's birth time
-        target.insert(DicomTag(0x0010, 0x1000));   // Other patient IDs
-        target.insert(DicomTag(0x0010, 0x1002));   // Other patient IDs sequence
-        target.insert(DicomTag(0x0010, 0x1001));   // Other patient names
-        target.insert(DicomTag(0x0010, 0x2160));   // Ethnic group
-        target.insert(DicomTag(0x0010, 0x4000));   // Patient comments
-        target.insert(DicomTag(0x0010, 0x2201));   // Patient species description
-        target.insert(DicomTag(0x0010, 0x2202));   // Patient species code sequence
-        target.insert(DicomTag(0x0010, 0x2292));   // Patient breed description
-        target.insert(DicomTag(0x0010, 0x2293));   // Patient breed code sequence
-        target.insert(DicomTag(0x0010, 0x2294));   // Breed registration sequence
-        target.insert(DicomTag(0x0010, 0x2297));   // Responsible person
-        target.insert(DicomTag(0x0010, 0x2298));   // Responsible person role
-        target.insert(DicomTag(0x0010, 0x2299));   // Responsible organization
-        target.insert(DicomTag(0x0012, 0x0062));   // Patient identity removed
-        target.insert(DicomTag(0x0012, 0x0063));   // De-identification method
-        target.insert(DicomTag(0x0012, 0x0064));   // De-identification method code sequence
-
-        // Table 10-18 ISSUER OF PATIENT ID MACRO (p. 112)
-        target.insert(DicomTag(0x0010, 0x0021));   // Issuer of Patient ID
-        target.insert(DicomTag(0x0010, 0x0024));   // Issuer of Patient ID qualifiers sequence
-        break;
-
-      case DicomModule_Study:
-        // This is Table C.7-3 "General Study Module Attributes" (p. 378)
-        target.insert(DicomTag(0x0020, 0x000d));   // Study instance UID
-        target.insert(DicomTag(0x0008, 0x0020));   // Study date
-        target.insert(DicomTag(0x0008, 0x0030));   // Study time
-        target.insert(DicomTag(0x0008, 0x0090));   // Referring physician's name
-        target.insert(DicomTag(0x0008, 0x0096));   // Referring physician identification sequence
-        target.insert(DicomTag(0x0020, 0x0010));   // Study ID
-        target.insert(DicomTag(0x0008, 0x0050));   // Accession number
-        target.insert(DicomTag(0x0008, 0x0051));   // Issuer of accession number sequence
-        target.insert(DicomTag(0x0008, 0x1030));   // Study description
-        target.insert(DicomTag(0x0008, 0x1048));   // Physician(s) of record
-        target.insert(DicomTag(0x0008, 0x1049));   // Physician(s) of record identification sequence
-        target.insert(DicomTag(0x0008, 0x1060));   // Name of physician(s) reading study
-        target.insert(DicomTag(0x0008, 0x1062));   // Physician(s) reading study identification sequence
-        target.insert(DicomTag(0x0032, 0x1034));   // Requesting service code sequence
-        target.insert(DicomTag(0x0008, 0x1110));   // Referenced study sequence
-        target.insert(DicomTag(0x0008, 0x1032));   // Procedure code sequence
-        target.insert(DicomTag(0x0040, 0x1012));   // Reason for performed procedure code sequence
-        break;
-
-      case DicomModule_Series:
-        // This is Table C.7-5 "General Series Module Attributes" (p. 385)
-        target.insert(DicomTag(0x0008, 0x0060));   // Modality 
-        target.insert(DicomTag(0x0020, 0x000e));   // Series Instance UID 
-        target.insert(DicomTag(0x0020, 0x0011));   // Series Number 
-        target.insert(DicomTag(0x0020, 0x0060));   // Laterality 
-        target.insert(DicomTag(0x0008, 0x0021));   // Series Date 
-        target.insert(DicomTag(0x0008, 0x0031));   // Series Time 
-        target.insert(DicomTag(0x0008, 0x1050));   // Performing Physicians’ Name 
-        target.insert(DicomTag(0x0008, 0x1052));   // Performing Physician Identification Sequence 
-        target.insert(DicomTag(0x0018, 0x1030));   // Protocol Name
-        target.insert(DicomTag(0x0008, 0x103e));   // Series Description 
-        target.insert(DicomTag(0x0008, 0x103f));   // Series Description Code Sequence 
-        target.insert(DicomTag(0x0008, 0x1070));   // Operators' Name 
-        target.insert(DicomTag(0x0008, 0x1072));   // Operator Identification Sequence 
-        target.insert(DicomTag(0x0008, 0x1111));   // Referenced Performed Procedure Step Sequence
-        target.insert(DicomTag(0x0008, 0x1250));   // Related Series Sequence
-        target.insert(DicomTag(0x0018, 0x0015));   // Body Part Examined
-        target.insert(DicomTag(0x0018, 0x5100));   // Patient Position
-        target.insert(DicomTag(0x0028, 0x0108));   // Smallest Pixel Value in Series 
-        target.insert(DicomTag(0x0029, 0x0109));   // Largest Pixel Value in Series 
-        target.insert(DicomTag(0x0040, 0x0275));   // Request Attributes Sequence 
-        target.insert(DicomTag(0x0010, 0x2210));   // Anatomical Orientation Type
-
-        // Table 10-16 PERFORMED PROCEDURE STEP SUMMARY MACRO ATTRIBUTES
-        target.insert(DicomTag(0x0040, 0x0253));   // Performed Procedure Step ID 
-        target.insert(DicomTag(0x0040, 0x0244));   // Performed Procedure Step Start Date 
-        target.insert(DicomTag(0x0040, 0x0245));   // Performed Procedure Step Start Time 
-        target.insert(DicomTag(0x0040, 0x0254));   // Performed Procedure Step Description 
-        target.insert(DicomTag(0x0040, 0x0260));   // Performed Protocol Code Sequence 
-        target.insert(DicomTag(0x0040, 0x0280));   // Comments on the Performed Procedure Step
-        break;
-
-      case DicomModule_Instance:
-        // This is Table C.12-1 "SOP Common Module Attributes" (p. 1207)
-        target.insert(DicomTag(0x0008, 0x0016));   // SOP Class UID
-        target.insert(DicomTag(0x0008, 0x0018));   // SOP Instance UID 
-        target.insert(DicomTag(0x0008, 0x0005));   // Specific Character Set 
-        target.insert(DicomTag(0x0008, 0x0012));   // Instance Creation Date 
-        target.insert(DicomTag(0x0008, 0x0013));   // Instance Creation Time 
-        target.insert(DicomTag(0x0008, 0x0014));   // Instance Creator UID 
-        target.insert(DicomTag(0x0008, 0x001a));   // Related General SOP Class UID 
-        target.insert(DicomTag(0x0008, 0x001b));   // Original Specialized SOP Class UID 
-        target.insert(DicomTag(0x0008, 0x0110));   // Coding Scheme Identification Sequence 
-        target.insert(DicomTag(0x0008, 0x0201));   // Timezone Offset From UTC 
-        target.insert(DicomTag(0x0018, 0xa001));   // Contributing Equipment Sequence
-        target.insert(DicomTag(0x0020, 0x0013));   // Instance Number 
-        target.insert(DicomTag(0x0100, 0x0410));   // SOP Instance Status 
-        target.insert(DicomTag(0x0100, 0x0420));   // SOP Authorization DateTime 
-        target.insert(DicomTag(0x0100, 0x0424));   // SOP Authorization Comment 
-        target.insert(DicomTag(0x0100, 0x0426));   // Authorization Equipment Certification Number
-        target.insert(DicomTag(0x0400, 0x0500));   // Encrypted Attributes Sequence
-        target.insert(DicomTag(0x0400, 0x0561));   // Original Attributes Sequence 
-        target.insert(DicomTag(0x0040, 0xa390));   // HL7 Structured Document Reference Sequence
-        target.insert(DicomTag(0x0028, 0x0303));   // Longitudinal Temporal Information Modified 
-
-        // Table C.12-6 "DIGITAL SIGNATURES MACRO ATTRIBUTES" (p. 1216)
-        target.insert(DicomTag(0x4ffe, 0x0001));   // MAC Parameters sequence
-        target.insert(DicomTag(0xfffa, 0xfffa));   // Digital signatures sequence
-        break;
-
-        // TODO IMAGE MODULE?
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomTag.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <string>
-#include <set>
-#include <stdint.h>
-
-#include "../Enumerations.h"
-
-namespace Orthanc
-{
-  class DicomTag
-  {
-    // This must stay a POD (plain old data structure) 
-
-  private:
-    uint16_t group_;
-    uint16_t element_;
-
-  public:
-    DicomTag(uint16_t group,
-             uint16_t element) :
-      group_(group),
-      element_(element)
-    {
-    }
-
-    uint16_t GetGroup() const
-    {
-      return group_;
-    }
-
-    uint16_t GetElement() const
-    {
-      return element_;
-    }
-
-    bool IsPrivate() const
-    {
-      return group_ % 2 == 1;
-    }
-
-    const char* GetMainTagsName() const;
-
-    bool operator< (const DicomTag& other) const;
-
-    bool operator== (const DicomTag& other) const
-    {
-      return group_ == other.group_ && element_ == other.element_;
-    }
-
-    bool operator!= (const DicomTag& other) const
-    {
-      return !(*this == other);
-    }
-
-    std::string Format() const;
-
-    friend std::ostream& operator<< (std::ostream& o, const DicomTag& tag);
-
-    static void AddTagsForModule(std::set<DicomTag>& target,
-                                 DicomModule module);
-  };
-
-  // Aliases for the most useful tags
-  static const DicomTag DICOM_TAG_ACCESSION_NUMBER(0x0008, 0x0050);
-  static const DicomTag DICOM_TAG_SOP_INSTANCE_UID(0x0008, 0x0018);
-  static const DicomTag DICOM_TAG_PATIENT_ID(0x0010, 0x0020);
-  static const DicomTag DICOM_TAG_SERIES_INSTANCE_UID(0x0020, 0x000e);
-  static const DicomTag DICOM_TAG_STUDY_INSTANCE_UID(0x0020, 0x000d);
-  static const DicomTag DICOM_TAG_PIXEL_DATA(0x7fe0, 0x0010);
-  static const DicomTag DICOM_TAG_TRANSFER_SYNTAX_UID(0x0002, 0x0010);
-
-  static const DicomTag DICOM_TAG_IMAGE_INDEX(0x0054, 0x1330);
-  static const DicomTag DICOM_TAG_INSTANCE_NUMBER(0x0020, 0x0013);
-
-  static const DicomTag DICOM_TAG_NUMBER_OF_SLICES(0x0054, 0x0081);
-  static const DicomTag DICOM_TAG_NUMBER_OF_TIME_SLICES(0x0054, 0x0101);
-  static const DicomTag DICOM_TAG_NUMBER_OF_FRAMES(0x0028, 0x0008);
-  static const DicomTag DICOM_TAG_CARDIAC_NUMBER_OF_IMAGES(0x0018, 0x1090);
-  static const DicomTag DICOM_TAG_IMAGES_IN_ACQUISITION(0x0020, 0x1002);
-  static const DicomTag DICOM_TAG_PATIENT_NAME(0x0010, 0x0010);
-  static const DicomTag DICOM_TAG_ENCAPSULATED_DOCUMENT(0x0042, 0x0011);
-
-  static const DicomTag DICOM_TAG_STUDY_DESCRIPTION(0x0008, 0x1030);
-  static const DicomTag DICOM_TAG_SERIES_DESCRIPTION(0x0008, 0x103e);
-  static const DicomTag DICOM_TAG_MODALITY(0x0008, 0x0060);
-
-  // The following is used for "modify/anonymize" operations
-  static const DicomTag DICOM_TAG_SOP_CLASS_UID(0x0008, 0x0016);
-  static const DicomTag DICOM_TAG_MEDIA_STORAGE_SOP_CLASS_UID(0x0002, 0x0002);
-  static const DicomTag DICOM_TAG_MEDIA_STORAGE_SOP_INSTANCE_UID(0x0002, 0x0003);
-  static const DicomTag DICOM_TAG_DEIDENTIFICATION_METHOD(0x0012, 0x0063);
-
-  // DICOM tags used for fMRI (thanks to Will Ryder)
-  static const DicomTag DICOM_TAG_NUMBER_OF_TEMPORAL_POSITIONS(0x0020, 0x0105);
-  static const DicomTag DICOM_TAG_TEMPORAL_POSITION_IDENTIFIER(0x0020, 0x0100);
-
-  // Tags for C-FIND and C-MOVE
-  static const DicomTag DICOM_TAG_MESSAGE_ID(0x0000, 0x0110);
-  static const DicomTag DICOM_TAG_SPECIFIC_CHARACTER_SET(0x0008, 0x0005);
-  static const DicomTag DICOM_TAG_QUERY_RETRIEVE_LEVEL(0x0008, 0x0052);
-  static const DicomTag DICOM_TAG_MODALITIES_IN_STUDY(0x0008, 0x0061);
-
-  // Tags for images
-  static const DicomTag DICOM_TAG_COLUMNS(0x0028, 0x0011);
-  static const DicomTag DICOM_TAG_ROWS(0x0028, 0x0010);
-  static const DicomTag DICOM_TAG_SAMPLES_PER_PIXEL(0x0028, 0x0002);
-  static const DicomTag DICOM_TAG_BITS_ALLOCATED(0x0028, 0x0100);
-  static const DicomTag DICOM_TAG_BITS_STORED(0x0028, 0x0101);
-  static const DicomTag DICOM_TAG_HIGH_BIT(0x0028, 0x0102);
-  static const DicomTag DICOM_TAG_PIXEL_REPRESENTATION(0x0028, 0x0103);
-  static const DicomTag DICOM_TAG_PLANAR_CONFIGURATION(0x0028, 0x0006);
-  static const DicomTag DICOM_TAG_PHOTOMETRIC_INTERPRETATION(0x0028, 0x0004);
-  static const DicomTag DICOM_TAG_IMAGE_ORIENTATION_PATIENT(0x0020, 0x0037);
-  static const DicomTag DICOM_TAG_IMAGE_POSITION_PATIENT(0x0020, 0x0032);
-
-  // Tags related to date and time
-  static const DicomTag DICOM_TAG_ACQUISITION_DATE(0x0008, 0x0022);
-  static const DicomTag DICOM_TAG_ACQUISITION_TIME(0x0008, 0x0032);
-  static const DicomTag DICOM_TAG_CONTENT_DATE(0x0008, 0x0023);
-  static const DicomTag DICOM_TAG_CONTENT_TIME(0x0008, 0x0033);
-  static const DicomTag DICOM_TAG_INSTANCE_CREATION_DATE(0x0008, 0x0012);
-  static const DicomTag DICOM_TAG_INSTANCE_CREATION_TIME(0x0008, 0x0013);
-  static const DicomTag DICOM_TAG_PATIENT_BIRTH_DATE(0x0010, 0x0030);
-  static const DicomTag DICOM_TAG_PATIENT_BIRTH_TIME(0x0010, 0x0032);
-  static const DicomTag DICOM_TAG_SERIES_DATE(0x0008, 0x0021);
-  static const DicomTag DICOM_TAG_SERIES_TIME(0x0008, 0x0031);
-  static const DicomTag DICOM_TAG_STUDY_DATE(0x0008, 0x0020);
-  static const DicomTag DICOM_TAG_STUDY_TIME(0x0008, 0x0030);
-
-  // Various tags
-  static const DicomTag DICOM_TAG_SERIES_TYPE(0x0054, 0x1000);
-  static const DicomTag DICOM_TAG_REQUESTED_PROCEDURE_DESCRIPTION(0x0032, 0x1060);
-  static const DicomTag DICOM_TAG_INSTITUTION_NAME(0x0008, 0x0080);
-  static const DicomTag DICOM_TAG_REQUESTING_PHYSICIAN(0x0032, 0x1032);
-  static const DicomTag DICOM_TAG_REFERRING_PHYSICIAN_NAME(0x0008, 0x0090);
-  static const DicomTag DICOM_TAG_OPERATOR_NAME(0x0008, 0x1070);
-  static const DicomTag DICOM_TAG_PERFORMED_PROCEDURE_STEP_DESCRIPTION(0x0040, 0x0254);
-  static const DicomTag DICOM_TAG_IMAGE_COMMENTS(0x0020, 0x4000);
-  static const DicomTag DICOM_TAG_ACQUISITION_DEVICE_PROCESSING_DESCRIPTION(0x0018, 0x1400);
-  static const DicomTag DICOM_TAG_CONTRAST_BOLUS_AGENT(0x0018, 0x0010);
-
-  // Tags used within the Stone of Orthanc
-  static const DicomTag DICOM_TAG_FRAME_INCREMENT_POINTER(0x0028, 0x0009);
-  static const DicomTag DICOM_TAG_GRID_FRAME_OFFSET_VECTOR(0x3004, 0x000c);
-  static const DicomTag DICOM_TAG_PIXEL_SPACING(0x0028, 0x0030);
-  static const DicomTag DICOM_TAG_RESCALE_INTERCEPT(0x0028, 0x1052);
-  static const DicomTag DICOM_TAG_RESCALE_SLOPE(0x0028, 0x1053);
-  static const DicomTag DICOM_TAG_SLICE_THICKNESS(0x0018, 0x0050);
-  static const DicomTag DICOM_TAG_WINDOW_CENTER(0x0028, 0x1050);
-  static const DicomTag DICOM_TAG_WINDOW_WIDTH(0x0028, 0x1051);
-  static const DicomTag DICOM_TAG_DOSE_GRID_SCALING(0x3004, 0x000e);
-                                    
-  // Counting patients, studies and series
-  // https://www.medicalconnections.co.uk/kb/Counting_Studies_Series_and_Instances
-  static const DicomTag DICOM_TAG_NUMBER_OF_PATIENT_RELATED_STUDIES(0x0020, 0x1200);  
-  static const DicomTag DICOM_TAG_NUMBER_OF_PATIENT_RELATED_SERIES(0x0020, 0x1202);  
-  static const DicomTag DICOM_TAG_NUMBER_OF_PATIENT_RELATED_INSTANCES(0x0020, 0x1204);  
-  static const DicomTag DICOM_TAG_NUMBER_OF_STUDY_RELATED_SERIES(0x0020, 0x1206);  
-  static const DicomTag DICOM_TAG_NUMBER_OF_STUDY_RELATED_INSTANCES(0x0020, 0x1208);  
-  static const DicomTag DICOM_TAG_NUMBER_OF_SERIES_RELATED_INSTANCES(0x0020, 0x1209);  
-  static const DicomTag DICOM_TAG_SOP_CLASSES_IN_STUDY(0x0008, 0x0062);  
-
-  // Tags to preserve relationships during anonymization
-  static const DicomTag DICOM_TAG_REFERENCED_IMAGE_SEQUENCE(0x0008, 0x1140);
-  static const DicomTag DICOM_TAG_REFERENCED_SOP_INSTANCE_UID(0x0008, 0x1155);
-  static const DicomTag DICOM_TAG_SOURCE_IMAGE_SEQUENCE(0x0008, 0x2112);
-  static const DicomTag DICOM_TAG_FRAME_OF_REFERENCE_UID(0x0020, 0x0052);
-  static const DicomTag DICOM_TAG_REFERENCED_FRAME_OF_REFERENCE_UID(0x3006, 0x0024);
-  static const DicomTag DICOM_TAG_RELATED_FRAME_OF_REFERENCE_UID(0x3006, 0x00c2);
-  static const DicomTag DICOM_TAG_CURRENT_REQUESTED_PROCEDURE_EVIDENCE_SEQUENCE(0x0040, 0xa375);
-  static const DicomTag DICOM_TAG_REFERENCED_SERIES_SEQUENCE(0x0008, 0x1115);
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomValue.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +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-2018 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.
- *
- * 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"
-
-#include <boost/lexical_cast.hpp>
-
-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);
-  }
-
-  
-#if ORTHANC_ENABLE_BASE64 == 1
-  void DicomValue::FormatDataUriScheme(std::string& target,
-                                       const std::string& mime) const
-  {
-    Toolbox::EncodeBase64(target, GetContent());
-    target.insert(0, "data:" + mime + ";base64,");
-  }
-#endif
-
-
-  template <typename T,
-            bool allowSigned>
-  static bool ParseValue(T& result,
-                         const DicomValue& source)
-  {
-    if (source.IsBinary() ||
-        source.IsNull())
-    {
-      return false;
-    }
-    
-    try
-    {
-      std::string value = Toolbox::StripSpaces(source.GetContent());
-      if (value.empty())
-      {
-        return false;
-      }
-
-      if (!allowSigned &&
-          value[0] == '-')
-      {
-        return false;
-      }
-      
-      result = boost::lexical_cast<T>(value);
-      return true;
-    }
-    catch (boost::bad_lexical_cast&)
-    {
-      return false;
-    }
-  }
-
-  bool DicomValue::ParseInteger32(int32_t& result) const
-  {
-    int64_t tmp;
-    if (ParseValue<int64_t, true>(tmp, *this))
-    {
-      result = static_cast<int32_t>(tmp);
-      return (tmp == static_cast<int64_t>(result));  // Check no overflow occurs
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-  bool DicomValue::ParseInteger64(int64_t& result) const
-  {
-    return ParseValue<int64_t, true>(result, *this);
-  }
-
-  bool DicomValue::ParseUnsignedInteger32(uint32_t& result) const
-  {
-    uint64_t tmp;
-    if (ParseValue<uint64_t, false>(tmp, *this))
-    {
-      result = static_cast<uint32_t>(tmp);
-      return (tmp == static_cast<uint64_t>(result));  // Check no overflow occurs
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-  bool DicomValue::ParseUnsignedInteger64(uint64_t& result) const
-  {
-    return ParseValue<uint64_t, false>(result, *this);
-  }
-
-  bool DicomValue::ParseFloat(float& result) const
-  {
-    return ParseValue<float, true>(result, *this);
-  }
-
-  bool DicomValue::ParseDouble(double& result) const
-  {
-    return ParseValue<double, true>(result, *this);
-  }
-
-  bool DicomValue::CopyToString(std::string& result,
-                                bool allowBinary) const
-  {
-    if (IsNull())
-    {
-      return false;
-    }
-    else if (IsBinary() && !allowBinary)
-    {
-      return false;
-    }
-    else
-    {
-      result.assign(content_);
-      return true;
-    }
-  }    
-}
--- a/Resources/Orthanc/Core/DicomFormat/DicomValue.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <stdint.h>
-#include <string>
-#include <boost/noncopyable.hpp>
-
-#if !defined(ORTHANC_ENABLE_BASE64)
-#  error The macro ORTHANC_ENABLE_BASE64 must be defined
-#endif
-
-
-namespace Orthanc
-{
-  class DicomValue : public boost::noncopyable
-  {
-  private:
-    enum Type
-    {
-      Type_Null,
-      Type_String,
-      Type_Binary
-    };
-
-    Type         type_;
-    std::string  content_;
-
-    DicomValue(const DicomValue& other);
-
-  public:
-    DicomValue() : type_(Type_Null)
-    {
-    }
-    
-    DicomValue(const std::string& content,
-               bool isBinary);
-    
-    DicomValue(const char* data,
-               size_t size,
-               bool isBinary);
-    
-    const std::string& GetContent() const;
-
-    bool IsNull() const
-    {
-      return type_ == Type_Null;
-    }
-
-    bool IsBinary() const
-    {
-      return type_ == Type_Binary;
-    }
-    
-    DicomValue* Clone() const;
-
-#if ORTHANC_ENABLE_BASE64 == 1
-    void FormatDataUriScheme(std::string& target,
-                             const std::string& mime) const;
-
-    void FormatDataUriScheme(std::string& target) const
-    {
-      FormatDataUriScheme(target, "application/octet-stream");
-    }
-#endif
-
-    bool CopyToString(std::string& result,
-                      bool allowBinary) const;
-    
-    bool ParseInteger32(int32_t& result) const;
-
-    bool ParseInteger64(int64_t& result) const;                                
-
-    bool ParseUnsignedInteger32(uint32_t& result) const;
-
-    bool ParseUnsignedInteger64(uint64_t& result) const;                                
-
-    bool ParseFloat(float& result) const;                                
-
-    bool ParseDouble(double& result) const;                                
-  };
-}
--- a/Resources/Orthanc/Core/Endianness.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,207 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-
-/********************************************************************
- ** LINUX-LIKE ARCHITECTURES
- ********************************************************************/
-
-#if defined(__LSB_VERSION__)
-// Linux Standard Base (LSB) does not come with be16toh, be32toh, and
-// be64toh
-#  define ORTHANC_HAS_BUILTIN_BYTE_SWAP 0
-#  include <endian.h>
-#elif defined(__linux__) || defined(__EMSCRIPTEN__)
-#  define ORTHANC_HAS_BUILTIN_BYTE_SWAP 1
-#  include <endian.h>
-#endif
-
-
-/********************************************************************
- ** WINDOWS ARCHITECTURES
- **
- ** On Windows x86, "host" will always be little-endian ("le").
- ********************************************************************/
-
-#if defined(_WIN32)
-#  if defined(_MSC_VER)
-//   Visual Studio - http://msdn.microsoft.com/en-us/library/a3140177.aspx
-#    define ORTHANC_HAS_BUILTIN_BYTE_SWAP 1
-#    define be16toh(x) _byteswap_ushort(x)
-#    define be32toh(x) _byteswap_ulong(x)
-#    define be64toh(x) _byteswap_uint64(x)
-#  elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
-//   MinGW >= 4.3 - Use builtin intrinsic for byte swapping
-#    define ORTHANC_HAS_BUILTIN_BYTE_SWAP 1
-#    define be16toh(x) __builtin_bswap16(x)
-#    define be32toh(x) __builtin_bswap32(x)
-#    define be64toh(x) __builtin_bswap64(x)
-#  else
-//   MinGW <= 4.2, we must manually implement the byte swapping
-#    define ORTHANC_HAS_BUILTIN_BYTE_SWAP 0
-#    define be16toh(x) __orthanc_bswap16(x)
-#    define be32toh(x) __orthanc_bswap32(x)
-#    define be64toh(x) __orthanc_bswap64(x)
-#  endif
-
-#  define htobe16(x) be16toh(x)
-#  define htobe32(x) be32toh(x)
-#  define htobe64(x) be64toh(x)
-
-#  define htole16(x) x
-#  define htole32(x) x
-#  define htole64(x) x
-
-#  define le16toh(x) x
-#  define le32toh(x) x
-#  define le64toh(x) x
-#endif
-
-
-/********************************************************************
- ** FREEBSD ARCHITECTURES
- ********************************************************************/
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#  define ORTHANC_HAS_BUILTIN_BYTE_SWAP 1
-#  include <arpa/inet.h>
-#endif
-
-
-/********************************************************************
- ** OPENBSD ARCHITECTURES
- ********************************************************************/
-
-#if defined(__OpenBSD__)
-#  define ORTHANC_HAS_BUILTIN_BYTE_SWAP 1
-#  include <endian.h>
-#endif
-
-
-/********************************************************************
- ** APPLE ARCHITECTURES (including OS X)
- ********************************************************************/
-
-#if defined(__APPLE__)
-#  define ORTHANC_HAS_BUILTIN_BYTE_SWAP 1
-#  include <libkern/OSByteOrder.h>
-#  define be16toh(x) OSSwapBigToHostInt16(x)
-#  define be32toh(x) OSSwapBigToHostInt32(x)
-#  define be64toh(x) OSSwapBigToHostInt64(x)
-
-#  define htobe16(x) OSSwapHostToBigInt16(x)
-#  define htobe32(x) OSSwapHostToBigInt32(x)
-#  define htobe64(x) OSSwapHostToBigInt64(x)
-
-#  define htole16(x) OSSwapHostToLittleInt16(x)
-#  define htole32(x) OSSwapHostToLittleInt32(x)
-#  define htole64(x) OSSwapHostToLittleInt64(x)
-
-#  define le16toh(x) OSSwapLittleToHostInt16(x)
-#  define le32toh(x) OSSwapLittleToHostInt32(x)
-#  define le64toh(x) OSSwapLittleToHostInt64(x)
-#endif
-
-
-/********************************************************************
- ** PORTABLE (BUT SLOW) IMPLEMENTATION OF BYTE-SWAPPING
- ********************************************************************/
-
-#if ORTHANC_HAS_BUILTIN_BYTE_SWAP != 1
-
-#include <stdint.h>
-
-static inline uint16_t __orthanc_bswap16(uint16_t a)
-{
-  return (a << 8) | (a >> 8);
-}
-
-static inline uint32_t __orthanc_bswap32(uint32_t a)
-{
-  const uint8_t* p = reinterpret_cast<const uint8_t*>(&a);
-  return (static_cast<uint32_t>(p[0]) << 24 |
-          static_cast<uint32_t>(p[1]) << 16 |
-          static_cast<uint32_t>(p[2]) << 8 |
-          static_cast<uint32_t>(p[3]));
-}
-
-static inline uint64_t __orthanc_bswap64(uint64_t a)
-{
-  const uint8_t* p = reinterpret_cast<const uint8_t*>(&a);
-  return (static_cast<uint64_t>(p[0]) << 56 |
-          static_cast<uint64_t>(p[1]) << 48 |
-          static_cast<uint64_t>(p[2]) << 40 |
-          static_cast<uint64_t>(p[3]) << 32 |
-          static_cast<uint64_t>(p[4]) << 24 |
-          static_cast<uint64_t>(p[5]) << 16 |
-          static_cast<uint64_t>(p[6]) << 8 |
-          static_cast<uint64_t>(p[7]));
-}
-
-#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN)
-#  if __BYTE_ORDER == __LITTLE_ENDIAN
-#    define be16toh(x) __orthanc_bswap16(x)
-#    define be32toh(x) __orthanc_bswap32(x)
-#    define be64toh(x) __orthanc_bswap64(x)
-#    define htobe16(x) __orthanc_bswap16(x)
-#    define htobe32(x) __orthanc_bswap32(x)
-#    define htobe64(x) __orthanc_bswap64(x)
-#    define htole16(x) x
-#    define htole32(x) x
-#    define htole64(x) x
-#    define le16toh(x) x
-#    define le32toh(x) x
-#    define le64toh(x) x
-#  elif __BYTE_ORDER == __BIG_ENDIAN
-#    define be16toh(x) x
-#    define be32toh(x) x
-#    define be64toh(x) x
-#    define htobe16(x) x
-#    define htobe32(x) x
-#    define htobe64(x) x
-#    define htole16(x) __orthanc_bswap16(x)
-#    define htole32(x) __orthanc_bswap32(x)
-#    define htole64(x) __orthanc_bswap64(x)
-#    define le16toh(x) __orthanc_bswap16(x)
-#    define le32toh(x) __orthanc_bswap32(x)
-#    define le64toh(x) __orthanc_bswap64(x)
-#  else
-#    error Please support your platform here
-#  endif
-#else
-#  error Please support your platform here
-#endif
-
-#endif
--- a/Resources/Orthanc/Core/Enumerations.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1822 +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-2018 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.
- *
- * 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 "Enumerations.h"
-
-#include "OrthancException.h"
-#include "Toolbox.h"
-#include "Logging.h"
-
-#include <boost/thread/mutex.hpp>
-#include <string.h>
-#include <cassert>
-
-namespace Orthanc
-{
-  // This function is autogenerated by the script
-  // "Resources/GenerateErrorCodes.py"
-  const char* EnumerationToString(ErrorCode error)
-  {
-    switch (error)
-    {
-      case ErrorCode_InternalError:
-        return "Internal error";
-
-      case ErrorCode_Success:
-        return "Success";
-
-      case ErrorCode_Plugin:
-        return "Error encountered within the plugin engine";
-
-      case ErrorCode_NotImplemented:
-        return "Not implemented yet";
-
-      case ErrorCode_ParameterOutOfRange:
-        return "Parameter out of range";
-
-      case ErrorCode_NotEnoughMemory:
-        return "The server hosting Orthanc is running out of memory";
-
-      case ErrorCode_BadParameterType:
-        return "Bad type for a parameter";
-
-      case ErrorCode_BadSequenceOfCalls:
-        return "Bad sequence of calls";
-
-      case ErrorCode_InexistentItem:
-        return "Accessing an inexistent item";
-
-      case ErrorCode_BadRequest:
-        return "Bad request";
-
-      case ErrorCode_NetworkProtocol:
-        return "Error in the network protocol";
-
-      case ErrorCode_SystemCommand:
-        return "Error while calling a system command";
-
-      case ErrorCode_Database:
-        return "Error with the database engine";
-
-      case ErrorCode_UriSyntax:
-        return "Badly formatted URI";
-
-      case ErrorCode_InexistentFile:
-        return "Inexistent file";
-
-      case ErrorCode_CannotWriteFile:
-        return "Cannot write to file";
-
-      case ErrorCode_BadFileFormat:
-        return "Bad file format";
-
-      case ErrorCode_Timeout:
-        return "Timeout";
-
-      case ErrorCode_UnknownResource:
-        return "Unknown resource";
-
-      case ErrorCode_IncompatibleDatabaseVersion:
-        return "Incompatible version of the database";
-
-      case ErrorCode_FullStorage:
-        return "The file storage is full";
-
-      case ErrorCode_CorruptedFile:
-        return "Corrupted file (e.g. inconsistent MD5 hash)";
-
-      case ErrorCode_InexistentTag:
-        return "Inexistent tag";
-
-      case ErrorCode_ReadOnly:
-        return "Cannot modify a read-only data structure";
-
-      case ErrorCode_IncompatibleImageFormat:
-        return "Incompatible format of the images";
-
-      case ErrorCode_IncompatibleImageSize:
-        return "Incompatible size of the images";
-
-      case ErrorCode_SharedLibrary:
-        return "Error while using a shared library (plugin)";
-
-      case ErrorCode_UnknownPluginService:
-        return "Plugin invoking an unknown service";
-
-      case ErrorCode_UnknownDicomTag:
-        return "Unknown DICOM tag";
-
-      case ErrorCode_BadJson:
-        return "Cannot parse a JSON document";
-
-      case ErrorCode_Unauthorized:
-        return "Bad credentials were provided to an HTTP request";
-
-      case ErrorCode_BadFont:
-        return "Badly formatted font file";
-
-      case ErrorCode_DatabasePlugin:
-        return "The plugin implementing a custom database back-end does not fulfill the proper interface";
-
-      case ErrorCode_StorageAreaPlugin:
-        return "Error in the plugin implementing a custom storage area";
-
-      case ErrorCode_EmptyRequest:
-        return "The request is empty";
-
-      case ErrorCode_NotAcceptable:
-        return "Cannot send a response which is acceptable according to the Accept HTTP header";
-
-      case ErrorCode_NullPointer:
-        return "Cannot handle a NULL pointer";
-
-      case ErrorCode_DatabaseUnavailable:
-        return "The database is currently not available (probably a transient situation)";
-
-      case ErrorCode_SQLiteNotOpened:
-        return "SQLite: The database is not opened";
-
-      case ErrorCode_SQLiteAlreadyOpened:
-        return "SQLite: Connection is already open";
-
-      case ErrorCode_SQLiteCannotOpen:
-        return "SQLite: Unable to open the database";
-
-      case ErrorCode_SQLiteStatementAlreadyUsed:
-        return "SQLite: This cached statement is already being referred to";
-
-      case ErrorCode_SQLiteExecute:
-        return "SQLite: Cannot execute a command";
-
-      case ErrorCode_SQLiteRollbackWithoutTransaction:
-        return "SQLite: Rolling back a nonexistent transaction (have you called Begin()?)";
-
-      case ErrorCode_SQLiteCommitWithoutTransaction:
-        return "SQLite: Committing a nonexistent transaction";
-
-      case ErrorCode_SQLiteRegisterFunction:
-        return "SQLite: Unable to register a function";
-
-      case ErrorCode_SQLiteFlush:
-        return "SQLite: Unable to flush the database";
-
-      case ErrorCode_SQLiteCannotRun:
-        return "SQLite: Cannot run a cached statement";
-
-      case ErrorCode_SQLiteCannotStep:
-        return "SQLite: Cannot step over a cached statement";
-
-      case ErrorCode_SQLiteBindOutOfRange:
-        return "SQLite: Bing a value while out of range (serious error)";
-
-      case ErrorCode_SQLitePrepareStatement:
-        return "SQLite: Cannot prepare a cached statement";
-
-      case ErrorCode_SQLiteTransactionAlreadyStarted:
-        return "SQLite: Beginning the same transaction twice";
-
-      case ErrorCode_SQLiteTransactionCommit:
-        return "SQLite: Failure when committing the transaction";
-
-      case ErrorCode_SQLiteTransactionBegin:
-        return "SQLite: Cannot start a transaction";
-
-      case ErrorCode_DirectoryOverFile:
-        return "The directory to be created is already occupied by a regular file";
-
-      case ErrorCode_FileStorageCannotWrite:
-        return "Unable to create a subdirectory or a file in the file storage";
-
-      case ErrorCode_DirectoryExpected:
-        return "The specified path does not point to a directory";
-
-      case ErrorCode_HttpPortInUse:
-        return "The TCP port of the HTTP server is privileged or already in use";
-
-      case ErrorCode_DicomPortInUse:
-        return "The TCP port of the DICOM server is privileged or already in use";
-
-      case ErrorCode_BadHttpStatusInRest:
-        return "This HTTP status is not allowed in a REST API";
-
-      case ErrorCode_RegularFileExpected:
-        return "The specified path does not point to a regular file";
-
-      case ErrorCode_PathToExecutable:
-        return "Unable to get the path to the executable";
-
-      case ErrorCode_MakeDirectory:
-        return "Cannot create a directory";
-
-      case ErrorCode_BadApplicationEntityTitle:
-        return "An application entity title (AET) cannot be empty or be longer than 16 characters";
-
-      case ErrorCode_NoCFindHandler:
-        return "No request handler factory for DICOM C-FIND SCP";
-
-      case ErrorCode_NoCMoveHandler:
-        return "No request handler factory for DICOM C-MOVE SCP";
-
-      case ErrorCode_NoCStoreHandler:
-        return "No request handler factory for DICOM C-STORE SCP";
-
-      case ErrorCode_NoApplicationEntityFilter:
-        return "No application entity filter";
-
-      case ErrorCode_NoSopClassOrInstance:
-        return "DicomUserConnection: Unable to find the SOP class and instance";
-
-      case ErrorCode_NoPresentationContext:
-        return "DicomUserConnection: No acceptable presentation context for modality";
-
-      case ErrorCode_DicomFindUnavailable:
-        return "DicomUserConnection: The C-FIND command is not supported by the remote SCP";
-
-      case ErrorCode_DicomMoveUnavailable:
-        return "DicomUserConnection: The C-MOVE command is not supported by the remote SCP";
-
-      case ErrorCode_CannotStoreInstance:
-        return "Cannot store an instance";
-
-      case ErrorCode_CreateDicomNotString:
-        return "Only string values are supported when creating DICOM instances";
-
-      case ErrorCode_CreateDicomOverrideTag:
-        return "Trying to override a value inherited from a parent module";
-
-      case ErrorCode_CreateDicomUseContent:
-        return "Use \"Content\" to inject an image into a new DICOM instance";
-
-      case ErrorCode_CreateDicomNoPayload:
-        return "No payload is present for one instance in the series";
-
-      case ErrorCode_CreateDicomUseDataUriScheme:
-        return "The payload of the DICOM instance must be specified according to Data URI scheme";
-
-      case ErrorCode_CreateDicomBadParent:
-        return "Trying to attach a new DICOM instance to an inexistent resource";
-
-      case ErrorCode_CreateDicomParentIsInstance:
-        return "Trying to attach a new DICOM instance to an instance (must be a series, study or patient)";
-
-      case ErrorCode_CreateDicomParentEncoding:
-        return "Unable to get the encoding of the parent resource";
-
-      case ErrorCode_UnknownModality:
-        return "Unknown modality";
-
-      case ErrorCode_BadJobOrdering:
-        return "Bad ordering of filters in a job";
-
-      case ErrorCode_JsonToLuaTable:
-        return "Cannot convert the given JSON object to a Lua table";
-
-      case ErrorCode_CannotCreateLua:
-        return "Cannot create the Lua context";
-
-      case ErrorCode_CannotExecuteLua:
-        return "Cannot execute a Lua command";
-
-      case ErrorCode_LuaAlreadyExecuted:
-        return "Arguments cannot be pushed after the Lua function is executed";
-
-      case ErrorCode_LuaBadOutput:
-        return "The Lua function does not give the expected number of outputs";
-
-      case ErrorCode_NotLuaPredicate:
-        return "The Lua function is not a predicate (only true/false outputs allowed)";
-
-      case ErrorCode_LuaReturnsNoString:
-        return "The Lua function does not return a string";
-
-      case ErrorCode_StorageAreaAlreadyRegistered:
-        return "Another plugin has already registered a custom storage area";
-
-      case ErrorCode_DatabaseBackendAlreadyRegistered:
-        return "Another plugin has already registered a custom database back-end";
-
-      case ErrorCode_DatabaseNotInitialized:
-        return "Plugin trying to call the database during its initialization";
-
-      case ErrorCode_SslDisabled:
-        return "Orthanc has been built without SSL support";
-
-      case ErrorCode_CannotOrderSlices:
-        return "Unable to order the slices of the series";
-
-      case ErrorCode_NoWorklistHandler:
-        return "No request handler factory for DICOM C-Find Modality SCP";
-
-      case ErrorCode_AlreadyExistingTag:
-        return "Cannot override the value of a tag that already exists";
-
-      default:
-        if (error >= ErrorCode_START_PLUGINS)
-        {
-          return "Error encountered within some plugin";
-        }
-        else
-        {
-          return "Unknown error code";
-        }
-    }
-  }
-
-
-  const char* EnumerationToString(HttpMethod method)
-  {
-    switch (method)
-    {
-      case HttpMethod_Get:
-        return "GET";
-
-      case HttpMethod_Post:
-        return "POST";
-
-      case HttpMethod_Delete:
-        return "DELETE";
-
-      case HttpMethod_Put:
-        return "PUT";
-
-      default:
-        return "?";
-    }
-  }
-
-
-  const char* EnumerationToString(HttpStatus status)
-  {
-    switch (status)
-    {
-    case HttpStatus_100_Continue:
-      return "Continue";
-
-    case HttpStatus_101_SwitchingProtocols:
-      return "Switching Protocols";
-
-    case HttpStatus_102_Processing:
-      return "Processing";
-
-    case HttpStatus_200_Ok:
-      return "OK";
-
-    case HttpStatus_201_Created:
-      return "Created";
-
-    case HttpStatus_202_Accepted:
-      return "Accepted";
-
-    case HttpStatus_203_NonAuthoritativeInformation:
-      return "Non-Authoritative Information";
-
-    case HttpStatus_204_NoContent:
-      return "No Content";
-
-    case HttpStatus_205_ResetContent:
-      return "Reset Content";
-
-    case HttpStatus_206_PartialContent:
-      return "Partial Content";
-
-    case HttpStatus_207_MultiStatus:
-      return "Multi-Status";
-
-    case HttpStatus_208_AlreadyReported:
-      return "Already Reported";
-
-    case HttpStatus_226_IMUsed:
-      return "IM Used";
-
-    case HttpStatus_300_MultipleChoices:
-      return "Multiple Choices";
-
-    case HttpStatus_301_MovedPermanently:
-      return "Moved Permanently";
-
-    case HttpStatus_302_Found:
-      return "Found";
-
-    case HttpStatus_303_SeeOther:
-      return "See Other";
-
-    case HttpStatus_304_NotModified:
-      return "Not Modified";
-
-    case HttpStatus_305_UseProxy:
-      return "Use Proxy";
-
-    case HttpStatus_307_TemporaryRedirect:
-      return "Temporary Redirect";
-
-    case HttpStatus_400_BadRequest:
-      return "Bad Request";
-
-    case HttpStatus_401_Unauthorized:
-      return "Unauthorized";
-
-    case HttpStatus_402_PaymentRequired:
-      return "Payment Required";
-
-    case HttpStatus_403_Forbidden:
-      return "Forbidden";
-
-    case HttpStatus_404_NotFound:
-      return "Not Found";
-
-    case HttpStatus_405_MethodNotAllowed:
-      return "Method Not Allowed";
-
-    case HttpStatus_406_NotAcceptable:
-      return "Not Acceptable";
-
-    case HttpStatus_407_ProxyAuthenticationRequired:
-      return "Proxy Authentication Required";
-
-    case HttpStatus_408_RequestTimeout:
-      return "Request Timeout";
-
-    case HttpStatus_409_Conflict:
-      return "Conflict";
-
-    case HttpStatus_410_Gone:
-      return "Gone";
-
-    case HttpStatus_411_LengthRequired:
-      return "Length Required";
-
-    case HttpStatus_412_PreconditionFailed:
-      return "Precondition Failed";
-
-    case HttpStatus_413_RequestEntityTooLarge:
-      return "Request Entity Too Large";
-
-    case HttpStatus_414_RequestUriTooLong:
-      return "Request-URI Too Long";
-
-    case HttpStatus_415_UnsupportedMediaType:
-      return "Unsupported Media Type";
-
-    case HttpStatus_416_RequestedRangeNotSatisfiable:
-      return "Requested Range Not Satisfiable";
-
-    case HttpStatus_417_ExpectationFailed:
-      return "Expectation Failed";
-
-    case HttpStatus_422_UnprocessableEntity:
-      return "Unprocessable Entity";
-
-    case HttpStatus_423_Locked:
-      return "Locked";
-
-    case HttpStatus_424_FailedDependency:
-      return "Failed Dependency";
-
-    case HttpStatus_426_UpgradeRequired:
-      return "Upgrade Required";
-
-    case HttpStatus_500_InternalServerError:
-      return "Internal Server Error";
-
-    case HttpStatus_501_NotImplemented:
-      return "Not Implemented";
-
-    case HttpStatus_502_BadGateway:
-      return "Bad Gateway";
-
-    case HttpStatus_503_ServiceUnavailable:
-      return "Service Unavailable";
-
-    case HttpStatus_504_GatewayTimeout:
-      return "Gateway Timeout";
-
-    case HttpStatus_505_HttpVersionNotSupported:
-      return "HTTP Version Not Supported";
-
-    case HttpStatus_506_VariantAlsoNegotiates:
-      return "Variant Also Negotiates";
-
-    case HttpStatus_507_InsufficientStorage:
-      return "Insufficient Storage";
-
-    case HttpStatus_509_BandwidthLimitExceeded:
-      return "Bandwidth Limit Exceeded";
-
-    case HttpStatus_510_NotExtended:
-      return "Not Extended";
-
-    default:
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  const char* EnumerationToString(ResourceType type)
-  {
-    switch (type)
-    {
-      case ResourceType_Patient:
-        return "Patient";
-
-      case ResourceType_Study:
-        return "Study";
-
-      case ResourceType_Series:
-        return "Series";
-
-      case ResourceType_Instance:
-        return "Instance";
-      
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  const char* EnumerationToString(ImageFormat format)
-  {
-    switch (format)
-    {
-      case ImageFormat_Png:
-        return "Png";
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  const char* EnumerationToString(Encoding encoding)
-  {
-    switch (encoding)
-    {
-      case Encoding_Ascii:
-        return "Ascii";
-
-      case Encoding_Utf8:
-        return "Utf8";
-
-      case Encoding_Latin1:
-        return "Latin1";
-
-      case Encoding_Latin2:
-        return "Latin2";
-
-      case Encoding_Latin3:
-        return "Latin3";
-
-      case Encoding_Latin4:
-        return "Latin4";
-
-      case Encoding_Latin5:
-        return "Latin5";
-
-      case Encoding_Cyrillic:
-        return "Cyrillic";
-
-      case Encoding_Windows1251:
-        return "Windows1251";
-
-      case Encoding_Arabic:
-        return "Arabic";
-
-      case Encoding_Greek:
-        return "Greek";
-
-      case Encoding_Hebrew:
-        return "Hebrew";
-
-      case Encoding_Thai:
-        return "Thai";
-
-      case Encoding_Japanese:
-        return "Japanese";
-
-      case Encoding_Chinese:
-        return "Chinese";
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  const char* EnumerationToString(PhotometricInterpretation photometric)
-  {
-    switch (photometric)
-    {
-      case PhotometricInterpretation_RGB:
-        return "RGB";
-
-      case PhotometricInterpretation_Monochrome1:
-        return "MONOCHROME1";
-
-      case PhotometricInterpretation_Monochrome2:
-        return "MONOCHROME2";
-
-      case PhotometricInterpretation_ARGB:
-        return "ARGB";
-
-      case PhotometricInterpretation_CMYK:
-        return "CMYK";
-
-      case PhotometricInterpretation_HSV:
-        return "HSV";
-
-      case PhotometricInterpretation_Palette:
-        return "PALETTE COLOR";
-
-      case PhotometricInterpretation_YBRFull:
-        return "YBR_FULL";
-
-      case PhotometricInterpretation_YBRFull422:
-        return "YBR_FULL_422";
-
-      case PhotometricInterpretation_YBRPartial420:
-        return "YBR_PARTIAL_420"; 
-
-      case PhotometricInterpretation_YBRPartial422:
-        return "YBR_PARTIAL_422"; 
-
-      case PhotometricInterpretation_YBR_ICT:
-        return "YBR_ICT"; 
-
-      case PhotometricInterpretation_YBR_RCT:
-        return "YBR_RCT"; 
-
-      case PhotometricInterpretation_Unknown:
-        return "Unknown";
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  const char* EnumerationToString(RequestOrigin origin)
-  {
-    switch (origin)
-    {
-      case RequestOrigin_Unknown:
-        return "Unknown";
-
-      case RequestOrigin_DicomProtocol:
-        return "DicomProtocol";
-
-      case RequestOrigin_RestApi:
-        return "RestApi";
-
-      case RequestOrigin_Plugins:
-        return "Plugins";
-
-      case RequestOrigin_Lua:
-        return "Lua";
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  const char* EnumerationToString(LogLevel level)
-  {
-    switch (level)
-    {
-      case LogLevel_Error:
-        return "ERROR";
-
-      case LogLevel_Warning:
-        return "WARNING";
-
-      case LogLevel_Info:
-        return "INFO";
-
-      case LogLevel_Trace:
-        return "TRACE";
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  const char* EnumerationToString(PixelFormat format)
-  {
-    switch (format)
-    {
-      case PixelFormat_RGB24:
-        return "RGB24";
-
-      case PixelFormat_RGBA32:
-        return "RGBA32";
-
-      case PixelFormat_BGRA32:
-        return "BGRA32";
-
-      case PixelFormat_Grayscale8:
-        return "Grayscale (unsigned 8bpp)";
-
-      case PixelFormat_Grayscale16:
-        return "Grayscale (unsigned 16bpp)";
-
-      case PixelFormat_SignedGrayscale16:
-        return "Grayscale (signed 16bpp)";
-
-      case PixelFormat_Float32:
-        return "Grayscale (float 32bpp)";
-
-      case PixelFormat_Grayscale32:
-        return "Grayscale (unsigned 32bpp)";
-
-      case PixelFormat_RGB48:
-        return "RGB48";
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  const char* EnumerationToString(ModalityManufacturer manufacturer)
-  {
-    switch (manufacturer)
-    {
-      case ModalityManufacturer_Generic:
-        return "Generic";
-
-      case ModalityManufacturer_GenericNoWildcardInDates:
-        return "GenericNoWildcardInDates";
-
-      case ModalityManufacturer_GenericNoUniversalWildcard:
-        return "GenericNoUniversalWildcard";
-
-      case ModalityManufacturer_StoreScp:
-        return "StoreScp";
-      
-      case ModalityManufacturer_ClearCanvas:
-        return "ClearCanvas";
-      
-      case ModalityManufacturer_Dcm4Chee:
-        return "Dcm4Chee";
-      
-      case ModalityManufacturer_Vitrea:
-        return "Vitrea";
-      
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  const char* EnumerationToString(DicomRequestType type)
-  {
-    switch (type)
-    {
-      case DicomRequestType_Echo:
-        return "Echo";
-        break;
-
-      case DicomRequestType_Find:
-        return "Find";
-        break;
-
-      case DicomRequestType_Get:
-        return "Get";
-        break;
-
-      case DicomRequestType_Move:
-        return "Move";
-        break;
-
-      case DicomRequestType_Store:
-        return "Store";
-        break;
-
-      default: 
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  const char* EnumerationToString(TransferSyntax syntax)
-  {
-    switch (syntax)
-    {
-      case TransferSyntax_Deflated:
-        return "Deflated";
-
-      case TransferSyntax_Jpeg:
-        return "JPEG";
-
-      case TransferSyntax_Jpeg2000:
-        return "JPEG2000";
-
-      case TransferSyntax_JpegLossless:
-        return "JPEG Lossless";
-
-      case TransferSyntax_Jpip:
-        return "JPIP";
-
-      case TransferSyntax_Mpeg2:
-        return "MPEG2";
-
-      case TransferSyntax_Rle:
-        return "RLE";
-
-      default: 
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  const char* EnumerationToString(DicomVersion version)
-  {
-    switch (version)
-    {
-      case DicomVersion_2008:
-        return "2008";
-        break;
-
-      case DicomVersion_2017c:
-        return "2017c";
-        break;
-
-      default: 
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  const char* EnumerationToString(ValueRepresentation vr)
-  {
-    switch (vr)
-    {
-      case ValueRepresentation_ApplicationEntity:     // AE
-        return "AE";
-
-      case ValueRepresentation_AgeString:             // AS
-        return "AS";
-
-      case ValueRepresentation_AttributeTag:          // AT (2 x uint16_t)
-        return "AT";
-
-      case ValueRepresentation_CodeString:            // CS
-        return "CS";
-
-      case ValueRepresentation_Date:                  // DA
-        return "DA";
-
-      case ValueRepresentation_DecimalString:         // DS
-        return "DS";
-
-      case ValueRepresentation_DateTime:              // DT
-        return "DT";
-
-      case ValueRepresentation_FloatingPointSingle:   // FL (float)
-        return "FL";
-
-      case ValueRepresentation_FloatingPointDouble:   // FD (double)
-        return "FD";
-
-      case ValueRepresentation_IntegerString:         // IS
-        return "IS";
-
-      case ValueRepresentation_LongString:            // LO
-        return "LO";
-
-      case ValueRepresentation_LongText:              // LT
-        return "LT";
-
-      case ValueRepresentation_OtherByte:             // OB
-        return "OB";
-
-      case ValueRepresentation_OtherDouble:           // OD
-        return "OD";
-
-      case ValueRepresentation_OtherFloat:            // OF
-        return "OF";
-
-      case ValueRepresentation_OtherLong:             // OL
-        return "OL";
-
-      case ValueRepresentation_OtherWord:             // OW
-        return "OW";
-
-      case ValueRepresentation_PersonName:            // PN
-        return "PN";
-
-      case ValueRepresentation_ShortString:           // SH
-        return "SH";
-
-      case ValueRepresentation_SignedLong:            // SL (int32_t)
-        return "SL";
-
-      case ValueRepresentation_Sequence:              // SQ
-        return "SQ";
-
-      case ValueRepresentation_SignedShort:           // SS (int16_t)
-        return "SS";
-
-      case ValueRepresentation_ShortText:             // ST
-        return "ST";
-
-      case ValueRepresentation_Time:                  // TM
-        return "TM";
-
-      case ValueRepresentation_UnlimitedCharacters:   // UC
-        return "UC";
-
-      case ValueRepresentation_UniqueIdentifier:      // UI (UID)
-        return "UI";
-
-      case ValueRepresentation_UnsignedLong:          // UL (uint32_t)
-        return "UL";
-
-      case ValueRepresentation_Unknown:               // UN
-        return "UN";
-
-      case ValueRepresentation_UniversalResource:     // UR (URI or URL)
-        return "UR";
-
-      case ValueRepresentation_UnsignedShort:         // US (uint16_t)
-        return "US";
-
-      case ValueRepresentation_UnlimitedText:         // UT
-        return "UT";
-
-      case ValueRepresentation_NotSupported:
-        return "Not supported";
-
-      default: 
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  Encoding StringToEncoding(const char* encoding)
-  {
-    std::string s(encoding);
-    Toolbox::ToUpperCase(s);
-
-    if (s == "UTF8")
-    {
-      return Encoding_Utf8;
-    }
-
-    if (s == "ASCII")
-    {
-      return Encoding_Ascii;
-    }
-
-    if (s == "LATIN1")
-    {
-      return Encoding_Latin1;
-    }
-
-    if (s == "LATIN2")
-    {
-      return Encoding_Latin2;
-    }
-
-    if (s == "LATIN3")
-    {
-      return Encoding_Latin3;
-    }
-
-    if (s == "LATIN4")
-    {
-      return Encoding_Latin4;
-    }
-
-    if (s == "LATIN5")
-    {
-      return Encoding_Latin5;
-    }
-
-    if (s == "CYRILLIC")
-    {
-      return Encoding_Cyrillic;
-    }
-
-    if (s == "WINDOWS1251")
-    {
-      return Encoding_Windows1251;
-    }
-
-    if (s == "ARABIC")
-    {
-      return Encoding_Arabic;
-    }
-
-    if (s == "GREEK")
-    {
-      return Encoding_Greek;
-    }
-
-    if (s == "HEBREW")
-    {
-      return Encoding_Hebrew;
-    }
-
-    if (s == "THAI")
-    {
-      return Encoding_Thai;
-    }
-
-    if (s == "JAPANESE")
-    {
-      return Encoding_Japanese;
-    }
-
-    if (s == "CHINESE")
-    {
-      return Encoding_Chinese;
-    }
-
-    throw OrthancException(ErrorCode_ParameterOutOfRange);
-  }
-
-
-  ResourceType StringToResourceType(const char* type)
-  {
-    std::string s(type);
-    Toolbox::ToUpperCase(s);
-
-    if (s == "PATIENT" || s == "PATIENTS")
-    {
-      return ResourceType_Patient;
-    }
-    else if (s == "STUDY" || s == "STUDIES")
-    {
-      return ResourceType_Study;
-    }
-    else if (s == "SERIES")
-    {
-      return ResourceType_Series;
-    }
-    else if (s == "INSTANCE"  || s == "IMAGE" || 
-             s == "INSTANCES" || s == "IMAGES")
-    {
-      return ResourceType_Instance;
-    }
-
-    throw OrthancException(ErrorCode_ParameterOutOfRange);
-  }
-
-
-  ImageFormat StringToImageFormat(const char* format)
-  {
-    std::string s(format);
-    Toolbox::ToUpperCase(s);
-
-    if (s == "PNG")
-    {
-      return ImageFormat_Png;
-    }
-
-    throw OrthancException(ErrorCode_ParameterOutOfRange);
-  }
-
-
-  LogLevel StringToLogLevel(const char *level)
-  {
-    if (strcmp(level, "ERROR") == 0)
-    {
-      return LogLevel_Error;
-    }
-    else if (strcmp(level, "WARNING") == 0)
-    {
-      return LogLevel_Warning;
-    }
-    else if (strcmp(level, "INFO") == 0)
-    {
-      return LogLevel_Info;
-    }
-    else if (strcmp(level, "TRACE") == 0)
-    {
-      return LogLevel_Trace;
-    }
-    else 
-    {
-      throw OrthancException(ErrorCode_InternalError);
-    }
-  }
-
-
-  ValueRepresentation StringToValueRepresentation(const std::string& vr,
-                                                  bool throwIfUnsupported)
-  {
-    if (vr == "AE")
-    {
-      return ValueRepresentation_ApplicationEntity;
-    }
-    else if (vr == "AS")
-    {
-      return ValueRepresentation_AgeString;
-    }
-    else if (vr == "AT")
-    {
-      return ValueRepresentation_AttributeTag;
-    }
-    else if (vr == "CS")
-    {
-      return ValueRepresentation_CodeString;
-    }
-    else if (vr == "DA")
-    {
-      return ValueRepresentation_Date;
-    }
-    else if (vr == "DS")
-    {
-      return ValueRepresentation_DecimalString;
-    }
-    else if (vr == "DT")
-    {
-      return ValueRepresentation_DateTime;
-    }
-    else if (vr == "FL")
-    {
-      return ValueRepresentation_FloatingPointSingle;
-    }
-    else if (vr == "FD")
-    {
-      return ValueRepresentation_FloatingPointDouble;
-    }
-    else if (vr == "IS")
-    {
-      return ValueRepresentation_IntegerString;
-    }
-    else if (vr == "LO")
-    {
-      return ValueRepresentation_LongString;
-    }
-    else if (vr == "LT")
-    {
-      return ValueRepresentation_LongText;
-    }
-    else if (vr == "OB")
-    {
-      return ValueRepresentation_OtherByte;
-    }
-    else if (vr == "OD")
-    {
-      return ValueRepresentation_OtherDouble;
-    }
-    else if (vr == "OF")
-    {
-      return ValueRepresentation_OtherFloat;
-    }
-    else if (vr == "OL")
-    {
-      return ValueRepresentation_OtherLong;
-    }
-    else if (vr == "OW")
-    {
-      return ValueRepresentation_OtherWord;
-    }
-    else if (vr == "PN")
-    {
-      return ValueRepresentation_PersonName;
-    }
-    else if (vr == "SH")
-    {
-      return ValueRepresentation_ShortString;
-    }
-    else if (vr == "SL")
-    {
-      return ValueRepresentation_SignedLong;
-    }
-    else if (vr == "SQ")
-    {
-      return ValueRepresentation_Sequence;
-    }
-    else if (vr == "SS")
-    {
-      return ValueRepresentation_SignedShort;
-    }
-    else if (vr == "ST")
-    {
-      return ValueRepresentation_ShortText;
-    }
-    else if (vr == "TM")
-    {
-      return ValueRepresentation_Time;
-    }
-    else if (vr == "UC")
-    {
-      return ValueRepresentation_UnlimitedCharacters;
-    }
-    else if (vr == "UI")
-    {
-      return ValueRepresentation_UniqueIdentifier;
-    }
-    else if (vr == "UL")
-    {
-      return ValueRepresentation_UnsignedLong;
-    }
-    else if (vr == "UN")
-    {
-      return ValueRepresentation_Unknown;
-    }
-    else if (vr == "UR")
-    {
-      return ValueRepresentation_UniversalResource;
-    }
-    else if (vr == "US")
-    {
-      return ValueRepresentation_UnsignedShort;
-    }
-    else if (vr == "UT")
-    {
-      return ValueRepresentation_UnlimitedText;
-    }
-    else
-    {
-      std::string s = "Unsupported value representation encountered: " + vr;
-
-      if (throwIfUnsupported)
-      {
-        LOG(ERROR) << s;
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-      }
-      else
-      {
-        LOG(INFO) << s;
-        return ValueRepresentation_NotSupported;
-      }
-    }
-  }
-
-
-  PhotometricInterpretation StringToPhotometricInterpretation(const char* value)
-  {
-    // http://dicom.nema.org/medical/dicom/2017a/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2
-    std::string s(value);
-
-    if (s == "MONOCHROME1")
-    {
-      return PhotometricInterpretation_Monochrome1;
-    }
-    
-    if (s == "MONOCHROME2")
-    {
-      return PhotometricInterpretation_Monochrome2;
-    }
-
-    if (s == "PALETTE COLOR")
-    {
-      return PhotometricInterpretation_Palette;
-    }
-    
-    if (s == "RGB")
-    {
-      return PhotometricInterpretation_RGB;
-    }
-    
-    if (s == "HSV")
-    {
-      return PhotometricInterpretation_HSV;
-    }
-    
-    if (s == "ARGB")
-    {
-      return PhotometricInterpretation_ARGB;
-    }    
-
-    if (s == "CMYK")
-    {
-      return PhotometricInterpretation_CMYK;
-    }    
-
-    if (s == "YBR_FULL")
-    {
-      return PhotometricInterpretation_YBRFull;
-    }
-    
-    if (s == "YBR_FULL_422")
-    {
-      return PhotometricInterpretation_YBRFull422;
-    }
-    
-    if (s == "YBR_PARTIAL_422")
-    {
-      return PhotometricInterpretation_YBRPartial422;
-    }
-    
-    if (s == "YBR_PARTIAL_420")
-    {
-      return PhotometricInterpretation_YBRPartial420;
-    }
-    
-    if (s == "YBR_ICT")
-    {
-      return PhotometricInterpretation_YBR_ICT;
-    }
-    
-    if (s == "YBR_RCT")
-    {
-      return PhotometricInterpretation_YBR_RCT;
-    }
-
-    throw OrthancException(ErrorCode_ParameterOutOfRange);
-  }
-  
-
-  ModalityManufacturer StringToModalityManufacturer(const std::string& manufacturer)
-  {
-    ModalityManufacturer result;
-    bool obsolete = false;
-    
-    if (manufacturer == "Generic")
-    {
-      return ModalityManufacturer_Generic;
-    }
-    else if (manufacturer == "GenericNoWildcardInDates")
-    {
-      return ModalityManufacturer_GenericNoWildcardInDates;
-    }
-    else if (manufacturer == "GenericNoUniversalWildcard")
-    {
-      return ModalityManufacturer_GenericNoUniversalWildcard;
-    }
-    else if (manufacturer == "ClearCanvas")
-    {
-      return ModalityManufacturer_ClearCanvas;
-    }
-    else if (manufacturer == "StoreScp")
-    {
-      return ModalityManufacturer_StoreScp;
-    }
-    else if (manufacturer == "Dcm4Chee")
-    {
-      return ModalityManufacturer_Dcm4Chee;
-    }
-    else if (manufacturer == "Vitrea")
-    {
-      return ModalityManufacturer_Vitrea;
-    }
-    else if (manufacturer == "AgfaImpax" ||
-             manufacturer == "SyngoVia")
-    {
-      result = ModalityManufacturer_GenericNoWildcardInDates;
-      obsolete = true;
-    }
-    else if (manufacturer == "EFilm2" ||
-             manufacturer == "MedInria")
-    {
-      result = ModalityManufacturer_Generic;
-      obsolete = true;
-    }
-    else
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    if (obsolete)
-    {
-      LOG(WARNING) << "The \"" << manufacturer << "\" manufacturer is obsolete since "
-                   << "Orthanc 1.3.0. To guarantee compatibility with future Orthanc "
-                   << "releases, you should replace it by \""
-                   << EnumerationToString(result)
-                   << "\" in your configuration file.";
-    }
-
-    return result;
-  }
-
-
-  DicomVersion StringToDicomVersion(const std::string& version)
-  {
-    if (version == "2008")
-    {
-      return DicomVersion_2008;
-    }
-    else if (version == "2017c")
-    {
-      return DicomVersion_2017c;
-    }
-    else
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  unsigned int GetBytesPerPixel(PixelFormat format)
-  {
-    switch (format)
-    {
-      case PixelFormat_Grayscale8:
-        return 1;
-
-      case PixelFormat_Grayscale16:
-      case PixelFormat_SignedGrayscale16:
-        return 2;
-
-      case PixelFormat_RGB24:
-        return 3;
-
-      case PixelFormat_RGBA32:
-      case PixelFormat_BGRA32:
-      case PixelFormat_Grayscale32:
-        return 4;
-
-      case PixelFormat_Float32:
-        assert(sizeof(float) == 4);
-        return 4;
-
-      case PixelFormat_RGB48:
-        return 6;
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  bool GetDicomEncoding(Encoding& encoding,
-                        const char* specificCharacterSet)
-  {
-    std::string s = Toolbox::StripSpaces(specificCharacterSet);
-    Toolbox::ToUpperCase(s);
-
-    // http://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.12.1.1.2
-    // https://github.com/dcm4che/dcm4che/blob/master/dcm4che-core/src/main/java/org/dcm4che3/data/SpecificCharacterSet.java
-    if (s == "ISO_IR 6" ||
-        s == "ISO 2022 IR 6")
-    {
-      encoding = Encoding_Ascii;
-    }
-    else if (s == "ISO_IR 192")
-    {
-      encoding = Encoding_Utf8;
-    }
-    else if (s == "ISO_IR 100" ||
-             s == "ISO 2022 IR 100")
-    {
-      encoding = Encoding_Latin1;
-    }
-    else if (s == "ISO_IR 101" ||
-             s == "ISO 2022 IR 101")
-    {
-      encoding = Encoding_Latin2;
-    }
-    else if (s == "ISO_IR 109" ||
-             s == "ISO 2022 IR 109")
-    {
-      encoding = Encoding_Latin3;
-    }
-    else if (s == "ISO_IR 110" ||
-             s == "ISO 2022 IR 110")
-    {
-      encoding = Encoding_Latin4;
-    }
-    else if (s == "ISO_IR 148" ||
-             s == "ISO 2022 IR 148")
-    {
-      encoding = Encoding_Latin5;
-    }
-    else if (s == "ISO_IR 144" ||
-             s == "ISO 2022 IR 144")
-    {
-      encoding = Encoding_Cyrillic;
-    }
-    else if (s == "ISO_IR 127" ||
-             s == "ISO 2022 IR 127")
-    {
-      encoding = Encoding_Arabic;
-    }
-    else if (s == "ISO_IR 126" ||
-             s == "ISO 2022 IR 126")
-    {
-      encoding = Encoding_Greek;
-    }
-    else if (s == "ISO_IR 138" ||
-             s == "ISO 2022 IR 138")
-    {
-      encoding = Encoding_Hebrew;
-    }
-    else if (s == "ISO_IR 166" || s == "ISO 2022 IR 166")
-    {
-      encoding = Encoding_Thai;
-    }
-    else if (s == "ISO_IR 13" || s == "ISO 2022 IR 13")
-    {
-      encoding = Encoding_Japanese;
-    }
-    else if (s == "GB18030" || s == "GBK")
-    {
-      /**
-       * According to tumashu@163.com, "In China, many dicom file's
-       * 0008,0005 tag is set as "GBK", instead of "GB18030", GBK is a
-       * subset of GB18030, and which is used frequently in China,
-       * suggest support it."
-       * https://groups.google.com/d/msg/orthanc-users/WMM8LMbjpUc/02-1f_yFCgAJ
-       **/
-      encoding = Encoding_Chinese;
-    }
-    /*
-      else if (s == "ISO 2022 IR 149")
-      {
-      TODO
-      }
-      else if (s == "ISO 2022 IR 159")
-      {
-      TODO
-      }
-      else if (s == "ISO 2022 IR 87")
-      {
-      TODO
-      }
-    */
-    else
-    {
-      return false;
-    }
-
-    // The encoding was properly detected
-    return true;
-  }
-
-
-  ResourceType GetChildResourceType(ResourceType type)
-  {
-    switch (type)
-    {
-      case ResourceType_Patient:
-        return ResourceType_Study;
-
-      case ResourceType_Study:
-        return ResourceType_Series;
-        
-      case ResourceType_Series:
-        return ResourceType_Instance;
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  ResourceType GetParentResourceType(ResourceType type)
-  {
-    switch (type)
-    {
-      case ResourceType_Study:
-        return ResourceType_Patient;
-        
-      case ResourceType_Series:
-        return ResourceType_Study;
-
-      case ResourceType_Instance:
-        return ResourceType_Series;
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  DicomModule GetModule(ResourceType type)
-  {
-    switch (type)
-    {
-      case ResourceType_Patient:
-        return DicomModule_Patient;
-
-      case ResourceType_Study:
-        return DicomModule_Study;
-        
-      case ResourceType_Series:
-        return DicomModule_Series;
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-
-  const char* GetDicomSpecificCharacterSet(Encoding encoding)
-  {
-    // http://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.12.1.1.2
-    switch (encoding)
-    {
-      case Encoding_Ascii:
-        return "ISO_IR 6";
-
-      case Encoding_Utf8:
-        return "ISO_IR 192";
-
-      case Encoding_Latin1:
-        return "ISO_IR 100";
-
-      case Encoding_Latin2:
-        return "ISO_IR 101";
-
-      case Encoding_Latin3:
-        return "ISO_IR 109";
-
-      case Encoding_Latin4:
-        return "ISO_IR 110";
-
-      case Encoding_Latin5:
-        return "ISO_IR 148";
-
-      case Encoding_Cyrillic:
-        return "ISO_IR 144";
-
-      case Encoding_Arabic:
-        return "ISO_IR 127";
-
-      case Encoding_Greek:
-        return "ISO_IR 126";
-
-      case Encoding_Hebrew:
-        return "ISO_IR 138";
-
-      case Encoding_Japanese:
-        return "ISO_IR 13";
-
-      case Encoding_Chinese:
-        return "GB18030";
-
-      case Encoding_Thai:
-        return "ISO_IR 166";
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  // This function is autogenerated by the script
-  // "Resources/GenerateErrorCodes.py"
-  HttpStatus ConvertErrorCodeToHttpStatus(ErrorCode error)
-  {
-    switch (error)
-    {
-      case ErrorCode_Success:
-        return HttpStatus_200_Ok;
-
-      case ErrorCode_ParameterOutOfRange:
-        return HttpStatus_400_BadRequest;
-
-      case ErrorCode_BadParameterType:
-        return HttpStatus_400_BadRequest;
-
-      case ErrorCode_InexistentItem:
-        return HttpStatus_404_NotFound;
-
-      case ErrorCode_BadRequest:
-        return HttpStatus_400_BadRequest;
-
-      case ErrorCode_UriSyntax:
-        return HttpStatus_400_BadRequest;
-
-      case ErrorCode_InexistentFile:
-        return HttpStatus_404_NotFound;
-
-      case ErrorCode_BadFileFormat:
-        return HttpStatus_400_BadRequest;
-
-      case ErrorCode_UnknownResource:
-        return HttpStatus_404_NotFound;
-
-      case ErrorCode_InexistentTag:
-        return HttpStatus_404_NotFound;
-
-      case ErrorCode_BadJson:
-        return HttpStatus_400_BadRequest;
-
-      case ErrorCode_Unauthorized:
-        return HttpStatus_401_Unauthorized;
-
-      case ErrorCode_NotAcceptable:
-        return HttpStatus_406_NotAcceptable;
-
-      case ErrorCode_DatabaseUnavailable:
-        return HttpStatus_503_ServiceUnavailable;
-
-      default:
-        return HttpStatus_500_InternalServerError;
-    }
-  }
-
-
-  bool IsUserContentType(FileContentType type)
-  {
-    return (type >= FileContentType_StartUser &&
-            type <= FileContentType_EndUser);
-  }
-
-
-  bool IsBinaryValueRepresentation(ValueRepresentation vr)
-  {
-    // http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_6.2.html
-
-    switch (vr)
-    {
-      case ValueRepresentation_ApplicationEntity:     // AE
-      case ValueRepresentation_AgeString:             // AS
-      case ValueRepresentation_CodeString:            // CS
-      case ValueRepresentation_Date:                  // DA
-      case ValueRepresentation_DecimalString:         // DS
-      case ValueRepresentation_DateTime:              // DT
-      case ValueRepresentation_IntegerString:         // IS
-      case ValueRepresentation_LongString:            // LO
-      case ValueRepresentation_LongText:              // LT
-      case ValueRepresentation_PersonName:            // PN
-      case ValueRepresentation_ShortString:           // SH
-      case ValueRepresentation_ShortText:             // ST
-      case ValueRepresentation_Time:                  // TM
-      case ValueRepresentation_UnlimitedCharacters:   // UC
-      case ValueRepresentation_UniqueIdentifier:      // UI (UID)
-      case ValueRepresentation_UniversalResource:     // UR (URI or URL)
-      case ValueRepresentation_UnlimitedText:         // UT
-      {
-        return false;
-      }
-
-      /**
-       * Below are all the VR whose character repertoire is tagged as
-       * "not applicable"
-       **/
-      case ValueRepresentation_AttributeTag:          // AT (2 x uint16_t)
-      case ValueRepresentation_FloatingPointSingle:   // FL (float)
-      case ValueRepresentation_FloatingPointDouble:   // FD (double)
-      case ValueRepresentation_OtherByte:             // OB
-      case ValueRepresentation_OtherDouble:           // OD
-      case ValueRepresentation_OtherFloat:            // OF
-      case ValueRepresentation_OtherLong:             // OL
-      case ValueRepresentation_OtherWord:             // OW
-      case ValueRepresentation_SignedLong:            // SL (int32_t)
-      case ValueRepresentation_Sequence:              // SQ
-      case ValueRepresentation_SignedShort:           // SS (int16_t)
-      case ValueRepresentation_UnsignedLong:          // UL (uint32_t)
-      case ValueRepresentation_Unknown:               // UN
-      case ValueRepresentation_UnsignedShort:         // US (uint16_t)
-      {
-        return true;
-      }
-
-      case ValueRepresentation_NotSupported:
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }  
-
-
-  static boost::mutex  defaultEncodingMutex_;  // Should not be necessary
-  static Encoding      defaultEncoding_ = ORTHANC_DEFAULT_DICOM_ENCODING;
-  
-  Encoding GetDefaultDicomEncoding()
-  {
-    boost::mutex::scoped_lock lock(defaultEncodingMutex_);
-    return defaultEncoding_;
-  }
-
-  void SetDefaultDicomEncoding(Encoding encoding)
-  {
-    std::string name = EnumerationToString(encoding);
-    
-    {
-      boost::mutex::scoped_lock lock(defaultEncodingMutex_);
-      defaultEncoding_ = encoding;
-    }
-
-    LOG(INFO) << "Default encoding for DICOM was changed to: " << name;
-  }
-
-}
--- a/Resources/Orthanc/Core/Enumerations.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,664 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <string>
-
-
-#if defined(_MSC_VER)
-#  define ORTHANC_FORCE_INLINE __forceinline
-#elif defined(__GNUC__) || defined(__clang__) || defined(__EMSCRIPTEN__)
-#  define ORTHANC_FORCE_INLINE inline __attribute((always_inline))
-#else
-#  error Please support your compiler here
-#endif
-
-
-namespace Orthanc
-{
-  enum Endianness
-  {
-    Endianness_Unknown,
-    Endianness_Big,
-    Endianness_Little
-  };
-
-  // This enumeration is autogenerated by the script
-  // "Resources/GenerateErrorCodes.py"
-  enum ErrorCode
-  {
-    ErrorCode_InternalError = -1    /*!< Internal error */,
-    ErrorCode_Success = 0    /*!< Success */,
-    ErrorCode_Plugin = 1    /*!< Error encountered within the plugin engine */,
-    ErrorCode_NotImplemented = 2    /*!< Not implemented yet */,
-    ErrorCode_ParameterOutOfRange = 3    /*!< Parameter out of range */,
-    ErrorCode_NotEnoughMemory = 4    /*!< The server hosting Orthanc is running out of memory */,
-    ErrorCode_BadParameterType = 5    /*!< Bad type for a parameter */,
-    ErrorCode_BadSequenceOfCalls = 6    /*!< Bad sequence of calls */,
-    ErrorCode_InexistentItem = 7    /*!< Accessing an inexistent item */,
-    ErrorCode_BadRequest = 8    /*!< Bad request */,
-    ErrorCode_NetworkProtocol = 9    /*!< Error in the network protocol */,
-    ErrorCode_SystemCommand = 10    /*!< Error while calling a system command */,
-    ErrorCode_Database = 11    /*!< Error with the database engine */,
-    ErrorCode_UriSyntax = 12    /*!< Badly formatted URI */,
-    ErrorCode_InexistentFile = 13    /*!< Inexistent file */,
-    ErrorCode_CannotWriteFile = 14    /*!< Cannot write to file */,
-    ErrorCode_BadFileFormat = 15    /*!< Bad file format */,
-    ErrorCode_Timeout = 16    /*!< Timeout */,
-    ErrorCode_UnknownResource = 17    /*!< Unknown resource */,
-    ErrorCode_IncompatibleDatabaseVersion = 18    /*!< Incompatible version of the database */,
-    ErrorCode_FullStorage = 19    /*!< The file storage is full */,
-    ErrorCode_CorruptedFile = 20    /*!< Corrupted file (e.g. inconsistent MD5 hash) */,
-    ErrorCode_InexistentTag = 21    /*!< Inexistent tag */,
-    ErrorCode_ReadOnly = 22    /*!< Cannot modify a read-only data structure */,
-    ErrorCode_IncompatibleImageFormat = 23    /*!< Incompatible format of the images */,
-    ErrorCode_IncompatibleImageSize = 24    /*!< Incompatible size of the images */,
-    ErrorCode_SharedLibrary = 25    /*!< Error while using a shared library (plugin) */,
-    ErrorCode_UnknownPluginService = 26    /*!< Plugin invoking an unknown service */,
-    ErrorCode_UnknownDicomTag = 27    /*!< Unknown DICOM tag */,
-    ErrorCode_BadJson = 28    /*!< Cannot parse a JSON document */,
-    ErrorCode_Unauthorized = 29    /*!< Bad credentials were provided to an HTTP request */,
-    ErrorCode_BadFont = 30    /*!< Badly formatted font file */,
-    ErrorCode_DatabasePlugin = 31    /*!< The plugin implementing a custom database back-end does not fulfill the proper interface */,
-    ErrorCode_StorageAreaPlugin = 32    /*!< Error in the plugin implementing a custom storage area */,
-    ErrorCode_EmptyRequest = 33    /*!< The request is empty */,
-    ErrorCode_NotAcceptable = 34    /*!< Cannot send a response which is acceptable according to the Accept HTTP header */,
-    ErrorCode_NullPointer = 35    /*!< Cannot handle a NULL pointer */,
-    ErrorCode_DatabaseUnavailable = 36    /*!< The database is currently not available (probably a transient situation) */,
-    ErrorCode_SQLiteNotOpened = 1000    /*!< SQLite: The database is not opened */,
-    ErrorCode_SQLiteAlreadyOpened = 1001    /*!< SQLite: Connection is already open */,
-    ErrorCode_SQLiteCannotOpen = 1002    /*!< SQLite: Unable to open the database */,
-    ErrorCode_SQLiteStatementAlreadyUsed = 1003    /*!< SQLite: This cached statement is already being referred to */,
-    ErrorCode_SQLiteExecute = 1004    /*!< SQLite: Cannot execute a command */,
-    ErrorCode_SQLiteRollbackWithoutTransaction = 1005    /*!< SQLite: Rolling back a nonexistent transaction (have you called Begin()?) */,
-    ErrorCode_SQLiteCommitWithoutTransaction = 1006    /*!< SQLite: Committing a nonexistent transaction */,
-    ErrorCode_SQLiteRegisterFunction = 1007    /*!< SQLite: Unable to register a function */,
-    ErrorCode_SQLiteFlush = 1008    /*!< SQLite: Unable to flush the database */,
-    ErrorCode_SQLiteCannotRun = 1009    /*!< SQLite: Cannot run a cached statement */,
-    ErrorCode_SQLiteCannotStep = 1010    /*!< SQLite: Cannot step over a cached statement */,
-    ErrorCode_SQLiteBindOutOfRange = 1011    /*!< SQLite: Bing a value while out of range (serious error) */,
-    ErrorCode_SQLitePrepareStatement = 1012    /*!< SQLite: Cannot prepare a cached statement */,
-    ErrorCode_SQLiteTransactionAlreadyStarted = 1013    /*!< SQLite: Beginning the same transaction twice */,
-    ErrorCode_SQLiteTransactionCommit = 1014    /*!< SQLite: Failure when committing the transaction */,
-    ErrorCode_SQLiteTransactionBegin = 1015    /*!< SQLite: Cannot start a transaction */,
-    ErrorCode_DirectoryOverFile = 2000    /*!< The directory to be created is already occupied by a regular file */,
-    ErrorCode_FileStorageCannotWrite = 2001    /*!< Unable to create a subdirectory or a file in the file storage */,
-    ErrorCode_DirectoryExpected = 2002    /*!< The specified path does not point to a directory */,
-    ErrorCode_HttpPortInUse = 2003    /*!< The TCP port of the HTTP server is privileged or already in use */,
-    ErrorCode_DicomPortInUse = 2004    /*!< The TCP port of the DICOM server is privileged or already in use */,
-    ErrorCode_BadHttpStatusInRest = 2005    /*!< This HTTP status is not allowed in a REST API */,
-    ErrorCode_RegularFileExpected = 2006    /*!< The specified path does not point to a regular file */,
-    ErrorCode_PathToExecutable = 2007    /*!< Unable to get the path to the executable */,
-    ErrorCode_MakeDirectory = 2008    /*!< Cannot create a directory */,
-    ErrorCode_BadApplicationEntityTitle = 2009    /*!< An application entity title (AET) cannot be empty or be longer than 16 characters */,
-    ErrorCode_NoCFindHandler = 2010    /*!< No request handler factory for DICOM C-FIND SCP */,
-    ErrorCode_NoCMoveHandler = 2011    /*!< No request handler factory for DICOM C-MOVE SCP */,
-    ErrorCode_NoCStoreHandler = 2012    /*!< No request handler factory for DICOM C-STORE SCP */,
-    ErrorCode_NoApplicationEntityFilter = 2013    /*!< No application entity filter */,
-    ErrorCode_NoSopClassOrInstance = 2014    /*!< DicomUserConnection: Unable to find the SOP class and instance */,
-    ErrorCode_NoPresentationContext = 2015    /*!< DicomUserConnection: No acceptable presentation context for modality */,
-    ErrorCode_DicomFindUnavailable = 2016    /*!< DicomUserConnection: The C-FIND command is not supported by the remote SCP */,
-    ErrorCode_DicomMoveUnavailable = 2017    /*!< DicomUserConnection: The C-MOVE command is not supported by the remote SCP */,
-    ErrorCode_CannotStoreInstance = 2018    /*!< Cannot store an instance */,
-    ErrorCode_CreateDicomNotString = 2019    /*!< Only string values are supported when creating DICOM instances */,
-    ErrorCode_CreateDicomOverrideTag = 2020    /*!< Trying to override a value inherited from a parent module */,
-    ErrorCode_CreateDicomUseContent = 2021    /*!< Use \"Content\" to inject an image into a new DICOM instance */,
-    ErrorCode_CreateDicomNoPayload = 2022    /*!< No payload is present for one instance in the series */,
-    ErrorCode_CreateDicomUseDataUriScheme = 2023    /*!< The payload of the DICOM instance must be specified according to Data URI scheme */,
-    ErrorCode_CreateDicomBadParent = 2024    /*!< Trying to attach a new DICOM instance to an inexistent resource */,
-    ErrorCode_CreateDicomParentIsInstance = 2025    /*!< Trying to attach a new DICOM instance to an instance (must be a series, study or patient) */,
-    ErrorCode_CreateDicomParentEncoding = 2026    /*!< Unable to get the encoding of the parent resource */,
-    ErrorCode_UnknownModality = 2027    /*!< Unknown modality */,
-    ErrorCode_BadJobOrdering = 2028    /*!< Bad ordering of filters in a job */,
-    ErrorCode_JsonToLuaTable = 2029    /*!< Cannot convert the given JSON object to a Lua table */,
-    ErrorCode_CannotCreateLua = 2030    /*!< Cannot create the Lua context */,
-    ErrorCode_CannotExecuteLua = 2031    /*!< Cannot execute a Lua command */,
-    ErrorCode_LuaAlreadyExecuted = 2032    /*!< Arguments cannot be pushed after the Lua function is executed */,
-    ErrorCode_LuaBadOutput = 2033    /*!< The Lua function does not give the expected number of outputs */,
-    ErrorCode_NotLuaPredicate = 2034    /*!< The Lua function is not a predicate (only true/false outputs allowed) */,
-    ErrorCode_LuaReturnsNoString = 2035    /*!< The Lua function does not return a string */,
-    ErrorCode_StorageAreaAlreadyRegistered = 2036    /*!< Another plugin has already registered a custom storage area */,
-    ErrorCode_DatabaseBackendAlreadyRegistered = 2037    /*!< Another plugin has already registered a custom database back-end */,
-    ErrorCode_DatabaseNotInitialized = 2038    /*!< Plugin trying to call the database during its initialization */,
-    ErrorCode_SslDisabled = 2039    /*!< Orthanc has been built without SSL support */,
-    ErrorCode_CannotOrderSlices = 2040    /*!< Unable to order the slices of the series */,
-    ErrorCode_NoWorklistHandler = 2041    /*!< No request handler factory for DICOM C-Find Modality SCP */,
-    ErrorCode_AlreadyExistingTag = 2042    /*!< Cannot override the value of a tag that already exists */,
-    ErrorCode_START_PLUGINS = 1000000
-  };
-
-  enum LogLevel
-  {
-    LogLevel_Error,
-    LogLevel_Warning,
-    LogLevel_Info,
-    LogLevel_Trace
-  };
-
-
-  /**
-   * {summary}{The memory layout of the pixels (resp. voxels) of a 2D (resp. 3D) image.}
-   **/
-  enum PixelFormat
-  {
-    /**
-     * {summary}{Color image in RGB24 format.}
-     * {description}{This format describes a color image. The pixels are stored in 3
-     * consecutive bytes. The memory layout is RGB.}
-     **/
-    PixelFormat_RGB24 = 1,
-
-    /**
-     * {summary}{Color image in RGBA32 format.}
-     * {description}{This format describes a color image. The pixels are stored in 4
-     * consecutive bytes. The memory layout is RGBA.}
-     **/
-    PixelFormat_RGBA32 = 2,
-
-    /**
-     * {summary}{Graylevel 8bpp image.}
-     * {description}{The image is graylevel. Each pixel is unsigned and stored in one byte.}
-     **/
-    PixelFormat_Grayscale8 = 3,
-      
-    /**
-     * {summary}{Graylevel, unsigned 16bpp image.}
-     * {description}{The image is graylevel. Each pixel is unsigned and stored in two bytes.}
-     **/
-    PixelFormat_Grayscale16 = 4,
-      
-    /**
-     * {summary}{Graylevel, signed 16bpp image.}
-     * {description}{The image is graylevel. Each pixel is signed and stored in two bytes.}
-     **/
-    PixelFormat_SignedGrayscale16 = 5,
-      
-    /**
-     * {summary}{Graylevel, floating-point image.}
-     * {description}{The image is graylevel. Each pixel is floating-point and stored in 4 bytes.}
-     **/
-    PixelFormat_Float32 = 6,
-
-    // This is the memory layout for Cairo (for internal use in Stone of Orthanc)
-    PixelFormat_BGRA32 = 7,
-
-    /**
-     * {summary}{Graylevel, unsigned 32bpp image.}
-     * {description}{The image is graylevel. Each pixel is unsigned and stored in 4 bytes.}
-     **/
-    PixelFormat_Grayscale32 = 8,
-    
-    /**
-     * {summary}{Color image in RGB48 format.}
-     * {description}{This format describes a color image. The pixels are stored in 6
-     * consecutive bytes. The memory layout is RGB.}
-     **/
-    PixelFormat_RGB48 = 9
-  };
-
-
-  /**
-   * {summary}{The extraction mode specifies the way the values of the pixels are scaled when downloading a 2D image.}
-   **/
-  enum ImageExtractionMode
-  {
-    /**
-     * {summary}{Rescaled to 8bpp.}
-     * {description}{The minimum value of the image is set to 0, and its maximum value is set to 255.}
-     **/
-    ImageExtractionMode_Preview = 1,
-
-    /**
-     * {summary}{Truncation to the [0, 255] range.}
-     **/
-    ImageExtractionMode_UInt8 = 2,
-
-    /**
-     * {summary}{Truncation to the [0, 65535] range.}
-     **/
-    ImageExtractionMode_UInt16 = 3,
-
-    /**
-     * {summary}{Truncation to the [-32768, 32767] range.}
-     **/
-    ImageExtractionMode_Int16 = 4
-  };
-
-
-  /**
-   * Most common, non-joke and non-experimental HTTP status codes
-   * http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
-   **/
-  enum HttpStatus
-  {
-    HttpStatus_None = -1,
-
-    // 1xx Informational
-    HttpStatus_100_Continue = 100,
-    HttpStatus_101_SwitchingProtocols = 101,
-    HttpStatus_102_Processing = 102,
-
-    // 2xx Success
-    HttpStatus_200_Ok = 200,
-    HttpStatus_201_Created = 201,
-    HttpStatus_202_Accepted = 202,
-    HttpStatus_203_NonAuthoritativeInformation = 203,
-    HttpStatus_204_NoContent = 204,
-    HttpStatus_205_ResetContent = 205,
-    HttpStatus_206_PartialContent = 206,
-    HttpStatus_207_MultiStatus = 207,
-    HttpStatus_208_AlreadyReported = 208,
-    HttpStatus_226_IMUsed = 226,
-
-    // 3xx Redirection
-    HttpStatus_300_MultipleChoices = 300,
-    HttpStatus_301_MovedPermanently = 301,
-    HttpStatus_302_Found = 302,
-    HttpStatus_303_SeeOther = 303,
-    HttpStatus_304_NotModified = 304,
-    HttpStatus_305_UseProxy = 305,
-    HttpStatus_307_TemporaryRedirect = 307,
-
-    // 4xx Client Error
-    HttpStatus_400_BadRequest = 400,
-    HttpStatus_401_Unauthorized = 401,
-    HttpStatus_402_PaymentRequired = 402,
-    HttpStatus_403_Forbidden = 403,
-    HttpStatus_404_NotFound = 404,
-    HttpStatus_405_MethodNotAllowed = 405,
-    HttpStatus_406_NotAcceptable = 406,
-    HttpStatus_407_ProxyAuthenticationRequired = 407,
-    HttpStatus_408_RequestTimeout = 408,
-    HttpStatus_409_Conflict = 409,
-    HttpStatus_410_Gone = 410,
-    HttpStatus_411_LengthRequired = 411,
-    HttpStatus_412_PreconditionFailed = 412,
-    HttpStatus_413_RequestEntityTooLarge = 413,
-    HttpStatus_414_RequestUriTooLong = 414,
-    HttpStatus_415_UnsupportedMediaType = 415,
-    HttpStatus_416_RequestedRangeNotSatisfiable = 416,
-    HttpStatus_417_ExpectationFailed = 417,
-    HttpStatus_422_UnprocessableEntity = 422,
-    HttpStatus_423_Locked = 423,
-    HttpStatus_424_FailedDependency = 424,
-    HttpStatus_426_UpgradeRequired = 426,
-
-    // 5xx Server Error
-    HttpStatus_500_InternalServerError = 500,
-    HttpStatus_501_NotImplemented = 501,
-    HttpStatus_502_BadGateway = 502,
-    HttpStatus_503_ServiceUnavailable = 503,
-    HttpStatus_504_GatewayTimeout = 504,
-    HttpStatus_505_HttpVersionNotSupported = 505,
-    HttpStatus_506_VariantAlsoNegotiates = 506,
-    HttpStatus_507_InsufficientStorage = 507,
-    HttpStatus_509_BandwidthLimitExceeded = 509,
-    HttpStatus_510_NotExtended = 510
-  };
-
-
-  enum HttpMethod
-  {
-    HttpMethod_Get = 0,
-    HttpMethod_Post = 1,
-    HttpMethod_Delete = 2,
-    HttpMethod_Put = 3
-  };
-
-
-  enum ImageFormat
-  {
-    ImageFormat_Png = 1
-  };
-
-
-  // https://en.wikipedia.org/wiki/HTTP_compression
-  enum HttpCompression
-  {
-    HttpCompression_None,
-    HttpCompression_Deflate,
-    HttpCompression_Gzip
-  };
-
-
-  // Specific Character Sets
-  // http://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.12.1.1.2
-  enum Encoding
-  {
-    Encoding_Ascii,
-    Encoding_Utf8,
-    Encoding_Latin1,
-    Encoding_Latin2,
-    Encoding_Latin3,
-    Encoding_Latin4,
-    Encoding_Latin5,                        // Turkish
-    Encoding_Cyrillic,
-    Encoding_Windows1251,                   // Windows-1251 (commonly used for Cyrillic)
-    Encoding_Arabic,
-    Encoding_Greek,
-    Encoding_Hebrew,
-    Encoding_Thai,                          // TIS 620-2533
-    Encoding_Japanese,                      // JIS X 0201 (Shift JIS): Katakana
-    Encoding_Chinese                        // GB18030 - Chinese simplified
-    //Encoding_JapaneseKanji,               // Multibyte - JIS X 0208: Kanji
-    //Encoding_JapaneseSupplementaryKanji,  // Multibyte - JIS X 0212: Supplementary Kanji set
-    //Encoding_Korean,                      // Multibyte - KS X 1001: Hangul and Hanja
-  };
-
-
-  // http://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.7.6.3.1.2
-  enum PhotometricInterpretation
-  {
-    PhotometricInterpretation_ARGB,  // Retired
-    PhotometricInterpretation_CMYK,  // Retired
-    PhotometricInterpretation_HSV,   // Retired
-    PhotometricInterpretation_Monochrome1,
-    PhotometricInterpretation_Monochrome2,
-    PhotometricInterpretation_Palette,
-    PhotometricInterpretation_RGB,
-    PhotometricInterpretation_YBRFull,
-    PhotometricInterpretation_YBRFull422,
-    PhotometricInterpretation_YBRPartial420,
-    PhotometricInterpretation_YBRPartial422,
-    PhotometricInterpretation_YBR_ICT,
-    PhotometricInterpretation_YBR_RCT,
-    PhotometricInterpretation_Unknown
-  };
-
-  enum DicomModule
-  {
-    DicomModule_Patient,
-    DicomModule_Study,
-    DicomModule_Series,
-    DicomModule_Instance,
-    DicomModule_Image
-  };
-
-  enum RequestOrigin
-  {
-    RequestOrigin_Unknown,
-    RequestOrigin_DicomProtocol,
-    RequestOrigin_RestApi,
-    RequestOrigin_Plugins,
-    RequestOrigin_Lua
-  };
-
-  enum ServerBarrierEvent
-  {
-    ServerBarrierEvent_Stop,
-    ServerBarrierEvent_Reload  // SIGHUP signal: reload configuration file
-  };
-
-  enum FileMode
-  {
-    FileMode_ReadBinary,
-    FileMode_WriteBinary
-  };
-
-  /**
-   * The value representations Orthanc knows about. They correspond to
-   * the DICOM 2016b version of the standard.
-   * http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_6.2.html
-   **/
-  enum ValueRepresentation
-  {
-    ValueRepresentation_ApplicationEntity = 1,     // AE
-    ValueRepresentation_AgeString = 2,             // AS
-    ValueRepresentation_AttributeTag = 3,          // AT (2 x uint16_t)
-    ValueRepresentation_CodeString = 4,            // CS
-    ValueRepresentation_Date = 5,                  // DA
-    ValueRepresentation_DecimalString = 6,         // DS
-    ValueRepresentation_DateTime = 7,              // DT
-    ValueRepresentation_FloatingPointSingle = 8,   // FL (float)
-    ValueRepresentation_FloatingPointDouble = 9,   // FD (double)
-    ValueRepresentation_IntegerString = 10,        // IS
-    ValueRepresentation_LongString = 11,           // LO
-    ValueRepresentation_LongText = 12,             // LT
-    ValueRepresentation_OtherByte = 13,            // OB
-    ValueRepresentation_OtherDouble = 14,          // OD
-    ValueRepresentation_OtherFloat = 15,           // OF
-    ValueRepresentation_OtherLong = 16,            // OL
-    ValueRepresentation_OtherWord = 17,            // OW
-    ValueRepresentation_PersonName = 18,           // PN
-    ValueRepresentation_ShortString = 19,          // SH
-    ValueRepresentation_SignedLong = 20,           // SL (int32_t)
-    ValueRepresentation_Sequence = 21,             // SQ
-    ValueRepresentation_SignedShort = 22,          // SS (int16_t)
-    ValueRepresentation_ShortText = 23,            // ST
-    ValueRepresentation_Time = 24,                 // TM
-    ValueRepresentation_UnlimitedCharacters = 25,  // UC
-    ValueRepresentation_UniqueIdentifier = 26,     // UI (UID)
-    ValueRepresentation_UnsignedLong = 27,         // UL (uint32_t)
-    ValueRepresentation_Unknown = 28,              // UN
-    ValueRepresentation_UniversalResource = 29,    // UR (URI or URL)
-    ValueRepresentation_UnsignedShort = 30,        // US (uint16_t)
-    ValueRepresentation_UnlimitedText = 31,        // UT
-    ValueRepresentation_NotSupported               // Not supported by Orthanc, or tag not in dictionary
-  };
-
-  enum DicomReplaceMode
-  {
-    DicomReplaceMode_InsertIfAbsent,
-    DicomReplaceMode_ThrowIfAbsent,
-    DicomReplaceMode_IgnoreIfAbsent
-  };
-
-  enum DicomToJsonFormat
-  {
-    DicomToJsonFormat_Full,
-    DicomToJsonFormat_Short,
-    DicomToJsonFormat_Human
-  };
-
-  enum DicomToJsonFlags
-  {
-    DicomToJsonFlags_IncludeBinary         = (1 << 0),
-    DicomToJsonFlags_IncludePrivateTags    = (1 << 1),
-    DicomToJsonFlags_IncludeUnknownTags    = (1 << 2),
-    DicomToJsonFlags_IncludePixelData      = (1 << 3),
-    DicomToJsonFlags_ConvertBinaryToAscii  = (1 << 4),
-    DicomToJsonFlags_ConvertBinaryToNull   = (1 << 5),
-
-    // Some predefined combinations
-    DicomToJsonFlags_None     = 0,
-    DicomToJsonFlags_Default  = (DicomToJsonFlags_IncludeBinary |
-                                 DicomToJsonFlags_IncludePixelData | 
-                                 DicomToJsonFlags_IncludePrivateTags | 
-                                 DicomToJsonFlags_IncludeUnknownTags | 
-                                 DicomToJsonFlags_ConvertBinaryToNull)
-  };
-  
-  enum DicomFromJsonFlags
-  {
-    DicomFromJsonFlags_DecodeDataUriScheme = (1 << 0),
-    DicomFromJsonFlags_GenerateIdentifiers = (1 << 1)
-  };
-  
-  enum DicomVersion
-  {
-    DicomVersion_2008,
-    DicomVersion_2017c
-  };
-
-  enum ModalityManufacturer
-  {
-    ModalityManufacturer_Generic,
-    ModalityManufacturer_GenericNoWildcardInDates,
-    ModalityManufacturer_GenericNoUniversalWildcard,
-    ModalityManufacturer_StoreScp,
-    ModalityManufacturer_ClearCanvas,
-    ModalityManufacturer_Dcm4Chee,
-    ModalityManufacturer_Vitrea
-  };
-
-  enum DicomRequestType
-  {
-    DicomRequestType_Echo,
-    DicomRequestType_Find,
-    DicomRequestType_Get,
-    DicomRequestType_Move,
-    DicomRequestType_Store
-  };
-
-  enum TransferSyntax
-  {
-    TransferSyntax_Deflated,
-    TransferSyntax_Jpeg,
-    TransferSyntax_Jpeg2000,
-    TransferSyntax_JpegLossless,
-    TransferSyntax_Jpip,
-    TransferSyntax_Mpeg2,
-    TransferSyntax_Rle
-  };
-
-
-  /**
-   * WARNING: Do not change the explicit values in the enumerations
-   * below this point. This would result in incompatible databases
-   * between versions of Orthanc!
-   **/
-
-  enum CompressionType
-  {
-    /**
-     * Buffer/file that is stored as-is, in a raw fashion, without
-     * compression.
-     **/
-    CompressionType_None = 1,
-
-    /**
-     * Buffer that is compressed using the "deflate" algorithm (RFC
-     * 1951), wrapped inside the zlib data format (RFC 1950), prefixed
-     * with a "uint64_t" (8 bytes) that encodes the size of the
-     * uncompressed buffer. If the compressed buffer is empty, its
-     * represents an empty uncompressed buffer. This format is
-     * internal to Orthanc. If the 8 first bytes are skipped AND the
-     * buffer is non-empty, the buffer is compatible with the
-     * "deflate" HTTP compression.
-     **/
-    CompressionType_ZlibWithSize = 2
-  };
-
-  enum FileContentType
-  {
-    // If you add a value below, insert it in "PluginStorageArea" in
-    // the file "Plugins/Engine/OrthancPlugins.cpp"
-    FileContentType_Unknown = 0,
-    FileContentType_Dicom = 1,
-    FileContentType_DicomAsJson = 2,
-
-    // Make sure that the value "65535" can be stored into this enumeration
-    FileContentType_StartUser = 1024,
-    FileContentType_EndUser = 65535
-  };
-
-  enum ResourceType
-  {
-    ResourceType_Patient = 1,
-    ResourceType_Study = 2,
-    ResourceType_Series = 3,
-    ResourceType_Instance = 4
-  };
-
-
-  const char* EnumerationToString(ErrorCode code);
-
-  const char* EnumerationToString(HttpMethod method);
-
-  const char* EnumerationToString(HttpStatus status);
-
-  const char* EnumerationToString(ResourceType type);
-
-  const char* EnumerationToString(ImageFormat format);
-
-  const char* EnumerationToString(Encoding encoding);
-
-  const char* EnumerationToString(PhotometricInterpretation photometric);
-
-  const char* EnumerationToString(LogLevel level);
-
-  const char* EnumerationToString(RequestOrigin origin);
-
-  const char* EnumerationToString(PixelFormat format);
-
-  const char* EnumerationToString(ModalityManufacturer manufacturer);
-
-  const char* EnumerationToString(DicomRequestType type);
-
-  const char* EnumerationToString(TransferSyntax syntax);
-
-  const char* EnumerationToString(DicomVersion version);
-
-  const char* EnumerationToString(ValueRepresentation vr);
-
-  Encoding StringToEncoding(const char* encoding);
-
-  ResourceType StringToResourceType(const char* type);
-
-  ImageFormat StringToImageFormat(const char* format);
-
-  LogLevel StringToLogLevel(const char* level);
-
-  ValueRepresentation StringToValueRepresentation(const std::string& vr,
-                                                  bool throwIfUnsupported);
-
-  PhotometricInterpretation StringToPhotometricInterpretation(const char* value);
-
-  ModalityManufacturer StringToModalityManufacturer(const std::string& manufacturer);
-
-  DicomVersion StringToDicomVersion(const std::string& version);
-  
-  unsigned int GetBytesPerPixel(PixelFormat format);
-
-  bool GetDicomEncoding(Encoding& encoding,
-                        const char* specificCharacterSet);
-
-  ResourceType GetChildResourceType(ResourceType type);
-
-  ResourceType GetParentResourceType(ResourceType type);
-
-  DicomModule GetModule(ResourceType type);
-
-  const char* GetDicomSpecificCharacterSet(Encoding encoding);
-
-  HttpStatus ConvertErrorCodeToHttpStatus(ErrorCode error);
-
-  bool IsUserContentType(FileContentType type);
-
-  bool IsBinaryValueRepresentation(ValueRepresentation vr);
-  
-  Encoding GetDefaultDicomEncoding();
-
-  void SetDefaultDicomEncoding(Encoding encoding);
-}
--- a/Resources/Orthanc/Core/FileStorage/FileInfo.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <string>
-#include <stdint.h>
-#include "../Enumerations.h"
-
-namespace Orthanc
-{
-  struct FileInfo
-  {
-  private:
-    std::string uuid_;
-    FileContentType contentType_;
-
-    uint64_t uncompressedSize_;
-    std::string uncompressedMD5_;
-
-    CompressionType compressionType_;
-    uint64_t compressedSize_;
-    std::string compressedMD5_;
-
-  public:
-    FileInfo()
-    {
-    }
-
-    /**
-     * Constructor for an uncompressed attachment.
-     **/
-    FileInfo(const std::string& uuid,
-             FileContentType contentType,
-             uint64_t size,
-             const std::string& md5) :
-      uuid_(uuid),
-      contentType_(contentType),
-      uncompressedSize_(size),
-      uncompressedMD5_(md5),
-      compressionType_(CompressionType_None),
-      compressedSize_(size),
-      compressedMD5_(md5)
-    {
-    }
-
-    /**
-     * Constructor for a compressed attachment.
-     **/
-    FileInfo(const std::string& uuid,
-             FileContentType contentType,
-             uint64_t uncompressedSize,
-             const std::string& uncompressedMD5,
-             CompressionType compressionType,
-             uint64_t compressedSize,
-             const std::string& compressedMD5) :
-      uuid_(uuid),
-      contentType_(contentType),
-      uncompressedSize_(uncompressedSize),
-      uncompressedMD5_(uncompressedMD5),
-      compressionType_(compressionType),
-      compressedSize_(compressedSize),
-      compressedMD5_(compressedMD5)
-    {
-    }
-
-    const std::string& GetUuid() const
-    {
-      return uuid_;
-    }
-
-    FileContentType GetContentType() const
-    {
-      return contentType_;
-    }
-
-    uint64_t GetUncompressedSize() const
-    {
-      return uncompressedSize_;
-    }
-
-    CompressionType GetCompressionType() const
-    {
-      return compressionType_;
-    }
-
-    uint64_t GetCompressedSize() const
-    {
-      return compressedSize_;
-    }
-
-    const std::string& GetCompressedMD5() const
-    {
-      return compressedMD5_;
-    }
-
-    const std::string& GetUncompressedMD5() const
-    {
-      return uncompressedMD5_;
-    }
-  };
-}
--- a/Resources/Orthanc/Core/FileStorage/FilesystemStorage.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,274 +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-2018 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.
- *
- * 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 "FilesystemStorage.h"
-
-// http://stackoverflow.com/questions/1576272/storing-large-number-of-files-in-file-system
-// http://stackoverflow.com/questions/446358/storing-a-large-number-of-images
-
-#include "../Logging.h"
-#include "../OrthancException.h"
-#include "../Toolbox.h"
-#include "../SystemToolbox.h"
-
-#include <boost/filesystem/fstream.hpp>
-
-
-static std::string ToString(const boost::filesystem::path& p)
-{
-#if BOOST_HAS_FILESYSTEM_V3 == 1
-  return p.filename().string();
-#else
-  return p.filename();
-#endif
-}
-
-
-namespace Orthanc
-{
-  boost::filesystem::path FilesystemStorage::GetPath(const std::string& uuid) const
-  {
-    namespace fs = boost::filesystem;
-
-    if (!Toolbox::IsUuid(uuid))
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    fs::path path = root_;
-
-    path /= std::string(&uuid[0], &uuid[2]);
-    path /= std::string(&uuid[2], &uuid[4]);
-    path /= uuid;
-
-#if BOOST_HAS_FILESYSTEM_V3 == 1
-    path.make_preferred();
-#endif
-
-    return path;
-  }
-
-  FilesystemStorage::FilesystemStorage(std::string root)
-  {
-    //root_ = boost::filesystem::absolute(root).string();
-    root_ = root;
-
-    SystemToolbox::MakeDirectory(root);
-  }
-
-
-
-  static const char* GetDescriptionInternal(FileContentType content)
-  {
-    // This function is for logging only (internal use), a more
-    // fully-featured version is available in ServerEnumerations.cpp
-    switch (content)
-    {
-      case FileContentType_Unknown:
-        return "Unknown";
-
-      case FileContentType_Dicom:
-        return "DICOM";
-
-      case FileContentType_DicomAsJson:
-        return "JSON summary of DICOM";
-
-      default:
-        return "User-defined";
-    }
-  }
-
-
-  void FilesystemStorage::Create(const std::string& uuid,
-                                 const void* content, 
-                                 size_t size,
-                                 FileContentType type)
-  {
-    LOG(INFO) << "Creating attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) 
-              << "\" type (size: " << (size / (1024 * 1024) + 1) << "MB)";
-
-    boost::filesystem::path path;
-    
-    path = GetPath(uuid);
-
-    if (boost::filesystem::exists(path))
-    {
-      // Extremely unlikely case: This Uuid has already been created
-      // in the past.
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-    if (boost::filesystem::exists(path.parent_path()))
-    {
-      if (!boost::filesystem::is_directory(path.parent_path()))
-      {
-        throw OrthancException(ErrorCode_DirectoryOverFile);
-      }
-    }
-    else
-    {
-      if (!boost::filesystem::create_directories(path.parent_path()))
-      {
-        throw OrthancException(ErrorCode_FileStorageCannotWrite);
-      }
-    }
-
-    SystemToolbox::WriteFile(content, size, path.string());
-  }
-
-
-  void FilesystemStorage::Read(std::string& content,
-                               const std::string& uuid,
-                               FileContentType type)
-  {
-    LOG(INFO) << "Reading attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) 
-              << "\" content type";
-
-    content.clear();
-    SystemToolbox::ReadFile(content, GetPath(uuid).string());
-  }
-
-
-  uintmax_t FilesystemStorage::GetSize(const std::string& uuid) const
-  {
-    boost::filesystem::path path = GetPath(uuid);
-    return boost::filesystem::file_size(path);
-  }
-
-
-
-  void FilesystemStorage::ListAllFiles(std::set<std::string>& result) const
-  {
-    namespace fs = boost::filesystem;
-
-    result.clear();
-
-    if (fs::exists(root_) && fs::is_directory(root_))
-    {
-      for (fs::recursive_directory_iterator current(root_), end; current != end ; ++current)
-      {
-        if (SystemToolbox::IsRegularFile(current->path().string()))
-        {
-          try
-          {
-            fs::path d = current->path();
-            std::string uuid = ToString(d);
-            if (Toolbox::IsUuid(uuid))
-            {
-              fs::path p0 = d.parent_path().parent_path().parent_path();
-              std::string p1 = ToString(d.parent_path().parent_path());
-              std::string p2 = ToString(d.parent_path());
-              if (p1.length() == 2 &&
-                  p2.length() == 2 &&
-                  p1 == uuid.substr(0, 2) &&
-                  p2 == uuid.substr(2, 2) &&
-                  p0 == root_)
-              {
-                result.insert(uuid);
-              }
-            }
-          }
-          catch (fs::filesystem_error)
-          {
-          }
-        }
-      }
-    }
-  }
-
-
-  void FilesystemStorage::Clear()
-  {
-    namespace fs = boost::filesystem;
-    typedef std::set<std::string> List;
-
-    List result;
-    ListAllFiles(result);
-
-    for (List::const_iterator it = result.begin(); it != result.end(); ++it)
-    {
-      Remove(*it, FileContentType_Unknown /*ignored in this class*/);
-    }
-  }
-
-
-  void FilesystemStorage::Remove(const std::string& uuid,
-                                 FileContentType type)
-  {
-    LOG(INFO) << "Deleting attachment \"" << uuid << "\" of type " << static_cast<int>(type);
-
-    namespace fs = boost::filesystem;
-
-    fs::path p = GetPath(uuid);
-
-    try
-    {
-      fs::remove(p);
-    }
-    catch (...)
-    {
-      // Ignore the error
-    }
-
-    // Remove the two parent directories, ignoring the error code if
-    // these directories are not empty
-
-    try
-    {
-#if BOOST_HAS_FILESYSTEM_V3 == 1
-      boost::system::error_code err;
-      fs::remove(p.parent_path(), err);
-      fs::remove(p.parent_path().parent_path(), err);
-#else
-      fs::remove(p.parent_path());
-      fs::remove(p.parent_path().parent_path());
-#endif
-    }
-    catch (...)
-    {
-      // Ignore the error
-    }
-  }
-
-
-  uintmax_t FilesystemStorage::GetCapacity() const
-  {
-    return boost::filesystem::space(root_).capacity;
-  }
-
-  uintmax_t FilesystemStorage::GetAvailableSpace() const
-  {
-    return boost::filesystem::space(root_).available;
-  }
-}
--- a/Resources/Orthanc/Core/FileStorage/FilesystemStorage.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_SANDBOXED)
-#  error The macro ORTHANC_SANDBOXED must be defined
-#endif
-
-#if ORTHANC_SANDBOXED == 1
-#  error The class FilesystemStorage cannot be used in sandboxed environments
-#endif
-
-#include "IStorageArea.h"
-
-#include <stdint.h>
-#include <boost/filesystem.hpp>
-#include <set>
-
-namespace Orthanc
-{
-  class FilesystemStorage : public IStorageArea
-  {
-    // TODO REMOVE THIS
-    friend class FilesystemHttpSender;
-    friend class FileStorageAccessor;
-
-  private:
-    boost::filesystem::path root_;
-
-    boost::filesystem::path GetPath(const std::string& uuid) const;
-
-  public:
-    explicit FilesystemStorage(std::string root);
-
-    virtual void Create(const std::string& uuid,
-                        const void* content, 
-                        size_t size,
-                        FileContentType type);
-
-    virtual void Read(std::string& content,
-                      const std::string& uuid,
-                      FileContentType type);
-
-    virtual void Remove(const std::string& uuid,
-                        FileContentType type);
-
-    void ListAllFiles(std::set<std::string>& result) const;
-
-    uintmax_t GetSize(const std::string& uuid) const;
-
-    void Clear();
-
-    uintmax_t GetCapacity() const;
-
-    uintmax_t GetAvailableSpace() const;
-  };
-}
--- a/Resources/Orthanc/Core/FileStorage/IStorageArea.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "../Enumerations.h"
-
-#include <string>
-#include <boost/noncopyable.hpp>
-
-namespace Orthanc
-{
-  class IStorageArea : public boost::noncopyable
-  {
-  public:
-    virtual ~IStorageArea()
-    {
-    }
-
-    virtual void Create(const std::string& uuid,
-                        const void* content,
-                        size_t size,
-                        FileContentType type) = 0;
-
-    virtual void Read(std::string& content,
-                      const std::string& uuid,
-                      FileContentType type) = 0;
-
-    virtual void Remove(const std::string& uuid,
-                        FileContentType type) = 0;
-  };
-}
--- a/Resources/Orthanc/Core/FileStorage/StorageAccessor.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,204 +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-2018 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.
- *
- * 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 "StorageAccessor.h"
-
-#include "../Compression/ZlibCompressor.h"
-#include "../OrthancException.h"
-#include "../Toolbox.h"
-#include "../Toolbox.h"
-
-#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
-#  include "../HttpServer/HttpStreamTranscoder.h"
-#endif
-
-namespace Orthanc
-{
-  FileInfo StorageAccessor::Write(const void* data,
-                                  size_t size,
-                                  FileContentType type,
-                                  CompressionType compression,
-                                  bool storeMd5)
-  {
-    std::string uuid = Toolbox::GenerateUuid();
-
-    std::string md5;
-
-    if (storeMd5)
-    {
-      Toolbox::ComputeMD5(md5, data, size);
-    }
-
-    switch (compression)
-    {
-      case CompressionType_None:
-      {
-        area_.Create(uuid, data, size, type);
-        return FileInfo(uuid, type, size, md5);
-      }
-
-      case CompressionType_ZlibWithSize:
-      {
-        ZlibCompressor zlib;
-
-        std::string compressed;
-        zlib.Compress(compressed, data, size);
-
-        std::string compressedMD5;
-      
-        if (storeMd5)
-        {
-          Toolbox::ComputeMD5(compressedMD5, compressed);
-        }
-
-        if (compressed.size() > 0)
-        {
-          area_.Create(uuid, &compressed[0], compressed.size(), type);
-        }
-        else
-        {
-          area_.Create(uuid, NULL, 0, type);
-        }
-
-        return FileInfo(uuid, type, size, md5,
-                        CompressionType_ZlibWithSize, compressed.size(), compressedMD5);
-      }
-
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }
-  }
-
-
-  void StorageAccessor::Read(std::string& content,
-                             const FileInfo& info)
-  {
-    switch (info.GetCompressionType())
-    {
-      case CompressionType_None:
-      {
-        area_.Read(content, info.GetUuid(), info.GetContentType());
-        break;
-      }
-
-      case CompressionType_ZlibWithSize:
-      {
-        ZlibCompressor zlib;
-
-        std::string compressed;
-        area_.Read(compressed, info.GetUuid(), info.GetContentType());
-        IBufferCompressor::Uncompress(content, zlib, compressed);
-        break;
-      }
-
-      default:
-      {
-        throw OrthancException(ErrorCode_NotImplemented);
-      }
-    }
-
-    // TODO Check the validity of the uncompressed MD5?
-  }
-
-
-  void StorageAccessor::Read(Json::Value& content,
-                             const FileInfo& info)
-  {
-    std::string s;
-    Read(s, info);
-
-    Json::Reader reader;
-    if (!reader.parse(s, content))
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-  }
-
-
-#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
-  void StorageAccessor::SetupSender(BufferHttpSender& sender,
-                                    const FileInfo& info,
-                                    const std::string& mime)
-  {
-    area_.Read(sender.GetBuffer(), info.GetUuid(), info.GetContentType());
-    sender.SetContentType(mime);
-
-    const char* extension;
-    switch (info.GetContentType())
-    {
-      case FileContentType_Dicom:
-        extension = ".dcm";
-        break;
-
-      case FileContentType_DicomAsJson:
-        extension = ".json";
-        break;
-
-      default:
-        // Non-standard content type
-        extension = "";
-    }
-
-    sender.SetContentFilename(info.GetUuid() + std::string(extension));
-  }
-#endif
-
-
-#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
-  void StorageAccessor::AnswerFile(HttpOutput& output,
-                                   const FileInfo& info,
-                                   const std::string& mime)
-  {
-    BufferHttpSender sender;
-    SetupSender(sender, info, mime);
-  
-    HttpStreamTranscoder transcoder(sender, info.GetCompressionType());
-    output.Answer(transcoder);
-  }
-#endif
-
-
-#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
-  void StorageAccessor::AnswerFile(RestApiOutput& output,
-                                   const FileInfo& info,
-                                   const std::string& mime)
-  {
-    BufferHttpSender sender;
-    SetupSender(sender, info, mime);
-  
-    HttpStreamTranscoder transcoder(sender, info.GetCompressionType());
-    output.AnswerStream(transcoder);
-  }
-#endif
-}
--- a/Resources/Orthanc/Core/FileStorage/StorageAccessor.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_SANDBOXED)
-#  error The macro ORTHANC_SANDBOXED must be defined
-#endif
-
-#if ORTHANC_SANDBOXED == 1
-#  error The class StorageAccessor cannot be used in sandboxed environments
-#endif
-
-#if !defined(ORTHANC_ENABLE_CIVETWEB)
-#  error Macro ORTHANC_ENABLE_CIVETWEB must be defined to use this file
-#endif
-
-#if !defined(ORTHANC_ENABLE_MONGOOSE)
-#  error Macro ORTHANC_ENABLE_MONGOOSE must be defined to use this file
-#endif
-
-#include "IStorageArea.h"
-#include "FileInfo.h"
-
-#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
-#  include "../HttpServer/BufferHttpSender.h"
-#  include "../RestApi/RestApiOutput.h"
-#endif
-
-#include <vector>
-#include <string>
-#include <boost/noncopyable.hpp>
-#include <stdint.h>
-#include <json/value.h>
-
-namespace Orthanc
-{
-  class StorageAccessor : boost::noncopyable
-  {
-  private:
-    IStorageArea&  area_;
-
-#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
-    void SetupSender(BufferHttpSender& sender,
-                     const FileInfo& info,
-                     const std::string& mime);
-#endif
-
-  public:
-    StorageAccessor(IStorageArea& area) : area_(area)
-    {
-    }
-
-    FileInfo Write(const void* data,
-                   size_t size,
-                   FileContentType type,
-                   CompressionType compression,
-                   bool storeMd5);
-
-    FileInfo Write(const std::string& data, 
-                   FileContentType type,
-                   CompressionType compression,
-                   bool storeMd5)
-    {
-      return Write((data.size() == 0 ? NULL : data.c_str()),
-                   data.size(), type, compression, storeMd5);
-    }
-
-    void Read(std::string& content,
-              const FileInfo& info);
-
-    void Read(Json::Value& content,
-              const FileInfo& info);
-
-    void Remove(const FileInfo& info)
-    {
-      area_.Remove(info.GetUuid(), info.GetContentType());
-    }
-
-#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
-    void AnswerFile(HttpOutput& output,
-                    const FileInfo& info,
-                    const std::string& mime);
-
-    void AnswerFile(RestApiOutput& output,
-                    const FileInfo& info,
-                    const std::string& mime);
-#endif
-  };
-}
--- a/Resources/Orthanc/Core/HttpClient.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,845 +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-2018 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.
- *
- * 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 "HttpClient.h"
-
-#include "Toolbox.h"
-#include "OrthancException.h"
-#include "Logging.h"
-#include "ChunkedBuffer.h"
-#include "SystemToolbox.h"
-
-#include <string.h>
-#include <curl/curl.h>
-#include <boost/algorithm/string/predicate.hpp>
-#include <boost/thread/mutex.hpp>
-
-
-#if ORTHANC_ENABLE_SSL == 1
-// For OpenSSL initialization and finalization
-#  include <openssl/conf.h>
-#  include <openssl/engine.h>
-#  include <openssl/err.h>
-#  include <openssl/evp.h>
-#  include <openssl/ssl.h>
-#endif
-
-
-#if ORTHANC_ENABLE_PKCS11 == 1
-#  include "Pkcs11.h"
-#endif
-
-
-extern "C"
-{
-  static CURLcode GetHttpStatus(CURLcode code, CURL* curl, long* status)
-  {
-    if (code == CURLE_OK)
-    {
-      code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, status);
-      return code;
-    }
-    else
-    {
-      *status = 0;
-      return code;
-    }
-  }
-
-  // This is a dummy wrapper function to suppress any OpenSSL-related
-  // problem in valgrind. Inlining is prevented.
-#if defined(__GNUC__) || defined(__clang__)
-    __attribute__((noinline)) 
-#endif
-    static CURLcode OrthancHttpClientPerformSSL(CURL* curl, long* status)
-  {
-#if ORTHANC_ENABLE_SSL == 1
-    return GetHttpStatus(curl_easy_perform(curl), curl, status);
-#else
-    LOG(ERROR) << "Orthanc was compiled without SSL support, cannot make HTTPS request";
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-#endif
-  }
-}
-
-
-
-namespace Orthanc
-{
-  class HttpClient::GlobalParameters
-  {
-  private:
-    boost::mutex    mutex_;
-    bool            httpsVerifyPeers_;
-    std::string     httpsCACertificates_;
-    std::string     proxy_;
-    long            timeout_;
-
-    GlobalParameters() : 
-      httpsVerifyPeers_(true),
-      timeout_(0)
-    {
-    }
-
-  public:
-    // Singleton pattern
-    static GlobalParameters& GetInstance()
-    {
-      static GlobalParameters parameters;
-      return parameters;
-    }
-
-    void ConfigureSsl(bool httpsVerifyPeers,
-                      const std::string& httpsCACertificates)
-    {
-      boost::mutex::scoped_lock lock(mutex_);
-      httpsVerifyPeers_ = httpsVerifyPeers;
-      httpsCACertificates_ = httpsCACertificates;
-    }
-
-    void GetSslConfiguration(bool& httpsVerifyPeers,
-                             std::string& httpsCACertificates)
-    {
-      boost::mutex::scoped_lock lock(mutex_);
-      httpsVerifyPeers = httpsVerifyPeers_;
-      httpsCACertificates = httpsCACertificates_;
-    }
-
-    void SetDefaultProxy(const std::string& proxy)
-    {
-      LOG(INFO) << "Setting the default proxy for HTTP client connections: " << proxy;
-
-      {
-        boost::mutex::scoped_lock lock(mutex_);
-        proxy_ = proxy;
-      }
-    }
-
-    void GetDefaultProxy(std::string& target)
-    {
-      boost::mutex::scoped_lock lock(mutex_);
-      target = proxy_;
-    }
-
-    void SetDefaultTimeout(long seconds)
-    {
-      LOG(INFO) << "Setting the default timeout for HTTP client connections: " << seconds << " seconds";
-
-      {
-        boost::mutex::scoped_lock lock(mutex_);
-        timeout_ = seconds;
-      }
-    }
-
-    long GetDefaultTimeout()
-    {
-      boost::mutex::scoped_lock lock(mutex_);
-      return timeout_;
-    }
-
-#if ORTHANC_ENABLE_PKCS11 == 1
-    bool IsPkcs11Initialized()
-    {
-      boost::mutex::scoped_lock lock(mutex_);
-      return Pkcs11::IsInitialized();
-    }
-
-    void InitializePkcs11(const std::string& module,
-                          const std::string& pin,
-                          bool verbose)
-    {
-      boost::mutex::scoped_lock lock(mutex_);
-      Pkcs11::Initialize(module, pin, verbose);
-    }
-#endif
-  };
-
-
-  struct HttpClient::PImpl
-  {
-    CURL* curl_;
-    struct curl_slist *defaultPostHeaders_;
-    struct curl_slist *userHeaders_;
-  };
-
-
-  static void ThrowException(HttpStatus status)
-  {
-    switch (status)
-    {
-      case HttpStatus_400_BadRequest:
-        throw OrthancException(ErrorCode_BadRequest);
-
-      case HttpStatus_401_Unauthorized:
-      case HttpStatus_403_Forbidden:
-        throw OrthancException(ErrorCode_Unauthorized);
-
-      case HttpStatus_404_NotFound:
-        throw OrthancException(ErrorCode_UnknownResource);
-
-      default:
-        throw OrthancException(ErrorCode_NetworkProtocol);
-    }
-  }
-
-
-  static CURLcode CheckCode(CURLcode code)
-  {
-    if (code == CURLE_NOT_BUILT_IN)
-    {
-      LOG(ERROR) << "Your libcurl does not contain a required feature, "
-                 << "please recompile Orthanc with -DUSE_SYSTEM_CURL=OFF";
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-    if (code != CURLE_OK)
-    {
-      LOG(ERROR) << "libCURL error: " + std::string(curl_easy_strerror(code));
-      throw OrthancException(ErrorCode_NetworkProtocol);
-    }
-
-    return code;
-  }
-
-
-  static size_t CurlBodyCallback(void *buffer, size_t size, size_t nmemb, void *payload)
-  {
-    ChunkedBuffer& target = *(static_cast<ChunkedBuffer*>(payload));
-
-    size_t length = size * nmemb;
-    if (length == 0)
-    {
-      return 0;
-    }
-    else
-    {
-      target.AddChunk(buffer, length);
-      return length;
-    }
-  }
-
-
-  struct CurlHeaderParameters
-  {
-    bool lowerCase_;
-    HttpClient::HttpHeaders* headers_;
-  };
-
-
-  static size_t CurlHeaderCallback(void *buffer, size_t size, size_t nmemb, void *payload)
-  {
-    CurlHeaderParameters& parameters = *(static_cast<CurlHeaderParameters*>(payload));
-    assert(parameters.headers_ != NULL);
-
-    size_t length = size * nmemb;
-    if (length == 0)
-    {
-      return 0;
-    }
-    else
-    {
-      std::string s(reinterpret_cast<const char*>(buffer), length);
-      std::size_t colon = s.find(':');
-      std::size_t eol = s.find("\r\n");
-      if (colon != std::string::npos &&
-          eol != std::string::npos)
-      {
-        std::string tmp(s.substr(0, colon));
-
-        if (parameters.lowerCase_)
-        {
-          Toolbox::ToLowerCase(tmp);
-        }
-
-        std::string key = Toolbox::StripSpaces(tmp);
-
-        if (!key.empty())
-        {
-          std::string value = Toolbox::StripSpaces(s.substr(colon + 1, eol));
-          (*parameters.headers_) [key] = value;
-        }
-      }
-
-      return length;
-    }
-  }
-
-
-  void HttpClient::Setup()
-  {
-    pimpl_->userHeaders_ = NULL;
-    pimpl_->defaultPostHeaders_ = NULL;
-    if ((pimpl_->defaultPostHeaders_ = curl_slist_append(pimpl_->defaultPostHeaders_, "Expect:")) == NULL)
-    {
-      throw OrthancException(ErrorCode_NotEnoughMemory);
-    }
-
-    pimpl_->curl_ = curl_easy_init();
-    if (!pimpl_->curl_)
-    {
-      curl_slist_free_all(pimpl_->defaultPostHeaders_);
-      throw OrthancException(ErrorCode_NotEnoughMemory);
-    }
-
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_WRITEFUNCTION, &CurlBodyCallback));
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADER, 0));
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_FOLLOWLOCATION, 1));
-
-    // This fixes the "longjmp causes uninitialized stack frame" crash
-    // that happens on modern Linux versions.
-    // http://stackoverflow.com/questions/9191668/error-longjmp-causes-uninitialized-stack-frame
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_NOSIGNAL, 1));
-
-    url_ = "";
-    method_ = HttpMethod_Get;
-    lastStatus_ = HttpStatus_200_Ok;
-    SetVerbose(false);
-    timeout_ = GlobalParameters::GetInstance().GetDefaultTimeout();
-    GlobalParameters::GetInstance().GetDefaultProxy(proxy_);
-    GlobalParameters::GetInstance().GetSslConfiguration(verifyPeers_, caCertificates_);    
-  }
-
-
-  HttpClient::HttpClient() : 
-    pimpl_(new PImpl), 
-    verifyPeers_(true),
-    pkcs11Enabled_(false),
-    headersToLowerCase_(true),
-    redirectionFollowed_(true)
-  {
-    Setup();
-  }
-
-
-  HttpClient::HttpClient(const WebServiceParameters& service,
-                         const std::string& uri) : 
-    pimpl_(new PImpl), 
-    verifyPeers_(true),
-    headersToLowerCase_(true),
-    redirectionFollowed_(true)
-  {
-    Setup();
-
-    if (service.GetUsername().size() != 0 && 
-        service.GetPassword().size() != 0)
-    {
-      SetCredentials(service.GetUsername().c_str(), 
-                     service.GetPassword().c_str());
-    }
-
-    if (!service.GetCertificateFile().empty())
-    {
-      SetClientCertificate(service.GetCertificateFile(),
-                           service.GetCertificateKeyFile(),
-                           service.GetCertificateKeyPassword());
-    }
-
-    SetPkcs11Enabled(service.IsPkcs11Enabled());
-
-    SetUrl(service.GetUrl() + uri);
-  }
-
-
-  HttpClient::~HttpClient()
-  {
-    curl_easy_cleanup(pimpl_->curl_);
-    curl_slist_free_all(pimpl_->defaultPostHeaders_);
-    ClearHeaders();
-  }
-
-
-  void HttpClient::SetVerbose(bool isVerbose)
-  {
-    isVerbose_ = isVerbose;
-
-    if (isVerbose_)
-    {
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_VERBOSE, 1));
-    }
-    else
-    {
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_VERBOSE, 0));
-    }
-  }
-
-
-  void HttpClient::AddHeader(const std::string& key,
-                             const std::string& value)
-  {
-    if (key.empty())
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    std::string s = key + ": " + value;
-
-    if ((pimpl_->userHeaders_ = curl_slist_append(pimpl_->userHeaders_, s.c_str())) == NULL)
-    {
-      throw OrthancException(ErrorCode_NotEnoughMemory);
-    }
-  }
-
-
-  void HttpClient::ClearHeaders()
-  {
-    if (pimpl_->userHeaders_ != NULL)
-    {
-      curl_slist_free_all(pimpl_->userHeaders_);
-      pimpl_->userHeaders_ = NULL;
-    }
-  }
-
-
-  bool HttpClient::ApplyInternal(std::string& answerBody,
-                                 HttpHeaders* answerHeaders)
-  {
-    answerBody.clear();
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_URL, url_.c_str()));
-
-    CurlHeaderParameters headerParameters;
-
-    if (answerHeaders == NULL)
-    {
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERFUNCTION, NULL));
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERDATA, NULL));
-    }
-    else
-    {
-      headerParameters.lowerCase_ = headersToLowerCase_;
-      headerParameters.headers_ = answerHeaders;
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERFUNCTION, &CurlHeaderCallback));
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HEADERDATA, &headerParameters));
-    }
-
-#if ORTHANC_ENABLE_SSL == 1
-    // Setup HTTPS-related options
-
-    if (verifyPeers_)
-    {
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_CAINFO, caCertificates_.c_str()));
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYHOST, 2));  // libcurl default is strict verifyhost
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 1)); 
-    }
-    else
-    {
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYHOST, 0)); 
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSL_VERIFYPEER, 0)); 
-    }
-#endif
-
-    // Setup the HTTPS client certificate
-    if (!clientCertificateFile_.empty() &&
-        pkcs11Enabled_)
-    {
-      LOG(ERROR) << "Cannot enable both client certificates and PKCS#11 authentication";
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    if (pkcs11Enabled_)
-    {
-#if ORTHANC_ENABLE_PKCS11 == 1
-      if (GlobalParameters::GetInstance().IsPkcs11Initialized())
-      {
-        CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLENGINE, Pkcs11::GetEngineIdentifier()));
-        CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLKEYTYPE, "ENG"));
-        CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLCERTTYPE, "ENG"));
-      }
-      else
-      {
-        LOG(ERROR) << "Cannot use PKCS#11 for a HTTPS request, because it has not been initialized";
-        throw OrthancException(ErrorCode_BadSequenceOfCalls);
-      }
-#else
-      LOG(ERROR) << "This version of Orthanc is compiled without support for PKCS#11";
-      throw OrthancException(ErrorCode_InternalError);
-#endif
-    }
-    else if (!clientCertificateFile_.empty())
-    {
-#if ORTHANC_ENABLE_SSL == 1
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLCERTTYPE, "PEM"));
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLCERT, clientCertificateFile_.c_str()));
-
-      if (!clientCertificateKeyPassword_.empty())
-      {
-        CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_KEYPASSWD, clientCertificateKeyPassword_.c_str()));
-      }
-
-      // NB: If no "clientKeyFile_" is provided, the key must be
-      // prepended to the certificate file
-      if (!clientCertificateKeyFile_.empty())
-      {
-        CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLKEYTYPE, "PEM"));
-        CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_SSLKEY, clientCertificateKeyFile_.c_str()));
-      }
-#else
-      LOG(ERROR) << "This version of Orthanc is compiled without OpenSSL support, cannot use HTTPS client authentication";
-      throw OrthancException(ErrorCode_InternalError);
-#endif
-    }
-
-    // Reset the parameters from previous calls to Apply()
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HTTPHEADER, pimpl_->userHeaders_));
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HTTPGET, 0L));
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POST, 0L));
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_NOBODY, 0L));
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_CUSTOMREQUEST, NULL));
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POSTFIELDS, NULL));
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POSTFIELDSIZE, 0L));
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_PROXY, NULL));
-
-    if (redirectionFollowed_)
-    {
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_FOLLOWLOCATION, 1L));
-    }
-    else
-    {
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_FOLLOWLOCATION, 0L));
-    }
-
-    // Set timeouts
-    if (timeout_ <= 0)
-    {
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_TIMEOUT, 10));  /* default: 10 seconds */
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_CONNECTTIMEOUT, 10));  /* default: 10 seconds */
-    }
-    else
-    {
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_TIMEOUT, timeout_));
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_CONNECTTIMEOUT, timeout_));
-    }
-
-    if (credentials_.size() != 0)
-    {
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_USERPWD, credentials_.c_str()));
-    }
-
-    if (proxy_.size() != 0)
-    {
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_PROXY, proxy_.c_str()));
-    }
-
-    switch (method_)
-    {
-    case HttpMethod_Get:
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HTTPGET, 1L));
-      break;
-
-    case HttpMethod_Post:
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POST, 1L));
-
-      if (pimpl_->userHeaders_ == NULL)
-      {
-        CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HTTPHEADER, pimpl_->defaultPostHeaders_));
-      }
-
-      break;
-
-    case HttpMethod_Delete:
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_NOBODY, 1L));
-      CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_CUSTOMREQUEST, "DELETE"));
-      break;
-
-    case HttpMethod_Put:
-      // http://stackoverflow.com/a/7570281/881731: Don't use
-      // CURLOPT_PUT if there is a body
-
-      // CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_PUT, 1L));
-
-      curl_easy_setopt(pimpl_->curl_, CURLOPT_CUSTOMREQUEST, "PUT"); /* !!! */
-
-      if (pimpl_->userHeaders_ == NULL)
-      {
-        CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_HTTPHEADER, pimpl_->defaultPostHeaders_));
-      }
-
-      break;
-
-    default:
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-
-    if (method_ == HttpMethod_Post ||
-        method_ == HttpMethod_Put)
-    {
-      if (body_.size() > 0)
-      {
-        CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POSTFIELDS, body_.c_str()));
-        CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POSTFIELDSIZE, body_.size()));
-      }
-      else
-      {
-        CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POSTFIELDS, NULL));
-        CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_POSTFIELDSIZE, 0));
-      }
-    }
-
-
-    // Do the actual request
-    CURLcode code;
-    long status = 0;
-
-    ChunkedBuffer buffer;
-    CheckCode(curl_easy_setopt(pimpl_->curl_, CURLOPT_WRITEDATA, &buffer));
-
-    if (boost::starts_with(url_, "https://"))
-    {
-      code = OrthancHttpClientPerformSSL(pimpl_->curl_, &status);
-    }
-    else
-    {
-      code = GetHttpStatus(curl_easy_perform(pimpl_->curl_), pimpl_->curl_, &status);
-    }
-
-    CheckCode(code);
-
-    if (status == 0)
-    {
-      // This corresponds to a call to an inexistent host
-      lastStatus_ = HttpStatus_500_InternalServerError;
-    }
-    else
-    {
-      lastStatus_ = static_cast<HttpStatus>(status);
-    }
-
-    bool success = (status >= 200 && status < 300);
-
-    if (success)
-    {
-      buffer.Flatten(answerBody);
-    }
-    else
-    {
-      answerBody.clear();
-      LOG(INFO) << "Error in HTTP request, received HTTP status " << status 
-                << " (" << EnumerationToString(lastStatus_) << ")";
-    }
-
-    return success;
-  }
-
-
-  bool HttpClient::ApplyInternal(Json::Value& answerBody,
-                                 HttpClient::HttpHeaders* answerHeaders)
-  {
-    std::string s;
-    if (ApplyInternal(s, answerHeaders))
-    {
-      Json::Reader reader;
-      return reader.parse(s, answerBody);
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-
-  void HttpClient::SetCredentials(const char* username,
-                                  const char* password)
-  {
-    credentials_ = std::string(username) + ":" + std::string(password);
-  }
-
-
-  void HttpClient::ConfigureSsl(bool httpsVerifyPeers,
-                                const std::string& httpsVerifyCertificates)
-  {
-#if ORTHANC_ENABLE_SSL == 1
-    if (httpsVerifyPeers)
-    {
-      if (httpsVerifyCertificates.empty())
-      {
-        LOG(WARNING) << "No certificates are provided to validate peers, "
-                     << "set \"HttpsCACertificates\" if you need to do HTTPS requests";
-      }
-      else
-      {
-        LOG(WARNING) << "HTTPS will use the CA certificates from this file: " << httpsVerifyCertificates;
-      }
-    }
-    else
-    {
-      LOG(WARNING) << "The verification of the peers in HTTPS requests is disabled";
-    }
-#endif
-
-    GlobalParameters::GetInstance().ConfigureSsl(httpsVerifyPeers, httpsVerifyCertificates);
-  }
-
-  
-  void HttpClient::GlobalInitialize()
-  {
-#if ORTHANC_ENABLE_SSL == 1
-    CheckCode(curl_global_init(CURL_GLOBAL_ALL));
-#else
-    CheckCode(curl_global_init(CURL_GLOBAL_ALL & ~CURL_GLOBAL_SSL));
-#endif
-  }
-
-
-  void HttpClient::GlobalFinalize()
-  {
-    curl_global_cleanup();
-
-#if ORTHANC_ENABLE_PKCS11 == 1
-    Pkcs11::Finalize();
-#endif
-  }
-  
-
-  void HttpClient::SetDefaultProxy(const std::string& proxy)
-  {
-    GlobalParameters::GetInstance().SetDefaultProxy(proxy);
-  }
-
-
-  void HttpClient::SetDefaultTimeout(long timeout)
-  {
-    GlobalParameters::GetInstance().SetDefaultTimeout(timeout);
-  }
-
-
-  void HttpClient::ApplyAndThrowException(std::string& answerBody)
-  {
-    if (!Apply(answerBody))
-    {
-      ThrowException(GetLastStatus());
-    }
-  }
-
-  
-  void HttpClient::ApplyAndThrowException(Json::Value& answerBody)
-  {
-    if (!Apply(answerBody))
-    {
-      ThrowException(GetLastStatus());
-    }
-  }
-
-
-  void HttpClient::ApplyAndThrowException(std::string& answerBody,
-                                          HttpHeaders& answerHeaders)
-  {
-    if (!Apply(answerBody, answerHeaders))
-    {
-      ThrowException(GetLastStatus());
-    }
-  }
-  
-
-  void HttpClient::ApplyAndThrowException(Json::Value& answerBody,
-                                          HttpHeaders& answerHeaders)
-  {
-    if (!Apply(answerBody, answerHeaders))
-    {
-      ThrowException(GetLastStatus());
-    }
-  }
-
-
-  void HttpClient::SetClientCertificate(const std::string& certificateFile,
-                                        const std::string& certificateKeyFile,
-                                        const std::string& certificateKeyPassword)
-  {
-    if (certificateFile.empty())
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    if (!SystemToolbox::IsRegularFile(certificateFile))
-    {
-      LOG(ERROR) << "Cannot open certificate file: " << certificateFile;
-      throw OrthancException(ErrorCode_InexistentFile);
-    }
-
-    if (!certificateKeyFile.empty() && 
-        !SystemToolbox::IsRegularFile(certificateKeyFile))
-    {
-      LOG(ERROR) << "Cannot open key file: " << certificateKeyFile;
-      throw OrthancException(ErrorCode_InexistentFile);
-    }
-
-    clientCertificateFile_ = certificateFile;
-    clientCertificateKeyFile_ = certificateKeyFile;
-    clientCertificateKeyPassword_ = certificateKeyPassword;
-  }
-
-
-  void HttpClient::InitializePkcs11(const std::string& module,
-                                    const std::string& pin,
-                                    bool verbose)
-  {
-#if ORTHANC_ENABLE_PKCS11 == 1
-    LOG(INFO) << "Initializing PKCS#11 using " << module 
-              << (pin.empty() ? " (no PIN provided)" : " (PIN is provided)");
-    GlobalParameters::GetInstance().InitializePkcs11(module, pin, verbose);    
-#else
-    LOG(ERROR) << "This version of Orthanc is compiled without support for PKCS#11";
-    throw OrthancException(ErrorCode_InternalError);
-#endif
-  }
-
-
-  void HttpClient::InitializeOpenSsl()
-  {
-#if ORTHANC_ENABLE_SSL == 1
-    // https://wiki.openssl.org/index.php/Library_Initialization
-    SSL_library_init();
-    SSL_load_error_strings();
-    OpenSSL_add_all_algorithms();
-    ERR_load_crypto_strings();
-#endif
-  }
-
-
-  void HttpClient::FinalizeOpenSsl()
-  {
-#if ORTHANC_ENABLE_SSL == 1
-    // Finalize OpenSSL
-    // https://wiki.openssl.org/index.php/Library_Initialization#Cleanup
-#ifdef FIPS_mode_set
-    FIPS_mode_set(0);
-#endif
-    ENGINE_cleanup();
-    CONF_modules_unload(1);
-    EVP_cleanup();
-    CRYPTO_cleanup_all_ex_data();
-    ERR_remove_state(0);
-    ERR_free_strings();
-#endif
-  }
-}
--- a/Resources/Orthanc/Core/HttpClient.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,296 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "Enumerations.h"
-#include "WebServiceParameters.h"
-
-#include <string>
-#include <boost/shared_ptr.hpp>
-#include <json/json.h>
-
-#if !defined(ORTHANC_ENABLE_SSL)
-#  error The macro ORTHANC_ENABLE_SSL must be defined
-#endif
-
-#if !defined(ORTHANC_ENABLE_PKCS11)
-#  error The macro ORTHANC_ENABLE_PKCS11 must be defined
-#endif
-
-
-namespace Orthanc
-{
-  class HttpClient
-  {
-  public:
-    typedef std::map<std::string, std::string>  HttpHeaders;
-
-  private:
-    class GlobalParameters;
-
-    struct PImpl;
-    boost::shared_ptr<PImpl> pimpl_;
-
-    std::string url_;
-    std::string credentials_;
-    HttpMethod method_;
-    HttpStatus lastStatus_;
-    std::string body_;  // This only makes sense for POST and PUT requests
-    bool isVerbose_;
-    long timeout_;
-    std::string proxy_;
-    bool verifyPeers_;
-    std::string caCertificates_;
-    std::string clientCertificateFile_;
-    std::string clientCertificateKeyFile_;
-    std::string clientCertificateKeyPassword_;
-    bool pkcs11Enabled_;
-    bool headersToLowerCase_;
-    bool redirectionFollowed_;
-
-    void Setup();
-
-    void operator= (const HttpClient&);  // Assignment forbidden
-    HttpClient(const HttpClient& base);  // Copy forbidden
-
-    bool ApplyInternal(std::string& answerBody,
-                       HttpHeaders* answerHeaders);
-
-    bool ApplyInternal(Json::Value& answerBody,
-                       HttpHeaders* answerHeaders);
-
-  public:
-    HttpClient();
-
-    HttpClient(const WebServiceParameters& service,
-               const std::string& uri);
-
-    ~HttpClient();
-
-    void SetUrl(const char* url)
-    {
-      url_ = std::string(url);
-    }
-
-    void SetUrl(const std::string& url)
-    {
-      url_ = url;
-    }
-
-    const std::string& GetUrl() const
-    {
-      return url_;
-    }
-
-    void SetMethod(HttpMethod method)
-    {
-      method_ = method;
-    }
-
-    HttpMethod GetMethod() const
-    {
-      return method_;
-    }
-
-    void SetTimeout(long seconds)
-    {
-      timeout_ = seconds;
-    }
-
-    long GetTimeout() const
-    {
-      return timeout_;
-    }
-
-    void SetBody(const std::string& data)
-    {
-      body_ = data;
-    }
-
-    std::string& GetBody()
-    {
-      return body_;
-    }
-
-    const std::string& GetBody() const
-    {
-      return body_;
-    }
-
-    void SetVerbose(bool isVerbose);
-
-    bool IsVerbose() const
-    {
-      return isVerbose_;
-    }
-
-    void AddHeader(const std::string& key,
-                   const std::string& value);
-
-    void ClearHeaders();
-
-    bool Apply(std::string& answerBody)
-    {
-      return ApplyInternal(answerBody, NULL);
-    }
-
-    bool Apply(Json::Value& answerBody)
-    {
-      return ApplyInternal(answerBody, NULL);
-    }
-
-    bool Apply(std::string& answerBody,
-               HttpHeaders& answerHeaders)
-    {
-      return ApplyInternal(answerBody, &answerHeaders);
-    }
-
-    bool Apply(Json::Value& answerBody,
-               HttpHeaders& answerHeaders)
-    {
-      return ApplyInternal(answerBody, &answerHeaders);
-    }
-
-    HttpStatus GetLastStatus() const
-    {
-      return lastStatus_;
-    }
-
-    void SetCredentials(const char* username,
-                        const char* password);
-
-    void SetProxy(const std::string& proxy)
-    {
-      proxy_ = proxy;
-    }
-
-    void SetHttpsVerifyPeers(bool verify)
-    {
-      verifyPeers_ = verify;
-    }
-
-    bool IsHttpsVerifyPeers() const
-    {
-      return verifyPeers_;
-    }
-
-    void SetHttpsCACertificates(const std::string& certificates)
-    {
-      caCertificates_ = certificates;
-    }
-
-    const std::string& GetHttpsCACertificates() const
-    {
-      return caCertificates_;
-    }
-
-    void SetClientCertificate(const std::string& certificateFile,
-                              const std::string& certificateKeyFile,
-                              const std::string& certificateKeyPassword);
-
-    void SetPkcs11Enabled(bool enabled)
-    {
-      pkcs11Enabled_ = enabled;
-    }
-
-    bool IsPkcs11Enabled() const
-    {
-      return pkcs11Enabled_;
-    }
-
-    const std::string& GetClientCertificateFile() const
-    {
-      return clientCertificateFile_;
-    }
-
-    const std::string& GetClientCertificateKeyFile() const
-    {
-      return clientCertificateKeyFile_;
-    }
-
-    const std::string& GetClientCertificateKeyPassword() const
-    {
-      return clientCertificateKeyPassword_;
-    }
-
-    void SetConvertHeadersToLowerCase(bool lowerCase)
-    {
-      headersToLowerCase_ = lowerCase;
-    }
-
-    bool IsConvertHeadersToLowerCase() const
-    {
-      return headersToLowerCase_;
-    }
-
-    void SetRedirectionFollowed(bool follow)
-    {
-      redirectionFollowed_ = follow;
-    }
-
-    bool IsRedirectionFollowed() const
-    {
-      return redirectionFollowed_;
-    }
-
-    static void GlobalInitialize();
-  
-    static void GlobalFinalize();
-
-    static void InitializeOpenSsl();
-
-    static void FinalizeOpenSsl();
-
-    static void InitializePkcs11(const std::string& module,
-                                 const std::string& pin,
-                                 bool verbose);
-
-    static void ConfigureSsl(bool httpsVerifyPeers,
-                             const std::string& httpsCACertificates);
-
-    static void SetDefaultProxy(const std::string& proxy);
-
-    static void SetDefaultTimeout(long timeout);
-
-    void ApplyAndThrowException(std::string& answerBody);
-
-    void ApplyAndThrowException(Json::Value& answerBody);
-
-    void ApplyAndThrowException(std::string& answerBody,
-                                HttpHeaders& answerHeaders);
-
-    void ApplyAndThrowException(Json::Value& answerBody,
-                                HttpHeaders& answerHeaders);
-  };
-}
--- a/Resources/Orthanc/Core/ICommand.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "IDynamicObject.h"
-
-namespace Orthanc
-{
-  /**
-   * This class is the base class for the "Command" design pattern.
-   * http://en.wikipedia.org/wiki/Command_pattern
-   **/
-  class ICommand : public IDynamicObject
-  {
-  public:
-    virtual bool Execute() = 0;
-  };
-}
--- a/Resources/Orthanc/Core/IDynamicObject.h	Mon May 21 09:02:03 2018 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <boost/noncopyable.hpp>
-
-namespace Orthanc
-{
-  /**
-   * This class should be the ancestor to any class whose type is
-   * determined at the runtime, and that can be dynamically allocated.
-   * Being a child of IDynamicObject only implies the existence of a
-   * virtual destructor.
-   **/
-  class IDynamicObject : public boost::noncopyable
-  {
-  public:
-    virtual ~IDynamicObject()
-    {
-    }
-  };
-}
--- a/Resources/Orthanc/Core/Images/Font.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,318 +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-2018 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.
- *
- * 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 "Font.h"
-
-#if !defined(ORTHANC_ENABLE_LOCALE)
-#  error ORTHANC_ENABLE_LOCALE must be defined to use this file
-#endif
-
-#if ORTHANC_SANDBOXED == 0
-#  include "../SystemToolbox.h"
-#endif
-
-#include "../Toolbox.h"
-#include "../OrthancException.h"
-
-#include <stdio.h>
-#include <memory>
-#include <boost/lexical_cast.hpp>
-
-namespace Orthanc
-{
-  Font::~Font()
-  {
-    for (Characters::iterator it = characters_.begin();
-         it != characters_.end(); ++it)
-    {
-      delete it->second;
-    }
-  }
-
-
-  void Font::LoadFromMemory(const std::string& font)
-  {
-    Json::Value v;
-    Json::Reader reader;
-    if (!reader.parse(font, v) ||
-        v.type() != Json::objectValue ||
-        !v.isMember("Name") ||
-        !v.isMember("Size") ||
-        !v.isMember("Characters") ||
-        v["Name"].type() != Json::stringValue ||
-        v["Size"].type() != Json::intValue ||
-        v["Characters"].type() != Json::objectValue)
-    {
-      throw OrthancException(ErrorCode_BadFont);
-    }
-
-    name_ = v["Name"].asString();
-    size_ = v["Size"].asUInt();
-    maxHeight_ = 0;
-
-    Json::Value::Members characters = v["Characters"].getMemberNames();
-
-    for (size_t i = 0; i < characters.size(); i++)
-    {
-      const Json::Value& info = v["Characters"][characters[i]];
-      if (info.type() != Json::objectValue ||
-          !info.isMember("Advance") ||
-          !info.isMember("Bitmap") ||
-          !info.isMember("Height") ||
-          !info.isMember("Top") ||
-          !info.isMember("Width") ||
-          info["Advance"].type() != Json::intValue ||
-          info["Bitmap"].type() != Json::arrayValue ||
-          info["Height"].type() != Json::intValue ||
-          info["Top"].type() != Json::intValue ||
-          info["Width"].type() != Json::intValue)
-      {
-        throw OrthancException(ErrorCode_BadFont);
-      }
-
-      std::auto_ptr<Character> c(new Character);
-      
-      c->advance_ = info["Advance"].asUInt();
-      c->height_ = info["Height"].asUInt();
-      c->top_ = info["Top"].asUInt();
-      c->width_ = info["Width"].asUInt();
-      c->bitmap_.resize(info["Bitmap"].size());
-
-      if (c->height_ > maxHeight_)
-      {
-        maxHeight_ = c->height_;
-      }
-      
-      for (Json::Value::ArrayIndex j = 0; j < info["Bitmap"].size(); j++)
-      {
-        if (info["Bitmap"][j].type() != Json::intValue)
-        {
-          throw OrthancException(ErrorCode_BadFont);
-        }
-
-        int value = info["Bitmap"][j].asInt();
-        if (value < 0 || value > 255)
-        {
-          throw OrthancException(ErrorCode_BadFont);
-        }
-
-        c->bitmap_[j] = static_cast<uint8_t>(value);
-      }
-
-      int index = boost::lexical_cast<int>(characters[i]);
-      if (index < 0 || index > 255)
-      {
-        throw OrthancException(ErrorCode_BadFont);
-      }
-
-      characters_[static_cast<char>(index)] = c.release();
-    }
-  }
-
-
-#if ORTHANC_SANDBOXED == 0
-  void Font::LoadFromFile(const std::string& path)
-  {
-    std::string font;
-    SystemToolbox::ReadFile(font, path);
-    LoadFromMemory(font);
-  }
-#endif
-
-
-  static unsigned int MyMin(unsigned int a, 
-                            unsigned int b)
-  {
-    return a < b ? a : b;
-  }
-
-
-  void Font::DrawCharacter(ImageAccessor& target,
-                           const Character& character,
-                           int x,
-                           int y,
-                           const uint8_t color[4]) const
-  {
-    // Compute the bounds of the character
-    if (x >= static_cast<int>(target.GetWidth()) ||
-        y >= static_cast<int>(target.GetHeight()))
-    {
-      // The character is out of the image
-      return;
-    }
-
-    unsigned int left = x < 0 ? -x : 0;
-    unsigned int top = y < 0 ? -y : 0;
-    unsigned int width = MyMin(character.width_, target.GetWidth() - x);
-    unsigned int height = MyMin(character.height_, target.GetHeight() - y);
-
-    unsigned int bpp = target.GetBytesPerPixel();
-
-    // Blit the font bitmap OVER the target image
-    // https://en.wikipedia.org/wiki/Alpha_compositing
-
-    for (unsigned int cy = top; cy < height; cy++)
-    {
-      uint8_t* p = reinterpret_cast<uint8_t*>(target.GetRow(y + cy)) + (x + left) * bpp;
-      unsigned int pos = cy * character.width_ + left;
-
-      switch (target.GetFormat())
-      {
-        case PixelFormat_Grayscale8:
-        {
-          assert(bpp == 1);
-          for (unsigned int cx = left; cx < width; cx++, pos++, p++)
-          {
-            uint16_t alpha = character.bitmap_[pos];
-            uint16_t value = alpha * static_cast<uint16_t>(color[0]) + (255 - alpha) * static_cast<uint16_t>(*p);
-            *p = static_cast<uint8_t>(value >> 8);
-          }
-
-          break;
-        }
-
-        case PixelFormat_RGB24:
-        {
-          assert(bpp == 3);
-          for (unsigned int cx = left; cx < width; cx++, pos++, p += 3)
-          {
-            uint16_t alpha = character.bitmap_[pos];
-            for (uint8_t i = 0; i < 3; i++)
-            {
-              uint16_t value = alpha * static_cast<uint16_t>(color[i]) + (255 - alpha) * static_cast<uint16_t>(p[i]);
-              p[i] = static_cast<uint8_t>(value >> 8);
-            }
-          }
-
-          break;
-        }
-
-        case PixelFormat_RGBA32:
-        {
-          assert(bpp == 4);
-
-          for (unsigned int cx = left; cx < width; cx++, pos++, p += 4)
-          {
-            float alpha = static_cast<float>(character.bitmap_[pos]) / 255.0f;
-            float beta = (1.0f - alpha) * static_cast<float>(p[3]) / 255.0f;
-            float denom = 1.0f / (alpha + beta);
-
-            for (uint8_t i = 0; i < 3; i++)
-            {
-              p[i] = static_cast<uint8_t>((alpha * static_cast<float>(color[i]) +
-                                           beta * static_cast<float>(p[i])) * denom);
-            }
-
-            p[3] = static_cast<uint8_t>(255.0f * (alpha + beta));
-          }
-
-          break;
-        }
-
-        default:
-          throw OrthancException(ErrorCode_NotImplemented);
-      }
-    }
-
-  }
-
-
-  void Font::DrawInternal(ImageAccessor& target,
-                          const std::string& utf8,
-                          int x,
-                          int y,
-                          const uint8_t color[4]) const
-  {
-    if (target.GetFormat() != PixelFormat_Grayscale8 &&
-        target.GetFormat() != PixelFormat_RGB24 &&
-        target.GetFormat() != PixelFormat_RGBA32)
-    {
-      throw OrthancException(ErrorCode_NotImplemented);
-    }
-
-    int a = x;
-
-#if ORTHANC_ENABLE_LOCALE == 1
-    std::string s = Toolbox::ConvertFromUtf8(utf8, Encoding_Latin1);
-#else
-    // If the locale support is disabled, simply drop non-ASCII
-    // characters from the source UTF-8 string
-    std::string s = Toolbox::ConvertToAscii(utf8);
-#endif
-
-    for (size_t i = 0; i < s.size(); i++)
-    {
-      if (s[i] == '\n')
-      {
-        // Go to the next line
-        a = x;
-        y += maxHeight_ + 1;
-      }
-      else
-      {
-        Characters::const_iterator c = characters_.find(s[i]);
-        if (c != characters_.end())
-        {
-          DrawCharacter(target, *c->second, a, y + static_cast<int>(c->second->top_), color);
-          a += c->second->advance_;
-        }
-      }
-    }
-  }
-
-
-  void Font::Draw(ImageAccessor& target,
-                  const std::string& utf8,
-                  int x,
-                  int y,
-                  uint8_t grayscale) const
-  {
-    uint8_t color[4] = { grayscale, grayscale, grayscale, 255 };
-    DrawInternal(target, utf8, x, y, color);
-  }
-
-
-  void Font::Draw(ImageAccessor& target,
-                  const std::string& utf8,
-                  int x,
-                  int y,
-                  uint8_t r,
-                  uint8_t g,
-                  uint8_t b) const
-  {
-    uint8_t color[4] = { r, g, b, 255 };
-    DrawInternal(target, utf8, x, y, color);
-  }
-
-}
--- a/Resources/Orthanc/Core/Images/Font.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "ImageAccessor.h"
-
-#include <stdint.h>
-#include <vector>
-#include <map>
-#include <boost/noncopyable.hpp>
-
-namespace Orthanc
-{
-  class Font : public boost::noncopyable
-  {
-  private:
-    struct Character
-    {
-      unsigned int  width_;
-      unsigned int  height_;
-      unsigned int  top_;
-      unsigned int  advance_;
-      std::vector<uint8_t>  bitmap_;
-    };
-
-    typedef std::map<char, Character*>  Characters;
-
-    std::string   name_;
-    unsigned int  size_;
-    Characters    characters_;
-    unsigned int  maxHeight_;
-
-    void DrawCharacter(ImageAccessor& target,
-                       const Character& character,
-                       int x,
-                       int y,
-                       const uint8_t color[4]) const;
-
-    void DrawInternal(ImageAccessor& target,
-                      const std::string& utf8,
-                      int x,
-                      int y,
-                      const uint8_t color[4]) const;
-
-  public:
-    Font() : 
-      size_(0), 
-      maxHeight_(0)
-    {
-    }
-
-    ~Font();
-
-    void LoadFromMemory(const std::string& font);
-
-#if ORTHANC_SANDBOXED == 0
-    void LoadFromFile(const std::string& path);
-#endif
-
-    const std::string& GetName() const
-    {
-      return name_;
-    }
-
-    unsigned int GetSize() const
-    {
-      return size_;
-    }
-
-    void Draw(ImageAccessor& target,
-              const std::string& utf8,
-              int x,
-              int y,
-              uint8_t grayscale) const;
-
-    void Draw(ImageAccessor& target,
-              const std::string& utf8,
-              int x,
-              int y,
-              uint8_t r,
-              uint8_t g,
-              uint8_t b) const;
-  };
-}
--- a/Resources/Orthanc/Core/Images/FontRegistry.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +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-2018 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.
- *
- * 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 "FontRegistry.h"
-
-#include "../OrthancException.h"
-
-#include <memory>
-
-namespace Orthanc
-{
-  FontRegistry::~FontRegistry()
-  {
-    for (Fonts::iterator it = fonts_.begin(); it != fonts_.end(); ++it)
-    {
-      delete *it;
-    }
-  }
-
-
-  void FontRegistry::AddFromMemory(const std::string& font)
-  {
-    std::auto_ptr<Font> f(new Font);
-    f->LoadFromMemory(font);
-    fonts_.push_back(f.release());
-  }
-
-
-#if ORTHANC_SANDBOXED == 0
-  void FontRegistry::AddFromFile(const std::string& path)
-  {
-    std::auto_ptr<Font> f(new Font);
-    f->LoadFromFile(path);
-    fonts_.push_back(f.release());
-  }
-#endif
-
-
-#if ORTHANC_HAS_EMBEDDED_RESOURCES == 1
-  void FontRegistry::AddFromResource(EmbeddedResources::FileResourceId resource)
-  {
-    std::string content;
-    EmbeddedResources::GetFileResource(content, resource);
-    AddFromMemory(content);
-  }
-#endif
-
-
-  const Font& FontRegistry::GetFont(size_t i) const
-  {
-    if (i >= fonts_.size())
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-    else
-    {
-      return *fonts_[i];
-    }
-  }
-}
--- a/Resources/Orthanc/Core/Images/FontRegistry.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "Font.h"
-
-#if !defined(ORTHANC_HAS_EMBEDDED_RESOURCES)
-#  error Macro ORTHANC_HAS_EMBEDDED_RESOURCES must be defined
-#endif
-
-#if ORTHANC_HAS_EMBEDDED_RESOURCES == 1
-#  include <EmbeddedResources.h>   // Autogenerated file
-#endif
-
-namespace Orthanc
-{
-  class FontRegistry : public boost::noncopyable
-  {
-  private:
-    typedef std::vector<Font*>  Fonts;
-
-    Fonts  fonts_;
-
-  public:
-    ~FontRegistry();
-
-    void AddFromMemory(const std::string& font);
-
-#if ORTHANC_SANDBOXED == 0
-    void AddFromFile(const std::string& path);
-#endif
-
-#if ORTHANC_HAS_EMBEDDED_RESOURCES == 1
-    void AddFromResource(EmbeddedResources::FileResourceId resource);
-#endif
-
-    size_t GetSize() const
-    {
-      return fonts_.size();
-    }
-
-    const Font& GetFont(size_t i) const;
-  };
-}
--- a/Resources/Orthanc/Core/Images/IImageWriter.cpp	Mon May 21 09:02:03 2018 +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-2018 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.
- *
- * 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 "IImageWriter.h"
-
-#if ORTHANC_SANDBOXED == 0
-#  include "../SystemToolbox.h"
-#endif
-
-namespace Orthanc
-{
-#if ORTHANC_SANDBOXED == 0
-  void IImageWriter::WriteToFileInternal(const std::string& path,
-                                         unsigned int width,
-                                         unsigned int height,
-                                         unsigned int pitch,
-                                         PixelFormat format,
-                                         const void* buffer)
-  {
-    std::string compressed;
-    WriteToMemoryInternal(compressed, width, height, pitch, format, buffer);
-    SystemToolbox::WriteFile(compressed, path);
-  }
-#endif
-}
--- a/Resources/Orthanc/Core/Images/IImageWriter.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "ImageAccessor.h"
-
-#include <boost/noncopyable.hpp>
-
-#if !defined(ORTHANC_SANDBOXED)
-#  error The macro ORTHANC_SANDBOXED must be defined
-#endif
-
-namespace Orthanc
-{
-  class IImageWriter : public boost::noncopyable
-  {
-  protected:
-    virtual void WriteToMemoryInternal(std::string& compressed,
-                                       unsigned int width,
-                                       unsigned int height,
-                                       unsigned int pitch,
-                                       PixelFormat format,
-                                       const void* buffer) = 0;
-
-#if ORTHANC_SANDBOXED == 0
-    virtual void WriteToFileInternal(const std::string& path,
-                                     unsigned int width,
-                                     unsigned int height,
-                                     unsigned int pitch,
-                                     PixelFormat format,
-                                     const void* buffer);
-#endif
-
-  public:
-    virtual ~IImageWriter()
-    {
-    }
-
-    virtual void WriteToMemory(std::string& compressed,
-                               const ImageAccessor& accessor)
-    {
-      WriteToMemoryInternal(compressed, accessor.GetWidth(), accessor.GetHeight(),
-                            accessor.GetPitch(), accessor.GetFormat(), accessor.GetConstBuffer());
-    }
-
-#if ORTHANC_SANDBOXED == 0
-    virtual void WriteToFile(const std::string& path,
-                             const ImageAccessor& accessor)
-    {
-      WriteToFileInternal(path, accessor.GetWidth(), accessor.GetHeight(),
-                          accessor.GetPitch(), accessor.GetFormat(), accessor.GetConstBuffer());
-    }
-#endif
-  };
-}
--- a/Resources/Orthanc/Core/Images/Image.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +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-2018 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.
- *
- * 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 "Image.h"
-
-#include "ImageProcessing.h"
-
-#include <memory>
-
-namespace Orthanc
-{
-  Image::Image(PixelFormat format,
-               unsigned int width,
-               unsigned int height,
-               bool forceMinimalPitch) :
-    image_(format, width, height, forceMinimalPitch)
-  {
-    ImageAccessor accessor = image_.GetAccessor();
-    AssignWritable(format, width, height, accessor.GetPitch(), accessor.GetBuffer());
-  }
-
-
-  Image* Image::Clone(const ImageAccessor& source)
-  {
-    std::auto_ptr<Image> target(new Image(source.GetFormat(), source.GetWidth(), source.GetHeight(), false));
-    ImageProcessing::Copy(*target, source);
-    return target.release();
-  }
-}
--- a/Resources/Orthanc/Core/Images/Image.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "ImageAccessor.h"
-#include "ImageBuffer.h"
-
-namespace Orthanc
-{
-  class Image : public ImageAccessor
-  {
-  private:
-    ImageBuffer  image_;
-
-  public:
-    Image(PixelFormat format,
-          unsigned int width,
-          unsigned int height,
-          bool forceMinimalPitch);
-
-    static Image* Clone(const ImageAccessor& source);
-  };
-}
--- a/Resources/Orthanc/Core/Images/ImageAccessor.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,301 +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-2018 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.
- *
- * 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 "ImageAccessor.h"
-
-#include "../Logging.h"
-#include "../OrthancException.h"
-#include "../ChunkedBuffer.h"
-
-#include <stdint.h>
-#include <cassert>
-#include <boost/lexical_cast.hpp>
-
-
-
-namespace Orthanc
-{
-  template <typename PixelType>
-  static void ToMatlabStringInternal(ChunkedBuffer& target,
-                                     const ImageAccessor& source)
-  {
-    target.AddChunk("double([ ");
-
-    for (unsigned int y = 0; y < source.GetHeight(); y++)
-    {
-      const PixelType* p = reinterpret_cast<const PixelType*>(source.GetConstRow(y));
-
-      std::string s;
-      if (y > 0)
-      {
-        s = "; ";
-      }
-
-      s.reserve(source.GetWidth() * 8);
-
-      for (unsigned int x = 0; x < source.GetWidth(); x++, p++)
-      {
-        s += boost::lexical_cast<std::string>(static_cast<double>(*p)) + " ";
-      }
-
-      target.AddChunk(s);
-    }
-
-    target.AddChunk("])");
-  }
-
-
-  static void RGB24ToMatlabString(ChunkedBuffer& target,
-                                  const ImageAccessor& source)
-  {
-    assert(source.GetFormat() == PixelFormat_RGB24);
-
-    target.AddChunk("double(permute(reshape([ ");
-
-    for (unsigned int y = 0; y < source.GetHeight(); y++)
-    {
-      const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
-      
-      std::string s;
-      s.reserve(source.GetWidth() * 3 * 8);
-      
-      for (unsigned int x = 0; x < 3 * source.GetWidth(); x++, p++)
-      {
-        s += boost::lexical_cast<std::string>(static_cast<int>(*p)) + " ";
-      }
-      
-      target.AddChunk(s);
-    }
-
-    target.AddChunk("], [ 3 " + boost::lexical_cast<std::string>(source.GetHeight()) +
-                    " " + boost::lexical_cast<std::string>(source.GetWidth()) + " ]), [ 3 2 1 ]))");
-  }
-
-
-  void* ImageAccessor::GetBuffer() const
-  {
-    if (readOnly_)
-    {
-#if ORTHANC_ENABLE_LOGGING == 1
-      LOG(ERROR) << "Trying to write on a read-only image";
-#endif
-
-      throw OrthancException(ErrorCode_ReadOnly);
-    }
-
-    return buffer_;
-  }
-
-
-  const void* ImageAccessor::GetConstRow(unsigned int y) const
-  {
-    if (buffer_ != NULL)
-    {
-      return buffer_ + y * pitch_;
-    }
-    else
-    {
-      return NULL;
-    }
-  }
-
-
-  void* ImageAccessor::GetRow(unsigned int y) const
-  {
-    if (readOnly_)
-    {
-#if ORTHANC_ENABLE_LOGGING == 1
-      LOG(ERROR) << "Trying to write on a read-only image";
-#endif
-
-      throw OrthancException(ErrorCode_ReadOnly);
-    }
-
-    if (buffer_ != NULL)
-    {
-      return buffer_ + y * pitch_;
-    }
-    else
-    {
-      return NULL;
-    }
-  }
-
-
-  void ImageAccessor::AssignEmpty(PixelFormat format)
-  {
-    readOnly_ = false;
-    format_ = format;
-    width_ = 0;
-    height_ = 0;
-    pitch_ = 0;
-    buffer_ = NULL;
-  }
-
-
-  void ImageAccessor::AssignReadOnly(PixelFormat format,
-                                     unsigned int width,
-                                     unsigned int height,
-                                     unsigned int pitch,
-                                     const void *buffer)
-  {
-    readOnly_ = true;
-    format_ = format;
-    width_ = width;
-    height_ = height;
-    pitch_ = pitch;
-    buffer_ = reinterpret_cast<uint8_t*>(const_cast<void*>(buffer));
-
-    if (GetBytesPerPixel() * width_ > pitch_)
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  void ImageAccessor::AssignWritable(PixelFormat format,
-                                     unsigned int width,
-                                     unsigned int height,
-                                     unsigned int pitch,
-                                     void *buffer)
-  {
-    readOnly_ = false;
-    format_ = format;
-    width_ = width;
-    height_ = height;
-    pitch_ = pitch;
-    buffer_ = reinterpret_cast<uint8_t*>(buffer);
-
-    if (GetBytesPerPixel() * width_ > pitch_)
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  void ImageAccessor::ToMatlabString(std::string& target) const
-  {
-    ChunkedBuffer buffer;
-
-    switch (GetFormat())
-    {
-      case PixelFormat_Grayscale8:
-        ToMatlabStringInternal<uint8_t>(buffer, *this);
-        break;
-
-      case PixelFormat_Grayscale16:
-        ToMatlabStringInternal<uint16_t>(buffer, *this);
-        break;
-
-      case PixelFormat_Grayscale32:
-        ToMatlabStringInternal<uint32_t>(buffer, *this);
-        break;
-
-      case PixelFormat_SignedGrayscale16:
-        ToMatlabStringInternal<int16_t>(buffer, *this);
-        break;
-
-      case PixelFormat_Float32:
-        ToMatlabStringInternal<float>(buffer, *this);
-        break;
-
-      case PixelFormat_RGB24:
-        RGB24ToMatlabString(buffer, *this);
-        break;
-
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }   
-
-    buffer.Flatten(target);
-  }
-
-
-
-  ImageAccessor ImageAccessor::GetRegion(unsigned int x,
-                                         unsigned int y,
-                                         unsigned int width,
-                                         unsigned int height) const
-  {
-    if (x + width > width_ ||
-        y + height > height_)
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-    
-    ImageAccessor result;
-
-    if (width == 0 ||
-        height == 0)
-    {
-      result.AssignWritable(format_, 0, 0, 0, NULL);
-    }
-    else
-    {
-      uint8_t* p = (buffer_ + 
-                    y * pitch_ + 
-                    x * GetBytesPerPixel());
-
-      if (readOnly_)
-      {
-        result.AssignReadOnly(format_, width, height, pitch_, p);
-      }
-      else
-      {
-        result.AssignWritable(format_, width, height, pitch_, p);
-      }
-    }
-
-    return result;
-  }
-
-
-  void ImageAccessor::SetFormat(PixelFormat format)
-  {
-    if (readOnly_)
-    {
-#if ORTHANC_ENABLE_LOGGING == 1
-      LOG(ERROR) << "Trying to modify the format of a read-only image";
-#endif
-      throw OrthancException(ErrorCode_ReadOnly);
-    }
-
-    if (::Orthanc::GetBytesPerPixel(format) != ::Orthanc::GetBytesPerPixel(format_))
-    {
-      throw OrthancException(ErrorCode_IncompatibleImageFormat);
-    }
-
-    format_ = format;
-  }
-}
--- a/Resources/Orthanc/Core/Images/ImageAccessor.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "../Enumerations.h"
-
-#include <string>
-#include <stdint.h>
-
-namespace Orthanc
-{
-  class ImageAccessor
-  {
-  private:
-    template <Orthanc::PixelFormat Format>
-    friend struct ImageTraits;
-    
-    bool readOnly_;
-    PixelFormat format_;
-    unsigned int width_;
-    unsigned int height_;
-    unsigned int pitch_;
-    uint8_t *buffer_;
-
-    template <typename T>
-    const T& GetPixelUnchecked(unsigned int x,
-                               unsigned int y) const
-    {
-      const uint8_t* row = reinterpret_cast<const uint8_t*>(buffer_) + y * pitch_;
-      return reinterpret_cast<const T*>(row) [x];
-    }
-
-
-    template <typename T>
-    T& GetPixelUnchecked(unsigned int x,
-                         unsigned int y)
-    {
-      uint8_t* row = reinterpret_cast<uint8_t*>(buffer_) + y * pitch_;
-      return reinterpret_cast<T*>(row) [x];
-    }
-
-  public:
-    ImageAccessor()
-    {
-      AssignEmpty(PixelFormat_Grayscale8);
-    }
-
-    virtual ~ImageAccessor()
-    {
-    }
-
-    bool IsReadOnly() const
-    {
-      return readOnly_;
-    }
-
-    PixelFormat GetFormat() const
-    {
-      return format_;
-    }
-
-    unsigned int GetBytesPerPixel() const
-    {
-      return ::Orthanc::GetBytesPerPixel(format_);
-    }
-
-    unsigned int GetWidth() const
-    {
-      return width_;
-    }
-
-    unsigned int GetHeight() const
-    {
-      return height_;
-    }
-
-    unsigned int GetPitch() const
-    {
-      return pitch_;
-    }
-
-    unsigned int GetSize() const
-    {
-      return GetHeight() * GetPitch();
-    }
-
-    const void* GetConstBuffer() const
-    {
-      return buffer_;
-    }
-
-    void* GetBuffer() const;
-
-    const void* GetConstRow(unsigned int y) const;
-
-    void* GetRow(unsigned int y) const;
-
-    void AssignEmpty(PixelFormat format);
-
-    void AssignReadOnly(PixelFormat format,
-                        unsigned int width,
-                        unsigned int height,
-                        unsigned int pitch,
-                        const void *buffer);
-
-    void AssignWritable(PixelFormat format,
-                        unsigned int width,
-                        unsigned int height,
-                        unsigned int pitch,
-                        void *buffer);
-
-    void ToMatlabString(std::string& target) const; 
-
-    ImageAccessor GetRegion(unsigned int x,
-                            unsigned int y,
-                            unsigned int width,
-                            unsigned int height) const;
-
-    void SetFormat(PixelFormat format);
-  };
-}
--- a/Resources/Orthanc/Core/Images/ImageBuffer.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,185 +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-2018 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.
- *
- * 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 "ImageBuffer.h"
-
-#include "../OrthancException.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-namespace Orthanc
-{
-  void ImageBuffer::Allocate()
-  {
-    if (changed_)
-    {
-      Deallocate();
-
-      /*
-        if (forceMinimalPitch_)
-        {
-        TODO: Align pitch and memory buffer to optimal size for SIMD.
-        }
-      */
-
-      pitch_ = GetBytesPerPixel() * width_;
-      size_t size = pitch_ * height_;
-
-      if (size == 0)
-      {
-        buffer_ = NULL;
-      }
-      else
-      {
-        buffer_ = malloc(size);
-        if (buffer_ == NULL)
-        {
-          throw OrthancException(ErrorCode_NotEnoughMemory);
-        }
-      }
-
-      changed_ = false;
-    }
-  }
-
-
-  void ImageBuffer::Deallocate()
-  {
-    if (buffer_ != NULL)
-    {
-      free(buffer_);
-      buffer_ = NULL;
-      changed_ = true;
-    }
-  }
-
-
-  ImageBuffer::ImageBuffer(PixelFormat format,
-                           unsigned int width,
-                           unsigned int height,
-                           bool forceMinimalPitch) :
-    forceMinimalPitch_(forceMinimalPitch)
-  {
-    Initialize();
-    SetWidth(width);
-    SetHeight(height);
-    SetFormat(format);
-  }
-
-
-  void ImageBuffer::Initialize()
-  {
-    changed_ = false;
-    forceMinimalPitch_ = true;
-    format_ = PixelFormat_Grayscale8;
-    width_ = 0;
-    height_ = 0;
-    pitch_ = 0;
-    buffer_ = NULL;
-  }
-
-
-  void ImageBuffer::SetFormat(PixelFormat format)
-  {
-    if (format != format_)
-    {
-      changed_ = true;
-      format_ = format;
-    }
-  }
-
-
-  void ImageBuffer::SetWidth(unsigned int width)
-  {
-    if (width != width_)
-    {
-      changed_ = true;
-      width_ = width;     
-    }
-  }
-
-
-  void ImageBuffer::SetHeight(unsigned int height)
-  {
-    if (height != height_)
-    {
-      changed_ = true;
-      height_ = height;     
-    }
-  }
-
-
-  ImageAccessor ImageBuffer::GetAccessor()
-  {
-    Allocate();
-
-    ImageAccessor accessor;
-    accessor.AssignWritable(format_, width_, height_, pitch_, buffer_);
-    return accessor;
-  }
-
-
-  ImageAccessor ImageBuffer::GetConstAccessor()
-  {
-    Allocate();
-
-    ImageAccessor accessor;
-    accessor.AssignReadOnly(format_, width_, height_, pitch_, buffer_);
-    return accessor;
-  }
-
-
-  void ImageBuffer::AcquireOwnership(ImageBuffer& other)
-  {
-    // Remove the content of the current image
-    Deallocate();
-
-    // Force the allocation of the other image (if not already
-    // allocated)
-    other.Allocate();
-
-    // Transfer the content of the other image
-    changed_ = false;
-    forceMinimalPitch_ = other.forceMinimalPitch_;
-    format_ = other.format_;
-    width_ = other.width_;
-    height_ = other.height_;
-    pitch_ = other.pitch_;
-    buffer_ = other.buffer_;
-
-    // Force the reinitialization of the other image
-    other.Initialize();
-  }
-}
--- a/Resources/Orthanc/Core/Images/ImageBuffer.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "ImageAccessor.h"
-
-#include <vector>
-#include <stdint.h>
-#include <boost/noncopyable.hpp>
-
-namespace Orthanc
-{
-  class ImageBuffer : public boost::noncopyable
-  {
-  private:
-    bool changed_;
-
-    bool forceMinimalPitch_;  // Currently unused
-    PixelFormat format_;
-    unsigned int width_;
-    unsigned int height_;
-    unsigned int pitch_;
-    void *buffer_;
-
-    void Initialize();
-    
-    void Allocate();
-
-    void Deallocate();
-
-  public:
-    ImageBuffer(PixelFormat format,
-                unsigned int width,
-                unsigned int height,
-                bool forceMinimalPitch);
-
-    ImageBuffer()
-    {
-      Initialize();
-    }
-
-    ~ImageBuffer()
-    {
-      Deallocate();
-    }
-
-    PixelFormat GetFormat() const
-    {
-      return format_;
-    }
-
-    void SetFormat(PixelFormat format);
-
-    unsigned int GetWidth() const
-    {
-      return width_;
-    }
-
-    void SetWidth(unsigned int width);
-
-    unsigned int GetHeight() const
-    {
-      return height_;
-    }
-
-    void SetHeight(unsigned int height);
-
-    unsigned int GetBytesPerPixel() const
-    {
-      return ::Orthanc::GetBytesPerPixel(format_);
-    }
-
-    ImageAccessor GetAccessor();
-
-    ImageAccessor GetConstAccessor();
-
-    bool IsMinimalPitchForced() const
-    {
-      return forceMinimalPitch_;
-    }
-
-    void AcquireOwnership(ImageBuffer& other);
-  };
-}
--- a/Resources/Orthanc/Core/Images/ImageProcessing.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1226 +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-2018 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.
- *
- * 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 "ImageProcessing.h"
-
-#include "PixelTraits.h"
-
-#include <boost/math/special_functions/round.hpp>
-
-#include <cassert>
-#include <string.h>
-#include <limits>
-#include <stdint.h>
-
-namespace Orthanc
-{
-  template <typename TargetType, typename SourceType>
-  static void ConvertInternal(ImageAccessor& target,
-                              const ImageAccessor& source)
-  {
-    const TargetType minValue = std::numeric_limits<TargetType>::min();
-    const TargetType maxValue = std::numeric_limits<TargetType>::max();
-
-    for (unsigned int y = 0; y < source.GetHeight(); y++)
-    {
-      TargetType* t = reinterpret_cast<TargetType*>(target.GetRow(y));
-      const SourceType* s = reinterpret_cast<const SourceType*>(source.GetConstRow(y));
-
-      for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s++)
-      {
-        if (static_cast<int32_t>(*s) < static_cast<int32_t>(minValue))
-        {
-          *t = minValue;
-        }
-        else if (static_cast<int32_t>(*s) > static_cast<int32_t>(maxValue))
-        {
-          *t = maxValue;
-        }
-        else
-        {
-          *t = static_cast<TargetType>(*s);
-        }
-      }
-    }
-  }
-
-
-  template <typename SourceType>
-  static void ConvertGrayscaleToFloat(ImageAccessor& target,
-                                      const ImageAccessor& source)
-  {
-    assert(sizeof(float) == 4);
-
-    for (unsigned int y = 0; y < source.GetHeight(); y++)
-    {
-      float* t = reinterpret_cast<float*>(target.GetRow(y));
-      const SourceType* s = reinterpret_cast<const SourceType*>(source.GetConstRow(y));
-
-      for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s++)
-      {
-        *t = static_cast<float>(*s);
-      }
-    }
-  }
-
-
-  template <typename TargetType>
-  static void ConvertColorToGrayscale(ImageAccessor& target,
-                                      const ImageAccessor& source)
-  {
-    assert(source.GetFormat() == PixelFormat_RGB24);
-
-    const TargetType minValue = std::numeric_limits<TargetType>::min();
-    const TargetType maxValue = std::numeric_limits<TargetType>::max();
-
-    for (unsigned int y = 0; y < source.GetHeight(); y++)
-    {
-      TargetType* t = reinterpret_cast<TargetType*>(target.GetRow(y));
-      const uint8_t* s = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
-
-      for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s += 3)
-      {
-        // Y = 0.2126 R + 0.7152 G + 0.0722 B
-        int32_t v = (2126 * static_cast<int32_t>(s[0]) +
-                     7152 * static_cast<int32_t>(s[1]) +
-                     0722 * static_cast<int32_t>(s[2])) / 10000;
-        
-        if (static_cast<int32_t>(v) < static_cast<int32_t>(minValue))
-        {
-          *t = minValue;
-        }
-        else if (static_cast<int32_t>(v) > static_cast<int32_t>(maxValue))
-        {
-          *t = maxValue;
-        }
-        else
-        {
-          *t = static_cast<TargetType>(v);
-        }
-      }
-    }
-  }
-
-
-  template <typename PixelType>
-  static void SetInternal(ImageAccessor& image,
-                          int64_t constant)
-  {
-    for (unsigned int y = 0; y < image.GetHeight(); y++)
-    {
-      PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y));
-
-      for (unsigned int x = 0; x < image.GetWidth(); x++, p++)
-      {
-        *p = static_cast<PixelType>(constant);
-      }
-    }
-  }
-
-
-  template <typename PixelType>
-  static void GetMinMaxValueInternal(PixelType& minValue,
-                                     PixelType& maxValue,
-                                     const ImageAccessor& source)
-  {
-    // Deal with the special case of empty image
-    if (source.GetWidth() == 0 ||
-        source.GetHeight() == 0)
-    {
-      minValue = 0;
-      maxValue = 0;
-      return;
-    }
-
-    minValue = std::numeric_limits<PixelType>::max();
-    maxValue = std::numeric_limits<PixelType>::min();
-
-    const unsigned int width = source.GetWidth();
-
-    for (unsigned int y = 0; y < source.GetHeight(); y++)
-    {
-      const PixelType* p = reinterpret_cast<const PixelType*>(source.GetConstRow(y));
-
-      for (unsigned int x = 0; x < width; x++, p++)
-      {
-        if (*p < minValue)
-        {
-          minValue = *p;
-        }
-
-        if (*p > maxValue)
-        {
-          maxValue = *p;
-        }
-      }
-    }
-  }
-
-
-
-  template <typename PixelType>
-  static void AddConstantInternal(ImageAccessor& image,
-                                  int64_t constant)
-  {
-    if (constant == 0)
-    {
-      return;
-    }
-
-    const int64_t minValue = std::numeric_limits<PixelType>::min();
-    const int64_t maxValue = std::numeric_limits<PixelType>::max();
-
-    for (unsigned int y = 0; y < image.GetHeight(); y++)
-    {
-      PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y));
-
-      for (unsigned int x = 0; x < image.GetWidth(); x++, p++)
-      {
-        int64_t v = static_cast<int64_t>(*p) + constant;
-
-        if (v > maxValue)
-        {
-          *p = std::numeric_limits<PixelType>::max();
-        }
-        else if (v < minValue)
-        {
-          *p = std::numeric_limits<PixelType>::min();
-        }
-        else
-        {
-          *p = static_cast<PixelType>(v);
-        }
-      }
-    }
-  }
-
-
-
-  template <typename PixelType,
-            bool UseRound>
-  static void MultiplyConstantInternal(ImageAccessor& image,
-                                       float factor)
-  {
-    if (std::abs(factor - 1.0f) <= std::numeric_limits<float>::epsilon())
-    {
-      return;
-    }
-
-    const int64_t minValue = std::numeric_limits<PixelType>::min();
-    const int64_t maxValue = std::numeric_limits<PixelType>::max();
-    const unsigned int width = image.GetWidth();
-
-    for (unsigned int y = 0; y < image.GetHeight(); y++)
-    {
-      PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y));
-
-      for (unsigned int x = 0; x < width; x++, p++)
-      {
-        int64_t v;
-        if (UseRound)
-        {
-          // The "round" operation is very costly
-          v = boost::math::llround(static_cast<float>(*p) * factor);
-        }
-        else
-        {
-          v = static_cast<int64_t>(static_cast<float>(*p) * factor);
-        }
-
-        if (v > maxValue)
-        {
-          *p = std::numeric_limits<PixelType>::max();
-        }
-        else if (v < minValue)
-        {
-          *p = std::numeric_limits<PixelType>::min();
-        }
-        else
-        {
-          *p = static_cast<PixelType>(v);
-        }
-      }
-    }
-  }
-
-
-  template <typename PixelType,
-            bool UseRound>
-  static void ShiftScaleInternal(ImageAccessor& image,
-                                 float offset,
-                                 float scaling)
-  {
-    const float minFloatValue = static_cast<float>(std::numeric_limits<PixelType>::min());
-    const float maxFloatValue = static_cast<float>(std::numeric_limits<PixelType>::max());
-    const PixelType minPixelValue = std::numeric_limits<PixelType>::min();
-    const PixelType maxPixelValue = std::numeric_limits<PixelType>::max();
-
-    const unsigned int height = image.GetHeight();
-    const unsigned int width = image.GetWidth();
-    
-    for (unsigned int y = 0; y < height; y++)
-    {
-      PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y));
-
-      for (unsigned int x = 0; x < width; x++, p++)
-      {
-        float v = (static_cast<float>(*p) + offset) * scaling;
-
-        if (v > maxFloatValue)
-        {
-          *p = maxPixelValue;
-        }
-        else if (v < minFloatValue)
-        {
-          *p = minPixelValue;
-        }
-        else if (UseRound)
-        {
-          // The "round" operation is very costly
-          *p = static_cast<PixelType>(boost::math::iround(v));
-        }
-        else
-        {
-          *p = static_cast<PixelType>(v);
-        }
-      }
-    }
-  }
-
-
-  void ImageProcessing::Copy(ImageAccessor& target,
-                             const ImageAccessor& source)
-  {
-    if (target.GetWidth() != source.GetWidth() ||
-        target.GetHeight() != source.GetHeight())
-    {
-      throw OrthancException(ErrorCode_IncompatibleImageSize);
-    }
-
-    if (target.GetFormat() != source.GetFormat())
-    {
-      throw OrthancException(ErrorCode_IncompatibleImageFormat);
-    }
-
-    unsigned int lineSize = GetBytesPerPixel(source.GetFormat()) * source.GetWidth();
-
-    assert(source.GetPitch() >= lineSize && target.GetPitch() >= lineSize);
-
-    for (unsigned int y = 0; y < source.GetHeight(); y++)
-    {
-      memcpy(target.GetRow(y), source.GetConstRow(y), lineSize);
-    }
-  }
-
-
-  void ImageProcessing::Convert(ImageAccessor& target,
-                                const ImageAccessor& source)
-  {
-    if (target.GetWidth() != source.GetWidth() ||
-        target.GetHeight() != source.GetHeight())
-    {
-      throw OrthancException(ErrorCode_IncompatibleImageSize);
-    }
-
-    if (source.GetFormat() == target.GetFormat())
-    {
-      Copy(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_Grayscale16 &&
-        source.GetFormat() == PixelFormat_Grayscale8)
-    {
-      ConvertInternal<uint16_t, uint8_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_SignedGrayscale16 &&
-        source.GetFormat() == PixelFormat_Grayscale8)
-    {
-      ConvertInternal<int16_t, uint8_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_Grayscale8 &&
-        source.GetFormat() == PixelFormat_Grayscale16)
-    {
-      ConvertInternal<uint8_t, uint16_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_SignedGrayscale16 &&
-        source.GetFormat() == PixelFormat_Grayscale16)
-    {
-      ConvertInternal<int16_t, uint16_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_Grayscale8 &&
-        source.GetFormat() == PixelFormat_SignedGrayscale16)
-    {
-      ConvertInternal<uint8_t, int16_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_Grayscale16 &&
-        source.GetFormat() == PixelFormat_SignedGrayscale16)
-    {
-      ConvertInternal<uint16_t, int16_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_Grayscale8 &&
-        source.GetFormat() == PixelFormat_RGB24)
-    {
-      ConvertColorToGrayscale<uint8_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_Grayscale16 &&
-        source.GetFormat() == PixelFormat_RGB24)
-    {
-      ConvertColorToGrayscale<uint16_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_SignedGrayscale16 &&
-        source.GetFormat() == PixelFormat_RGB24)
-    {
-      ConvertColorToGrayscale<int16_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_Float32 &&
-        source.GetFormat() == PixelFormat_Grayscale8)
-    {
-      ConvertGrayscaleToFloat<uint8_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_Float32 &&
-        source.GetFormat() == PixelFormat_Grayscale16)
-    {
-      ConvertGrayscaleToFloat<uint16_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_Float32 &&
-        source.GetFormat() == PixelFormat_Grayscale32)
-    {
-      ConvertGrayscaleToFloat<uint32_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_Float32 &&
-        source.GetFormat() == PixelFormat_SignedGrayscale16)
-    {
-      ConvertGrayscaleToFloat<int16_t>(target, source);
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_Grayscale8 &&
-        source.GetFormat() == PixelFormat_RGBA32)
-    {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
-      {
-        const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
-        uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++, q++)
-        {
-          *q = static_cast<uint8_t>((2126 * static_cast<uint32_t>(p[0]) +
-                                     7152 * static_cast<uint32_t>(p[1]) +
-                                     0722 * static_cast<uint32_t>(p[2])) / 10000);
-          p += 4;
-        }
-      }
-
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_RGB24 &&
-        source.GetFormat() == PixelFormat_RGBA32)
-    {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
-      {
-        const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
-        uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
-        {
-          q[0] = p[0];
-          q[1] = p[1];
-          q[2] = p[2];
-          p += 4;
-          q += 3;
-        }
-      }
-
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_RGB24 &&
-        source.GetFormat() == PixelFormat_BGRA32)
-    {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
-      {
-        const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
-        uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
-        {
-          q[0] = p[2];
-          q[1] = p[1];
-          q[2] = p[0];
-          p += 4;
-          q += 3;
-        }
-      }
-
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_RGBA32 &&
-        source.GetFormat() == PixelFormat_RGB24)
-    {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
-      {
-        const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
-        uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
-        {
-          q[0] = p[0];
-          q[1] = p[1];
-          q[2] = p[2];
-          q[3] = 255;   // Set the alpha channel to full opacity
-          p += 3;
-          q += 4;
-        }
-      }
-
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_RGB24 &&
-        source.GetFormat() == PixelFormat_Grayscale8)
-    {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
-      {
-        const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
-        uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
-        {
-          q[0] = *p;
-          q[1] = *p;
-          q[2] = *p;
-          p += 1;
-          q += 3;
-        }
-      }
-
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_RGBA32 &&
-        source.GetFormat() == PixelFormat_Grayscale8)
-    {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
-      {
-        const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
-        uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
-        {
-          q[0] = *p;
-          q[1] = *p;
-          q[2] = *p;
-          q[3] = 255;
-          p += 1;
-          q += 4;
-        }
-      }
-
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_BGRA32 &&
-        source.GetFormat() == PixelFormat_Grayscale16)
-    {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
-      {
-        const uint16_t* p = reinterpret_cast<const uint16_t*>(source.GetConstRow(y));
-        uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
-        {
-          uint8_t value = (*p < 256 ? *p : 255);
-          q[0] = value;
-          q[1] = value;
-          q[2] = value;
-          q[3] = 255;
-          p += 1;
-          q += 4;
-        }
-      }
-
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_BGRA32 &&
-        source.GetFormat() == PixelFormat_SignedGrayscale16)
-    {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
-      {
-        const int16_t* p = reinterpret_cast<const int16_t*>(source.GetConstRow(y));
-        uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
-        {
-          uint8_t value;
-          if (*p < 0)
-          {
-            value = 0;
-          }
-          else if (*p > 255)
-          {
-            value = 255;
-          }
-          else
-          {
-            value = static_cast<uint8_t>(*p);
-          }
-
-          q[0] = value;
-          q[1] = value;
-          q[2] = value;
-          q[3] = 255;
-          p += 1;
-          q += 4;
-        }
-      }
-
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_BGRA32 &&
-        source.GetFormat() == PixelFormat_RGB24)
-    {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
-      {
-        const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
-        uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
-        {
-          q[0] = p[2];
-          q[1] = p[1];
-          q[2] = p[0];
-          q[3] = 255;
-          p += 3;
-          q += 4;
-        }
-      }
-
-      return;
-    }
-
-    if (target.GetFormat() == PixelFormat_RGB24 &&
-        source.GetFormat() == PixelFormat_RGB48)
-    {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
-      {
-        const uint16_t* p = reinterpret_cast<const uint16_t*>(source.GetConstRow(y));
-        uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
-        {
-          q[0] = p[0] >> 8;
-          q[1] = p[1] >> 8;
-          q[2] = p[2] >> 8;
-          p += 3;
-          q += 3;
-        }
-      }
-
-      return;
-    }
-
-    throw OrthancException(ErrorCode_NotImplemented);
-  }
-
-
-
-  void ImageProcessing::Set(ImageAccessor& image,
-                            int64_t value)
-  {
-    switch (image.GetFormat())
-    {
-      case PixelFormat_Grayscale8:
-        memset(image.GetBuffer(), static_cast<uint8_t>(value), image.GetPitch() * image.GetHeight());
-        return;
-
-      case PixelFormat_Grayscale16:
-        if (value == 0)
-        {
-          memset(image.GetBuffer(), 0, image.GetPitch() * image.GetHeight());
-        }
-        else
-        {
-          SetInternal<uint16_t>(image, value);
-        }
-        return;
-
-      case PixelFormat_Grayscale32:
-        if (value == 0)
-        {
-          memset(image.GetBuffer(), 0, image.GetPitch() * image.GetHeight());
-        }
-        else
-        {
-          SetInternal<uint32_t>(image, value);
-        }
-        return;
-
-      case PixelFormat_SignedGrayscale16:
-        if (value == 0)
-        {
-          memset(image.GetBuffer(), 0, image.GetPitch() * image.GetHeight());
-        }
-        else
-        {
-          SetInternal<int16_t>(image, value);
-        }
-        return;
-
-      case PixelFormat_Float32:
-        assert(sizeof(float) == 4);
-        SetInternal<float>(image, value);
-        return;
-
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }
-  }
-
-
-  void ImageProcessing::Set(ImageAccessor& image,
-                            uint8_t red,
-                            uint8_t green,
-                            uint8_t blue,
-                            uint8_t alpha)
-  {
-    uint8_t p[4];
-    unsigned int size;
-
-    switch (image.GetFormat())
-    {
-      case PixelFormat_RGBA32:
-        p[0] = red;
-        p[1] = green;
-        p[2] = blue;
-        p[3] = alpha;
-        size = 4;
-        break;
-
-      case PixelFormat_BGRA32:
-        p[0] = blue;
-        p[1] = green;
-        p[2] = red;
-        p[3] = alpha;
-        size = 4;
-        break;
-
-      case PixelFormat_RGB24:
-        p[0] = red;
-        p[1] = green;
-        p[2] = blue;
-        size = 3;
-        break;
-
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }    
-
-    for (unsigned int y = 0; y < image.GetHeight(); y++)
-    {
-      uint8_t* q = reinterpret_cast<uint8_t*>(image.GetRow(y));
-
-      for (unsigned int x = 0; x < image.GetWidth(); x++)
-      {
-        for (unsigned int i = 0; i < size; i++)
-        {
-          q[i] = p[i];
-        }
-
-        q += size;
-      }
-    }
-  }
-
-
-  void ImageProcessing::ShiftRight(ImageAccessor& image,
-                                   unsigned int shift)
-  {
-    if (image.GetWidth() == 0 ||
-        image.GetHeight() == 0 ||
-        shift == 0)
-    {
-      // Nothing to do
-      return;
-    }
-
-    throw OrthancException(ErrorCode_NotImplemented);
-  }
-
-
-  void ImageProcessing::GetMinMaxIntegerValue(int64_t& minValue,
-                                              int64_t& maxValue,
-                                              const ImageAccessor& image)
-  {
-    switch (image.GetFormat())
-    {
-      case PixelFormat_Grayscale8:
-      {
-        uint8_t a, b;
-        GetMinMaxValueInternal<uint8_t>(a, b, image);
-        minValue = a;
-        maxValue = b;
-        break;
-      }
-
-      case PixelFormat_Grayscale16:
-      {
-        uint16_t a, b;
-        GetMinMaxValueInternal<uint16_t>(a, b, image);
-        minValue = a;
-        maxValue = b;
-        break;
-      }
-
-      case PixelFormat_Grayscale32:
-      {
-        uint32_t a, b;
-        GetMinMaxValueInternal<uint32_t>(a, b, image);
-        minValue = a;
-        maxValue = b;
-        break;
-      }
-
-      case PixelFormat_SignedGrayscale16:
-      {
-        int16_t a, b;
-        GetMinMaxValueInternal<int16_t>(a, b, image);
-        minValue = a;
-        maxValue = b;
-        break;
-      }
-
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }
-  }
-
-
-  void ImageProcessing::GetMinMaxFloatValue(float& minValue,
-                                            float& maxValue,
-                                            const ImageAccessor& image)
-  {
-    switch (image.GetFormat())
-    {
-      case PixelFormat_Float32:
-      {
-        assert(sizeof(float) == 32);
-        float a, b;
-        GetMinMaxValueInternal<float>(a, b, image);
-        minValue = a;
-        maxValue = b;
-        break;
-      }
-
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }
-  }
-
-
-
-  void ImageProcessing::AddConstant(ImageAccessor& image,
-                                    int64_t value)
-  {
-    switch (image.GetFormat())
-    {
-      case PixelFormat_Grayscale8:
-        AddConstantInternal<uint8_t>(image, value);
-        return;
-
-      case PixelFormat_Grayscale16:
-        AddConstantInternal<uint16_t>(image, value);
-        return;
-
-      case PixelFormat_SignedGrayscale16:
-        AddConstantInternal<int16_t>(image, value);
-        return;
-
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }
-  }
-
-
-  void ImageProcessing::MultiplyConstant(ImageAccessor& image,
-                                         float factor,
-                                         bool useRound)
-  {
-    switch (image.GetFormat())
-    {
-      case PixelFormat_Grayscale8:
-        if (useRound)
-        {
-          MultiplyConstantInternal<uint8_t, true>(image, factor);
-        }
-        else
-        {
-          MultiplyConstantInternal<uint8_t, false>(image, factor);
-        }
-        return;
-
-      case PixelFormat_Grayscale16:
-        if (useRound)
-        {
-          MultiplyConstantInternal<uint16_t, true>(image, factor);
-        }
-        else
-        {
-          MultiplyConstantInternal<uint16_t, false>(image, factor);
-        }
-        return;
-
-      case PixelFormat_SignedGrayscale16:
-        if (useRound)
-        {
-          MultiplyConstantInternal<int16_t, true>(image, factor);
-        }
-        else
-        {
-          MultiplyConstantInternal<int16_t, false>(image, factor);
-        }
-        return;
-
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }
-  }
-
-
-  void ImageProcessing::ShiftScale(ImageAccessor& image,
-                                   float offset,
-                                   float scaling,
-                                   bool useRound)
-  {
-    switch (image.GetFormat())
-    {
-      case PixelFormat_Grayscale8:
-        if (useRound)
-        {
-          ShiftScaleInternal<uint8_t, true>(image, offset, scaling);
-        }
-        else
-        {
-          ShiftScaleInternal<uint8_t, false>(image, offset, scaling);
-        }
-        return;
-
-      case PixelFormat_Grayscale16:
-        if (useRound)
-        {
-          ShiftScaleInternal<uint16_t, true>(image, offset, scaling);
-        }
-        else
-        {
-          ShiftScaleInternal<uint16_t, false>(image, offset, scaling);
-        }
-        return;
-
-      case PixelFormat_SignedGrayscale16:
-        if (useRound)
-        {
-          ShiftScaleInternal<int16_t, true>(image, offset, scaling);
-        }
-        else
-        {
-          ShiftScaleInternal<int16_t, false>(image, offset, scaling);
-        }
-        return;
-
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }
-  }
-
-
-  void ImageProcessing::Invert(ImageAccessor& image)
-  {
-    switch (image.GetFormat())
-    {
-      case PixelFormat_Grayscale8:
-      {
-        for (unsigned int y = 0; y < image.GetHeight(); y++)
-        {
-          uint8_t* p = reinterpret_cast<uint8_t*>(image.GetRow(y));
-
-          for (unsigned int x = 0; x < image.GetWidth(); x++, p++)
-          {
-            *p = 255 - (*p);
-          }
-        }
-        
-        return;
-      }
-
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }   
-  }
-
-
-
-  namespace
-  {
-    template <Orthanc::PixelFormat Format>
-    class BresenhamPixelWriter
-    {
-    private:
-      typedef typename PixelTraits<Format>::PixelType  PixelType;
-    
-      Orthanc::ImageAccessor&  image_;
-      PixelType                value_;
-
-      void PlotLineLow(int x0,
-                       int y0,
-                       int x1,
-                       int y1)
-      {
-        int dx = x1 - x0;
-        int dy = y1 - y0;
-        int yi = 1;
-
-        if (dy < 0)
-        {
-          yi = -1;
-          dy = -dy;
-        }
-
-        int d = 2 * dy - dx;
-        int y = y0;
-
-        for (int x = x0; x <= x1; x++)
-        {
-          Write(x, y);
-          
-          if (d > 0)
-          {
-            y = y + yi;
-            d = d - 2 * dx;
-          }
-      
-          d = d + 2*dy;
-        }
-      }
-      
-      void PlotLineHigh(int x0,
-                        int y0,
-                        int x1,
-                        int y1)
-      {
-        int dx = x1 - x0;
-        int dy = y1 - y0;
-        int xi = 1;
-    
-        if (dx < 0)
-        {
-          xi = -1;
-          dx = -dx;
-        }
-    
-        int d = 2 * dx - dy;
-        int x = x0;
-
-        for (int y = y0; y <= y1; y++)
-        {
-          Write(x, y);
-          
-          if (d > 0)
-          {
-            x = x + xi;
-            d = d - 2 * dy;
-          }
-      
-          d = d + 2 * dx;
-        }
-      }
-
-    public:
-      BresenhamPixelWriter(Orthanc::ImageAccessor& image,
-                           int64_t value) :
-        image_(image),
-        value_(PixelTraits<Format>::IntegerToPixel(value))
-      {
-      }
-
-      BresenhamPixelWriter(Orthanc::ImageAccessor& image,
-                           const PixelType& value) :
-        image_(image),
-        value_(value)
-      {
-      }
-
-      void Write(int x,
-                 int y)
-      {
-        if (x >= 0 &&
-            y >= 0 &&
-            static_cast<unsigned int>(x) < image_.GetWidth() &&
-            static_cast<unsigned int>(y) < image_.GetHeight())
-        {
-          PixelType* p = reinterpret_cast<PixelType*>(image_.GetRow(y));
-          p[x] = value_;
-        }
-      }
-
-      void DrawSegment(int x0,
-                       int y0,
-                       int x1,
-                       int y1)
-      {
-        // This is an implementation of Bresenham's line algorithm
-        // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#All_cases
-    
-        if (abs(y1 - y0) < abs(x1 - x0))
-        {
-          if (x0 > x1)
-          {
-            PlotLineLow(x1, y1, x0, y0);
-          }
-          else
-          {
-            PlotLineLow(x0, y0, x1, y1);
-          }
-        }
-        else
-        {
-          if (y0 > y1)
-          {
-            PlotLineHigh(x1, y1, x0, y0);
-          }
-          else
-          {
-            PlotLineHigh(x0, y0, x1, y1);
-          }
-        }
-      }
-    };
-  }
-
-  
-  void ImageProcessing::DrawLineSegment(ImageAccessor& image,
-                                        int x0,
-                                        int y0,
-                                        int x1,
-                                        int y1,
-                                        int64_t value)
-  {
-    switch (image.GetFormat())
-    {       
-      case Orthanc::PixelFormat_Grayscale8:
-      {
-        BresenhamPixelWriter<Orthanc::PixelFormat_Grayscale8> writer(image, value);
-        writer.DrawSegment(x0, y0, x1, y1);
-        break;
-      }
-
-      case Orthanc::PixelFormat_Grayscale16:
-      {
-        BresenhamPixelWriter<Orthanc::PixelFormat_Grayscale16> writer(image, value);
-        writer.DrawSegment(x0, y0, x1, y1);
-        break;
-      }
-
-      case Orthanc::PixelFormat_SignedGrayscale16:
-      {
-        BresenhamPixelWriter<Orthanc::PixelFormat_SignedGrayscale16> writer(image, value);
-        writer.DrawSegment(x0, y0, x1, y1);
-        break;
-      }
-        
-      default:
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-    }
-  }
-
-  
-  void ImageProcessing::DrawLineSegment(ImageAccessor& image,
-                                        int x0,
-                                        int y0,
-                                        int x1,
-                                        int y1,
-                                        uint8_t red,
-                                        uint8_t green,
-                                        uint8_t blue,
-                                        uint8_t alpha)
-  {
-    switch (image.GetFormat())
-    {
-      case Orthanc::PixelFormat_BGRA32:
-      {
-        PixelTraits<Orthanc::PixelFormat_BGRA32>::PixelType pixel;
-        pixel.red_ = red;
-        pixel.green_ = green;
-        pixel.blue_ = blue;
-        pixel.alpha_ = alpha;
-
-        BresenhamPixelWriter<Orthanc::PixelFormat_BGRA32> writer(image, pixel);
-        writer.DrawSegment(x0, y0, x1, y1);
-        break;
-      }
-        
-      case Orthanc::PixelFormat_RGB24:
-      {
-        PixelTraits<Orthanc::PixelFormat_RGB24>::PixelType pixel;
-        pixel.red_ = red;
-        pixel.green_ = green;
-        pixel.blue_ = blue;
-
-        BresenhamPixelWriter<Orthanc::PixelFormat_RGB24> writer(image, pixel);
-        writer.DrawSegment(x0, y0, x1, y1);
-        break;
-      }
-        
-      default:
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-    }
-  }
-}
--- a/Resources/Orthanc/Core/Images/ImageProcessing.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "ImageAccessor.h"
-
-#include <stdint.h>
-
-namespace Orthanc
-{
-  namespace ImageProcessing
-  {
-    void Copy(ImageAccessor& target,
-              const ImageAccessor& source);
-
-    void Convert(ImageAccessor& target,
-                 const ImageAccessor& source);
-
-    void Set(ImageAccessor& image,
-             int64_t value);
-
-    void Set(ImageAccessor& image,
-             uint8_t red,
-             uint8_t green,
-             uint8_t blue,
-             uint8_t alpha);
-
-    void ShiftRight(ImageAccessor& target,
-                    unsigned int shift);
-
-    void GetMinMaxIntegerValue(int64_t& minValue,
-                               int64_t& maxValue,
-                               const ImageAccessor& image);
-
-    void GetMinMaxFloatValue(float& minValue,
-                             float& maxValue,
-                             const ImageAccessor& image);
-
-    void AddConstant(ImageAccessor& image,
-                     int64_t value);
-
-    // "useRound" is expensive
-    void MultiplyConstant(ImageAccessor& image,
-                          float factor,
-                          bool useRound);
-
-    // "useRound" is expensive
-    void ShiftScale(ImageAccessor& image,
-                    float offset,
-                    float scaling,
-                    bool useRound);
-
-    void Invert(ImageAccessor& image);
-
-    void DrawLineSegment(ImageAccessor& image,
-                         int x0,
-                         int y0,
-                         int x1,
-                         int y1,
-                         int64_t value);
-
-    void DrawLineSegment(ImageAccessor& image,
-                         int x0,
-                         int y0,
-                         int x1,
-                         int y1,
-                         uint8_t red,
-                         uint8_t green,
-                         uint8_t blue,
-                         uint8_t alpha);
-  };
-}
--- a/Resources/Orthanc/Core/Images/ImageTraits.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "ImageAccessor.h"
-#include "PixelTraits.h"
-
-#include <cassert>
-
-namespace Orthanc
-{
-  template <PixelFormat Format>
-  struct ImageTraits
-  {
-    typedef ::Orthanc::PixelTraits<Format>    PixelTraits;
-    typedef typename PixelTraits::PixelType   PixelType;
-
-    static PixelFormat GetPixelFormat()
-    {
-      return Format;
-    }
-
-    static void GetPixel(PixelType& target,
-                         const ImageAccessor& image,
-                         unsigned int x,
-                         unsigned int y)
-    {
-      assert(x < image.GetWidth() && y < image.GetHeight());
-      PixelTraits::Copy(target, image.GetPixelUnchecked<PixelType>(x, y));
-    }
-
-    static void SetPixel(ImageAccessor& image,
-                         const PixelType& value,
-                         unsigned int x,
-                         unsigned int y)
-    {
-      assert(x < image.GetWidth() && y < image.GetHeight());
-      PixelTraits::Copy(image.GetPixelUnchecked<PixelType>(x, y), value);
-    }
-
-    static float GetFloatPixel(const ImageAccessor& image,
-                               unsigned int x,
-                               unsigned int y)
-    {
-      assert(x < image.GetWidth() && y < image.GetHeight());
-      return PixelTraits::PixelToFloat(image.GetPixelUnchecked<PixelType>(x, y));
-    }
-
-    static void SetFloatPixel(ImageAccessor& image,
-                              float value,
-                              unsigned int x,
-                              unsigned int y)
-    {
-      assert(x < image.GetWidth() && y < image.GetHeight());
-      PixelTraits::FloatToPixel(image.GetPixelUnchecked<PixelType>(x, y), value);
-    }
-  };
-}
--- a/Resources/Orthanc/Core/Images/JpegErrorManager.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +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-2018 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.
- *
- * 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 "JpegErrorManager.h"
-
-namespace Orthanc
-{
-  namespace Internals
-  {
-    void JpegErrorManager::OutputMessage(j_common_ptr cinfo)
-    {
-      char message[JMSG_LENGTH_MAX];
-      (*cinfo->err->format_message) (cinfo, message);
-
-      JpegErrorManager* that = reinterpret_cast<JpegErrorManager*>(cinfo->err);
-      that->message = std::string(message);
-    }
-
-
-    void JpegErrorManager::ErrorExit(j_common_ptr cinfo)
-    {
-      (*cinfo->err->output_message) (cinfo);
-
-      JpegErrorManager* that = reinterpret_cast<JpegErrorManager*>(cinfo->err);
-      longjmp(that->setjmp_buffer, 1);
-    }
-      
-
-    JpegErrorManager::JpegErrorManager()
-    {
-      memset(&pub, 0, sizeof(struct jpeg_error_mgr));
-      memset(&setjmp_buffer, 0, sizeof(jmp_buf));
-
-      jpeg_std_error(&pub);
-      pub.error_exit = ErrorExit;
-      pub.output_message = OutputMessage;
-    }
-  }
-}
--- a/Resources/Orthanc/Core/Images/JpegErrorManager.h	Mon May 21 09:02:03 2018 +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-2018 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.
- *
- * 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/>.
- **/
-
-#pragma once
-
-#if !defined(ORTHANC_ENABLE_JPEG)
-#  error The macro ORTHANC_ENABLE_JPEG must be defined
-#endif
-
-#if ORTHANC_ENABLE_JPEG != 1
-#  error JPEG support must be enabled to include this file
-#endif
-
-#include <string.h>
-#include <stdio.h>
-#include <jpeglib.h>
-#include <setjmp.h>
-#include <string>
-
-namespace Orthanc
-{
-  namespace Internals
-  {
-    class JpegErrorManager 
-    {
-    private:
-      struct jpeg_error_mgr pub;  /* "public" fields */
-      jmp_buf setjmp_buffer;      /* for return to caller */
-      std::string message;
-
-      static void OutputMessage(j_common_ptr cinfo);
-
-      static void ErrorExit(j_common_ptr cinfo);
-
-    public:
-      JpegErrorManager();
-
-      struct jpeg_error_mgr* GetPublic()
-      {
-        return &pub;
-      }
-
-      jmp_buf& GetJumpBuffer()
-      {
-        return setjmp_buffer;
-      }
-
-      const std::string& GetMessage() const
-      {
-        return message;
-      }
-    };
-  }
-}
--- a/Resources/Orthanc/Core/Images/JpegReader.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +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-2018 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.
- *
- * 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 "JpegReader.h"
-
-#include "JpegErrorManager.h"
-#include "../OrthancException.h"
-#include "../Logging.h"
-
-#if ORTHANC_SANDBOXED == 0
-#  include "../SystemToolbox.h"
-#endif
-
-
-namespace Orthanc
-{
-  static void Uncompress(struct jpeg_decompress_struct& cinfo,
-                         std::string& content,
-                         ImageAccessor& accessor)
-  {
-    jpeg_read_header(&cinfo, TRUE);
-    jpeg_start_decompress(&cinfo);
-
-    PixelFormat format;
-    if (cinfo.output_components == 1 &&
-        cinfo.out_color_space == JCS_GRAYSCALE)
-    {
-      format = PixelFormat_Grayscale8;
-    }
-    else if (cinfo.output_components == 3 &&
-             cinfo.out_color_space == JCS_RGB)
-    {
-      format = PixelFormat_RGB24;
-    }
-    else
-    {
-      throw OrthancException(ErrorCode_NotImplemented);
-    }
-
-    unsigned int pitch = cinfo.output_width * cinfo.output_components;
-
-    /* Make a one-row-high sample array that will go away when done with image */
-    JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, pitch, 1);
-
-    try
-    {
-      content.resize(pitch * cinfo.output_height);
-    }
-    catch (...)
-    {
-      throw OrthancException(ErrorCode_NotEnoughMemory);
-    }
-
-    accessor.AssignWritable(format, cinfo.output_width, cinfo.output_height, pitch, 
-                            content.empty() ? NULL : &content[0]);
-
-    uint8_t* target = reinterpret_cast<uint8_t*>(&content[0]);
-    while (cinfo.output_scanline < cinfo.output_height) 
-    {
-      jpeg_read_scanlines(&cinfo, buffer, 1);
-      memcpy(target, buffer[0], pitch);
-      target += pitch;
-    }
-
-    // Everything went fine, "setjmp()" didn't get called
-
-    jpeg_finish_decompress(&cinfo);
-  }
-
-
-#if ORTHANC_SANDBOXED == 0
-  void JpegReader::ReadFromFile(const std::string& filename)
-  {
-    FILE* fp = SystemToolbox::OpenFile(filename, FileMode_ReadBinary);
-    if (!fp)
-    {
-      throw OrthancException(ErrorCode_InexistentFile);
-    }
-
-    struct jpeg_decompress_struct cinfo;
-    memset(&cinfo, 0, sizeof(struct jpeg_decompress_struct));
-
-    Internals::JpegErrorManager jerr;
-    cinfo.err = jerr.GetPublic();
-    
-    if (setjmp(jerr.GetJumpBuffer())) 
-    {
-      jpeg_destroy_decompress(&cinfo);
-      fclose(fp);
-      LOG(ERROR) << "Error during JPEG decoding: " << jerr.GetMessage();
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-    // Below this line, we are under the scope of a "setjmp"
-
-    jpeg_create_decompress(&cinfo);
-    jpeg_stdio_src(&cinfo, fp);
-
-    try
-    {
-      Uncompress(cinfo, content_, *this);
-    }
-    catch (OrthancException&)
-    {
-      jpeg_destroy_decompress(&cinfo);
-      fclose(fp);
-      throw;
-    }
-
-    jpeg_destroy_decompress(&cinfo);
-    fclose(fp);
-  }
-#endif
-
-
-  void JpegReader::ReadFromMemory(const void* buffer,
-                                  size_t size)
-  {
-    struct jpeg_decompress_struct cinfo;
-    memset(&cinfo, 0, sizeof(struct jpeg_decompress_struct));
-
-    Internals::JpegErrorManager jerr;
-    cinfo.err = jerr.GetPublic();
-    
-    if (setjmp(jerr.GetJumpBuffer())) 
-    {
-      jpeg_destroy_decompress(&cinfo);
-      LOG(ERROR) << "Error during JPEG decoding: " << jerr.GetMessage();
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-    // Below this line, we are under the scope of a "setjmp"
-    jpeg_create_decompress(&cinfo);
-    jpeg_mem_src(&cinfo, const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(buffer)), size);
-
-    try
-    {
-      Uncompress(cinfo, content_, *this);
-    }
-    catch (OrthancException&)
-    {
-      jpeg_destroy_decompress(&cinfo);
-      throw;
-    }
-
-    jpeg_destroy_decompress(&cinfo);
-  }
-
-
-  void JpegReader::ReadFromMemory(const std::string& buffer)
-  {
-    if (buffer.empty())
-    {
-      ReadFromMemory(NULL, 0);
-    }
-    else
-    {
-      ReadFromMemory(buffer.c_str(), buffer.size());
-    }
-  }
-}
--- a/Resources/Orthanc/Core/Images/JpegReader.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_SANDBOXED)
-#  error The macro ORTHANC_SANDBOXED must be defined
-#endif
-
-#if !defined(ORTHANC_ENABLE_JPEG)
-#  error The macro ORTHANC_ENABLE_JPEG must be defined
-#endif
-
-#if ORTHANC_ENABLE_JPEG != 1
-#  error JPEG support must be enabled to include this file
-#endif
-
-#include "ImageAccessor.h"
-
-#include <string>
-#include <boost/noncopyable.hpp>
-
-namespace Orthanc
-{
-  class JpegReader : 
-    public ImageAccessor,
-    public boost::noncopyable
-  {
-  private:
-    std::string  content_;
-
-  public:
-#if ORTHANC_SANDBOXED == 0
-    void ReadFromFile(const std::string& filename);
-#endif
-
-    void ReadFromMemory(const void* buffer,
-                        size_t size);
-
-    void ReadFromMemory(const std::string& buffer);
-  };
-}
--- a/Resources/Orthanc/Core/Images/JpegWriter.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,211 +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-2018 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.
- *
- * 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 "JpegWriter.h"
-
-#include "../OrthancException.h"
-#include "../Logging.h"
-#include "JpegErrorManager.h"
-
-#if ORTHANC_SANDBOXED == 0
-#  include "../SystemToolbox.h"
-#endif
-
-#include <stdlib.h>
-#include <vector>
-
-namespace Orthanc
-{
-  static void GetLines(std::vector<uint8_t*>& lines,
-                       unsigned int height,
-                       unsigned int pitch,
-                       PixelFormat format,
-                       const void* buffer)
-  {
-    if (format != PixelFormat_Grayscale8 &&
-        format != PixelFormat_RGB24)
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    lines.resize(height);
-
-    uint8_t* base = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(buffer));
-    for (unsigned int y = 0; y < height; y++)
-    {
-      lines[y] = base + static_cast<intptr_t>(y) * static_cast<intptr_t>(pitch);
-    }
-  }
-
-
-  static void Compress(struct jpeg_compress_struct& cinfo,
-                       std::vector<uint8_t*>& lines,
-                       unsigned int width,
-                       unsigned int height,
-                       PixelFormat format,
-                       uint8_t quality)
-  {
-    cinfo.image_width = width;
-    cinfo.image_height = height;
-
-    switch (format)
-    {
-      case PixelFormat_Grayscale8:
-        cinfo.input_components = 1;
-        cinfo.in_color_space = JCS_GRAYSCALE;
-        break;
-
-      case PixelFormat_RGB24:
-        cinfo.input_components = 3;
-        cinfo.in_color_space = JCS_RGB;
-        break;
-
-      default:
-        throw OrthancException(ErrorCode_InternalError);
-    }
-
-    jpeg_set_defaults(&cinfo);
-    jpeg_set_quality(&cinfo, quality, TRUE);
-    jpeg_start_compress(&cinfo, TRUE);
-    jpeg_write_scanlines(&cinfo, &lines[0], height);
-    jpeg_finish_compress(&cinfo);
-    jpeg_destroy_compress(&cinfo);
-  }
-                       
-
-  void JpegWriter::SetQuality(uint8_t quality)
-  {
-    if (quality == 0 || quality > 100)
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    quality_ = quality;
-  }
-
-
-#if ORTHANC_SANDBOXED == 0
-  void JpegWriter::WriteToFileInternal(const std::string& filename,
-                                       unsigned int width,
-                                       unsigned int height,
-                                       unsigned int pitch,
-                                       PixelFormat format,
-                                       const void* buffer)
-  {
-    FILE* fp = SystemToolbox::OpenFile(filename, FileMode_WriteBinary);
-    if (fp == NULL)
-    {
-      throw OrthancException(ErrorCode_CannotWriteFile);
-    }
-
-    std::vector<uint8_t*> lines;
-    GetLines(lines, height, pitch, format, buffer);
-
-    struct jpeg_compress_struct cinfo;
-    memset(&cinfo, 0, sizeof(struct jpeg_compress_struct));
-
-    Internals::JpegErrorManager jerr;
-    cinfo.err = jerr.GetPublic();
-
-    if (setjmp(jerr.GetJumpBuffer())) 
-    {
-      /* If we get here, the JPEG code has signaled an error.
-       * We need to clean up the JPEG object, close the input file, and return.
-       */
-      jpeg_destroy_compress(&cinfo);
-      fclose(fp);
-      LOG(ERROR) << "Error during JPEG encoding: " << jerr.GetMessage();
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-    // Do not allocate data on the stack below this line!
-
-    jpeg_create_compress(&cinfo);
-    jpeg_stdio_dest(&cinfo, fp);
-    Compress(cinfo, lines, width, height, format, quality_);
-
-    // Everything went fine, "setjmp()" didn't get called
-
-    fclose(fp);
-  }
-#endif
-
-
-#if ORTHANC_SANDBOXED == 0
-  void JpegWriter::WriteToMemoryInternal(std::string& jpeg,
-                                         unsigned int width,
-                                         unsigned int height,
-                                         unsigned int pitch,
-                                         PixelFormat format,
-                                         const void* buffer)
-  {
-    std::vector<uint8_t*> lines;
-    GetLines(lines, height, pitch, format, buffer);
-
-    struct jpeg_compress_struct cinfo;
-    memset(&cinfo, 0, sizeof(struct jpeg_compress_struct));
-
-    Internals::JpegErrorManager jerr;
-
-    unsigned char* data = NULL;
-    unsigned long size;
-
-    if (setjmp(jerr.GetJumpBuffer())) 
-    {
-      jpeg_destroy_compress(&cinfo);
-
-      if (data != NULL)
-      {
-        free(data);
-      }
-
-      LOG(ERROR) << "Error during JPEG encoding: " << jerr.GetMessage();
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-    // Do not allocate data on the stack below this line!
-
-    jpeg_create_compress(&cinfo);
-    cinfo.err = jerr.GetPublic();
-    jpeg_mem_dest(&cinfo, &data, &size);
-
-    Compress(cinfo, lines, width, height, format, quality_);
-
-    // Everything went fine, "setjmp()" didn't get called
-
-    jpeg.assign(reinterpret_cast<const char*>(data), size);
-    free(data);
-  }
-#endif
-}
--- a/Resources/Orthanc/Core/Images/JpegWriter.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_ENABLE_JPEG)
-#  error The macro ORTHANC_ENABLE_JPEG must be defined
-#endif
-
-#if ORTHANC_ENABLE_JPEG != 1
-#  error JPEG support must be enabled to include this file
-#endif
-
-#include "IImageWriter.h"
-
-namespace Orthanc
-{
-  class JpegWriter : public IImageWriter
-  {
-  protected:
-    virtual void WriteToFileInternal(const std::string& filename,
-                                     unsigned int width,
-                                     unsigned int height,
-                                     unsigned int pitch,
-                                     PixelFormat format,
-                                     const void* buffer);
-
-#if ORTHANC_SANDBOXED == 0
-    virtual void WriteToMemoryInternal(std::string& jpeg,
-                                       unsigned int width,
-                                       unsigned int height,
-                                       unsigned int pitch,
-                                       PixelFormat format,
-                                       const void* buffer);
-#endif
-
-  private:
-    uint8_t  quality_;
-
-  public:
-    JpegWriter() : quality_(90)
-    {
-    }
-
-    void SetQuality(uint8_t quality);
-
-    uint8_t GetQuality() const
-    {
-      return quality_;
-    }
-  };
-}
--- a/Resources/Orthanc/Core/Images/PixelTraits.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,267 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "../Enumerations.h"
-#include "../OrthancException.h"
-
-#include <limits>
-
-namespace Orthanc
-{
-  template <PixelFormat format,
-            typename _PixelType>
-  struct IntegerPixelTraits
-  {
-    typedef _PixelType  PixelType;
-
-    ORTHANC_FORCE_INLINE
-    static PixelFormat GetPixelFormat()
-    {
-      return format;
-    }
-
-    ORTHANC_FORCE_INLINE
-    static PixelType IntegerToPixel(int64_t value)
-    {
-      if (value < static_cast<int64_t>(std::numeric_limits<PixelType>::min()) ||
-          value > static_cast<int64_t>(std::numeric_limits<PixelType>::max()))
-      {
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-      }
-      else
-      {
-        return static_cast<PixelType>(value);
-      }
-    }
-
-    ORTHANC_FORCE_INLINE
-    static void SetZero(PixelType& target)
-    {
-      target = 0;
-    }
-
-    ORTHANC_FORCE_INLINE
-    static void SetMinValue(PixelType& target)
-    {
-      target = std::numeric_limits<PixelType>::min();
-    }
-
-    ORTHANC_FORCE_INLINE
-    static void SetMaxValue(PixelType& target)
-    {
-      target = std::numeric_limits<PixelType>::max();
-    }
-
-    ORTHANC_FORCE_INLINE
-    static void Copy(PixelType& target,
-                     const PixelType& source)
-    {
-      target = source;
-    }
-
-    ORTHANC_FORCE_INLINE
-    static float PixelToFloat(const PixelType& source)
-    {
-      return static_cast<float>(source);
-    }
-
-    ORTHANC_FORCE_INLINE
-    static void FloatToPixel(PixelType& target,
-                             float value)
-    {
-      if (value < static_cast<float>(std::numeric_limits<PixelType>::min()))
-      {
-        target = std::numeric_limits<PixelType>::min();
-      }
-      else if (value > static_cast<float>(std::numeric_limits<PixelType>::max()))
-      {
-        target = std::numeric_limits<PixelType>::max();
-      }
-      else
-      {
-        target = static_cast<PixelType>(value);
-      }
-    }
-
-    ORTHANC_FORCE_INLINE
-    static bool IsEqual(const PixelType& a,
-                        const PixelType& b)
-    {
-      return a == b;
-    }
-  };
-
-
-  template <PixelFormat Format>
-  struct PixelTraits;
-
-
-  template <>
-  struct PixelTraits<PixelFormat_Grayscale8> :
-    public IntegerPixelTraits<PixelFormat_Grayscale8, uint8_t>
-  {
-  };
-
-  
-  template <>
-  struct PixelTraits<PixelFormat_Grayscale16> :
-    public IntegerPixelTraits<PixelFormat_Grayscale16, uint16_t>
-  {
-  };
-
-  
-  template <>
-  struct PixelTraits<PixelFormat_SignedGrayscale16> :
-    public IntegerPixelTraits<PixelFormat_SignedGrayscale16, int16_t>
-  {
-  };
-
-
-  template <>
-  struct PixelTraits<PixelFormat_RGB24>
-  {
-    struct PixelType
-    {
-      uint8_t  red_;
-      uint8_t  green_;
-      uint8_t  blue_;
-    };
-
-    ORTHANC_FORCE_INLINE
-    static PixelFormat GetPixelFormat()
-    {
-      return PixelFormat_RGB24;
-    }
-
-    ORTHANC_FORCE_INLINE
-    static void SetZero(PixelType& target)
-    {
-      target.red_ = 0;
-      target.green_ = 0;
-      target.blue_ = 0;
-    }
-
-    ORTHANC_FORCE_INLINE
-    static void Copy(PixelType& target,
-                     const PixelType& source)
-    {
-      target.red_ = source.red_;
-      target.green_ = source.green_;
-      target.blue_ = source.blue_;
-    }
-
-    ORTHANC_FORCE_INLINE
-    static bool IsEqual(const PixelType& a,
-                        const PixelType& b)
-    {
-      return (a.red_ == b.red_ &&
-              a.green_ == b.green_ &&
-              a.blue_ == b.blue_);
-    }
-
-    ORTHANC_FORCE_INLINE
-    static void FloatToPixel(PixelType& target,
-                             float value)
-    {
-      uint8_t v;
-      PixelTraits<PixelFormat_Grayscale8>::FloatToPixel(v, value);
-
-      target.red_ = v;
-      target.green_ = v;
-      target.blue_ = v;
-    }
-  };
-
-
-  template <>
-  struct PixelTraits<PixelFormat_BGRA32>
-  {
-    struct PixelType
-    {
-      uint8_t  blue_;
-      uint8_t  green_;
-      uint8_t  red_;
-      uint8_t  alpha_;
-    };
-
-    ORTHANC_FORCE_INLINE
-    static PixelFormat GetPixelFormat()
-    {
-      return PixelFormat_BGRA32;
-    }
-
-    ORTHANC_FORCE_INLINE
-    static void SetZero(PixelType& target)
-    {
-      target.blue_ = 0;
-      target.green_ = 0;
-      target.red_ = 0;
-      target.alpha_ = 0;
-    }
-
-    ORTHANC_FORCE_INLINE
-    static void Copy(PixelType& target,
-                     const PixelType& source)
-    {
-      target.blue_ = source.blue_;
-      target.green_ = source.green_;
-      target.red_ = source.red_;
-      target.alpha_ = source.alpha_;
-    }
-
-    ORTHANC_FORCE_INLINE
-    static bool IsEqual(const PixelType& a,
-                        const PixelType& b)
-    {
-      return (a.blue_ == b.blue_ &&
-              a.green_ == b.green_ &&
-              a.red_ == b.red_ &&
-              a.alpha_ == b.alpha_);
-    }
-
-    ORTHANC_FORCE_INLINE
-    static void FloatToPixel(PixelType& target,
-                             float value)
-    {
-      uint8_t v;
-      PixelTraits<PixelFormat_Grayscale8>::FloatToPixel(v, value);
-
-      target.blue_ = v;
-      target.green_ = v;
-      target.red_ = v;
-      target.alpha_ = 255;      
-    }
-  };
-}
--- a/Resources/Orthanc/Core/Images/PngReader.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,325 +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-2018 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.
- *
- * 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 "PngReader.h"
-
-#include "../OrthancException.h"
-#include "../Toolbox.h"
-
-#if ORTHANC_SANDBOXED == 0
-#  include "../SystemToolbox.h"
-#endif
-
-#include <png.h>
-#include <string.h>  // For memcpy()
-
-namespace Orthanc
-{
-#if ORTHANC_SANDBOXED == 0
-  namespace 
-  {
-    struct FileRabi
-    {
-      FILE* fp_;
-
-      FileRabi(const char* filename)
-      {
-        fp_ = SystemToolbox::OpenFile(filename, FileMode_ReadBinary);
-        if (!fp_)
-        {
-          throw OrthancException(ErrorCode_InexistentFile);
-        }
-      }
-
-      ~FileRabi()
-      {
-        if (fp_)
-        {
-          fclose(fp_);
-        }
-      }
-    };
-  }
-#endif
-
-
-  struct PngReader::PngRabi
-  {
-    png_structp png_;
-    png_infop info_;
-    png_infop endInfo_;
-
-    void Destruct()
-    {
-      if (png_)
-      {
-        png_destroy_read_struct(&png_, &info_, &endInfo_);
-
-        png_ = NULL;
-        info_ = NULL;
-        endInfo_ = NULL;
-      }
-    }
-
-    PngRabi()
-    {
-      png_ = NULL;
-      info_ = NULL;
-      endInfo_ = NULL;
-
-      png_ = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-      if (!png_)
-      {
-        throw OrthancException(ErrorCode_NotEnoughMemory);
-      }
-
-      info_ = png_create_info_struct(png_);
-      if (!info_)
-      {
-        png_destroy_read_struct(&png_, NULL, NULL);
-        throw OrthancException(ErrorCode_NotEnoughMemory);
-      }
-
-      endInfo_ = png_create_info_struct(png_);
-      if (!info_)
-      {
-        png_destroy_read_struct(&png_, &info_, NULL);
-        throw OrthancException(ErrorCode_NotEnoughMemory);
-      }
-    }
-
-    ~PngRabi()
-    {
-      Destruct();
-    }
-
-    static void MemoryCallback(png_structp png_ptr, 
-                               png_bytep data, 
-                               png_size_t size);
-  };
-
-
-  void PngReader::CheckHeader(const void* header)
-  {
-    int is_png = !png_sig_cmp((png_bytep) header, 0, 8);
-    if (!is_png)
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-  }
-
-  PngReader::PngReader()
-  {
-  }
-
-  void PngReader::Read(PngRabi& rabi)
-  {
-    png_set_sig_bytes(rabi.png_, 8);
-
-    png_read_info(rabi.png_, rabi.info_);
-
-    png_uint_32 width, height;
-    int bit_depth, color_type, interlace_type;
-    int compression_type, filter_method;
-    // get size and bit-depth of the PNG-image
-    png_get_IHDR(rabi.png_, rabi.info_,
-                 &width, &height,
-                 &bit_depth, &color_type, &interlace_type,
-                 &compression_type, &filter_method);
-
-    PixelFormat format;
-    unsigned int pitch;
-
-    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 8)
-    {
-      format = PixelFormat_Grayscale8;
-      pitch = width;
-    }
-    else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 16)
-    {
-      format = PixelFormat_Grayscale16;
-      pitch = 2 * width;
-
-      if (Toolbox::DetectEndianness() == Endianness_Little)
-      {
-        png_set_swap(rabi.png_);
-      }
-    }
-    else if (color_type == PNG_COLOR_TYPE_RGB && bit_depth == 8)
-    {
-      format = PixelFormat_RGB24;
-      pitch = 3 * width;
-    }
-    else if (color_type == PNG_COLOR_TYPE_RGBA && bit_depth == 8)
-    {
-      format = PixelFormat_RGBA32;
-      pitch = 4 * width;
-    }
-    else
-    {
-      throw OrthancException(ErrorCode_NotImplemented);
-    }
-
-    data_.resize(height * pitch);
-
-    if (height == 0 || width == 0)
-    {
-      // Empty image, we are done
-      AssignEmpty(format);
-      return;
-    }
-    
-    png_read_update_info(rabi.png_, rabi.info_);
-
-    std::vector<png_bytep> rows(height);
-    for (size_t i = 0; i < height; i++)
-    {
-      rows[i] = &data_[0] + i * pitch;
-    }
-
-    png_read_image(rabi.png_, &rows[0]);
-
-    AssignWritable(format, width, height, pitch, &data_[0]);
-  }
-
-
-#if ORTHANC_SANDBOXED == 0
-  void PngReader::ReadFromFile(const std::string& filename)
-  {
-    FileRabi f(filename.c_str());
-
-    char header[8];
-    if (fread(header, 1, 8, f.fp_) != 8)
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-
-    CheckHeader(header);
-
-    PngRabi rabi;
-
-    if (setjmp(png_jmpbuf(rabi.png_)))
-    {
-      rabi.Destruct();
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-
-    png_init_io(rabi.png_, f.fp_);
-
-    Read(rabi);
-  }
-#endif
-
-
-  namespace
-  {
-    struct MemoryBuffer
-    {
-      const uint8_t* buffer_;
-      size_t size_;
-      size_t pos_;
-      bool ok_;
-    };
-  }
-
-
-  void PngReader::PngRabi::MemoryCallback(png_structp png_ptr, 
-                                          png_bytep outBytes, 
-                                          png_size_t byteCountToRead)
-  {
-    MemoryBuffer* from = reinterpret_cast<MemoryBuffer*>(png_get_io_ptr(png_ptr));
-
-    if (!from->ok_)
-    {
-      return;
-    }
-
-    if (from->pos_ + byteCountToRead > from->size_)
-    {
-      from->ok_ = false;
-      return;
-    }
-
-    memcpy(outBytes, from->buffer_ + from->pos_, byteCountToRead);
-
-    from->pos_ += byteCountToRead;
-  }
-
-
-  void PngReader::ReadFromMemory(const void* buffer,
-                                 size_t size)
-  {
-    if (size < 8)
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-
-    CheckHeader(buffer);
-
-    PngRabi rabi;
-
-    if (setjmp(png_jmpbuf(rabi.png_)))
-    {
-      rabi.Destruct();
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-
-    MemoryBuffer tmp;
-    tmp.buffer_ = reinterpret_cast<const uint8_t*>(buffer) + 8;  // We skip the header
-    tmp.size_ = size - 8;
-    tmp.pos_ = 0;
-    tmp.ok_ = true;
-
-    png_set_read_fn(rabi.png_, &tmp, PngRabi::MemoryCallback);
-
-    Read(rabi);
-
-    if (!tmp.ok_)
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-  }
-
-  void PngReader::ReadFromMemory(const std::string& buffer)
-  {
-    if (buffer.size() != 0)
-    {
-      ReadFromMemory(&buffer[0], buffer.size());
-    }
-    else
-    {
-      ReadFromMemory(NULL, 0);
-    }
-  }
-}
--- a/Resources/Orthanc/Core/Images/PngReader.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_ENABLE_PNG)
-#  error The macro ORTHANC_ENABLE_PNG must be defined
-#endif
-
-#if ORTHANC_ENABLE_PNG != 1
-#  error PNG support must be enabled to include this file
-#endif
-
-#include "ImageAccessor.h"
-
-#include "../Enumerations.h"
-
-#include <vector>
-#include <stdint.h>
-#include <boost/shared_ptr.hpp>
-#include <boost/noncopyable.hpp>
-
-#if !defined(ORTHANC_SANDBOXED)
-#  error The macro ORTHANC_SANDBOXED must be defined
-#endif
-
-namespace Orthanc
-{
-  class PngReader : 
-    public ImageAccessor, 
-    public boost::noncopyable
-  {
-  private:
-    struct PngRabi;
-
-    std::vector<uint8_t> data_;
-
-    void CheckHeader(const void* header);
-
-    void Read(PngRabi& rabi);
-
-  public:
-    PngReader();
-
-#if ORTHANC_SANDBOXED == 0
-    void ReadFromFile(const std::string& filename);
-#endif
-
-    void ReadFromMemory(const void* buffer,
-                        size_t size);
-
-    void ReadFromMemory(const std::string& buffer);
-  };
-}
--- a/Resources/Orthanc/Core/Images/PngWriter.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,276 +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-2018 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.
- *
- * 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 "PngWriter.h"
-
-#include <vector>
-#include <stdint.h>
-#include <png.h>
-#include "../OrthancException.h"
-#include "../ChunkedBuffer.h"
-#include "../Toolbox.h"
-
-#if ORTHANC_SANDBOXED == 0
-#  include "../SystemToolbox.h"
-#endif
-
-
-// http://www.libpng.org/pub/png/libpng-1.2.5-manual.html#section-4
-// http://zarb.org/~gc/html/libpng.html
-/*
-  void write_row_callback(png_ptr, png_uint_32 row, int pass)
-  {
-  }*/
-
-
-
-
-/*  bool isError_;
-
-// http://www.libpng.org/pub/png/book/chapter14.html#png.ch14.div.2
-
-static void ErrorHandler(png_structp png, png_const_charp message)
-{
-printf("** [%s]\n", message);
-
-PngWriter* that = (PngWriter*) png_get_error_ptr(png);
-that->isError_ = true;
-printf("** %d\n", (int)that);
-
-//((PngWriter*) payload)->isError_ = true;
-}
-
-static void WarningHandler(png_structp png, png_const_charp message)
-{
-  printf("++ %d\n", (int)message);
-}*/
-
-
-namespace Orthanc
-{
-  struct PngWriter::PImpl
-  {
-    png_structp png_;
-    png_infop info_;
-
-    // Filled by Prepare()
-    std::vector<uint8_t*> rows_;
-    int bitDepth_;
-    int colorType_;
-  };
-
-
-
-  PngWriter::PngWriter() : pimpl_(new PImpl)
-  {
-    pimpl_->png_ = NULL;
-    pimpl_->info_ = NULL;
-
-    pimpl_->png_ = png_create_write_struct
-      (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); //this, ErrorHandler, WarningHandler);
-    if (!pimpl_->png_)
-    {
-      throw OrthancException(ErrorCode_NotEnoughMemory);
-    }
-
-    pimpl_->info_ = png_create_info_struct(pimpl_->png_);
-    if (!pimpl_->info_)
-    {
-      png_destroy_write_struct(&pimpl_->png_, NULL);
-      throw OrthancException(ErrorCode_NotEnoughMemory);
-    }
-  }
-
-  PngWriter::~PngWriter()
-  {
-    if (pimpl_->info_)
-    {
-      png_destroy_info_struct(pimpl_->png_, &pimpl_->info_);
-    }
-
-    if (pimpl_->png_)
-    {
-      png_destroy_write_struct(&pimpl_->png_, NULL);
-    }
-  }
-
-
-
-  void PngWriter::Prepare(unsigned int width,
-                          unsigned int height,
-                          unsigned int pitch,
-                          PixelFormat format,
-                          const void* buffer)
-  {
-    pimpl_->rows_.resize(height);
-    for (unsigned int y = 0; y < height; y++)
-    {
-      pimpl_->rows_[y] = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(buffer)) + y * pitch;
-    }
-
-    switch (format)
-    {
-    case PixelFormat_RGB24:
-      pimpl_->bitDepth_ = 8;
-      pimpl_->colorType_ = PNG_COLOR_TYPE_RGB;
-      break;
-
-    case PixelFormat_RGBA32:
-      pimpl_->bitDepth_ = 8;
-      pimpl_->colorType_ = PNG_COLOR_TYPE_RGBA;
-      break;
-
-    case PixelFormat_Grayscale8:
-      pimpl_->bitDepth_ = 8;
-      pimpl_->colorType_ = PNG_COLOR_TYPE_GRAY;
-      break;
-
-    case PixelFormat_Grayscale16:
-    case PixelFormat_SignedGrayscale16:
-      pimpl_->bitDepth_ = 16;
-      pimpl_->colorType_ = PNG_COLOR_TYPE_GRAY;
-      break;
-
-    default:
-      throw OrthancException(ErrorCode_NotImplemented);
-    }
-  }
-
-
-  void PngWriter::Compress(unsigned int width,
-                           unsigned int height,
-                           unsigned int pitch,
-                           PixelFormat format)
-  {
-    png_set_IHDR(pimpl_->png_, pimpl_->info_, width, height,
-                 pimpl_->bitDepth_, pimpl_->colorType_, PNG_INTERLACE_NONE,
-                 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
-    png_write_info(pimpl_->png_, pimpl_->info_);
-
-    if (height > 0)
-    {
-      switch (format)
-      {
-      case PixelFormat_Grayscale16:
-      case PixelFormat_SignedGrayscale16:
-      {
-        int transforms = 0;
-        if (Toolbox::DetectEndianness() == Endianness_Little)
-        {
-          transforms = PNG_TRANSFORM_SWAP_ENDIAN;
-        }
-
-        png_set_rows(pimpl_->png_, pimpl_->info_, &pimpl_->rows_[0]);
-        png_write_png(pimpl_->png_, pimpl_->info_, transforms, NULL);
-
-        break;
-      }
-
-      default:
-        png_write_image(pimpl_->png_, &pimpl_->rows_[0]);
-      }
-    }
-
-    png_write_end(pimpl_->png_, NULL);
-  }
-
-
-#if ORTHANC_SANDBOXED == 0
-  void PngWriter::WriteToFileInternal(const std::string& filename,
-                                      unsigned int width,
-                                      unsigned int height,
-                                      unsigned int pitch,
-                                      PixelFormat format,
-                                      const void* buffer)
-  {
-    Prepare(width, height, pitch, format, buffer);
-
-    FILE* fp = SystemToolbox::OpenFile(filename, FileMode_WriteBinary);
-    if (!fp)
-    {
-      throw OrthancException(ErrorCode_CannotWriteFile);
-    }    
-
-    png_init_io(pimpl_->png_, fp);
-
-    if (setjmp(png_jmpbuf(pimpl_->png_)))
-    {
-      // Error during writing PNG
-      throw OrthancException(ErrorCode_CannotWriteFile);      
-    }
-
-    Compress(width, height, pitch, format);
-
-    fclose(fp);
-  }
-#endif
-
-
-  static void MemoryCallback(png_structp png_ptr, 
-                             png_bytep data, 
-                             png_size_t size)
-  {
-    ChunkedBuffer* buffer = reinterpret_cast<ChunkedBuffer*>(png_get_io_ptr(png_ptr));
-    buffer->AddChunk(reinterpret_cast<const char*>(data), size);
-  }
-
-
-
-#if ORTHANC_SANDBOXED == 0
-  void PngWriter::WriteToMemoryInternal(std::string& png,
-                                        unsigned int width,
-                                        unsigned int height,
-                                        unsigned int pitch,
-                                        PixelFormat format,
-                                        const void* buffer)
-  {
-    ChunkedBuffer chunks;
-
-    Prepare(width, height, pitch, format, buffer);
-
-    if (setjmp(png_jmpbuf(pimpl_->png_)))
-    {
-      // Error during writing PNG
-      throw OrthancException(ErrorCode_InternalError);      
-    }
-
-    png_set_write_fn(pimpl_->png_, &chunks, MemoryCallback, NULL);
-
-    Compress(width, height, pitch, format);
-
-    chunks.Flatten(png);
-  }
-#endif
-}
--- a/Resources/Orthanc/Core/Images/PngWriter.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_ENABLE_PNG)
-#  error The macro ORTHANC_ENABLE_PNG must be defined
-#endif
-
-#if ORTHANC_ENABLE_PNG != 1
-#  error PNG support must be enabled to include this file
-#endif
-
-#include "IImageWriter.h"
-
-#include <boost/shared_ptr.hpp>
-
-namespace Orthanc
-{
-  class PngWriter : public IImageWriter
-  {
-  protected:
-    virtual void WriteToFileInternal(const std::string& filename,
-                                     unsigned int width,
-                                     unsigned int height,
-                                     unsigned int pitch,
-                                     PixelFormat format,
-                                     const void* buffer);
-
-#if ORTHANC_SANDBOXED == 0
-    virtual void WriteToMemoryInternal(std::string& png,
-                                       unsigned int width,
-                                       unsigned int height,
-                                       unsigned int pitch,
-                                       PixelFormat format,
-                                       const void* buffer);
-#endif
-
-  private:
-    struct PImpl;
-    boost::shared_ptr<PImpl> pimpl_;
-
-    void Compress(unsigned int width,
-                  unsigned int height,
-                  unsigned int pitch,
-                  PixelFormat format);
-
-    void Prepare(unsigned int width,
-                 unsigned int height,
-                 unsigned int pitch,
-                 PixelFormat format,
-                 const void* buffer);
-
-  public:
-    PngWriter();
-
-    ~PngWriter();
-  };
-}
--- a/Resources/Orthanc/Core/Logging.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,603 +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-2018 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.
- *
- * 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 "Logging.h"
-
-#if ORTHANC_ENABLE_LOGGING != 1
-
-namespace Orthanc
-{
-  namespace Logging
-  {
-    void Initialize()
-    {
-    }
-
-    void Finalize()
-    {
-    }
-
-    void Reset()
-    {
-    }
-
-    void Flush()
-    {
-    }
-
-    void EnableInfoLevel(bool enabled)
-    {
-    }
-
-    void EnableTraceLevel(bool enabled)
-    {
-    }
-
-    void SetTargetFile(const std::string& path)
-    {
-    }
-
-    void SetTargetFolder(const std::string& path)
-    {
-    }
-  }
-}
-
-
-#elif ORTHANC_ENABLE_LOGGING_PLUGIN == 1
-
-/*********************************************************
- * Logger compatible with the Orthanc plugin SDK
- *********************************************************/
-
-#include <boost/lexical_cast.hpp>
-
-namespace Orthanc
-{
-  namespace Logging
-  {
-    static OrthancPluginContext* context_ = NULL;
-
-    void Initialize(OrthancPluginContext* context)
-    {
-      context_ = context;
-    }
-
-    InternalLogger::InternalLogger(InternalLevel level,
-                                   const char* file  /* ignored */,
-                                   int line  /* ignored */) :
-      level_(level)
-    {
-    }
-
-    InternalLogger::~InternalLogger()
-    {
-      if (context_ != NULL)
-      {
-        switch (level_)
-        {
-          case InternalLevel_ERROR:
-            OrthancPluginLogError(context_, message_.c_str());
-            break;
-
-          case InternalLevel_WARNING:
-            OrthancPluginLogWarning(context_, message_.c_str());
-            break;
-
-          case InternalLevel_INFO:
-            OrthancPluginLogInfo(context_, message_.c_str());
-            break;
-
-          case InternalLevel_TRACE:
-            // Not used by plugins
-            break;
-
-          default:
-          {
-            std::string s = ("Unknown log level (" + boost::lexical_cast<std::string>(level_) +
-                             ") for message: " + message_);
-            OrthancPluginLogError(context_, s.c_str());
-            break;
-          }
-        }
-      }
-    }
-  }
-}
-
-
-#elif ORTHANC_ENABLE_LOGGING_STDIO == 1
-
-/*********************************************************
- * Logger compatible with <stdio.h>
- *********************************************************/
-
-#include <stdio.h>
-#include <boost/lexical_cast.hpp>
-
-namespace Orthanc
-{
-  namespace Logging
-  {
-    static bool globalVerbose_ = false;
-    static bool globalTrace_ = false;
-    
-    InternalLogger::InternalLogger(InternalLevel level,
-                                   const char* file  /* ignored */,
-                                   int line  /* ignored */) :
-      level_(level)
-    {
-    }
-
-    InternalLogger::~InternalLogger()
-    {
-      switch (level_)
-      {
-        case InternalLevel_ERROR:
-          fprintf(stderr, "E: %s\n", message_.c_str());
-          break;
-
-        case InternalLevel_WARNING:
-          fprintf(stdout, "W: %s\n", message_.c_str());
-          break;
-
-        case InternalLevel_INFO:
-          if (globalVerbose_)
-          {
-            fprintf(stdout, "I: %s\n", message_.c_str());
-          }
-          break;
-
-        case InternalLevel_TRACE:
-          if (globalTrace_)
-          {
-            fprintf(stdout, "T: %s\n", message_.c_str());
-          }
-          break;
-
-        default:
-          fprintf(stderr, "Unknown log level (%d) for message: %s\n", level_, message_.c_str());
-      }
-    }
-
-    void EnableInfoLevel(bool enabled)
-    {
-      globalVerbose_ = enabled;
-    }
-
-    void EnableTraceLevel(bool enabled)
-    {
-      globalTrace_ = enabled;
-    }
-  }
-}
-
-
-#else  /* ORTHANC_ENABLE_LOGGING_PLUGIN == 0 && 
-          ORTHANC_ENABLE_LOGGING_STDIO == 0 && 
-          ORTHANC_ENABLE_LOGGING == 1 */
-
-/*********************************************************
- * Internal logger of Orthanc, that mimics some
- * behavior from Google Log.
- *********************************************************/
-
-#include "OrthancException.h"
-#include "Enumerations.h"
-#include "Toolbox.h"
-
-#if ORTHANC_SANDBOXED == 1
-#  include <stdio.h>
-#else
-#  include "SystemToolbox.h"
-#endif
-
-#include <fstream>
-#include <boost/filesystem.hpp>
-#include <boost/thread.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-
-
-namespace
-{
-  struct LoggingContext
-  {
-    bool infoEnabled_;
-    bool traceEnabled_;
-    std::string  targetFile_;
-    std::string  targetFolder_;
-
-    std::ostream* error_;
-    std::ostream* warning_;
-    std::ostream* info_;
-
-    std::auto_ptr<std::ofstream> file_;
-
-    LoggingContext() : 
-      infoEnabled_(false),
-      traceEnabled_(false),
-      error_(&std::cerr),
-      warning_(&std::cerr),
-      info_(&std::cerr)
-    {
-    }
-  };
-}
-
-
-
-static std::auto_ptr<LoggingContext> loggingContext_;
-static boost::mutex  loggingMutex_;
-
-
-
-namespace Orthanc
-{
-  namespace Logging
-  {
-    static void GetLogPath(boost::filesystem::path& log,
-                           boost::filesystem::path& link,
-                           const std::string& suffix,
-                           const std::string& directory)
-    {
-      /**
-         From Google Log documentation:
-
-         Unless otherwise specified, logs will be written to the filename
-         "<program name>.<hostname>.<user name>.log<suffix>.",
-         followed by the date, time, and pid (you can't prevent the date,
-         time, and pid from being in the filename).
-
-         In this implementation : "hostname" and "username" are not used
-      **/
-
-      boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
-      boost::filesystem::path root(directory);
-      boost::filesystem::path exe(SystemToolbox::GetPathToExecutable());
-      
-      if (!boost::filesystem::exists(root) ||
-          !boost::filesystem::is_directory(root))
-      {
-        throw OrthancException(ErrorCode_CannotWriteFile);
-      }
-
-      char date[64];
-      sprintf(date, "%04d%02d%02d-%02d%02d%02d.%d",
-              static_cast<int>(now.date().year()),
-              now.date().month().as_number(),
-              now.date().day().as_number(),
-              static_cast<int>(now.time_of_day().hours()),
-              static_cast<int>(now.time_of_day().minutes()),
-              static_cast<int>(now.time_of_day().seconds()),
-              SystemToolbox::GetProcessId());
-
-      std::string programName = exe.filename().replace_extension("").string();
-
-      log = (root / (programName + ".log" + suffix + "." + std::string(date)));
-      link = (root / (programName + ".log" + suffix));
-    }
-
-
-    static void PrepareLogFolder(std::auto_ptr<std::ofstream>& file,
-                                 const std::string& suffix,
-                                 const std::string& directory)
-    {
-      boost::filesystem::path log, link;
-      GetLogPath(log, link, suffix, directory);
-
-#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
-      boost::filesystem::remove(link);
-      boost::filesystem::create_symlink(log.filename(), link);
-#endif
-
-      file.reset(new std::ofstream(log.string().c_str()));
-    }
-
-
-    void Initialize()
-    {
-      boost::mutex::scoped_lock lock(loggingMutex_);
-      loggingContext_.reset(new LoggingContext);
-    }
-
-    void Finalize()
-    {
-      boost::mutex::scoped_lock lock(loggingMutex_);
-      loggingContext_.reset(NULL);
-    }
-
-    void Reset()
-    {
-      // Recover the old logging context
-      std::auto_ptr<LoggingContext> old;
-
-      {
-        boost::mutex::scoped_lock lock(loggingMutex_);
-        if (loggingContext_.get() == NULL)
-        {
-          return;
-        }
-        else
-        {
-          old = loggingContext_;
-
-          // Create a new logging context, 
-          loggingContext_.reset(new LoggingContext);
-        }
-      }
-      
-      EnableInfoLevel(old->infoEnabled_);
-      EnableTraceLevel(old->traceEnabled_);
-
-      if (!old->targetFolder_.empty())
-      {
-        SetTargetFolder(old->targetFolder_);
-      }
-      else if (!old->targetFile_.empty())
-      {
-        SetTargetFile(old->targetFile_);
-      }
-    }
-
-    void EnableInfoLevel(bool enabled)
-    {
-      boost::mutex::scoped_lock lock(loggingMutex_);
-      assert(loggingContext_.get() != NULL);
-
-      loggingContext_->infoEnabled_ = enabled;
-      
-      if (!enabled)
-      {
-        // Also disable the "TRACE" level when info-level debugging is disabled
-        loggingContext_->traceEnabled_ = false;
-      }
-    }
-
-    void EnableTraceLevel(bool enabled)
-    {
-      boost::mutex::scoped_lock lock(loggingMutex_);
-      assert(loggingContext_.get() != NULL);
-
-      loggingContext_->traceEnabled_ = enabled;
-      
-      if (enabled)
-      {
-        // Also enable the "INFO" level when trace-level debugging is enabled
-        loggingContext_->infoEnabled_ = true;
-      }
-    }
-
-
-    static void CheckFile(std::auto_ptr<std::ofstream>& f)
-    {
-      if (loggingContext_->file_.get() == NULL ||
-          !loggingContext_->file_->is_open())
-      {
-        throw OrthancException(ErrorCode_CannotWriteFile);
-      }
-    }
-
-    void SetTargetFolder(const std::string& path)
-    {
-      boost::mutex::scoped_lock lock(loggingMutex_);
-      assert(loggingContext_.get() != NULL);
-
-      PrepareLogFolder(loggingContext_->file_, "" /* no suffix */, path);
-      CheckFile(loggingContext_->file_);
-
-      loggingContext_->targetFile_.clear();
-      loggingContext_->targetFolder_ = path;
-      loggingContext_->warning_ = loggingContext_->file_.get();
-      loggingContext_->error_ = loggingContext_->file_.get();
-      loggingContext_->info_ = loggingContext_->file_.get();
-    }
-
-
-    void SetTargetFile(const std::string& path)
-    {
-      boost::mutex::scoped_lock lock(loggingMutex_);
-      assert(loggingContext_.get() != NULL);
-
-      loggingContext_->file_.reset(new std::ofstream(path.c_str(), std::fstream::app));
-      CheckFile(loggingContext_->file_);
-
-      loggingContext_->targetFile_ = path;
-      loggingContext_->targetFolder_.clear();
-      loggingContext_->warning_ = loggingContext_->file_.get();
-      loggingContext_->error_ = loggingContext_->file_.get();
-      loggingContext_->info_ = loggingContext_->file_.get();
-    }
-
-
-    InternalLogger::InternalLogger(const char* level,
-                                   const char* file,
-                                   int line) : 
-      lock_(loggingMutex_), 
-      stream_(&null_)  // By default, logging to "/dev/null" is simulated
-    {
-      if (loggingContext_.get() == NULL)
-      {
-        fprintf(stderr, "ERROR: Trying to log a message after the finalization of the logging engine\n");
-        return;
-      }
-
-      try
-      {
-        LogLevel l = StringToLogLevel(level);
-      
-        if ((l == LogLevel_Info  && !loggingContext_->infoEnabled_) ||
-            (l == LogLevel_Trace && !loggingContext_->traceEnabled_))
-        {
-          // This logging level is disabled, directly exit and unlock
-          // the mutex to speed-up things. The stream is set to "/dev/null"
-          lock_.unlock();
-          return;
-        }
-
-        // Compute the header of the line, temporary release the lock as
-        // this is a time-consuming operation
-        lock_.unlock();
-        std::string header;
-
-        {
-          boost::filesystem::path path(file);
-          boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
-          boost::posix_time::time_duration duration = now.time_of_day();
-
-          /**
-             From Google Log documentation:
-
-             "Log lines have this form:
-
-             Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
-
-             where the fields are defined as follows:
-
-             L                A single character, representing the log level (eg 'I' for INFO)
-             mm               The month (zero padded; ie May is '05')
-             dd               The day (zero padded)
-             hh:mm:ss.uuuuuu  Time in hours, minutes and fractional seconds
-             threadid         The space-padded thread ID as returned by GetTID() (this matches the PID on Linux)
-             file             The file name
-             line             The line number
-             msg              The user-supplied message"
-
-             In this implementation, "threadid" is not printed.
-          **/
-
-          char date[32];
-          sprintf(date, "%c%02d%02d %02d:%02d:%02d.%06d ",
-                  level[0],
-                  now.date().month().as_number(),
-                  now.date().day().as_number(),
-                  static_cast<int>(duration.hours()),
-                  static_cast<int>(duration.minutes()),
-                  static_cast<int>(duration.seconds()),
-                  static_cast<int>(duration.fractional_seconds()));
-
-          header = std::string(date) + path.filename().string() + ":" + boost::lexical_cast<std::string>(line) + "] ";
-        }
-
-
-        // The header is computed, we now re-lock the mutex to access
-        // the stream objects. Pay attention that "loggingContext_",
-        // "infoEnabled_" or "traceEnabled_" might have changed while
-        // the mutex was unlocked.
-        lock_.lock();
-
-        if (loggingContext_.get() == NULL)
-        {
-          fprintf(stderr, "ERROR: Trying to log a message after the finalization of the logging engine\n");
-          return;
-        }
-
-        switch (l)
-        {
-          case LogLevel_Error:
-            stream_ = loggingContext_->error_;
-            break;
-
-          case LogLevel_Warning:
-            stream_ = loggingContext_->warning_;
-            break;
-
-          case LogLevel_Info:
-            if (loggingContext_->infoEnabled_)
-            {
-              stream_ = loggingContext_->info_;
-            }
-
-            break;
-
-          case LogLevel_Trace:
-            if (loggingContext_->traceEnabled_)
-            {
-              stream_ = loggingContext_->info_;
-            }
-
-            break;
-
-          default:
-            throw OrthancException(ErrorCode_InternalError);
-        }
-
-        if (stream_ == &null_)
-        {
-          // The logging is disabled for this level. The stream is the
-          // "null_" member of this object, so we can release the global
-          // mutex.
-          lock_.unlock();
-        }
-
-        (*stream_) << header;
-      }
-      catch (...)
-      { 
-        // Something is going really wrong, probably running out of
-        // memory. Fallback to a degraded mode.
-        stream_ = loggingContext_->error_;
-        (*stream_) << "E???? ??:??:??.?????? ] ";
-      }
-    }
-
-
-    InternalLogger::~InternalLogger()
-    {
-      if (stream_ != &null_)
-      {
-#if defined(_WIN32)
-        *stream_ << "\r\n";
-#else
-        *stream_ << "\n";
-#endif
-
-        stream_->flush();
-      }
-    }
-      
-
-    void Flush()
-    {
-      boost::mutex::scoped_lock lock(loggingMutex_);
-
-      if (loggingContext_.get() != NULL &&
-          loggingContext_->file_.get() != NULL)
-      {
-        loggingContext_->file_->flush();
-      }
-    }
-  }
-}
-
-#endif   // ORTHANC_ENABLE_LOGGING
--- a/Resources/Orthanc/Core/Logging.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,194 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <iostream>
-
-#if !defined(ORTHANC_ENABLE_LOGGING)
-#  error The macro ORTHANC_ENABLE_LOGGING must be defined
-#endif
-
-#if !defined(ORTHANC_ENABLE_LOGGING_PLUGIN)
-#  if ORTHANC_ENABLE_LOGGING == 1
-#    error The macro ORTHANC_ENABLE_LOGGING_PLUGIN must be defined
-#  else
-#    define ORTHANC_ENABLE_LOGGING_PLUGIN 0
-#  endif
-#endif
-
-#if !defined(ORTHANC_ENABLE_LOGGING_STDIO)
-#  if ORTHANC_ENABLE_LOGGING == 1
-#    error The macro ORTHANC_ENABLE_LOGGING_STDIO must be defined
-#  else
-#    define ORTHANC_ENABLE_LOGGING_STDIO 0
-#  endif
-#endif
-
-#if ORTHANC_ENABLE_LOGGING_PLUGIN == 1
-#  include <orthanc/OrthancCPlugin.h>
-#endif
-
-#include <boost/lexical_cast.hpp>
-
-namespace Orthanc
-{
-  namespace Logging
-  {
-#if ORTHANC_ENABLE_LOGGING_PLUGIN == 1
-    void Initialize(OrthancPluginContext* context);
-#else
-    void Initialize();
-#endif
-
-    void Finalize();
-
-    void Reset();
-
-    void Flush();
-
-    void EnableInfoLevel(bool enabled);
-
-    void EnableTraceLevel(bool enabled);
-
-    void SetTargetFile(const std::string& path);
-
-    void SetTargetFolder(const std::string& path);
-
-    struct NullStream : public std::ostream 
-    {
-      NullStream() : 
-        std::ios(0), 
-        std::ostream(0)
-      {
-      }
-      
-      template <typename T>
-      std::ostream& operator<< (const T& message)
-      {
-        return *this;
-      }
-    };
-  }
-}
-
-
-#if ORTHANC_ENABLE_LOGGING != 1
-
-#  define LOG(level)   ::Orthanc::Logging::NullStream()
-#  define VLOG(level)  ::Orthanc::Logging::NullStream()
-
-
-#elif (ORTHANC_ENABLE_LOGGING_PLUGIN == 1 ||    \
-       ORTHANC_ENABLE_LOGGING_STDIO == 1)
-
-#  include <boost/noncopyable.hpp>
-#  define LOG(level)  ::Orthanc::Logging::InternalLogger \
-  (::Orthanc::Logging::InternalLevel_ ## level, __FILE__, __LINE__)
-#  define VLOG(level) ::Orthanc::Logging::InternalLogger \
-  (::Orthanc::Logging::InternalLevel_TRACE, __FILE__, __LINE__)
-
-namespace Orthanc
-{
-  namespace Logging
-  {
-    enum InternalLevel
-    {
-      InternalLevel_ERROR,
-      InternalLevel_WARNING,
-      InternalLevel_INFO,
-      InternalLevel_TRACE
-    };
-    
-    class InternalLogger : public boost::noncopyable
-    {
-    private:
-      InternalLevel  level_;
-      std::string    message_;
-
-    public:
-      InternalLogger(InternalLevel level,
-                     const char* file,
-                     int line);
-
-      ~InternalLogger();
-      
-      template <typename T>
-      InternalLogger& operator<< (const T& message)
-      {
-        message_ += boost::lexical_cast<std::string>(message);
-        return *this;
-      }
-    };
-  }
-}
-
-
-
-
-#else  /* ORTHANC_ENABLE_LOGGING_PLUGIN == 0 && 
-          ORTHANC_ENABLE_LOGGING_STDIO == 0 && 
-          ORTHANC_ENABLE_LOGGING == 1 */
-
-#  include <boost/thread/mutex.hpp>
-#  define LOG(level)  ::Orthanc::Logging::InternalLogger(#level,  __FILE__, __LINE__)
-#  define VLOG(level) ::Orthanc::Logging::InternalLogger("TRACE", __FILE__, __LINE__)
-
-namespace Orthanc
-{
-  namespace Logging
-  {
-    class InternalLogger
-    {
-    private:
-      boost::mutex::scoped_lock lock_;
-      NullStream                null_;
-      std::ostream*             stream_;
-
-    public:
-      InternalLogger(const char* level,
-                     const char* file,
-                     int line);
-
-      ~InternalLogger();
-      
-      template <typename T>
-      std::ostream& operator<< (const T& message)
-      {
-        return (*stream_) << boost::lexical_cast<std::string>(message);
-      }
-    };
-  }
-}
-
-#endif  // ORTHANC_ENABLE_LOGGING
--- a/Resources/Orthanc/Core/MultiThreading/BagOfTasks.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "../ICommand.h"
-
-#include <list>
-#include <cstddef>
-
-namespace Orthanc
-{
-  class BagOfTasks : public boost::noncopyable
-  {
-  private:
-    typedef std::list<ICommand*>  Tasks;
-
-    Tasks  tasks_;
-
-  public:
-    ~BagOfTasks()
-    {
-      for (Tasks::iterator it = tasks_.begin(); it != tasks_.end(); ++it)
-      {
-        delete *it;
-      }
-    }
-
-    ICommand* Pop()
-    {
-      ICommand* task = tasks_.front();
-      tasks_.pop_front();
-      return task;
-    }
-
-    void Push(ICommand* task)   // Takes ownership
-    {
-      if (task != NULL)
-      {
-        tasks_.push_back(task);
-      }
-    }
-
-    size_t GetSize() const
-    {
-      return tasks_.size();
-    }
-
-    bool IsEmpty() const
-    {
-      return tasks_.empty();
-    }
-  };
-}
--- a/Resources/Orthanc/Core/MultiThreading/BagOfTasksProcessor.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,277 +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-2018 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.
- *
- * 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 "BagOfTasksProcessor.h"
-
-#include "../Logging.h"
-#include "../OrthancException.h"
-
-#include <stdio.h>
-
-namespace Orthanc
-{
-  class BagOfTasksProcessor::Task : public IDynamicObject
-  {
-  private:
-    uint64_t                 bag_;
-    std::auto_ptr<ICommand>  command_;
-
-  public:
-    Task(uint64_t  bag,
-         ICommand* command) :
-      bag_(bag),
-      command_(command)
-    {
-    }
-
-    bool Execute()
-    {
-      try
-      {
-        return command_->Execute();
-      }
-      catch (OrthancException& e)
-      {
-        LOG(ERROR) << "Exception while processing a bag of tasks: " << e.What();
-        return false;
-      }
-      catch (std::runtime_error& e)
-      {
-        LOG(ERROR) << "Runtime exception while processing a bag of tasks: " << e.what();
-        return false;
-      }
-      catch (...)
-      {
-        LOG(ERROR) << "Native exception while processing a bag of tasks";
-        return false;
-      }
-    }
-
-    uint64_t GetBag()
-    {
-      return bag_;
-    }
-  };
-
-
-  void BagOfTasksProcessor::SignalProgress(Task& task,
-                                           Bag& bag)
-  {
-    assert(bag.done_ < bag.size_);
-
-    bag.done_ += 1;
-
-    if (bag.done_ == bag.size_)
-    {
-      exitStatus_[task.GetBag()] = (bag.status_ == BagStatus_Running);
-      bagFinished_.notify_all();
-    }
-  }
-
-  void BagOfTasksProcessor::Worker(BagOfTasksProcessor* that)
-  {
-    while (that->continue_)
-    {
-      std::auto_ptr<IDynamicObject> obj(that->queue_.Dequeue(100));
-      if (obj.get() != NULL)
-      {
-        Task& task = *dynamic_cast<Task*>(obj.get());
-
-        {
-          boost::mutex::scoped_lock lock(that->mutex_);
-
-          Bags::iterator bag = that->bags_.find(task.GetBag());
-          assert(bag != that->bags_.end());
-          assert(bag->second.done_ < bag->second.size_);
-
-          if (bag->second.status_ != BagStatus_Running)
-          {
-            // Do not execute this task, as its parent bag of tasks
-            // has failed or is tagged as canceled
-            that->SignalProgress(task, bag->second);
-            continue;
-          }
-        }
-
-        bool success = task.Execute();
-
-        {
-          boost::mutex::scoped_lock lock(that->mutex_);
-
-          Bags::iterator bag = that->bags_.find(task.GetBag());
-          assert(bag != that->bags_.end());
-
-          if (!success)
-          {
-            bag->second.status_ = BagStatus_Failed;
-          }
-
-          that->SignalProgress(task, bag->second);
-        }
-      }
-    }
-  }
-
-
-  void BagOfTasksProcessor::Cancel(int64_t bag)
-  {
-    boost::mutex::scoped_lock  lock(mutex_);
-
-    Bags::iterator it = bags_.find(bag);
-    if (it != bags_.end())
-    {
-      it->second.status_ = BagStatus_Canceled;
-    }
-  }
-
-
-  bool BagOfTasksProcessor::Join(int64_t bag)
-  {
-    boost::mutex::scoped_lock  lock(mutex_);
-
-    while (continue_)
-    {
-      ExitStatus::iterator it = exitStatus_.find(bag);
-      if (it == exitStatus_.end())  // The bag is still running
-      {
-        bagFinished_.wait(lock);
-      }
-      else
-      {
-        bool status = it->second;
-        exitStatus_.erase(it);
-        return status;
-      }
-    }
-
-    return false;   // The processor is stopping
-  }
-
-
-  float BagOfTasksProcessor::GetProgress(int64_t bag)
-  {
-    boost::mutex::scoped_lock  lock(mutex_);
-
-    Bags::const_iterator it = bags_.find(bag);
-    if (it == bags_.end())
-    {
-      // The bag of tasks has finished
-      return 1.0f;
-    }
-    else
-    {
-      return (static_cast<float>(it->second.done_) / 
-              static_cast<float>(it->second.size_));
-    }
-  }
-
-
-  bool BagOfTasksProcessor::Handle::Join()
-  {
-    if (hasJoined_)
-    {
-      return status_;
-    }
-    else
-    {
-      status_ = that_.Join(bag_);
-      hasJoined_ = true;
-      return status_;
-    }
-  }
-
-
-  BagOfTasksProcessor::BagOfTasksProcessor(size_t countThreads) : 
-    countBags_(0),
-    continue_(true)
-  {
-    if (countThreads == 0)
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    threads_.resize(countThreads);
-
-    for (size_t i = 0; i < threads_.size(); i++)
-    {
-      threads_[i] = new boost::thread(Worker, this);
-    }
-  }
-
-
-  BagOfTasksProcessor::~BagOfTasksProcessor()
-  {
-    continue_ = false;
-
-    bagFinished_.notify_all();   // Wakes up all the pending "Join()"
-
-    for (size_t i = 0; i < threads_.size(); i++)
-    {
-      if (threads_[i])
-      {
-        if (threads_[i]->joinable())
-        {
-          threads_[i]->join();
-        }
-
-        delete threads_[i];
-        threads_[i] = NULL;
-      }
-    }
-  }
-
-
-  BagOfTasksProcessor::Handle* BagOfTasksProcessor::Submit(BagOfTasks& tasks)
-  {
-    if (tasks.GetSize() == 0)
-    {
-      return new Handle(*this, 0, true);
-    }
-
-    boost::mutex::scoped_lock lock(mutex_);
-
-    uint64_t id = countBags_;
-    countBags_ += 1;
-
-    Bag bag(tasks.GetSize());
-    bags_[id] = bag;
-
-    while (!tasks.IsEmpty())
-    {
-      queue_.Enqueue(new Task(id, tasks.Pop()));
-    }
-
-    return new Handle(*this, id, false);
-  }
-}
--- a/Resources/Orthanc/Core/MultiThreading/BagOfTasksProcessor.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "BagOfTasks.h"
-#include "SharedMessageQueue.h"
-
-#include <stdint.h>
-#include <map>
-
-namespace Orthanc
-{
-  class BagOfTasksProcessor : public boost::noncopyable
-  {
-  private:
-    enum BagStatus
-    {
-      BagStatus_Running,
-      BagStatus_Canceled,
-      BagStatus_Failed
-    };
-
-
-    struct Bag
-    {
-      size_t    size_;
-      size_t    done_;
-      BagStatus status_;
-
-      Bag() :
-        size_(0),
-        done_(0),
-        status_(BagStatus_Failed)
-      {
-      }
-
-      explicit Bag(size_t size) : 
-        size_(size),
-        done_(0),
-        status_(BagStatus_Running)
-      {
-      }
-    };
-
-    class Task;
-
-
-    typedef std::map<uint64_t, Bag>   Bags;
-    typedef std::map<uint64_t, bool>  ExitStatus;
-
-    SharedMessageQueue  queue_;
-
-    boost::mutex  mutex_;
-    uint64_t  countBags_;
-    Bags bags_;
-    std::vector<boost::thread*>   threads_;
-    ExitStatus  exitStatus_;
-    bool continue_;
-
-    boost::condition_variable  bagFinished_;
-
-    static void Worker(BagOfTasksProcessor* that);
-
-    void Cancel(int64_t bag);
-
-    bool Join(int64_t bag);
-
-    float GetProgress(int64_t bag);
-
-    void SignalProgress(Task& task,
-                        Bag& bag);
-
-  public:
-    class Handle : public boost::noncopyable
-    {
-      friend class BagOfTasksProcessor;
-
-    private:
-      BagOfTasksProcessor&  that_;
-      uint64_t              bag_;
-      bool                  hasJoined_;
-      bool                  status_;
- 
-      Handle(BagOfTasksProcessor&  that,
-             uint64_t bag,
-             bool empty) : 
-        that_(that),
-        bag_(bag),
-        hasJoined_(empty)
-      {
-      }
-
-    public:
-      ~Handle()
-      {
-        Join();
-      }
-
-      void Cancel()
-      {
-        that_.Cancel(bag_);
-      }
-
-      bool Join();
-
-      float GetProgress()
-      {
-        return that_.GetProgress(bag_);
-      }
-    };
-  
-
-    explicit BagOfTasksProcessor(size_t countThreads);
-
-    ~BagOfTasksProcessor();
-
-    Handle* Submit(BagOfTasks& tasks);
-  };
-}
--- a/Resources/Orthanc/Core/MultiThreading/ILockable.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <boost/noncopyable.hpp>
-
-namespace Orthanc
-{
-  class ILockable : public boost::noncopyable
-  {
-    friend class Locker;
-
-  protected:
-    virtual void Lock() = 0;
-
-    virtual void Unlock() = 0;
-
-  public:
-    virtual ~ILockable()
-    {
-    }
-  };
-}
--- a/Resources/Orthanc/Core/MultiThreading/IRunnableBySteps.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "../IDynamicObject.h"
-
-namespace Orthanc
-{
-  class IRunnableBySteps : public IDynamicObject
-  {
-  public:
-    virtual ~IRunnableBySteps()
-    {
-    }
-
-    // Must return "true" if the runnable wishes to continue. Must
-    // return "false" if the runnable has not finished its job.
-    virtual bool Step() = 0;
-
-    static void RunUntilDone(IRunnableBySteps& runnable)
-    {
-      while (runnable.Step());
-    }
-  };
-}
--- a/Resources/Orthanc/Core/MultiThreading/Mutex.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +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-2018 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.
- *
- * 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 "Mutex.h"
-
-#include "../OrthancException.h"
-
-#if defined(_WIN32)
-#include <windows.h>
-#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-#include <pthread.h>
-#else
-#error Support your platform here
-#endif
-
-namespace Orthanc
-{
-#if defined (_WIN32)
-
-  struct Mutex::PImpl
-  {
-    CRITICAL_SECTION criticalSection_;
-  };
-
-  Mutex::Mutex()
-  {
-    pimpl_ = new PImpl;
-    ::InitializeCriticalSection(&pimpl_->criticalSection_);
-  }
-
-  Mutex::~Mutex()
-  {
-    ::DeleteCriticalSection(&pimpl_->criticalSection_);
-    delete pimpl_;
-  }
-
-  void Mutex::Lock()
-  {
-    ::EnterCriticalSection(&pimpl_->criticalSection_);
-  }
-
-  void Mutex::Unlock()
-  {
-    ::LeaveCriticalSection(&pimpl_->criticalSection_);
-  }
-
-
-#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-
-  struct Mutex::PImpl
-  {
-    pthread_mutex_t mutex_;
-  };
-
-  Mutex::Mutex()
-  {
-    pimpl_ = new PImpl;
-
-    if (pthread_mutex_init(&pimpl_->mutex_, NULL) != 0)
-    {
-      delete pimpl_;
-      throw OrthancException(ErrorCode_InternalError);
-    }
-  }
-
-  Mutex::~Mutex()
-  {
-    pthread_mutex_destroy(&pimpl_->mutex_);
-    delete pimpl_;
-  }
-
-  void Mutex::Lock()
-  {
-    if (pthread_mutex_lock(&pimpl_->mutex_) != 0)
-    {
-      throw OrthancException(ErrorCode_InternalError);    
-    }
-  }
-
-  void Mutex::Unlock()
-  {
-    if (pthread_mutex_unlock(&pimpl_->mutex_) != 0)
-    {
-      throw OrthancException(ErrorCode_InternalError);    
-    }
-  }
-
-#else
-#error Support your plateform here
-#endif
-}
--- a/Resources/Orthanc/Core/MultiThreading/Mutex.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "ILockable.h"
-
-namespace Orthanc
-{
-  class Mutex : public ILockable
-  {
-  private:
-    struct PImpl;
-
-    PImpl *pimpl_;
-
-  protected:
-    virtual void Lock();
-
-    virtual void Unlock();
-    
-  public:
-    Mutex();
-
-    ~Mutex();
-  };
-}
--- a/Resources/Orthanc/Core/MultiThreading/ReaderWriterLock.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +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-2018 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.
- *
- * 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 "ReaderWriterLock.h"
-
-#include <boost/thread/shared_mutex.hpp>
-
-namespace Orthanc
-{
-  namespace
-  {
-    // Anonymous namespace to avoid clashes between compilation
-    // modules.
-
-    class ReaderLockable : public ILockable
-    {
-    private:
-      boost::shared_mutex& lock_;
-
-    protected:
-      virtual void Lock()
-      {
-        lock_.lock_shared();
-      }
-
-      virtual void Unlock()
-      {
-        lock_.unlock_shared();        
-      }
-
-    public:
-      explicit ReaderLockable(boost::shared_mutex& lock) : lock_(lock)
-      {
-      }
-    };
-
-
-    class WriterLockable : public ILockable
-    {
-    private:
-      boost::shared_mutex& lock_;
-
-    protected:
-      virtual void Lock()
-      {
-        lock_.lock();
-      }
-
-      virtual void Unlock()
-      {
-        lock_.unlock();        
-      }
-
-    public:
-      explicit WriterLockable(boost::shared_mutex& lock) : lock_(lock)
-      {
-      }
-    };
-  }
-
-  struct ReaderWriterLock::PImpl
-  {
-    boost::shared_mutex lock_;
-    ReaderLockable reader_;
-    WriterLockable writer_;
-
-    PImpl() : reader_(lock_), writer_(lock_)
-    {
-    }
-  };
-
-
-  ReaderWriterLock::ReaderWriterLock()
-  {
-    pimpl_ = new PImpl;
-  }
-
-
-  ReaderWriterLock::~ReaderWriterLock()
-  {
-    delete pimpl_;
-  }
-
-
-  ILockable&  ReaderWriterLock::ForReader()
-  {
-    return pimpl_->reader_;
-  }
-
-
-  ILockable&  ReaderWriterLock::ForWriter()
-  {
-    return pimpl_->writer_;
-  }
-}
--- a/Resources/Orthanc/Core/MultiThreading/ReaderWriterLock.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "ILockable.h"
-
-#include <boost/noncopyable.hpp>
-
-namespace Orthanc
-{
-  class ReaderWriterLock : public boost::noncopyable
-  {
-  private:
-    struct PImpl;
-
-    PImpl *pimpl_;
-
-  public:
-    ReaderWriterLock();
-
-    virtual ~ReaderWriterLock();
-
-    ILockable& ForReader();
-
-    ILockable& ForWriter();
-  };
-}
--- a/Resources/Orthanc/Core/MultiThreading/RunnableWorkersPool.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,170 +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-2018 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.
- *
- * 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 "RunnableWorkersPool.h"
-
-#include "SharedMessageQueue.h"
-#include "../OrthancException.h"
-#include "../Logging.h"
-
-namespace Orthanc
-{
-  struct RunnableWorkersPool::PImpl
-  {
-    class Worker
-    {
-    private:
-      const bool&           continue_;
-      SharedMessageQueue&   queue_;
-      boost::thread         thread_;
- 
-      static void WorkerThread(Worker* that)
-      {
-        while (that->continue_)
-        {
-          try
-          {
-            std::auto_ptr<IDynamicObject>  obj(that->queue_.Dequeue(100));
-            if (obj.get() != NULL)
-            {
-              IRunnableBySteps& runnable = *dynamic_cast<IRunnableBySteps*>(obj.get());
-              
-              bool wishToContinue = runnable.Step();
-              
-              if (wishToContinue)
-              {
-                // The runnable wishes to continue, reinsert it at the beginning of the queue
-                that->queue_.Enqueue(obj.release());
-              }
-            }
-          }
-          catch (OrthancException& e)
-          {
-            LOG(ERROR) << "Exception while handling some runnable object: " << e.What();
-          }
-          catch (std::bad_alloc&)
-          {
-            LOG(ERROR) << "Not enough memory to handle some runnable object";
-          }
-          catch (std::exception& e)
-          {
-            LOG(ERROR) << "std::exception while handling some runnable object: " << e.what();
-          }
-          catch (...)
-          {
-            LOG(ERROR) << "Native exception while handling some runnable object";
-          }
-        }
-      }
-
-    public:
-      Worker(const bool& globalContinue,
-             SharedMessageQueue& queue) : 
-        continue_(globalContinue),
-        queue_(queue)
-      {
-        thread_ = boost::thread(WorkerThread, this);
-      }
-
-      void Join()
-      {
-        if (thread_.joinable())
-        {
-          thread_.join();
-        }
-      }
-    };
-
-
-    bool                  continue_;
-    std::vector<Worker*>  workers_;
-    SharedMessageQueue    queue_;
-  };
-
-
-
-  RunnableWorkersPool::RunnableWorkersPool(size_t countWorkers) : pimpl_(new PImpl)
-  {
-    pimpl_->continue_ = true;
-
-    if (countWorkers == 0)
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    pimpl_->workers_.resize(countWorkers);
-
-    for (size_t i = 0; i < countWorkers; i++)
-    {
-      pimpl_->workers_[i] = new PImpl::Worker(pimpl_->continue_, pimpl_->queue_);
-    }
-  }
-
-
-  void RunnableWorkersPool::Stop()
-  {
-    if (pimpl_->continue_)
-    {
-      pimpl_->continue_ = false;
-
-      for (size_t i = 0; i < pimpl_->workers_.size(); i++)
-      {
-        PImpl::Worker* worker = pimpl_->workers_[i];
-
-        if (worker != NULL)
-        {
-          worker->Join();
-          delete worker;
-        }
-      }
-    }
-  }
-
-
-  RunnableWorkersPool::~RunnableWorkersPool()
-  {
-    Stop();
-  }
-
-
-  void RunnableWorkersPool::Add(IRunnableBySteps* runnable)
-  {
-    if (!pimpl_->continue_)
-    {
-      throw OrthancException(ErrorCode_BadSequenceOfCalls);
-    }
-
-    pimpl_->queue_.Enqueue(runnable);
-  }
-}
--- a/Resources/Orthanc/Core/MultiThreading/RunnableWorkersPool.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "IRunnableBySteps.h"
-
-#include <boost/shared_ptr.hpp>
-
-namespace Orthanc
-{
-  class RunnableWorkersPool : public boost::noncopyable
-  {
-  private:
-    struct PImpl;
-    boost::shared_ptr<PImpl> pimpl_;
-
-    void Stop();
-
-  public:
-    explicit RunnableWorkersPool(size_t countWorkers);
-
-    ~RunnableWorkersPool();
-
-    void Add(IRunnableBySteps* runnable);  // Takes the ownership
-  };
-}
--- a/Resources/Orthanc/Core/MultiThreading/Semaphore.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +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-2018 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.
- *
- * 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 "Semaphore.h"
-
-#include "../OrthancException.h"
-
-
-namespace Orthanc
-{
-  Semaphore::Semaphore(unsigned int count) : count_(count)
-  {
-  }
-
-  void Semaphore::Release()
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-
-    count_++;
-    condition_.notify_one(); 
-  }
-
-  void Semaphore::Acquire()
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-
-    while (count_ == 0)
-    {
-      condition_.wait(lock);
-    }
-
-    count_++;
-  }
-}
--- a/Resources/Orthanc/Core/MultiThreading/Semaphore.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <boost/noncopyable.hpp>
-#include <boost/thread.hpp>
-
-namespace Orthanc
-{
-  class Semaphore : public boost::noncopyable
-  {
-  private:
-    unsigned int count_;
-    boost::mutex mutex_;
-    boost::condition_variable condition_;
-
-  public:
-    explicit Semaphore(unsigned int count);
-
-    void Release();
-
-    void Acquire();
-
-    class Locker : public boost::noncopyable
-    {
-    private:
-      Semaphore&  that_;
-
-    public:
-      explicit Locker(Semaphore& that) :
-        that_(that)
-      {
-        that_.Acquire();
-      }
-
-      ~Locker()
-      {
-        that_.Release();
-      }
-    };
-  };
-}
--- a/Resources/Orthanc/Core/MultiThreading/SharedMessageQueue.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +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-2018 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.
- *
- * 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 "SharedMessageQueue.h"
-
-
-
-/**
- * FIFO (queue):
- * 
- *            back                         front
- *            +--+--+--+--+--+--+--+--+--+--+--+
- * Enqueue -> |  |  |  |  |  |  |  |  |  |  |  |
- *            |  |  |  |  |  |  |  |  |  |  |  | -> Dequeue
- *            +--+--+--+--+--+--+--+--+--+--+--+
- *                                            ^
- *                                            |
- *                                      Make room here
- *
- *
- * LIFO (stack):
- * 
- *            back                         front
- *            +--+--+--+--+--+--+--+--+--+--+--+
- *            |  |  |  |  |  |  |  |  |  |  |  | <- Enqueue
- *            |  |  |  |  |  |  |  |  |  |  |  | -> Dequeue
- *            +--+--+--+--+--+--+--+--+--+--+--+
- *              ^
- *              |
- *        Make room here
- **/
-
-
-namespace Orthanc
-{
-  SharedMessageQueue::SharedMessageQueue(unsigned int maxSize) :
-    isFifo_(true),
-    maxSize_(maxSize)
-  {
-  }
-
-
-  SharedMessageQueue::~SharedMessageQueue()
-  {
-    for (Queue::iterator it = queue_.begin(); it != queue_.end(); ++it)
-    {
-      delete *it;
-    }
-  }
-
-
-  void SharedMessageQueue::Enqueue(IDynamicObject* message)
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-
-    if (maxSize_ != 0 && queue_.size() > maxSize_)
-    {
-      if (isFifo_)
-      {
-        // Too many elements in the queue: Make room
-        delete queue_.front();
-        queue_.pop_front();
-      }
-      else
-      {
-        // Too many elements in the stack: Make room
-        delete queue_.back();
-        queue_.pop_back();
-      }
-    }
-
-    if (isFifo_)
-    {
-      // Queue policy (FIFO)
-      queue_.push_back(message);
-    }
-    else
-    {
-      // Stack policy (LIFO)
-      queue_.push_front(message);
-    }
-
-    elementAvailable_.notify_one();
-  }
-
-
-  IDynamicObject* SharedMessageQueue::Dequeue(int32_t millisecondsTimeout)
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-
-    // Wait for a message to arrive in the FIFO queue
-    while (queue_.empty())
-    {
-      if (millisecondsTimeout == 0)
-      {
-        elementAvailable_.wait(lock);
-      }
-      else
-      {
-        bool success = elementAvailable_.timed_wait
-          (lock, boost::posix_time::milliseconds(millisecondsTimeout));
-        if (!success)
-        {
-          return NULL;
-        }
-      }
-    }
-
-    std::auto_ptr<IDynamicObject> message(queue_.front());
-    queue_.pop_front();
-
-    if (queue_.empty())
-    {
-      emptied_.notify_all();
-    }
-
-    return message.release();
-  }
-
-
-
-  bool SharedMessageQueue::WaitEmpty(int32_t millisecondsTimeout)
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-    
-    // Wait for the queue to become empty
-    while (!queue_.empty())
-    {
-      if (millisecondsTimeout == 0)
-      {
-        emptied_.wait(lock);
-      }
-      else
-      {
-        if (!emptied_.timed_wait
-            (lock, boost::posix_time::milliseconds(millisecondsTimeout)))
-        {
-          return false;
-        }
-      }
-    }
-
-    return true;
-  }
-
-
-  void SharedMessageQueue::SetFifoPolicy()
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-    isFifo_ = true;
-  }
-
-  void SharedMessageQueue::SetLifoPolicy()
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-    isFifo_ = false;
-  }
-
-  void SharedMessageQueue::Clear()
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-
-    if (queue_.empty())
-    {
-      return;
-    }
-    else
-    {
-      while (!queue_.empty())
-      {
-        std::auto_ptr<IDynamicObject> message(queue_.front());
-        queue_.pop_front();
-      }
-
-      emptied_.notify_all();
-    }
-  }
-}
--- a/Resources/Orthanc/Core/MultiThreading/SharedMessageQueue.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "../IDynamicObject.h"
-
-#include <stdint.h>
-#include <list>
-#include <boost/thread.hpp>
-
-namespace Orthanc
-{
-  class SharedMessageQueue : public boost::noncopyable
-  {
-  private:
-    typedef std::list<IDynamicObject*>  Queue;
-
-    bool isFifo_;
-    unsigned int maxSize_;
-    Queue queue_;
-    boost::mutex mutex_;
-    boost::condition_variable elementAvailable_;
-    boost::condition_variable emptied_;
-
-  public:
-    explicit SharedMessageQueue(unsigned int maxSize = 0);
-    
-    ~SharedMessageQueue();
-
-    // This transfers the ownership of the message
-    void Enqueue(IDynamicObject* message);
-
-    // The caller is responsible to delete the dequeud message!
-    IDynamicObject* Dequeue(int32_t millisecondsTimeout);
-
-    bool WaitEmpty(int32_t millisecondsTimeout);
-
-    bool IsFifoPolicy() const
-    {
-      return isFifo_;
-    }
-
-    bool IsLifoPolicy() const
-    {
-      return !isFifo_;
-    }
-
-    void SetFifoPolicy();
-
-    void SetLifoPolicy();
-
-    void Clear();
-  };
-}
--- a/Resources/Orthanc/Core/OrthancException.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <stdint.h>
-#include <string>
-#include "Enumerations.h"
-
-namespace Orthanc
-{
-  class OrthancException
-  {
-  protected:
-    ErrorCode  errorCode_;
-    HttpStatus httpStatus_;
-
-  public:
-    explicit OrthancException(ErrorCode errorCode) : 
-      errorCode_(errorCode),
-      httpStatus_(ConvertErrorCodeToHttpStatus(errorCode))
-    {
-    }
-
-    OrthancException(ErrorCode errorCode,
-                     HttpStatus httpStatus) :
-      errorCode_(errorCode),
-      httpStatus_(httpStatus)
-    {
-    }
-
-    ErrorCode GetErrorCode() const
-    {
-      return errorCode_;
-    }
-
-    HttpStatus GetHttpStatus() const
-    {
-      return httpStatus_;
-    }
-
-    const char* What() const
-    {
-      return EnumerationToString(errorCode_);
-    }
-  };
-}
--- a/Resources/Orthanc/Core/PrecompiledHeaders.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +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-2018 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.
- *
- * 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"
--- a/Resources/Orthanc/Core/PrecompiledHeaders.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if defined(_WIN32) && !defined(NOMINMAX)
-#define NOMINMAX
-#endif
-
-#if ORTHANC_USE_PRECOMPILED_HEADERS == 1
-
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/locale.hpp>
-#include <boost/regex.hpp>
-#include <boost/thread.hpp>
-#include <boost/thread/shared_mutex.hpp>
-
-#include <json/value.h>
-
-#if ORTHANC_ENABLE_PUGIXML == 1
-#  include <pugixml.hpp>
-#endif
-
-#include "Enumerations.h"
-#include "Logging.h"
-#include "OrthancException.h"
-#include "Toolbox.h"
-
-#if ORTHANC_ENABLE_DCMTK == 1
-// Headers from DCMTK used in Orthanc headers 
-#  include <dcmtk/dcmdata/dcdatset.h>
-#  include <dcmtk/dcmdata/dcfilefo.h>
-#  include <dcmtk/dcmdata/dcmetinf.h>
-#  include <dcmtk/dcmdata/dcpixseq.h>
-#endif
-
-#if ORTHANC_ENABLE_DCMTK_NETWORKING == 1
-#  include "DicomNetworking/DicomServer.h"
-
-// Headers from DCMTK used in Orthanc headers 
-#  include <dcmtk/dcmnet/dimse.h>
-#endif
-
-#endif
--- a/Resources/Orthanc/Core/SharedLibrary.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +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-2018 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.
- *
- * 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 "SharedLibrary.h"
-
-#include "Logging.h"
-#include "OrthancException.h"
-
-#include <boost/filesystem.hpp>
-
-#if defined(_WIN32)
-#include <windows.h>
-#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-#include <dlfcn.h>
-#else
-#error Support your platform here
-#endif
-
-namespace Orthanc
-{
-  SharedLibrary::SharedLibrary(const std::string& path) : 
-    path_(path), 
-    handle_(NULL)
-  {
-#if defined(_WIN32)
-    handle_ = ::LoadLibraryA(path_.c_str());
-    if (handle_ == NULL)
-    {
-      LOG(ERROR) << "LoadLibrary(" << path_ << ") failed: Error " << ::GetLastError();
-      throw OrthancException(ErrorCode_SharedLibrary);
-    }
-
-#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-    handle_ = ::dlopen(path_.c_str(), RTLD_NOW);
-    if (handle_ == NULL) 
-    {
-      std::string explanation;
-      const char *tmp = ::dlerror();
-      if (tmp)
-      {
-        explanation = ": Error " + std::string(tmp);
-      }
-
-      LOG(ERROR) << "dlopen(" << path_ << ") failed" << explanation;
-      throw OrthancException(ErrorCode_SharedLibrary);
-    }
-
-#else
-#error Support your platform here
-#endif   
-  }
-
-  SharedLibrary::~SharedLibrary()
-  {
-    if (handle_)
-    {
-#if defined(_WIN32)
-      ::FreeLibrary((HMODULE)handle_);
-#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-      ::dlclose(handle_);
-#else
-#error Support your platform here
-#endif
-    }
-  }
-
-
-  SharedLibrary::FunctionPointer SharedLibrary::GetFunctionInternal(const std::string& name)
-  {
-    if (!handle_)
-    {
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-#if defined(_WIN32)
-    return ::GetProcAddress((HMODULE)handle_, name.c_str());
-#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-    return ::dlsym(handle_, name.c_str());
-#else
-#error Support your platform here
-#endif
-  }
-
-
-  SharedLibrary::FunctionPointer SharedLibrary::GetFunction(const std::string& name)
-  {
-    SharedLibrary::FunctionPointer result = GetFunctionInternal(name);
-  
-    if (result == NULL)
-    {
-      LOG(ERROR) << "Shared library does not expose function \"" << name << "\"";
-      throw OrthancException(ErrorCode_SharedLibrary);
-    }
-    else
-    {
-      return result;
-    }
-  }
-
-
-  bool SharedLibrary::HasFunction(const std::string& name)
-  {
-    return GetFunctionInternal(name) != NULL;
-  }
-}
--- a/Resources/Orthanc/Core/SharedLibrary.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_SANDBOXED)
-#  error The macro ORTHANC_SANDBOXED must be defined
-#endif
-
-#if ORTHANC_SANDBOXED == 1
-#  error The namespace SystemToolbox cannot be used in sandboxed environments
-#endif
-
-#if defined(_WIN32)
-#include <windows.h>
-#endif
-
-#include <string>
-#include <boost/noncopyable.hpp>
-
-namespace Orthanc
-{
-  class SharedLibrary : public boost::noncopyable
-  {
-  public:
-#if defined(_WIN32)
-    typedef FARPROC FunctionPointer;
-#else
-    typedef void* FunctionPointer;
-#endif
-
-  private:
-    std::string path_;
-    void *handle_;
-
-    FunctionPointer GetFunctionInternal(const std::string& name);
-
-  public:
-    explicit SharedLibrary(const std::string& path);
-
-    ~SharedLibrary();
-
-    const std::string& GetPath() const
-    {
-      return path_;
-    }
-
-    bool HasFunction(const std::string& name);
-
-    FunctionPointer GetFunction(const std::string& name);
-  };
-}
--- a/Resources/Orthanc/Core/SystemToolbox.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,563 +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-2018 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.
- *
- * 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 "SystemToolbox.h"
-
-
-#if defined(_WIN32)
-#  include <windows.h>
-#  include <process.h>   // For "_spawnvp()" and "_getpid()"
-#else
-#  include <unistd.h>    // For "execvp()"
-#  include <sys/wait.h>  // For "waitpid()"
-#endif
-
-
-#if defined(__APPLE__) && defined(__MACH__)
-#  include <mach-o/dyld.h> /* _NSGetExecutablePath */
-#  include <limits.h>      /* PATH_MAX */
-#endif
-
-
-#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
-#  include <limits.h>      /* PATH_MAX */
-#  include <signal.h>
-#  include <unistd.h>
-#endif
-
-
-#if defined(__OpenBSD__)
-#  include <sys/sysctl.h>  // For "sysctl", "CTL_KERN" and "KERN_PROC_ARGS"
-#endif
-
-
-#include "Logging.h"
-#include "OrthancException.h"
-#include "Toolbox.h"
-
-#include <boost/filesystem.hpp>
-#include <boost/filesystem/fstream.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-
-
-namespace Orthanc
-{
-  static bool finish_;
-  static ServerBarrierEvent barrierEvent_;
-
-#if defined(_WIN32)
-  static BOOL WINAPI ConsoleControlHandler(DWORD dwCtrlType)
-  {
-    // http://msdn.microsoft.com/en-us/library/ms683242(v=vs.85).aspx
-    finish_ = true;
-    return true;
-  }
-#else
-  static void SignalHandler(int signal)
-  {
-    if (signal == SIGHUP)
-    {
-      barrierEvent_ = ServerBarrierEvent_Reload;
-    }
-
-    finish_ = true;
-  }
-#endif
-
-
-  static ServerBarrierEvent ServerBarrierInternal(const bool* stopFlag)
-  {
-#if defined(_WIN32)
-    SetConsoleCtrlHandler(ConsoleControlHandler, true);
-#else
-    signal(SIGINT, SignalHandler);
-    signal(SIGQUIT, SignalHandler);
-    signal(SIGTERM, SignalHandler);
-    signal(SIGHUP, SignalHandler);
-#endif
-  
-    // Active loop that awakens every 100ms
-    finish_ = false;
-    barrierEvent_ = ServerBarrierEvent_Stop;
-    while (!(*stopFlag || finish_))
-    {
-      SystemToolbox::USleep(100 * 1000);
-    }
-
-#if defined(_WIN32)
-    SetConsoleCtrlHandler(ConsoleControlHandler, false);
-#else
-    signal(SIGINT, NULL);
-    signal(SIGQUIT, NULL);
-    signal(SIGTERM, NULL);
-    signal(SIGHUP, NULL);
-#endif
-
-    return barrierEvent_;
-  }
-
-
-  ServerBarrierEvent SystemToolbox::ServerBarrier(const bool& stopFlag)
-  {
-    return ServerBarrierInternal(&stopFlag);
-  }
-
-
-  ServerBarrierEvent SystemToolbox::ServerBarrier()
-  {
-    const bool stopFlag = false;
-    return ServerBarrierInternal(&stopFlag);
-  }
-
-
-  void SystemToolbox::USleep(uint64_t microSeconds)
-  {
-#if defined(_WIN32)
-    ::Sleep(static_cast<DWORD>(microSeconds / static_cast<uint64_t>(1000)));
-#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__native_client__)
-    usleep(microSeconds);
-#else
-#error Support your platform here
-#endif
-  }
-
-
-  static std::streamsize GetStreamSize(std::istream& f)
-  {
-    // http://www.cplusplus.com/reference/iostream/istream/tellg/
-    f.seekg(0, std::ios::end);
-    std::streamsize size = f.tellg();
-    f.seekg(0, std::ios::beg);
-
-    return size;
-  }
-
-
-  void SystemToolbox::ReadFile(std::string& content,
-                               const std::string& path) 
-  {
-    if (!IsRegularFile(path))
-    {
-      LOG(ERROR) << "The path does not point to a regular file: " << path;
-      throw OrthancException(ErrorCode_RegularFileExpected);
-    }
-
-    boost::filesystem::ifstream f;
-    f.open(path, std::ifstream::in | std::ifstream::binary);
-    if (!f.good())
-    {
-      throw OrthancException(ErrorCode_InexistentFile);
-    }
-
-    std::streamsize size = GetStreamSize(f);
-    content.resize(static_cast<size_t>(size));
-    if (size != 0)
-    {
-      f.read(reinterpret_cast<char*>(&content[0]), size);
-    }
-
-    f.close();
-  }
-
-
-  bool SystemToolbox::ReadHeader(std::string& header,
-                                 const std::string& path,
-                                 size_t headerSize)
-  {
-    if (!IsRegularFile(path))
-    {
-      LOG(ERROR) << "The path does not point to a regular file: " << path;
-      throw OrthancException(ErrorCode_RegularFileExpected);
-    }
-
-    boost::filesystem::ifstream f;
-    f.open(path, std::ifstream::in | std::ifstream::binary);
-    if (!f.good())
-    {
-      throw OrthancException(ErrorCode_InexistentFile);
-    }
-
-    bool full = true;
-
-    {
-      std::streamsize size = GetStreamSize(f);
-      if (size <= 0)
-      {
-        headerSize = 0;
-        full = false;
-      }
-      else if (static_cast<size_t>(size) < headerSize)
-      {
-        headerSize = static_cast<size_t>(size);  // Truncate to the size of the file
-        full = false;
-      }
-    }
-
-    header.resize(headerSize);
-    if (headerSize != 0)
-    {
-      f.read(reinterpret_cast<char*>(&header[0]), headerSize);
-    }
-
-    f.close();
-
-    return full;
-  }
-
-
-  void SystemToolbox::WriteFile(const void* content,
-                                size_t size,
-                                const std::string& path)
-  {
-    boost::filesystem::ofstream f;
-    f.open(path, std::ofstream::out | std::ofstream::binary);
-    if (!f.good())
-    {
-      throw OrthancException(ErrorCode_CannotWriteFile);
-    }
-
-    if (size != 0)
-    {
-      f.write(reinterpret_cast<const char*>(content), size);
-
-      if (!f.good())
-      {
-        f.close();
-        throw OrthancException(ErrorCode_FileStorageCannotWrite);
-      }
-    }
-
-    f.close();
-  }
-
-
-  void SystemToolbox::WriteFile(const std::string& content,
-                                const std::string& path)
-  {
-    WriteFile(content.size() > 0 ? content.c_str() : NULL,
-              content.size(), path);
-  }
-
-
-  void SystemToolbox::RemoveFile(const std::string& path)
-  {
-    if (boost::filesystem::exists(path))
-    {
-      if (IsRegularFile(path))
-      {
-        boost::filesystem::remove(path);
-      }
-      else
-      {
-        throw OrthancException(ErrorCode_RegularFileExpected);
-      }
-    }
-  }
-
-
-  uint64_t SystemToolbox::GetFileSize(const std::string& path)
-  {
-    try
-    {
-      return static_cast<uint64_t>(boost::filesystem::file_size(path));
-    }
-    catch (boost::filesystem::filesystem_error&)
-    {
-      throw OrthancException(ErrorCode_InexistentFile);
-    }
-  }
-
-
-  void SystemToolbox::MakeDirectory(const std::string& path)
-  {
-    if (boost::filesystem::exists(path))
-    {
-      if (!boost::filesystem::is_directory(path))
-      {
-        throw OrthancException(ErrorCode_DirectoryOverFile);
-      }
-    }
-    else
-    {
-      if (!boost::filesystem::create_directories(path))
-      {
-        throw OrthancException(ErrorCode_MakeDirectory);
-      }
-    }
-  }
-
-
-  bool SystemToolbox::IsExistingFile(const std::string& path)
-  {
-    return boost::filesystem::exists(path);
-  }
-
-
-#if defined(_WIN32)
-  static std::string GetPathToExecutableInternal()
-  {
-    // Yes, this is ugly, but there is no simple way to get the 
-    // required buffer size, so we use a big constant
-    std::vector<char> buffer(32768);
-    /*int bytes =*/ GetModuleFileNameA(NULL, &buffer[0], static_cast<DWORD>(buffer.size() - 1));
-    return std::string(&buffer[0]);
-  }
-
-#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
-  static std::string GetPathToExecutableInternal()
-  {
-    // NOTE: For FreeBSD, using KERN_PROC_PATHNAME might be a better alternative
-
-    std::vector<char> buffer(PATH_MAX + 1);
-    ssize_t bytes = readlink("/proc/self/exe", &buffer[0], buffer.size() - 1);
-    if (bytes == 0)
-    {
-      throw OrthancException(ErrorCode_PathToExecutable);
-    }
-
-    return std::string(&buffer[0]);
-  }
-
-#elif defined(__APPLE__) && defined(__MACH__)
-  static std::string GetPathToExecutableInternal()
-  {
-    char pathbuf[PATH_MAX + 1];
-    unsigned int  bufsize = static_cast<int>(sizeof(pathbuf));
-
-    _NSGetExecutablePath( pathbuf, &bufsize);
-
-    return std::string(pathbuf);
-  }
-
-#elif defined(__OpenBSD__)
-  static std::string GetPathToExecutableInternal()
-  {
-    // This is an adapted version of the patch proposed in issue #64
-    // without an explicit call to "malloc()" to prevent memory leak
-    // https://bitbucket.org/sjodogne/orthanc/issues/64/add-openbsd-support
-    // https://stackoverflow.com/q/31494901/881731
-
-    const int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV };
-
-    size_t len;
-    if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1) 
-    {
-      throw OrthancException(ErrorCode_PathToExecutable);
-    }
-
-    std::string tmp;
-    tmp.resize(len);
-
-    char** buffer = reinterpret_cast<char**>(&tmp[0]);
-
-    if (sysctl(mib, 4, buffer, &len, NULL, 0) == -1) 
-    {
-      throw OrthancException(ErrorCode_PathToExecutable);
-    }
-    else
-    {
-      return std::string(buffer[0]);
-    }
-  }
-
-#else
-#error Support your platform here
-#endif
-
-
-  std::string SystemToolbox::GetPathToExecutable()
-  {
-    boost::filesystem::path p(GetPathToExecutableInternal());
-    return boost::filesystem::absolute(p).string();
-  }
-
-
-  std::string SystemToolbox::GetDirectoryOfExecutable()
-  {
-    boost::filesystem::path p(GetPathToExecutableInternal());
-    return boost::filesystem::absolute(p.parent_path()).string();
-  }
-
-
-  void SystemToolbox::ExecuteSystemCommand(const std::string& command,
-                                           const std::vector<std::string>& arguments)
-  {
-    // Convert the arguments as a C array
-    std::vector<char*>  args(arguments.size() + 2);
-
-    args.front() = const_cast<char*>(command.c_str());
-
-    for (size_t i = 0; i < arguments.size(); i++)
-    {
-      args[i + 1] = const_cast<char*>(arguments[i].c_str());
-    }
-
-    args.back() = NULL;
-
-    int status;
-
-#if defined(_WIN32)
-    // http://msdn.microsoft.com/en-us/library/275khfab.aspx
-    status = static_cast<int>(_spawnvp(_P_OVERLAY, command.c_str(), &args[0]));
-
-#else
-    int pid = fork();
-
-    if (pid == -1)
-    {
-      // Error in fork()
-#if ORTHANC_ENABLE_LOGGING == 1
-      LOG(ERROR) << "Cannot fork a child process";
-#endif
-
-      throw OrthancException(ErrorCode_SystemCommand);
-    }
-    else if (pid == 0)
-    {
-      // Execute the system command in the child process
-      execvp(command.c_str(), &args[0]);
-
-      // We should never get here
-      _exit(1);
-    }
-    else
-    {
-      // Wait for the system command to exit
-      waitpid(pid, &status, 0);
-    }
-#endif
-
-    if (status != 0)
-    {
-#if ORTHANC_ENABLE_LOGGING == 1
-      LOG(ERROR) << "System command failed with status code " << status;
-#endif
-
-      throw OrthancException(ErrorCode_SystemCommand);
-    }
-  }
-
-
-  int SystemToolbox::GetProcessId()
-  {
-#if defined(_WIN32)
-    return static_cast<int>(_getpid());
-#else
-    return static_cast<int>(getpid());
-#endif
-  }
-
-
-  bool SystemToolbox::IsRegularFile(const std::string& path)
-  {
-    namespace fs = boost::filesystem;
-
-    try
-    {
-      if (fs::exists(path))
-      {
-        fs::file_status status = fs::status(path);
-        return (status.type() == boost::filesystem::regular_file ||
-                status.type() == boost::filesystem::reparse_file);   // Fix BitBucket issue #11
-      }
-    }
-    catch (fs::filesystem_error&)
-    {
-    }
-
-    return false;
-  }
-
-
-  FILE* SystemToolbox::OpenFile(const std::string& path,
-                                FileMode mode)
-  {
-#if defined(_WIN32)
-    // TODO Deal with special characters by converting to the current locale
-#endif
-
-    const char* m;
-    switch (mode)
-    {
-      case FileMode_ReadBinary:
-        m = "rb";
-        break;
-
-      case FileMode_WriteBinary:
-        m = "wb";
-        break;
-
-      default:
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    return fopen(path.c_str(), m);
-  }
-
-
-  static boost::posix_time::ptime GetNow(bool utc)
-  {
-    if (utc)
-    {
-      return boost::posix_time::second_clock::universal_time();
-    }
-    else
-    {
-      return boost::posix_time::second_clock::local_time();
-    }
-  }
-
-
-  std::string SystemToolbox::GetNowIsoString(bool utc)
-  {
-    return boost::posix_time::to_iso_string(GetNow(utc));
-  }
-
-  
-  void SystemToolbox::GetNowDicom(std::string& date,
-                                  std::string& time,
-                                  bool utc)
-  {
-    boost::posix_time::ptime now = GetNow(utc);
-    tm tm = boost::posix_time::to_tm(now);
-
-    char s[32];
-    sprintf(s, "%04d%02d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
-    date.assign(s);
-
-    // TODO milliseconds
-    sprintf(s, "%02d%02d%02d.%06d", tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
-    time.assign(s);
-  }
-}
--- a/Resources/Orthanc/Core/SystemToolbox.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_SANDBOXED)
-#  error The macro ORTHANC_SANDBOXED must be defined
-#endif
-
-#if ORTHANC_SANDBOXED == 1
-#  error The namespace SystemToolbox cannot be used in sandboxed environments
-#endif
-
-#include "Enumerations.h"
-
-#include <vector>
-#include <string>
-#include <stdint.h>
-
-namespace Orthanc
-{
-  namespace SystemToolbox
-  {
-    void USleep(uint64_t microSeconds);
-
-    ServerBarrierEvent ServerBarrier(const bool& stopFlag);
-
-    ServerBarrierEvent ServerBarrier();
-
-    void ReadFile(std::string& content,
-                  const std::string& path);
-
-    bool ReadHeader(std::string& header,
-                    const std::string& path,
-                    size_t headerSize);
-
-    void WriteFile(const void* content,
-                   size_t size,
-                   const std::string& path);
-
-    void WriteFile(const std::string& content,
-                   const std::string& path);
-
-    void RemoveFile(const std::string& path);
-
-    uint64_t GetFileSize(const std::string& path);
-
-    void MakeDirectory(const std::string& path);
-
-    bool IsExistingFile(const std::string& path);
-
-    std::string GetPathToExecutable();
-
-    std::string GetDirectoryOfExecutable();
-
-    void ExecuteSystemCommand(const std::string& command,
-                              const std::vector<std::string>& arguments);
-
-    int GetProcessId();
-
-    bool IsRegularFile(const std::string& path);
-
-    FILE* OpenFile(const std::string& path,
-                   FileMode mode);
-
-    std::string GetNowIsoString(bool utc);
-
-    void GetNowDicom(std::string& date,
-                     std::string& time,
-                     bool utc);
-  }
-}
--- a/Resources/Orthanc/Core/TemporaryFile.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +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-2018 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.
- *
- * 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 "TemporaryFile.h"
-
-#include "SystemToolbox.h"
-#include "Toolbox.h"
-
-#include <boost/filesystem.hpp>
-
-namespace Orthanc
-{
-  static std::string CreateTemporaryPath(const char* extension)
-  {
-#if BOOST_HAS_FILESYSTEM_V3 == 1
-    boost::filesystem::path tmpDir = boost::filesystem::temp_directory_path();
-#elif defined(__linux__)
-    boost::filesystem::path tmpDir("/tmp");
-#else
-#error Support your platform here
-#endif
-
-    // We use UUID to create unique path to temporary files
-    std::string filename = "Orthanc-" + Orthanc::Toolbox::GenerateUuid();
-
-    if (extension != NULL)
-    {
-      filename.append(extension);
-    }
-
-    tmpDir /= filename;
-    return tmpDir.string();
-  }
-
-
-  TemporaryFile::TemporaryFile() : 
-    path_(CreateTemporaryPath(NULL))
-  {
-  }
-
-
-  TemporaryFile::TemporaryFile(const char* extension) :
-    path_(CreateTemporaryPath(extension))
-  {
-  }
-
-
-  TemporaryFile::~TemporaryFile()
-  {
-    boost::filesystem::remove(path_);
-  }
-
-
-  void TemporaryFile::Write(const std::string& content)
-  {
-    SystemToolbox::WriteFile(content, path_);
-  }
-
-
-  void TemporaryFile::Read(std::string& content) const
-  {
-    SystemToolbox::ReadFile(content, path_);
-  }
-}
--- a/Resources/Orthanc/Core/TemporaryFile.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_SANDBOXED)
-#  error The macro ORTHANC_SANDBOXED must be defined
-#endif
-
-#if ORTHANC_SANDBOXED == 1
-#  error The class TemporaryFile cannot be used in sandboxed environments
-#endif
-
-#include <string>
-
-namespace Orthanc
-{
-  class TemporaryFile
-  {
-  private:
-    std::string path_;
-
-  public:
-    TemporaryFile();
-
-    TemporaryFile(const char* extension);
-
-    ~TemporaryFile();
-
-    const std::string& GetPath() const
-    {
-      return path_;
-    }
-
-    void Write(const std::string& content);
-
-    void Read(std::string& content) const;
-  };
-}
--- a/Resources/Orthanc/Core/Toolbox.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1526 +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-2018 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.
- *
- * 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 "Toolbox.h"
-
-#include "OrthancException.h"
-#include "Logging.h"
-
-#include <boost/algorithm/string/case_conv.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/regex.hpp> 
-#include <boost/uuid/sha1.hpp>
- 
-#include <string>
-#include <stdint.h>
-#include <string.h>
-#include <algorithm>
-#include <ctype.h>
-
-
-#if ORTHANC_ENABLE_MD5 == 1
-#  include "../Resources/ThirdParty/md5/md5.h"
-#endif
-
-#if ORTHANC_ENABLE_BASE64 == 1
-#  include "../Resources/ThirdParty/base64/base64.h"
-#endif
-
-#if ORTHANC_ENABLE_LOCALE == 1
-#  include <boost/locale.hpp>
-#endif
-
-
-#if defined(_MSC_VER) && (_MSC_VER < 1800)
-// Patch for the missing "_strtoll" symbol when compiling with Visual Studio < 2013
-extern "C"
-{
-  int64_t _strtoi64(const char *nptr, char **endptr, int base);
-  int64_t strtoll(const char *nptr, char **endptr, int base)
-  {
-    return _strtoi64(nptr, endptr, base);
-  } 
-}
-#endif
-
-
-#if defined(_WIN32)
-#  include <windows.h>   // For ::Sleep
-#endif
-
-
-#if ORTHANC_ENABLE_PUGIXML == 1
-#  include "ChunkedBuffer.h"
-#  include <pugixml.hpp>
-#endif
-
-
-// Inclusions for UUID
-// http://stackoverflow.com/a/1626302
-
-extern "C"
-{
-#if defined(_WIN32)
-#  include <rpc.h>
-#else
-#  include <uuid/uuid.h>
-#endif
-}
-
-
-
-namespace Orthanc
-{
-  void Toolbox::LinesIterator::FindEndOfLine()
-  {
-    lineEnd_ = lineStart_;
-
-    while (lineEnd_ < content_.size() &&
-           content_[lineEnd_] != '\n' &&
-           content_[lineEnd_] != '\r')
-    {
-      lineEnd_ += 1;
-    }
-  }
-  
-
-  Toolbox::LinesIterator::LinesIterator(const std::string& content) :
-    content_(content),
-    lineStart_(0)
-  {
-    FindEndOfLine();
-  }
-
-    
-  bool Toolbox::LinesIterator::GetLine(std::string& target) const
-  {
-    assert(lineStart_ <= content_.size() &&
-           lineEnd_ <= content_.size() &&
-           lineStart_ <= lineEnd_);
-
-    if (lineStart_ == content_.size())
-    {
-      return false;
-    }
-    else
-    {
-      target = content_.substr(lineStart_, lineEnd_ - lineStart_);
-      return true;
-    }
-  }
-
-    
-  void Toolbox::LinesIterator::Next()
-  {
-    lineStart_ = lineEnd_;
-
-    if (lineStart_ != content_.size())
-    {
-      assert(content_[lineStart_] == '\r' ||
-             content_[lineStart_] == '\n');
-
-      char second;
-      
-      if (content_[lineStart_] == '\r')
-      {
-        second = '\n';
-      }
-      else
-      {
-        second = '\r';
-      }
-        
-      lineStart_ += 1;
-
-      if (lineStart_ < content_.size() &&
-          content_[lineStart_] == second)
-      {
-        lineStart_ += 1;
-      }
-
-      FindEndOfLine();
-    }
-  }
-
-  
-  void Toolbox::ToUpperCase(std::string& s)
-  {
-    std::transform(s.begin(), s.end(), s.begin(), toupper);
-  }
-
-
-  void Toolbox::ToLowerCase(std::string& s)
-  {
-    std::transform(s.begin(), s.end(), s.begin(), tolower);
-  }
-
-
-  void Toolbox::ToUpperCase(std::string& result,
-                            const std::string& source)
-  {
-    result = source;
-    ToUpperCase(result);
-  }
-
-  void Toolbox::ToLowerCase(std::string& result,
-                            const std::string& source)
-  {
-    result = source;
-    ToLowerCase(result);
-  }
-
-
-  void Toolbox::SplitUriComponents(UriComponents& components,
-                                   const std::string& uri)
-  {
-    static const char URI_SEPARATOR = '/';
-
-    components.clear();
-
-    if (uri.size() == 0 ||
-        uri[0] != URI_SEPARATOR)
-    {
-      throw OrthancException(ErrorCode_UriSyntax);
-    }
-
-    // Count the number of slashes in the URI to make an assumption
-    // about the number of components in the URI
-    unsigned int estimatedSize = 0;
-    for (unsigned int i = 0; i < uri.size(); i++)
-    {
-      if (uri[i] == URI_SEPARATOR)
-        estimatedSize++;
-    }
-
-    components.reserve(estimatedSize - 1);
-
-    unsigned int start = 1;
-    unsigned int end = 1;
-    while (end < uri.size())
-    {
-      // This is the loop invariant
-      assert(uri[start - 1] == '/' && (end >= start));
-
-      if (uri[end] == '/')
-      {
-        components.push_back(std::string(&uri[start], end - start));
-        end++;
-        start = end;
-      }
-      else
-      {
-        end++;
-      }
-    }
-
-    if (start < uri.size())
-    {
-      components.push_back(std::string(&uri[start], end - start));
-    }
-
-    for (size_t i = 0; i < components.size(); i++)
-    {
-      if (components[i].size() == 0)
-      {
-        // Empty component, as in: "/coucou//e"
-        throw OrthancException(ErrorCode_UriSyntax);
-      }
-    }
-  }
-
-
-  void Toolbox::TruncateUri(UriComponents& target,
-                            const UriComponents& source,
-                            size_t fromLevel)
-  {
-    target.clear();
-
-    if (source.size() > fromLevel)
-    {
-      target.resize(source.size() - fromLevel);
-
-      size_t j = 0;
-      for (size_t i = fromLevel; i < source.size(); i++, j++)
-      {
-        target[j] = source[i];
-      }
-
-      assert(j == target.size());
-    }
-  }
-  
-
-
-  bool Toolbox::IsChildUri(const UriComponents& baseUri,
-                           const UriComponents& testedUri)
-  {
-    if (testedUri.size() < baseUri.size())
-    {
-      return false;
-    }
-
-    for (size_t i = 0; i < baseUri.size(); i++)
-    {
-      if (baseUri[i] != testedUri[i])
-        return false;
-    }
-
-    return true;
-  }
-
-
-  std::string Toolbox::AutodetectMimeType(const std::string& path)
-  {
-    std::string contentType;
-    size_t lastDot = path.rfind('.');
-    size_t lastSlash = path.rfind('/');
-
-    if (lastDot == std::string::npos ||
-        (lastSlash != std::string::npos && lastDot < lastSlash))
-    {
-      // No trailing dot, unable to detect the content type
-    }
-    else
-    {
-      const char* extension = &path[lastDot + 1];
-    
-      // http://en.wikipedia.org/wiki/Mime_types
-      // Text types
-      if (!strcmp(extension, "txt"))
-        contentType = "text/plain";
-      else if (!strcmp(extension, "html"))
-        contentType = "text/html";
-      else if (!strcmp(extension, "xml"))
-        contentType = "text/xml";
-      else if (!strcmp(extension, "css"))
-        contentType = "text/css";
-
-      // Application types
-      else if (!strcmp(extension, "js"))
-        contentType = "application/javascript";
-      else if (!strcmp(extension, "json"))
-        contentType = "application/json";
-      else if (!strcmp(extension, "pdf"))
-        contentType = "application/pdf";
-
-      // Images types
-      else if (!strcmp(extension, "jpg") || !strcmp(extension, "jpeg"))
-        contentType = "image/jpeg";
-      else if (!strcmp(extension, "gif"))
-        contentType = "image/gif";
-      else if (!strcmp(extension, "png"))
-        contentType = "image/png";
-    }
-
-    return contentType;
-  }
-
-
-  std::string Toolbox::FlattenUri(const UriComponents& components,
-                                  size_t fromLevel)
-  {
-    if (components.size() <= fromLevel)
-    {
-      return "/";
-    }
-    else
-    {
-      std::string r;
-
-      for (size_t i = fromLevel; i < components.size(); i++)
-      {
-        r += "/" + components[i];
-      }
-
-      return r;
-    }
-  }
-
-
-#if ORTHANC_ENABLE_MD5 == 1
-  static char GetHexadecimalCharacter(uint8_t value)
-  {
-    assert(value < 16);
-
-    if (value < 10)
-    {
-      return value + '0';
-    }
-    else
-    {
-      return (value - 10) + 'a';
-    }
-  }
-
-
-  void Toolbox::ComputeMD5(std::string& result,
-                           const std::string& data)
-  {
-    if (data.size() > 0)
-    {
-      ComputeMD5(result, &data[0], data.size());
-    }
-    else
-    {
-      ComputeMD5(result, NULL, 0);
-    }
-  }
-
-
-  void Toolbox::ComputeMD5(std::string& result,
-                           const void* data,
-                           size_t size)
-  {
-    md5_state_s state;
-    md5_init(&state);
-
-    if (size > 0)
-    {
-      md5_append(&state, 
-                 reinterpret_cast<const md5_byte_t*>(data), 
-                 static_cast<int>(size));
-    }
-
-    md5_byte_t actualHash[16];
-    md5_finish(&state, actualHash);
-
-    result.resize(32);
-    for (unsigned int i = 0; i < 16; i++)
-    {
-      result[2 * i] = GetHexadecimalCharacter(static_cast<uint8_t>(actualHash[i] / 16));
-      result[2 * i + 1] = GetHexadecimalCharacter(static_cast<uint8_t>(actualHash[i] % 16));
-    }
-  }
-#endif
-
-
-#if ORTHANC_ENABLE_BASE64 == 1
-  void Toolbox::EncodeBase64(std::string& result, 
-                             const std::string& data)
-  {
-    result = base64_encode(data);
-  }
-
-  void Toolbox::DecodeBase64(std::string& result, 
-                             const std::string& data)
-  {
-    for (size_t i = 0; i < data.length(); i++)
-    {
-      if (!isalnum(data[i]) &&
-          data[i] != '+' &&
-          data[i] != '/' &&
-          data[i] != '=')
-      {
-        // This is not a valid character for a Base64 string
-        throw OrthancException(ErrorCode_BadFileFormat);
-      }
-    }
-
-    result = base64_decode(data);
-  }
-
-
-  bool Toolbox::DecodeDataUriScheme(std::string& mime,
-                                    std::string& content,
-                                    const std::string& source)
-  {
-    boost::regex pattern("data:([^;]+);base64,([a-zA-Z0-9=+/]*)",
-                         boost::regex::icase /* case insensitive search */);
-
-    boost::cmatch what;
-    if (regex_match(source.c_str(), what, pattern))
-    {
-      mime = what[1];
-      DecodeBase64(content, what[2]);
-      return true;
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-
-  void Toolbox::EncodeDataUriScheme(std::string& result,
-                                    const std::string& mime,
-                                    const std::string& content)
-  {
-    result = "data:" + mime + ";base64," + base64_encode(content);
-  }
-
-#endif
-
-
-#if ORTHANC_ENABLE_LOCALE == 1
-  static const char* GetBoostLocaleEncoding(const Encoding sourceEncoding)
-  {
-    switch (sourceEncoding)
-    {
-      case Encoding_Utf8:
-        return "UTF-8";
-
-      case Encoding_Ascii:
-        return "ASCII";
-
-      case Encoding_Latin1:
-        return "ISO-8859-1";
-        break;
-
-      case Encoding_Latin2:
-        return "ISO-8859-2";
-        break;
-
-      case Encoding_Latin3:
-        return "ISO-8859-3";
-        break;
-
-      case Encoding_Latin4:
-        return "ISO-8859-4";
-        break;
-
-      case Encoding_Latin5:
-        return "ISO-8859-9";
-        break;
-
-      case Encoding_Cyrillic:
-        return "ISO-8859-5";
-        break;
-
-      case Encoding_Windows1251:
-        return "WINDOWS-1251";
-        break;
-
-      case Encoding_Arabic:
-        return "ISO-8859-6";
-        break;
-
-      case Encoding_Greek:
-        return "ISO-8859-7";
-        break;
-
-      case Encoding_Hebrew:
-        return "ISO-8859-8";
-        break;
-        
-      case Encoding_Japanese:
-        return "SHIFT-JIS";
-        break;
-
-      case Encoding_Chinese:
-        return "GB18030";
-        break;
-
-      case Encoding_Thai:
-        return "TIS620.2533-0";
-        break;
-
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }
-  }
-#endif
-
-
-#if ORTHANC_ENABLE_LOCALE == 1
-  std::string Toolbox::ConvertToUtf8(const std::string& source,
-                                     Encoding sourceEncoding)
-  {
-    if (sourceEncoding == Encoding_Utf8)
-    {
-      // Already in UTF-8: No conversion is required
-      return source;
-    }
-
-    if (sourceEncoding == Encoding_Ascii)
-    {
-      return ConvertToAscii(source);
-    }
-
-    const char* encoding = GetBoostLocaleEncoding(sourceEncoding);
-
-    try
-    {
-      return boost::locale::conv::to_utf<char>(source, encoding);
-    }
-    catch (std::runtime_error&)
-    {
-      // Bad input string or bad encoding
-      return ConvertToAscii(source);
-    }
-  }
-#endif
-  
-
-#if ORTHANC_ENABLE_LOCALE == 1
-  std::string Toolbox::ConvertFromUtf8(const std::string& source,
-                                       Encoding targetEncoding)
-  {
-    if (targetEncoding == Encoding_Utf8)
-    {
-      // Already in UTF-8: No conversion is required
-      return source;
-    }
-
-    if (targetEncoding == Encoding_Ascii)
-    {
-      return ConvertToAscii(source);
-    }
-
-    const char* encoding = GetBoostLocaleEncoding(targetEncoding);
-
-    try
-    {
-      return boost::locale::conv::from_utf<char>(source, encoding);
-    }
-    catch (std::runtime_error&)
-    {
-      // Bad input string or bad encoding
-      return ConvertToAscii(source);
-    }
-  }
-#endif
-
-
-  bool Toolbox::IsAsciiString(const void* data,
-                              size_t size)
-  {
-    const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
-
-    for (size_t i = 0; i < size; i++, p++)
-    {
-      if (*p > 127 || *p == 0 || iscntrl(*p))
-      {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-
-  bool Toolbox::IsAsciiString(const std::string& s)
-  {
-    return IsAsciiString(s.c_str(), s.size());
-  }
-  
-
-  std::string Toolbox::ConvertToAscii(const std::string& source)
-  {
-    std::string result;
-
-    result.reserve(source.size() + 1);
-    for (size_t i = 0; i < source.size(); i++)
-    {
-      if (source[i] <= 127 && source[i] >= 0 && !iscntrl(source[i]))
-      {
-        result.push_back(source[i]);
-      }
-    }
-
-    return result;
-  }
-
-
-  void Toolbox::ComputeSHA1(std::string& result,
-                            const void* data,
-                            size_t size)
-  {
-    boost::uuids::detail::sha1 sha1;
-
-    if (size > 0)
-    {
-      sha1.process_bytes(data, size);
-    }
-
-    unsigned int digest[5];
-
-    // Sanity check for the memory layout: A SHA-1 digest is 160 bits wide
-    assert(sizeof(unsigned int) == 4 && sizeof(digest) == (160 / 8)); 
-    
-    sha1.get_digest(digest);
-
-    result.resize(8 * 5 + 4);
-    sprintf(&result[0], "%08x-%08x-%08x-%08x-%08x",
-            digest[0],
-            digest[1],
-            digest[2],
-            digest[3],
-            digest[4]);
-  }
-
-  void Toolbox::ComputeSHA1(std::string& result,
-                            const std::string& data)
-  {
-    if (data.size() > 0)
-    {
-      ComputeSHA1(result, data.c_str(), data.size());
-    }
-    else
-    {
-      ComputeSHA1(result, NULL, 0);
-    }
-  }
-
-
-  bool Toolbox::IsSHA1(const char* str,
-                       size_t size)
-  {
-    if (size == 0)
-    {
-      return false;
-    }
-
-    const char* start = str;
-    const char* end = str + size;
-
-    // Trim the beginning of the string
-    while (start < end)
-    {
-      if (*start == '\0' ||
-          isspace(*start))
-      {
-        start++;
-      }
-      else
-      {
-        break;
-      }
-    }
-
-    // Trim the trailing of the string
-    while (start < end)
-    {
-      if (*(end - 1) == '\0' ||
-          isspace(*(end - 1)))
-      {
-        end--;
-      }
-      else
-      {
-        break;
-      }
-    }
-
-    if (end - start != 44)
-    {
-      return false;
-    }
-
-    for (unsigned int i = 0; i < 44; i++)
-    {
-      if (i == 8 ||
-          i == 17 ||
-          i == 26 ||
-          i == 35)
-      {
-        if (start[i] != '-')
-          return false;
-      }
-      else
-      {
-        if (!isalnum(start[i]))
-          return false;
-      }
-    }
-
-    return true;
-  }
-
-
-  bool Toolbox::IsSHA1(const std::string& s)
-  {
-    if (s.size() == 0)
-    {
-      return false;
-    }
-    else
-    {
-      return IsSHA1(s.c_str(), s.size());
-    }
-  }
-
-
-  std::string Toolbox::StripSpaces(const std::string& source)
-  {
-    size_t first = 0;
-
-    while (first < source.length() &&
-           isspace(source[first]))
-    {
-      first++;
-    }
-
-    if (first == source.length())
-    {
-      // String containing only spaces
-      return "";
-    }
-
-    size_t last = source.length();
-    while (last > first &&
-           isspace(source[last - 1]))
-    {
-      last--;
-    }          
-    
-    assert(first <= last);
-    return source.substr(first, last - first);
-  }
-
-
-  static char Hex2Dec(char c)
-  {
-    return ((c >= '0' && c <= '9') ? c - '0' :
-            ((c >= 'a' && c <= 'f') ? c - 'a' + 10 : c - 'A' + 10));
-  }
-
-  void Toolbox::UrlDecode(std::string& s)
-  {
-    // http://en.wikipedia.org/wiki/Percent-encoding
-    // http://www.w3schools.com/tags/ref_urlencode.asp
-    // http://stackoverflow.com/questions/154536/encode-decode-urls-in-c
-
-    if (s.size() == 0)
-    {
-      return;
-    }
-
-    size_t source = 0;
-    size_t target = 0;
-
-    while (source < s.size())
-    {
-      if (s[source] == '%' &&
-          source + 2 < s.size() &&
-          isalnum(s[source + 1]) &&
-          isalnum(s[source + 2]))
-      {
-        s[target] = (Hex2Dec(s[source + 1]) << 4) | Hex2Dec(s[source + 2]);
-        source += 3;
-        target += 1;
-      }
-      else
-      {
-        if (s[source] == '+')
-          s[target] = ' ';
-        else
-          s[target] = s[source];
-
-        source++;
-        target++;
-      }
-    }
-
-    s.resize(target);
-  }
-
-
-  Endianness Toolbox::DetectEndianness()
-  {
-    // http://sourceforge.net/p/predef/wiki/Endianness/
-
-    uint8_t buffer[4];
-
-    buffer[0] = 0x00;
-    buffer[1] = 0x01;
-    buffer[2] = 0x02;
-    buffer[3] = 0x03;
-
-    switch (*((uint32_t *)buffer)) 
-    {
-      case 0x00010203: 
-        return Endianness_Big;
-
-      case 0x03020100: 
-        return Endianness_Little;
-        
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }
-  }
-
-
-  std::string Toolbox::WildcardToRegularExpression(const std::string& source)
-  {
-    // TODO - Speed up this with a regular expression
-
-    std::string result = source;
-
-    // Escape all special characters
-    boost::replace_all(result, "\\", "\\\\");
-    boost::replace_all(result, "^", "\\^");
-    boost::replace_all(result, ".", "\\.");
-    boost::replace_all(result, "$", "\\$");
-    boost::replace_all(result, "|", "\\|");
-    boost::replace_all(result, "(", "\\(");
-    boost::replace_all(result, ")", "\\)");
-    boost::replace_all(result, "[", "\\[");
-    boost::replace_all(result, "]", "\\]");
-    boost::replace_all(result, "+", "\\+");
-    boost::replace_all(result, "/", "\\/");
-    boost::replace_all(result, "{", "\\{");
-    boost::replace_all(result, "}", "\\}");
-
-    // Convert wildcards '*' and '?' to their regex equivalents
-    boost::replace_all(result, "?", ".");
-    boost::replace_all(result, "*", ".*");
-
-    return result;
-  }
-
-
-  void Toolbox::TokenizeString(std::vector<std::string>& result,
-                               const std::string& value,
-                               char separator)
-  {
-    result.clear();
-
-    std::string currentItem;
-
-    for (size_t i = 0; i < value.size(); i++)
-    {
-      if (value[i] == separator)
-      {
-        result.push_back(currentItem);
-        currentItem.clear();
-      }
-      else
-      {
-        currentItem.push_back(value[i]);
-      }
-    }
-
-    result.push_back(currentItem);
-  }
-
-
-#if ORTHANC_ENABLE_PUGIXML == 1
-  class ChunkedBufferWriter : public pugi::xml_writer
-  {
-  private:
-    ChunkedBuffer buffer_;
-
-  public:
-    virtual void write(const void *data, size_t size)
-    {
-      if (size > 0)
-      {
-        buffer_.AddChunk(reinterpret_cast<const char*>(data), size);
-      }
-    }
-
-    void Flatten(std::string& s)
-    {
-      buffer_.Flatten(s);
-    }
-  };
-
-
-  static void JsonToXmlInternal(pugi::xml_node& target,
-                                const Json::Value& source,
-                                const std::string& arrayElement)
-  {
-    // http://jsoncpp.sourceforge.net/value_8h_source.html#l00030
-
-    switch (source.type())
-    {
-      case Json::nullValue:
-      {
-        target.append_child(pugi::node_pcdata).set_value("null");
-        break;
-      }
-
-      case Json::intValue:
-      {
-        std::string s = boost::lexical_cast<std::string>(source.asInt());
-        target.append_child(pugi::node_pcdata).set_value(s.c_str());
-        break;
-      }
-
-      case Json::uintValue:
-      {
-        std::string s = boost::lexical_cast<std::string>(source.asUInt());
-        target.append_child(pugi::node_pcdata).set_value(s.c_str());
-        break;
-      }
-
-      case Json::realValue:
-      {
-        std::string s = boost::lexical_cast<std::string>(source.asFloat());
-        target.append_child(pugi::node_pcdata).set_value(s.c_str());
-        break;
-      }
-
-      case Json::stringValue:
-      {
-        target.append_child(pugi::node_pcdata).set_value(source.asString().c_str());
-        break;
-      }
-
-      case Json::booleanValue:
-      {
-        target.append_child(pugi::node_pcdata).set_value(source.asBool() ? "true" : "false");
-        break;
-      }
-
-      case Json::arrayValue:
-      {
-        for (Json::Value::ArrayIndex i = 0; i < source.size(); i++)
-        {
-          pugi::xml_node node = target.append_child();
-          node.set_name(arrayElement.c_str());
-          JsonToXmlInternal(node, source[i], arrayElement);
-        }
-        break;
-      }
-        
-      case Json::objectValue:
-      {
-        Json::Value::Members members = source.getMemberNames();
-
-        for (size_t i = 0; i < members.size(); i++)
-        {
-          pugi::xml_node node = target.append_child();
-          node.set_name(members[i].c_str());
-          JsonToXmlInternal(node, source[members[i]], arrayElement);          
-        }
-
-        break;
-      }
-
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
-    }
-  }
-
-
-  void Toolbox::JsonToXml(std::string& target,
-                          const Json::Value& source,
-                          const std::string& rootElement,
-                          const std::string& arrayElement)
-  {
-    pugi::xml_document doc;
-
-    pugi::xml_node n = doc.append_child(rootElement.c_str());
-    JsonToXmlInternal(n, source, arrayElement);
-
-    pugi::xml_node decl = doc.prepend_child(pugi::node_declaration);
-    decl.append_attribute("version").set_value("1.0");
-    decl.append_attribute("encoding").set_value("utf-8");
-
-    ChunkedBufferWriter writer;
-    doc.save(writer, "  ", pugi::format_default, pugi::encoding_utf8);
-    writer.Flatten(target);
-  }
-
-#endif
-
-
-  
-  bool Toolbox::IsInteger(const std::string& str)
-  {
-    std::string s = StripSpaces(str);
-
-    if (s.size() == 0)
-    {
-      return false;
-    }
-
-    size_t pos = 0;
-    if (s[0] == '-')
-    {
-      if (s.size() == 1)
-      {
-        return false;
-      }
-
-      pos = 1;
-    }
-
-    while (pos < s.size())
-    {
-      if (!isdigit(s[pos]))
-      {
-        return false;
-      }
-
-      pos++;
-    }
-
-    return true;
-  }
-
-
-  void Toolbox::CopyJsonWithoutComments(Json::Value& target,
-                                        const Json::Value& source)
-  {
-    switch (source.type())
-    {
-      case Json::nullValue:
-        target = Json::nullValue;
-        break;
-
-      case Json::intValue:
-        target = source.asInt64();
-        break;
-
-      case Json::uintValue:
-        target = source.asUInt64();
-        break;
-
-      case Json::realValue:
-        target = source.asDouble();
-        break;
-
-      case Json::stringValue:
-        target = source.asString();
-        break;
-
-      case Json::booleanValue:
-        target = source.asBool();
-        break;
-
-      case Json::arrayValue:
-      {
-        target = Json::arrayValue;
-        for (Json::Value::ArrayIndex i = 0; i < source.size(); i++)
-        {
-          Json::Value& item = target.append(Json::nullValue);
-          CopyJsonWithoutComments(item, source[i]);
-        }
-
-        break;
-      }
-
-      case Json::objectValue:
-      {
-        target = Json::objectValue;
-        Json::Value::Members members = source.getMemberNames();
-        for (Json::Value::ArrayIndex i = 0; i < members.size(); i++)
-        {
-          const std::string item = members[i];
-          CopyJsonWithoutComments(target[item], source[item]);
-        }
-
-        break;
-      }
-
-      default:
-        break;
-    }
-  }
-
-
-  bool Toolbox::StartsWith(const std::string& str,
-                           const std::string& prefix)
-  {
-    if (str.size() < prefix.size())
-    {
-      return false;
-    }
-    else
-    {
-      return str.compare(0, prefix.size(), prefix) == 0;
-    }
-  }
-  
-
-  static bool IsUnreservedCharacter(char c)
-  {
-    // This function checks whether "c" is an unserved character
-    // wrt. an URI percent-encoding
-    // https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding%5Fin%5Fa%5FURI
-
-    return ((c >= 'A' && c <= 'Z') ||
-            (c >= 'a' && c <= 'z') ||
-            (c >= '0' && c <= '9') ||
-            c == '-' ||
-            c == '_' ||
-            c == '.' ||
-            c == '~');
-  }
-
-  void Toolbox::UriEncode(std::string& target,
-                          const std::string& source)
-  {
-    // Estimate the length of the percent-encoded URI
-    size_t length = 0;
-
-    for (size_t i = 0; i < source.size(); i++)
-    {
-      if (IsUnreservedCharacter(source[i]))
-      {
-        length += 1;
-      }
-      else
-      {
-        // This character must be percent-encoded
-        length += 3;
-      }
-    }
-
-    target.clear();
-    target.reserve(length);
-
-    for (size_t i = 0; i < source.size(); i++)
-    {
-      if (IsUnreservedCharacter(source[i]))
-      {
-        target.push_back(source[i]);
-      }
-      else
-      {
-        // This character must be percent-encoded
-        uint8_t byte = static_cast<uint8_t>(source[i]);
-        uint8_t a = byte >> 4;
-        uint8_t b = byte & 0x0f;
-
-        target.push_back('%');
-        target.push_back(a < 10 ? a + '0' : a - 10 + 'A');
-        target.push_back(b < 10 ? b + '0' : b - 10 + 'A');
-      }
-    }
-  }
-
-
-  static bool HasField(const Json::Value& json,
-                       const std::string& key,
-                       Json::ValueType expectedType)
-  {
-    if (json.type() != Json::objectValue ||
-        !json.isMember(key))
-    {
-      return false;
-    }
-    else if (json[key].type() == expectedType)
-    {
-      return true;
-    }
-    else
-    {
-      throw OrthancException(ErrorCode_BadParameterType);
-    }
-  }
-
-
-  std::string Toolbox::GetJsonStringField(const Json::Value& json,
-                                          const std::string& key,
-                                          const std::string& defaultValue)
-  {
-    if (HasField(json, key, Json::stringValue))
-    {
-      return json[key].asString();
-    }
-    else
-    {
-      return defaultValue;
-    }
-  }
-
-
-  bool Toolbox::GetJsonBooleanField(const ::Json::Value& json,
-                                    const std::string& key,
-                                    bool defaultValue)
-  {
-    if (HasField(json, key, Json::booleanValue))
-    {
-      return json[key].asBool();
-    }
-    else
-    {
-      return defaultValue;
-    }
-  }
-
-
-  int Toolbox::GetJsonIntegerField(const ::Json::Value& json,
-                                   const std::string& key,
-                                   int defaultValue)
-  {
-    if (HasField(json, key, Json::intValue))
-    {
-      return json[key].asInt();
-    }
-    else
-    {
-      return defaultValue;
-    }
-  }
-
-
-  unsigned int Toolbox::GetJsonUnsignedIntegerField(const ::Json::Value& json,
-                                                    const std::string& key,
-                                                    unsigned int defaultValue)
-  {
-    int v = GetJsonIntegerField(json, key, defaultValue);
-
-    if (v < 0)
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-    else
-    {
-      return static_cast<unsigned int>(v);
-    }
-  }
-
-
-  bool Toolbox::IsUuid(const std::string& str)
-  {
-    if (str.size() != 36)
-    {
-      return false;
-    }
-
-    for (size_t i = 0; i < str.length(); i++)
-    {
-      if (i == 8 || i == 13 || i == 18 || i == 23)
-      {
-        if (str[i] != '-')
-          return false;
-      }
-      else
-      {
-        if (!isalnum(str[i]))
-          return false;
-      }
-    }
-
-    return true;
-  }
-
-
-  bool Toolbox::StartsWithUuid(const std::string& str)
-  {
-    if (str.size() < 36)
-    {
-      return false;
-    }
-
-    if (str.size() == 36)
-    {
-      return IsUuid(str);
-    }
-
-    assert(str.size() > 36);
-    if (!isspace(str[36]))
-    {
-      return false;
-    }
-
-    return IsUuid(str.substr(0, 36));
-  }
-
-
-#if ORTHANC_ENABLE_LOCALE == 1
-  static std::auto_ptr<std::locale>  globalLocale_;
-
-  static bool SetGlobalLocale(const char* locale)
-  {
-    globalLocale_.reset(NULL);
-
-    try
-    {
-      if (locale == NULL)
-      {
-        LOG(WARNING) << "Falling back to system-wide default locale";
-        globalLocale_.reset(new std::locale());
-      }
-      else
-      {
-        LOG(INFO) << "Using locale: \"" << locale << "\" for case-insensitive comparison of strings";
-        globalLocale_.reset(new std::locale(locale));
-      }
-    }
-    catch (std::runtime_error&)
-    {
-    }
-
-    return (globalLocale_.get() != NULL);
-  }
-  
-  void Toolbox::InitializeGlobalLocale(const char* locale)
-  {
-    // Make Orthanc use English, United States locale
-    // Linux: use "en_US.UTF-8"
-    // Windows: use ""
-    // Wine: use NULL
-    
-#if defined(__MINGW32__)
-    // Visibly, there is no support of locales in MinGW yet
-    // http://mingw.5.n7.nabble.com/How-to-use-std-locale-global-with-MinGW-correct-td33048.html
-    static const char* DEFAULT_LOCALE = NULL;
-#elif defined(_WIN32)
-    // For Windows: use default locale (using "en_US" does not work)
-    static const char* DEFAULT_LOCALE = "";
-#else
-    // For Linux & cie
-    static const char* DEFAULT_LOCALE = "en_US.UTF-8";
-#endif
-
-    bool ok;
-    
-    if (locale == NULL)
-    {
-      ok = SetGlobalLocale(DEFAULT_LOCALE);
-
-#if defined(__MINGW32__)
-      LOG(WARNING) << "This is a MinGW build, case-insensitive comparison of "
-                   << "strings with accents will not work outside of Wine";
-#endif
-    }
-    else
-    {
-      ok = SetGlobalLocale(locale);
-    }
-
-    if (!ok &&
-        !SetGlobalLocale(NULL))
-    {
-      LOG(ERROR) << "Cannot initialize global locale";
-      throw OrthancException(ErrorCode_InternalError);
-    }
-
-  }
-
-
-  void Toolbox::FinalizeGlobalLocale()
-  {
-    globalLocale_.reset();
-  }
-
-  
-  std::string Toolbox::ToUpperCaseWithAccents(const std::string& source)
-  {
-    if (globalLocale_.get() == NULL)
-    {
-      LOG(ERROR) << "No global locale was set, call Toolbox::InitializeGlobalLocale()";
-      throw OrthancException(ErrorCode_BadSequenceOfCalls);
-    }
-
-    /**
-     * A few notes about locales:
-     *
-     * (1) We don't use "case folding":
-     * http://www.boost.org/doc/libs/1_64_0/libs/locale/doc/html/conversions.html
-     *
-     * Characters are made uppercase one by one. This is because, in
-     * static builds, we are using iconv, which is visibly not
-     * supported correctly (TODO: Understand why). Case folding seems
-     * to be working correctly if using the default backend under
-     * Linux (ICU or POSIX?). If one wishes to use case folding, one
-     * would use:
-     *
-     *   boost::locale::generator gen;
-     *   std::locale::global(gen(DEFAULT_LOCALE));
-     *   return boost::locale::to_upper(source);
-     *
-     * (2) The function "boost::algorithm::to_upper_copy" does not
-     * make use of the "std::locale::global()". We therefore create a
-     * global variable "globalLocale_".
-     * 
-     * (3) The variant of "boost::algorithm::to_upper_copy()" that
-     * uses std::string does not work properly. We need to apply it
-     * one wide strings (std::wstring). This explains the two calls to
-     * "utf_to_utf" in order to convert to/from std::wstring.
-     **/
-
-    std::wstring w = boost::locale::conv::utf_to_utf<wchar_t>(source);
-    w = boost::algorithm::to_upper_copy<std::wstring>(w, *globalLocale_);
-    return boost::locale::conv::utf_to_utf<char>(w);
-  }
-#endif
-
-
-  std::string Toolbox::GenerateUuid()
-  {
-#ifdef WIN32
-    UUID uuid;
-    UuidCreate ( &uuid );
-
-    unsigned char * str;
-    UuidToStringA ( &uuid, &str );
-
-    std::string s( ( char* ) str );
-
-    RpcStringFreeA ( &str );
-#else
-    uuid_t uuid;
-    uuid_generate_random ( uuid );
-    char s[37];
-    uuid_unparse ( uuid, s );
-#endif
-    return s;
-  }
-}
-
-
-
-OrthancLinesIterator* OrthancLinesIterator_Create(const std::string& content)
-{
-  return reinterpret_cast<OrthancLinesIterator*>(new Orthanc::Toolbox::LinesIterator(content));
-}
-
-
-bool OrthancLinesIterator_GetLine(std::string& target,
-                                         const OrthancLinesIterator* iterator)
-{
-  if (iterator != NULL)
-  {
-    return reinterpret_cast<const Orthanc::Toolbox::LinesIterator*>(iterator)->GetLine(target);
-  }
-  else
-  {
-    return false;
-  }
-}
-
-
-void OrthancLinesIterator_Next(OrthancLinesIterator* iterator)
-{
-  if (iterator != NULL)
-  {
-    reinterpret_cast<Orthanc::Toolbox::LinesIterator*>(iterator)->Next();
-  }
-}
-
-
-void OrthancLinesIterator_Free(OrthancLinesIterator* iterator)
-{
-  if (iterator != NULL)
-  {
-    delete reinterpret_cast<const Orthanc::Toolbox::LinesIterator*>(iterator);
-  }
-}
--- a/Resources/Orthanc/Core/Toolbox.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "Enumerations.h"
-
-#include <stdint.h>
-#include <vector>
-#include <string>
-#include <json/json.h>
-
-
-#if !defined(ORTHANC_ENABLE_BASE64)
-#  error The macro ORTHANC_ENABLE_BASE64 must be defined
-#endif
-
-#if !defined(ORTHANC_ENABLE_LOCALE)
-#  error The macro ORTHANC_ENABLE_LOCALE must be defined
-#endif
-
-#if !defined(ORTHANC_ENABLE_MD5)
-#  error The macro ORTHANC_ENABLE_MD5 must be defined
-#endif
-
-#if !defined(ORTHANC_ENABLE_PUGIXML)
-#  error The macro ORTHANC_ENABLE_PUGIXML must be defined
-#endif
-
-
-/**
- * NOTE: GUID vs. UUID
- * The simple answer is: no difference, they are the same thing. Treat
- * them as a 16 byte (128 bits) value that is used as a unique
- * value. In Microsoft-speak they are called GUIDs, but call them
- * UUIDs when not using Microsoft-speak.
- * http://stackoverflow.com/questions/246930/is-there-any-difference-between-a-guid-and-a-uuid
- **/
-
-
-
-namespace Orthanc
-{
-  typedef std::vector<std::string> UriComponents;
-
-  class NullType
-  {
-  };
-
-  namespace Toolbox
-  {
-    class LinesIterator
-    {
-    private:
-      const std::string& content_;
-      size_t             lineStart_;
-      size_t             lineEnd_;
-
-      void FindEndOfLine();
-  
-    public:
-      LinesIterator(const std::string& content);
-  
-      bool GetLine(std::string& target) const;
-
-      void Next();
-    };
-    
-    
-    void ToUpperCase(std::string& s);  // Inplace version
-
-    void ToLowerCase(std::string& s);  // Inplace version
-
-    void ToUpperCase(std::string& result,
-                     const std::string& source);
-
-    void ToLowerCase(std::string& result,
-                     const std::string& source);
-
-    void SplitUriComponents(UriComponents& components,
-                            const std::string& uri);
-  
-    void TruncateUri(UriComponents& target,
-                     const UriComponents& source,
-                     size_t fromLevel);
-  
-    bool IsChildUri(const UriComponents& baseUri,
-                    const UriComponents& testedUri);
-
-    std::string AutodetectMimeType(const std::string& path);
-
-    std::string FlattenUri(const UriComponents& components,
-                           size_t fromLevel = 0);
-
-#if ORTHANC_ENABLE_MD5 == 1
-    void ComputeMD5(std::string& result,
-                    const std::string& data);
-
-    void ComputeMD5(std::string& result,
-                    const void* data,
-                    size_t size);
-#endif
-
-    void ComputeSHA1(std::string& result,
-                     const std::string& data);
-
-    void ComputeSHA1(std::string& result,
-                     const void* data,
-                     size_t size);
-
-    bool IsSHA1(const char* str,
-                size_t size);
-
-    bool IsSHA1(const std::string& s);
-
-#if ORTHANC_ENABLE_BASE64 == 1
-    void DecodeBase64(std::string& result, 
-                      const std::string& data);
-
-    void EncodeBase64(std::string& result, 
-                      const std::string& data);
-
-    bool DecodeDataUriScheme(std::string& mime,
-                             std::string& content,
-                             const std::string& source);
-
-    void EncodeDataUriScheme(std::string& result,
-                             const std::string& mime,
-                             const std::string& content);
-#endif
-
-#if ORTHANC_ENABLE_LOCALE == 1
-    std::string ConvertToUtf8(const std::string& source,
-                              Encoding sourceEncoding);
-
-    std::string ConvertFromUtf8(const std::string& source,
-                                Encoding targetEncoding);
-#endif
-
-    bool IsAsciiString(const void* data,
-                       size_t size);
-
-    bool IsAsciiString(const std::string& s);
-
-    std::string ConvertToAscii(const std::string& source);
-
-    std::string StripSpaces(const std::string& source);
-
-    // In-place percent-decoding for URL
-    void UrlDecode(std::string& s);
-
-    Endianness DetectEndianness();
-
-    std::string WildcardToRegularExpression(const std::string& s);
-
-    void TokenizeString(std::vector<std::string>& result,
-                        const std::string& source,
-                        char separator);
-
-#if ORTHANC_ENABLE_PUGIXML == 1
-    void JsonToXml(std::string& target,
-                   const Json::Value& source,
-                   const std::string& rootElement = "root",
-                   const std::string& arrayElement = "item");
-#endif
-
-    bool IsInteger(const std::string& str);
-
-    void CopyJsonWithoutComments(Json::Value& target,
-                                 const Json::Value& source);
-
-    bool StartsWith(const std::string& str,
-                    const std::string& prefix);
-
-    void UriEncode(std::string& target,
-                   const std::string& source);
-
-    std::string GetJsonStringField(const ::Json::Value& json,
-                                   const std::string& key,
-                                   const std::string& defaultValue);
-
-    bool GetJsonBooleanField(const ::Json::Value& json,
-                             const std::string& key,
-                             bool defaultValue);
-
-    int GetJsonIntegerField(const ::Json::Value& json,
-                            const std::string& key,
-                            int defaultValue);
-
-    unsigned int GetJsonUnsignedIntegerField(const ::Json::Value& json,
-                                             const std::string& key,
-                                             unsigned int defaultValue);
-
-    bool IsUuid(const std::string& str);
-
-    bool StartsWithUuid(const std::string& str);
-
-#if ORTHANC_ENABLE_LOCALE == 1
-    void InitializeGlobalLocale(const char* locale);
-
-    void FinalizeGlobalLocale();
-
-    std::string ToUpperCaseWithAccents(const std::string& source);
-#endif
-
-    std::string GenerateUuid();
-  }
-}
-
-
-
-
-/**
- * The plain C, opaque data structure "OrthancLinesIterator" is a thin
- * wrapper around Orthanc::Toolbox::LinesIterator, and is only used by
- * "../Resources/WebAssembly/dcdict.cc", in order to avoid code
- * duplication
- **/
-
-struct OrthancLinesIterator;
-
-OrthancLinesIterator* OrthancLinesIterator_Create(const std::string& content);
-
-bool OrthancLinesIterator_GetLine(std::string& target,
-                                  const OrthancLinesIterator* iterator);
-
-void OrthancLinesIterator_Next(OrthancLinesIterator* iterator);
-
-void OrthancLinesIterator_Free(OrthancLinesIterator* iterator);
--- a/Resources/Orthanc/Core/WebServiceParameters.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +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-2018 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.
- *
- * 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 "WebServiceParameters.h"
-
-#include "../Core/Logging.h"
-#include "../Core/OrthancException.h"
-
-#if ORTHANC_SANDBOXED == 0
-#  include "../Core/SystemToolbox.h"
-#endif
-
-#include <cassert>
-
-namespace Orthanc
-{
-  WebServiceParameters::WebServiceParameters() : 
-    advancedFormat_(false),
-    url_("http://127.0.0.1:8042/"),
-    pkcs11Enabled_(false)
-  {
-  }
-
-
-  void WebServiceParameters::ClearClientCertificate()
-  {
-    certificateFile_.clear();
-    certificateKeyFile_.clear();
-    certificateKeyPassword_.clear();
-  }
-
-
-#if ORTHANC_SANDBOXED == 0
-  void WebServiceParameters::SetClientCertificate(const std::string& certificateFile,
-                                                  const std::string& certificateKeyFile,
-                                                  const std::string& certificateKeyPassword)
-  {
-    if (certificateFile.empty())
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    if (!SystemToolbox::IsRegularFile(certificateFile))
-    {
-      LOG(ERROR) << "Cannot open certificate file: " << certificateFile;
-      throw OrthancException(ErrorCode_InexistentFile);
-    }
-
-    if (!certificateKeyFile.empty() && 
-        !SystemToolbox::IsRegularFile(certificateKeyFile))
-    {
-      LOG(ERROR) << "Cannot open key file: " << certificateKeyFile;
-      throw OrthancException(ErrorCode_InexistentFile);
-    }
-
-    advancedFormat_ = true;
-    certificateFile_ = certificateFile;
-    certificateKeyFile_ = certificateKeyFile;
-    certificateKeyPassword_ = certificateKeyPassword;
-  }
-#endif
-
-
-  static void AddTrailingSlash(std::string& url)
-  {
-    if (url.size() != 0 && 
-        url[url.size() - 1] != '/')
-    {
-      url += '/';
-    }
-  }
-
-
-  void WebServiceParameters::FromJsonArray(const Json::Value& peer)
-  {
-    assert(peer.isArray());
-
-    advancedFormat_ = false;
-    pkcs11Enabled_ = false;
-
-    if (peer.size() != 1 && 
-        peer.size() != 3)
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-
-    std::string url = peer.get(0u, "").asString();
-    if (url.empty())
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-
-    AddTrailingSlash(url);
-    SetUrl(url);
-
-    if (peer.size() == 1)
-    {
-      SetUsername("");
-      SetPassword("");
-    }
-    else if (peer.size() == 3)
-    {
-      SetUsername(peer.get(1u, "").asString());
-      SetPassword(peer.get(2u, "").asString());
-    }
-    else
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-  }
-
-
-  static std::string GetStringMember(const Json::Value& peer,
-                                     const std::string& key,
-                                     const std::string& defaultValue)
-  {
-    if (!peer.isMember(key))
-    {
-      return defaultValue;
-    }
-    else if (peer[key].type() != Json::stringValue)
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-    else
-    {
-      return peer[key].asString();
-    }
-  }
-
-
-  void WebServiceParameters::FromJsonObject(const Json::Value& peer)
-  {
-    assert(peer.isObject());
-    advancedFormat_ = true;
-
-    std::string url = GetStringMember(peer, "Url", "");
-    if (url.empty())
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-
-    AddTrailingSlash(url);
-    SetUrl(url);
-
-    SetUsername(GetStringMember(peer, "Username", ""));
-    SetPassword(GetStringMember(peer, "Password", ""));
-
-#if ORTHANC_SANDBOXED == 0
-    if (peer.isMember("CertificateFile"))
-    {
-      SetClientCertificate(GetStringMember(peer, "CertificateFile", ""),
-                           GetStringMember(peer, "CertificateKeyFile", ""),
-                           GetStringMember(peer, "CertificateKeyPassword", ""));
-    }
-#endif
-
-    if (peer.isMember("Pkcs11"))
-    {
-      if (peer["Pkcs11"].type() == Json::booleanValue)
-      {
-        pkcs11Enabled_ = peer["Pkcs11"].asBool();
-      }
-      else
-      {
-        throw OrthancException(ErrorCode_BadFileFormat);
-      }
-    }
-  }
-
-
-  void WebServiceParameters::FromJson(const Json::Value& peer)
-  {
-    try
-    {
-      if (peer.isArray())
-      {
-        FromJsonArray(peer);
-      }
-      else if (peer.isObject())
-      {
-        FromJsonObject(peer);
-      }
-      else
-      {
-        throw OrthancException(ErrorCode_BadFileFormat);
-      }
-    }
-    catch (OrthancException&)
-    {
-      throw;
-    }
-    catch (...)
-    {
-      throw OrthancException(ErrorCode_BadFileFormat);
-    }
-  }
-
-
-  void WebServiceParameters::ToJson(Json::Value& value) const
-  {
-    if (advancedFormat_)
-    {
-      value = Json::objectValue;
-      value["Url"] = url_;
-
-      if (!username_.empty() ||
-          !password_.empty())
-      {
-        value["Username"] = username_;
-        value["Password"] = password_;
-      }
-
-      if (!certificateFile_.empty())
-      {
-        value["CertificateFile"] = certificateFile_;
-      }
-
-      if (!certificateKeyFile_.empty())
-      {
-        value["CertificateKeyFile"] = certificateKeyFile_;
-      }
-
-      if (!certificateKeyPassword_.empty())
-      {
-        value["CertificateKeyPassword"] = certificateKeyPassword_;
-      }
-    }
-    else
-    {
-      value = Json::arrayValue;
-      value.append(url_);
-
-      if (!username_.empty() ||
-          !password_.empty())
-      {
-        value.append(username_);
-        value.append(password_);
-      }
-    }
-  }
-}
--- a/Resources/Orthanc/Core/WebServiceParameters.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_SANDBOXED)
-#  error The macro ORTHANC_SANDBOXED must be defined
-#endif
-
-#include <string>
-#include <json/json.h>
-
-namespace Orthanc
-{
-  class WebServiceParameters
-  {
-  private:
-    bool        advancedFormat_;
-    std::string url_;
-    std::string username_;
-    std::string password_;
-    std::string certificateFile_;
-    std::string certificateKeyFile_;
-    std::string certificateKeyPassword_;
-    bool        pkcs11Enabled_;
-
-    void FromJsonArray(const Json::Value& peer);
-
-    void FromJsonObject(const Json::Value& peer);
-
-  public:
-    WebServiceParameters();
-
-    const std::string& GetUrl() const
-    {
-      return url_;
-    }
-
-    void SetUrl(const std::string& url)
-    {
-      url_ = url;
-    }
-
-    const std::string& GetUsername() const
-    {
-      return username_;
-    }
-
-    void SetUsername(const std::string& username)
-    {
-      username_ = username;
-    }
-    
-    const std::string& GetPassword() const
-    {
-      return password_;
-    }
-
-    void SetPassword(const std::string& password)
-    {
-      password_ = password;
-    }
-
-    void ClearClientCertificate();
-
-#if ORTHANC_SANDBOXED == 0
-    void SetClientCertificate(const std::string& certificateFile,
-                              const std::string& certificateKeyFile,
-                              const std::string& certificateKeyPassword);
-#endif
-
-    const std::string& GetCertificateFile() const
-    {
-      return certificateFile_;
-    }
-
-    const std::string& GetCertificateKeyFile() const
-    {
-      return certificateKeyFile_;
-    }
-
-    const std::string& GetCertificateKeyPassword() const
-    {
-      return certificateKeyPassword_;
-    }
-
-    void SetPkcs11Enabled(bool pkcs11Enabled)
-    {
-      pkcs11Enabled_ = pkcs11Enabled;
-    }
-
-    bool IsPkcs11Enabled() const
-    {
-      return pkcs11Enabled_;
-    }
-
-    void FromJson(const Json::Value& peer);
-
-    void ToJson(Json::Value& value) const;
-  };
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/Orthanc/DownloadOrthancFramework.cmake	Fri Jun 01 17:48:47 2018 +0200
@@ -0,0 +1,321 @@
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2018 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.
+#
+# 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/>.
+
+
+
+##
+## Check whether the parent script sets the mandatory variables
+##
+
+if (NOT DEFINED ORTHANC_FRAMEWORK_SOURCE OR
+    (NOT ORTHANC_FRAMEWORK_SOURCE STREQUAL "hg" AND
+     NOT ORTHANC_FRAMEWORK_SOURCE STREQUAL "web" AND
+     NOT ORTHANC_FRAMEWORK_SOURCE STREQUAL "archive" AND
+     NOT ORTHANC_FRAMEWORK_SOURCE STREQUAL "path"))
+  message(FATAL_ERROR "The variable ORTHANC_FRAMEWORK_SOURCE must be set to \"hg\", \"web\", \"archive\" or \"path\"")
+endif()
+
+
+##
+## Detection of the requested version
+##
+
+if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "hg" OR
+    ORTHANC_FRAMEWORK_SOURCE STREQUAL "archive" OR
+    ORTHANC_FRAMEWORK_SOURCE STREQUAL "web")
+  if (NOT DEFINED ORTHANC_FRAMEWORK_VERSION)
+    message(FATAL_ERROR "The variable ORTHANC_FRAMEWORK_VERSION must be set")
+  endif()
+
+  if (DEFINED ORTHANC_FRAMEWORK_MAJOR OR
+      DEFINED ORTHANC_FRAMEWORK_MINOR OR
+      DEFINED ORTHANC_FRAMEWORK_REVISION OR
+      DEFINED ORTHANC_FRAMEWORK_MD5)
+    message(FATAL_ERROR "Some internal variable has been set")
+  endif()
+
+  set(ORTHANC_FRAMEWORK_MD5 "")
+
+  if (ORTHANC_FRAMEWORK_VERSION STREQUAL "mainline")
+    set(ORTHANC_FRAMEWORK_BRANCH "default")
+
+  else()
+    set(ORTHANC_FRAMEWORK_BRANCH "Orthanc-${ORTHANC_FRAMEWORK_VERSION}")
+
+    set(RE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$")
+    string(REGEX REPLACE ${RE} "\\1" ORTHANC_FRAMEWORK_MAJOR ${ORTHANC_FRAMEWORK_VERSION})
+    string(REGEX REPLACE ${RE} "\\2" ORTHANC_FRAMEWORK_MINOR ${ORTHANC_FRAMEWORK_VERSION})
+    string(REGEX REPLACE ${RE} "\\3" ORTHANC_FRAMEWORK_REVISION ${ORTHANC_FRAMEWORK_VERSION})
+
+    if (NOT ORTHANC_FRAMEWORK_MAJOR MATCHES "^[0-9]+$" OR
+        NOT ORTHANC_FRAMEWORK_MINOR MATCHES "^[0-9]+$" OR
+        NOT ORTHANC_FRAMEWORK_REVISION MATCHES "^[0-9]+$")
+      message("Bad version of the Orthanc framework: ${ORTHANC_FRAMEWORK_VERSION}")
+    endif()
+
+    if (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.3.1")
+      set(ORTHANC_FRAMEWORK_MD5 "dac95bd6cf86fb19deaf4e612961f378")
+    elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.3.2")
+      set(ORTHANC_FRAMEWORK_MD5 "d0ccdf68e855d8224331f13774992750")
+    endif()
+  endif()
+endif()
+
+
+
+##
+## Detection of the third-party software
+##
+
+if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "hg")
+  find_program(ORTHANC_FRAMEWORK_HG hg)
+  
+  if (${ORTHANC_FRAMEWORK_HG} MATCHES "ORTHANC_FRAMEWORK_HG-NOTFOUND")
+    message(FATAL_ERROR "Please install Mercurial")
+  endif()
+endif()
+
+
+if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "archive" OR
+    ORTHANC_FRAMEWORK_SOURCE STREQUAL "web")
+  if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
+    find_program(ORTHANC_FRAMEWORK_7ZIP 7z 
+      PATHS 
+      "$ENV{ProgramFiles}/7-Zip"
+      "$ENV{ProgramW6432}/7-Zip"
+      )
+
+    if (${ORTHANC_FRAMEWORK_7ZIP} MATCHES "ORTHANC_FRAMEWORK_7ZIP-NOTFOUND")
+      message(FATAL_ERROR "Please install the '7-zip' software (http://www.7-zip.org/)")
+    endif()
+
+  else()
+    find_program(ORTHANC_FRAMEWORK_TAR tar)
+    if (${ORTHANC_FRAMEWORK_TAR} MATCHES "ORTHANC_FRAMEWORK_TAR-NOTFOUND")
+      message(FATAL_ERROR "Please install the 'tar' package")
+    endif()
+  endif()
+endif()
+
+
+
+##
+## Case of the Orthanc framework specified as a path on the filesystem
+##
+
+if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "path")
+  if (NOT DEFINED ORTHANC_FRAMEWORK_ROOT)
+    message(FATAL_ERROR "The variable ORTHANC_FRAMEWORK_ROOT must provide the path to the sources of Orthanc")
+  endif()
+  
+  if (NOT EXISTS ${ORTHANC_FRAMEWORK_ROOT})
+    message(FATAL_ERROR "Non-existing directory: ${ORTHANC_FRAMEWORK_ROOT}")
+  endif()
+  
+  if (NOT EXISTS ${ORTHANC_FRAMEWORK_ROOT}/Resources/CMake/OrthancFrameworkParameters.cmake)
+    message(FATAL_ERROR "Directory not containing the source code of Orthanc: ${ORTHANC_FRAMEWORK_ROOT}")
+  endif()
+  
+  set(ORTHANC_ROOT ${ORTHANC_FRAMEWORK_ROOT})
+endif()
+
+
+
+##
+## Case of the Orthanc framework cloned using Mercurial
+##
+
+if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "hg")
+  if (NOT STATIC_BUILD AND NOT ALLOW_DOWNLOADS)
+    message(FATAL_ERROR "CMake is not allowed to download from Internet. Please set the ALLOW_DOWNLOADS option to ON")
+  endif()
+
+  set(ORTHANC_ROOT ${CMAKE_BINARY_DIR}/orthanc)
+
+  if (EXISTS ${ORTHANC_ROOT})
+    message("Updating the Orthanc source repository using Mercurial")
+    execute_process(
+      COMMAND ${ORTHANC_FRAMEWORK_HG} pull
+      WORKING_DIRECTORY ${ORTHANC_ROOT}
+      RESULT_VARIABLE Failure
+      )    
+  else()
+    message("Forking the Orthanc source repository using Mercurial")
+    execute_process(
+      COMMAND ${ORTHANC_FRAMEWORK_HG} clone "https://bitbucket.org/sjodogne/orthanc"
+      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+      RESULT_VARIABLE Failure
+      )    
+  endif()
+
+  if (Failure OR NOT EXISTS ${ORTHANC_ROOT})
+    message(FATAL_ERROR "Cannot fork the Orthanc repository")
+  endif()
+
+  message("Setting branch of the Orthanc repository to: ${ORTHANC_FRAMEWORK_BRANCH}")
+
+  execute_process(
+    COMMAND ${ORTHANC_FRAMEWORK_HG} update -c ${ORTHANC_FRAMEWORK_BRANCH}
+    WORKING_DIRECTORY ${ORTHANC_ROOT}
+    RESULT_VARIABLE Failure
+    )
+
+  if (Failure)
+    message(FATAL_ERROR "Error while running Mercurial")
+  endif()
+endif()
+
+
+
+##
+## Case of the Orthanc framework provided as a source archive on the
+## filesystem
+##
+
+if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "archive")
+  if (NOT DEFINED ORTHANC_FRAMEWORK_ARCHIVE)
+    message(FATAL_ERROR "The variable ORTHANC_FRAMEWORK_ARCHIVE must provide the path to the sources of Orthanc")
+  endif()
+endif()
+
+
+
+##
+## Case of the Orthanc framework downloaded from the Web
+##
+
+if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "web")
+  if (DEFINED ORTHANC_FRAMEWORK_URL)
+    string(REGEX REPLACE "^.*/" "" ORTHANC_FRAMEMORK_FILENAME "${ORTHANC_FRAMEWORK_URL}")
+  else()
+    # Default case: Download from the official Web site
+    set(ORTHANC_FRAMEMORK_FILENAME Orthanc-${ORTHANC_FRAMEWORK_VERSION}.tar.gz)
+    #set(ORTHANC_FRAMEWORK_URL "http://www.orthanc-server.com/downloads/get.php?path=/orthanc/${ORTHANC_FRAMEMORK_FILENAME}")
+    set(ORTHANC_FRAMEWORK_URL "http://www.orthanc-server.com/downloads/third-party/orthanc-framework/${ORTHANC_FRAMEMORK_FILENAME}")
+  endif()
+
+  set(ORTHANC_FRAMEWORK_ARCHIVE "${CMAKE_SOURCE_DIR}/ThirdPartyDownloads/${ORTHANC_FRAMEMORK_FILENAME}")
+
+  if (NOT EXISTS "${ORTHANC_FRAMEWORK_ARCHIVE}")
+    if (NOT STATIC_BUILD AND NOT ALLOW_DOWNLOADS)
+      message(FATAL_ERROR "CMake is not allowed to download from Internet. Please set the ALLOW_DOWNLOADS option to ON")
+    endif()
+
+    message("Downloading: ${ORTHANC_FRAMEWORK_URL}")
+
+    file(DOWNLOAD
+      "${ORTHANC_FRAMEWORK_URL}" "${ORTHANC_FRAMEWORK_ARCHIVE}" 
+      SHOW_PROGRESS EXPECTED_MD5 "${ORTHANC_FRAMEWORK_MD5}"
+      TIMEOUT 60
+      INACTIVITY_TIMEOUT 60
+      )
+  else()
+    message("Using local copy of: ${ORTHANC_FRAMEWORK_URL}")
+  endif()  
+endif()
+
+
+
+
+##
+## Uncompressing the Orthanc framework, if it was retrieved from a
+## source archive on the filesystem, or from the official Web site
+##
+
+if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "archive" OR
+    ORTHANC_FRAMEWORK_SOURCE STREQUAL "web")
+
+  if (NOT DEFINED ORTHANC_FRAMEWORK_ARCHIVE OR
+      NOT DEFINED ORTHANC_FRAMEWORK_VERSION OR
+      NOT DEFINED ORTHANC_FRAMEWORK_MD5)
+    message(FATAL_ERROR "Internal error")
+  endif()
+
+  if (ORTHANC_FRAMEWORK_MD5 STREQUAL "")
+    message(FATAL_ERROR "Unknown release of Orthanc: ${ORTHANC_FRAMEWORK_VERSION}")
+  endif()
+
+  file(MD5 ${ORTHANC_FRAMEWORK_ARCHIVE} ActualMD5)
+
+  if (NOT "${ActualMD5}" STREQUAL "${ORTHANC_FRAMEWORK_MD5}")
+    message(FATAL_ERROR "The MD5 hash of the Orthanc archive is invalid: ${ORTHANC_FRAMEWORK_ARCHIVE}")
+  endif()
+
+  set(ORTHANC_ROOT "${CMAKE_BINARY_DIR}/Orthanc-${ORTHANC_FRAMEWORK_VERSION}")
+
+  if (NOT IS_DIRECTORY "${ORTHANC_ROOT}")
+    if (NOT ORTHANC_FRAMEWORK_ARCHIVE MATCHES ".tar.gz$")
+      message(FATAL_ERROR "Archive should have the \".tar.gz\" extension: ${ORTHANC_FRAMEWORK_ARCHIVE}")
+    endif()
+    
+    message("Uncompressing: ${ORTHANC_FRAMEWORK_ARCHIVE}")
+
+    if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
+      # How to silently extract files using 7-zip
+      # http://superuser.com/questions/331148/7zip-command-line-extract-silently-quietly
+
+      execute_process(
+        COMMAND ${ORTHANC_FRAMEWORK_7ZIP} e -y ${ORTHANC_FRAMEWORK_ARCHIVE}
+        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+        RESULT_VARIABLE Failure
+        OUTPUT_QUIET
+        )
+      
+      if (Failure)
+        message(FATAL_ERROR "Error while running the uncompression tool")
+      endif()
+
+      get_filename_component(TMP_FILENAME "${ORTHANC_FRAMEWORK_ARCHIVE}" NAME)
+      string(REGEX REPLACE ".gz$" "" TMP_FILENAME2 "${TMP_FILENAME}")
+
+      execute_process(
+        COMMAND ${ORTHANC_FRAMEWORK_7ZIP} x -y ${TMP_FILENAME2}
+        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+        RESULT_VARIABLE Failure
+        OUTPUT_QUIET
+        )
+
+    else()
+      execute_process(
+        COMMAND sh -c "${ORTHANC_FRAMEWORK_TAR} xfz ${ORTHANC_FRAMEWORK_ARCHIVE}"
+        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+        RESULT_VARIABLE Failure
+        )
+    endif()
+   
+    if (Failure)
+      message(FATAL_ERROR "Error while running the uncompression tool")
+    endif()
+
+    if (NOT IS_DIRECTORY "${ORTHANC_ROOT}")
+      message(FATAL_ERROR "The Orthanc framework was not uncompressed at the proper location. Check the CMake instructions.")
+    endif()
+  endif()
+endif()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/Orthanc/LinuxStandardBaseToolchain.cmake	Fri Jun 01 17:48:47 2018 +0200
@@ -0,0 +1,66 @@
+# LSB_CC=gcc-4.8 LSB_CXX=g++-4.8 cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../Resources/LinuxStandardBaseToolchain.cmake -DUSE_LEGACY_JSONCPP=ON
+
+INCLUDE(CMakeForceCompiler)
+
+SET(LSB_PATH $ENV{LSB_PATH})
+SET(LSB_CC $ENV{LSB_CC})
+SET(LSB_CXX $ENV{LSB_CXX})
+SET(LSB_TARGET_VERSION "4.0")
+
+IF ("${LSB_PATH}" STREQUAL "")
+  SET(LSB_PATH "/opt/lsb")
+ENDIF()
+
+IF (EXISTS ${LSB_PATH}/lib64)
+  SET(LSB_TARGET_PROCESSOR "x86_64")
+  SET(LSB_LIBPATH ${LSB_PATH}/lib64-${LSB_TARGET_VERSION})
+ELSEIF (EXISTS ${LSB_PATH}/lib)
+  SET(LSB_TARGET_PROCESSOR "x86")
+  SET(LSB_LIBPATH ${LSB_PATH}/lib-${LSB_TARGET_VERSION})
+ELSE()
+  MESSAGE(FATAL_ERROR "Unable to detect the target processor architecture. Check the LSB_PATH environment variable.")
+ENDIF()
+
+SET(LSB_CPPPATH ${LSB_PATH}/include)
+SET(PKG_CONFIG_PATH ${LSB_LIBPATH}/pkgconfig/)
+
+# the name of the target operating system
+SET(CMAKE_SYSTEM_NAME Linux)
+SET(CMAKE_SYSTEM_VERSION LinuxStandardBase)
+SET(CMAKE_SYSTEM_PROCESSOR ${LSB_TARGET_PROCESSOR})
+
+# which compilers to use for C and C++
+SET(CMAKE_C_COMPILER ${LSB_PATH}/bin/lsbcc)
+CMAKE_FORCE_CXX_COMPILER(${LSB_PATH}/bin/lsbc++ GNU)
+
+# here is the target environment located
+SET(CMAKE_FIND_ROOT_PATH ${LSB_PATH})
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search 
+# programs in the host environment
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER)
+
+SET(CMAKE_CROSSCOMPILING OFF)
+
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -I${LSB_PATH}/include" CACHE INTERNAL "" FORCE)
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -nostdinc++ -I${LSB_PATH}/include -I${LSB_PATH}/include/c++ -I${LSB_PATH}/include/c++/backward" CACHE INTERNAL "" FORCE)
+SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -L${LSB_LIBPATH} --lsb-besteffort" CACHE INTERNAL "" FORCE)
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -L${LSB_LIBPATH} --lsb-besteffort" CACHE INTERNAL "" FORCE)
+
+if (NOT "${LSB_CXX}" STREQUAL "")
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --lsb-cxx=${LSB_CXX}")
+  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --lsb-cxx=${LSB_CXX}")
+  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --lsb-cxx=${LSB_CXX}")
+endif()
+
+if (NOT "${LSB_CC}" STREQUAL "")
+  SET(CMAKE_C_FLAGS "${CMAKE_CC_FLAGS} --lsb-cc=${LSB_CC}")
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --lsb-cc=${LSB_CC}")
+  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --lsb-cc=${LSB_CC}")
+  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --lsb-cc=${LSB_CC}")
+endif()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/Orthanc/MinGW-W64-Toolchain32.cmake	Fri Jun 01 17:48:47 2018 +0200
@@ -0,0 +1,17 @@
+# the name of the target operating system
+set(CMAKE_SYSTEM_NAME Windows)
+
+# which compilers to use for C and C++
+set(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
+set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
+set(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
+
+# here is the target environment located
+set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search 
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/Orthanc/MinGW-W64-Toolchain64.cmake	Fri Jun 01 17:48:47 2018 +0200
@@ -0,0 +1,17 @@
+# the name of the target operating system
+set(CMAKE_SYSTEM_NAME Windows)
+
+# which compilers to use for C and C++
+set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
+set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
+set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
+
+# here is the target environment located
+set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search 
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/Orthanc/MinGWToolchain.cmake	Fri Jun 01 17:48:47 2018 +0200
@@ -0,0 +1,20 @@
+# the name of the target operating system
+set(CMAKE_SYSTEM_NAME Windows)
+
+# which compilers to use for C and C++
+set(CMAKE_C_COMPILER i586-mingw32msvc-gcc)
+set(CMAKE_CXX_COMPILER i586-mingw32msvc-g++)
+set(CMAKE_RC_COMPILER i586-mingw32msvc-windres)
+
+# here is the target environment located
+set(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc)
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search 
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSTACK_SIZE_PARAM_IS_A_RESERVATION=0x10000" CACHE INTERNAL "" FORCE)
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTACK_SIZE_PARAM_IS_A_RESERVATION=0x10000" CACHE INTERNAL "" FORCE)
--- a/Resources/Orthanc/NEWS	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,946 +0,0 @@
-Pending changes in the mainline
-===============================
-
-REST API
---------
-
-* "/system" URI returns the version of the Orthanc REST API
-* "/tools/now" returns the current UTC (universal) time
-* "/tools/now-local" returns the curent local time.
-  This was the behavior of "/tools/now" until release 1.3.1.
-* Added "?expand" GET argument to "/peers" and "/modalities" routes
-* New URI: "/tools/create-media-extended" to generate a DICOMDIR
-  archive from several resources, including additional type-3 tags
-* Preservation of UID relationships while anonymizing
-
-Lua
----
-
-* New CMake option: "-DENABLE_LUA_MODULES=ON" to enable support for
-  loading external Lua modules if the Lua engine is statically linked
-
-Plugins
--------
-
-* New error code: DatabaseUnavailable
-
-Maintenance
------------
-
-* Orthanc now uses UTC (universal time) instead of local time in its database
-* Fix to allow creating DICOM instances with empty Specific Character Set (0008,0005)
-* Support of Linux Standard Base
-* Static linking against libuuid (from e2fsprogs)
-* Fix static build on CentOS 6
-* Possibility of using JsonCpp 0.10.6 if the compiler does not support C++11
-  with the "-DUSE_LEGACY_JSONCPP=ON" CMake option
-* Upgraded dependencies for static and Windows builds:
-  - boost 1.66.0
-  - curl 7.57.0
-  - jsoncpp 1.8.4
-  - zlib 1.2.11
-
-
-Version 1.3.1 (2017-11-29)
-==========================
-
-General
--------
-
-* Built-in decoding of palette images
-
-REST API
---------
-
-* New URI: "/instances/.../frames/.../raw.gz" to compress raw frames using gzip
-* New argument "ignore-length" to force the inclusion of too long tags in JSON
-* New argument "/.../media?extended" to include additional type-3 tags in DICOMDIR
-
-Plugins
--------
-
-* New pixel formats exposed in SDK: BGRA32, Float32, Grayscale32, RGB48
-
-Maintenance
------------
-
-* Creation of ./Resources/CMake/OrthancFramework*.cmake to reuse the Orthanc
-  C++ framework in other projects
-* New security-related options: "DicomAlwaysAllowEcho"
-* Use "GBK" (frequently used in China) as an alias for "GB18030"
-* Experimental support of actively maintained Civetweb to replace Mongoose 3.8
-* Fix issue 31 for good (create new modality types for Philips ADW, GE Xeleris, GE AWServer)
-* Fix issue 64 (OpenBSD support)
-* Fix static compilation of DCMTK 3.6.2 on Fedora
-* Upgrade to Boost 1.65.1 in static builds
-* Upgrade to SQLite amalgamation 3.21.0 in static builds
-
-
-Version 1.3.0 (2017-07-19)
-==========================
-
-General
--------
-
-* Orthanc now anonymizes according to Basic Profile of PS 3.15-2017c Table E.1-1
-* In the "DicomModalities" configuration:
-  - Manufacturer type MedInria is now obsolete
-  - Manufacturer types AgfaImpax and SyngoVia are obsolete too
-    (use GenericNoWildcardInDates instead)
-  - Obsolete manufacturers are still accepted but might disappear in the future
-  - Added new manufacturer: GenericNoUniversalWildcard to replace all '*' by '' in
-    outgoing C-Find requests
-* New security-related options: "DicomAlwaysAllowStore" and "DicomCheckModalityHost"
-
-REST API
---------
-
-* Argument "Since" in URI "/tools/find" (related to issue 53)
-* Argument "DicomVersion" in URIs "/{...}/{...}/anonymization"
-
-Plugins
--------
-
-* New function: "OrthancPluginRegisterIncomingHttpRequestFilter2()"
-
-Lua
----
-
-* Added HTTP headers support for Lua HttpPost/HttpGet/HttpPut/HttpDelete
-
-Orthanc Explorer
-----------------
-
-* Query/retrieve: Added button for "DR" modality
-
-Maintenance
------------
-
-* Ability to retrieve raw frames encoded as unsigned 32-bits integers
-* Fix issue 29 (more consistent handling of the "--upgrade" argument)
-* Fix issue 31 (create new modality types for Philips ADW, GE Xeleris, GE AWServer)
-* Fix issue 35 (AET name is not transferred to Orthanc using DCMTK 3.6.0)
-* Fix issue 44 (bad interpretation of photometric interpretation MONOCHROME1)
-* Fix issue 45 (crash when providing a folder to "--config" command-line option)
-* Fix issue 46 (PHI remaining after anonymization)
-* Fix issue 49 (worklists: accentuated characters are removed from C-Find responses)
-* Fix issue 52 (DICOM level security association problems)
-* Fix issue 55 (modification/anonymization of tags that might break the database
-  model now requires the "Force" parameter to be set to "true" in the query)
-* Fix issue 56 (case-insensitive matching over accents)
-* Fix Debian #865606 (orthanc FTBFS with libdcmtk-dev 3.6.1~20170228-2)
-* Fix XSS inside DICOM in Orthanc Explorer (as reported by Victor Pasnkel, Morphus Labs)
-* Upgrade to DCMTK 3.6.2 in static builds (released on 2017-07-17)
-* Upgrade to Boost 1.64.0 in static builds
-* New advanced "Locale" configuration option
-* Removed configuration option "USE_DCMTK_361_PRIVATE_DIC"
-
-
-Version 1.2.0 (2016/12/13)
-==========================
-
-General
--------
-
-* Handling of private tags/creators in the "Dictionary" configuration option
-* New configuration options: "LoadPrivateDictionary", "DicomScuTimeout" and "DicomScpTimeout"
-* New metadata automatically computed at the instance level: "TransferSyntax" and "SopClassUid"
-
-REST API
---------
-
-* "/tools/invalidate-tags" to invalidate the JSON summary of all the DICOM files
-  (useful if private tags are registered, or if changing the default encoding)
-* "Permissive" flag for URI "/modalities/{...}/store" to ignore C-STORE transfer errors
-* "Asynchronous" flag for URIs "/modalities/{...}/store" and "/peers/{...}/store"
-  to avoid waiting for the completion of image transfers
-* Possibility to DELETE "dicom-as-json" attachments to reconstruct the JSON summaries
-  (useful if "Dictionary" has changed)
-* "Keep" option for modifications to keep original DICOM identifiers (advanced feature)
-* "/tools/default-encoding" to get or temporarily change the default encoding
-* "/{resource}/{id}/reconstruct" to reconstruct the main DICOM tags, the JSON summary and
-  the metadata of a resource (useful to compute new metadata, or if using "Keep" above)
-
-Plugins
--------
-
-* New function: "OrthancPluginRegisterPrivateDictionaryTag()" to register private tags
-* More control over client cache in the ServeFolders plugin
-* New C++ help wrappers in "Plugins/Samples/Common/" to read DICOM datasets from REST API
-* New data structure: "OrthancPluginFindMatcher" to match DICOM against C-FIND queries
-
-Maintenance
------------
-
-* Fix handling of encodings in C-FIND requests (including for worklists)
-* Use of DCMTK 3.6.1 dictionary of private tags in standalone builds
-* Avoid hard crash if not enough memory (handling of std::bad_alloc)
-* Improved robustness of Orthanc Explorer wrt. query/retrieve (maybe fix issue 24)
-* Fix serious performance issue with C-FIND
-* Fix extraction of the symbolic name of the private tags
-* Performance warning if runtime debug assertions are turned on
-* Improved robustness against files with no PatientID
-* Upgrade to curl 7.50.3 for static and Windows builds
-* Content-Type for JSON documents is now "application/json; charset=utf-8"
-* Ignore "Group Length" tags in C-FIND queries
-* Fix handling of worklist SCP with ReferencedStudySequence and ReferencedPatientSequence
-* Fix handling of Move Originator AET and ID in C-MOVE SCP
-* Fix vulnerability ZSL-2016-5379 "Unquoted Service Path Privilege Escalation" in the
-  Windows service
-* Fix vulnerability ZSL-2016-5380 "Remote Memory Corruption Vulnerability" in DCMTK 3.6.0
-
-
-Version 1.1.0 (2016/06/27)
-==========================
-
-General
--------
-
-* HTTPS client certificates can be associated with Orthanc peers to enhance security over Internet
-* Possibility to use PKCS#11 authentication for hardware security modules with Orthanc peers
-* New command-line option "--logfile" to output the Orthanc log to the given file
-* Support of SIGHUP signal (restart Orthanc only if the configuration files have changed)
-
-REST API
---------
-
-* New URI: "/instances/.../frames/.../raw" to access the raw frames (bypass image decoding)
-* New URI "/modalities/.../move" to issue C-MOVE SCU requests
-* "MoveOriginatorID" can be specified for "/modalities/.../store"
-
-Dicom protocol
---------------
-
-* Support of optional tags for counting resources in C-FIND:
-  0008-0061, 0008-0062, 0020-1200, 0020-1202, 0020-1204, 0020-1206, 0020-1208, 0020-1209
-* Support of Move Originator Message ID (0000,1031) in C-STORE responses driven by C-MOVE
-
-Plugins
--------
-
-* Speedup in plugins by removing unnecessary locks
-* New callback to filter incoming HTTP requests: OrthancPluginRegisterIncomingHttpRequestFilter()
-* New callback to handle non-worklists C-FIND requests: OrthancPluginRegisterFindCallback()
-* New callback to handle C-MOVE requests: OrthancPluginRegisterMoveCallback()
-* New function: "OrthancPluginHttpClient()" to do HTTP requests with full control
-* New function: "OrthancPluginGenerateUuid()" to generate a UUID
-* More than one custom image decoder can be installed (e.g. to handle different transfer syntaxes)
-
-Lua
----
-
-* Possibility to dynamically fix outgoing C-FIND requests using "OutgoingFindRequestFilter()"
-* Access to the HTTP headers in the "IncomingHttpRequestFilter()" callback
-
-Image decoding
---------------
-
-* Huge speedup if decoding the family of JPEG transfer syntaxes
-* Refactoring leading to speedups with custom image decoders (including Web viewer plugin)
-* Support decoding of RLE Lossless transfer syntax
-* Support of signed 16bpp images in ParsedDicomFile
-
-Maintenance
------------
-
-* New logo of Orthanc
-* Fix issue 11 (is_regular_file() fails for FILE_ATTRIBUTE_REPARSE_POINT)
-* Fix issue 16 ("Limit" parameter error in REST API /tools/find method)
-* Fix of Debian bug #818512 ("FTBFS: Please install libdcmtk*-dev")
-* Fix of Debian bug #823139 ("orthanc: Please provide RecoverCompressedFile.cpp")
-* Replaced "localhost" by "127.0.0.1", as it might impact performance on Windows
-* Compatibility with CMake >= 3.5.0
-* Possibility to use forthcoming DCMTK 3.6.1 in static builds (instead of 3.6.0)
-* Upgrade to Boost 1.60.0 for static builds
-* Use of HTTP status 403 Forbidden (instead of 401) if access to a REST resource is disallowed
-* Option "HttpsVerifyPeers" can be used to connect against self-signed HTTPS certificates
-* New configuration option "AllowFindSopClassesInStudy"
-* Macro "__linux" (now obsolete) replaced by macro "__linux__" (maybe solves Debian bug #821011)
-* Modification of instances can now replace PixelData (resp. EncapsulatedDocument) with 
-  provided a PNG/JPEG image (resp. PDF file) if it is encoded using Data URI Scheme
-* Dropped support of Google Log
-
-
-Version 1.0.0 (2015/12/15)
-==========================
-
-* Lua: "IncomingFindRequestFilter()" to apply filters to incoming C-FIND requests
-* New function in plugin SDK: "OrthancPluginSendMultipartItem2()"
-* Fix of DICOMDIR generation with DCMTK 3.6.1, support of encodings
-* Fix range search if the lower or upper limit is absent
-* Fix modality worklists lookups if tags with UN (unknown) VR are present
-* Warn about badly formatted modality/peer definitions in configuration file at startup
-
-
-Version 0.9.6 (2015/12/08)
-==========================
-
-* Promiscuous mode (accept unknown SOP class UID) is now turned off by default
-* Fix serialization of DICOM buffers that might contain garbage trailing
-* Fix modality worklists server if some fields are null
-* More tolerant "/series/.../ordered-slices" with broken series
-* Improved logging information if upgrade fails
-* Fix formatting of multipart HTTP answers (bis)
-
-
-Version 0.9.5 (2015/12/02)
-==========================
-
-Major
------
-
-* Experimental support of DICOM C-FIND SCP for modality worklists through plugins
-* Support of DICOM C-FIND SCU for modality worklists ("/modalities/{dicom}/find-worklist")
-
-REST API
---------
-
-* New URIs:
-  - "/series/.../ordered-slices" to order the slices of a 2D+t or 3D series
-  - "/tools/shutdown" to stop Orthanc from the REST API
-  - ".../compress", ".../uncompress" and ".../is-compressed" for attachments
-  - "/tools/create-archive" to create ZIP from a set of resources
-  - "/tools/create-media" to create ZIP+DICOMDIR from a set of resources
-  - "/instances/.../header" to get the meta information (header) of the DICOM instance
-* "/tools/create-dicom":
-  - Support of binary tags encoded using data URI scheme
-  - Support of hierarchical structures (creation of sequences)
-  - Create tags with unknown VR
-* "/modify" can insert/modify sequences
-* ".../preview" and ".../image-uint8" can return JPEG images if the HTTP Accept Header asks so
-* "Origin" metadata for the instances
-
-Minor
------
-
-* New configuration options:
-  - "UnknownSopClassAccepted" to disable promiscuous mode (accept unknown SOP class UID)
-  - New configuration option: "Dictionary" to declare custom DICOM tags
-* Add ".dcm" suffix to files in ZIP archives (cf. URI ".../archive")
-* MIME content type can be associated to custom attachments (cf. "UserContentType")
-
-Plugins
--------
-
-* New functions:
-  - "OrthancPluginRegisterDecodeImageCallback()" to replace the built-in image decoder
-  - "OrthancPluginDicomInstanceToJson()" to convert DICOM to JSON
-  - "OrthancPluginDicomBufferToJson()" to convert DICOM to JSON
-  - "OrthancPluginRegisterErrorCode()" to declare custom error codes
-  - "OrthancPluginRegisterDictionaryTag()" to declare custom DICOM tags
-  - "OrthancPluginLookupDictionary()" to get information about some DICOM tag
-  - "OrthancPluginRestApiGet2()" to provide HTTP headers when calling Orthanc API
-  - "OrthancPluginGetInstanceOrigin()" to know through which mechanism an instance was received
-  - "OrthancPluginCreateImage()" and "OrthancPluginCreateImageAccessor()" to create images
-  - "OrthancPluginDecodeDicomImage()" to decode DICOM images
-  - "OrthancPluginComputeMd5()" and "OrthancPluginComputeSha1()" to compute MD5/SHA-1 hash
-* New events in change callbacks:
-  - "OrthancStarted"
-  - "OrthancStopped"
-  - "UpdatedAttachment" 
-  - "UpdatedMetadata"
-* "/system" URI gives information about the plugins used for storage area and DB back-end
-* Plugin callbacks must now return explicit "OrthancPluginErrorCode" (instead of integers)
-
-Lua
----
-
-* Optional argument "keepStrings" in "DumpJson()"
-
-Maintenance
------------
-
-* Full indexation of the patient/study tags to speed up searches and C-FIND
-* Many refactorings, notably of the searching features and of the image decoding
-* C-MOVE SCP for studies using AccessionNumber tag
-* Fix issue 4 (C-STORE Association not renegotiated on Specific-to-specific transfer syntax change)
-* Fix formatting of multipart HTTP answers
-* "--logdir" flag creates a single log file instead of 3 separate files for errors/warnings/infos
-* "--errors" flag lists the error codes that could be returned by Orthanc
-* Under Windows, the exit status of Orthanc corresponds to the encountered error code
-* New "AgfaImpax", "EFilm2" and "Vitrea" modality manufacturers
-* C-FIND SCP will return tags with sequence value representation
-* Upgrade to Boost 1.59.0 for static builds
-
-
-Version 0.9.4 (2015/09/16)
-==========================
-
-* Preview of PDF files encapsulated in DICOM from Orthanc Explorer
-* Creation of DICOM files with encapsulated PDF through "/tools/create-dicom"
-* "limit" and "since" arguments while retrieving DICOM resources in the REST API
-* Support of "deflate" and "gzip" content-types in HTTP requests
-* Options to validate peers against CA certificates in HTTPS requests
-* New configuration option: "HttpTimeout" to set the default timeout for HTTP requests
-
-Lua
----
-
-* More information about the origin request in the "OnStoredInstance()" and
-  "ReceivedInstanceFilter()" callbacks. WARNING: This can result in
-  incompatibilities wrt. previous versions of Orthanc.
-* New function "GetOrthancConfiguration()" to get the Orthanc configuration
-
-Plugins
--------
-
-* New functions to compress/uncompress images using PNG and JPEG
-* New functions to issue HTTP requests from plugins
-* New function "OrthancPluginBufferCompression()" to (un)compress memory buffers
-* New function "OrthancPluginReadFile()" to read files from the filesystem
-* New function "OrthancPluginWriteFile()" to write files to the filesystem
-* New function "OrthancPluginGetErrorDescription()" to convert error codes to strings
-* New function "OrthancPluginSendHttpStatus()" to send HTTP status with a body
-* New function "OrthancPluginRegisterRestCallbackNoLock()" for high-performance plugins
-* Plugins have access to explicit error codes 
-* Improvements to the sample "ServeFolders" plugin
-* Primitives to upgrade the database version in plugins
-
-Maintenance
------------
-
-* Many code refactorings
-* Improved error codes (no more custom descriptions in exceptions)
-* If error while calling the REST API, the answer body contains description of the error
-  (this feature can be disabled with the "HttpDescribeErrors" option)
-* Upgrade to curl 7.44.0 for static and Windows builds
-* Upgrade to libcurl 1.0.2d for static and Windows builds
-* Depends on libjpeg 9a
-* Bypass zlib uncompression if "StorageCompression" is enabled and HTTP client supports deflate
-
-
-Version 0.9.3 (2015/08/07)
-==========================
-
-* C-Echo testing can be triggered from Orthanc Explorer (in the query/retrieve page)
-* Removal of the dependency upon Google Log, Orthanc now uses its internal logger 
-  (use -DENABLE_GOOGLE_LOG=ON to re-enable Google Log)
-* Upgrade to JsonCpp 0.10.5 for static and Windows builds
-
-
-Version 0.9.2 (2015/08/02)
-==========================
-
-* Upgrade to Boost 1.58.0 for static and Windows builds
-* Source code repository moved from Google Code to BitBucket
-* Inject version information into Windows binaries
-* Fix access to binary data in HTTP/REST requests by Lua scripts
-* Fix potential deadlock in the callbacks of plugins
-
-
-Version 0.9.1 (2015/07/02)
-==========================
-
-General
--------
-
-* The configuration can be splitted into several files stored inside the same folder
-* Custom setting of the local AET during C-STORE SCU (both in Lua and in the REST API)
-* Many code refactorings
-
-Lua
----
-
-* Access to the REST API of Orthanc (RestApiGet, RestApiPost, RestApiPut, RestApiDelete)
-* Functions to convert between Lua values and JSON strings: "ParseJson" and "DumpJson"
-* New events: "OnStablePatient", "OnStableStudy", "OnStableSeries", "Initialize", "Finalize"
-
-Plugins
--------
-
-* Plugins can retrieve the configuration file directly as a JSON string
-* Plugins can send answers as multipart messages
-
-Fixes
------
-
-* Fix compatibility issues for C-FIND SCU to Siemens Syngo.Via modalities SCP
-* Fix issue 15 (Lua scripts making HTTP requests)
-* Fix issue 35 (Characters in PatientID string are not protected for C-FIND)
-* Fix issue 37 (Hyphens trigger range query even if datatype does not support ranges)
-
-
-Version 0.9.0 (2015/06/03)
-==========================
-
-Major
------
-
-* DICOM Query/Retrieve available from Orthanc Explorer
-* C-MOVE SCU and C-FIND SCU are accessible through the REST API
-* "?expand" flag for URIs "/patients", "/studies" and "/series"
-* "/tools/find" URI to search for DICOM resources from REST
-* Support of FreeBSD
-* The "Orthanc Client" SDK is now a separate project
-
-Minor
------
-
-* Speed-up in Orthanc Explorer for large amount of images
-* Speed-up of the C-FIND SCP server of Orthanc
-* Allow replacing PatientID/StudyInstanceUID/SeriesInstanceUID from Lua scripts
-* Option "CaseSensitivePN" to enable case-insensitive C-FIND SCP
-
-Fixes
------
-
-* Prevent freeze on C-FIND if no DICOM tag is to be returned
-* Fix slow C-STORE SCP on recent versions of GNU/Linux, if
-  USE_SYSTEM_DCMTK is set to OFF (http://forum.dcmtk.org/viewtopic.php?f=1&t=4009)
-* Fix issue 30 (QR response missing "Query/Retrieve Level" (008,0052))
-* Fix issue 32 (Cyrillic symbols): Introduction of the "Windows1251" encoding
-* Plugins now receive duplicated GET arguments in their REST callbacks
-
-
-Version 0.8.6 (2015/02/12)
-==========================
-
-Major
------
-
-* URIs to get all the parents of a given resource in a single REST call
-* Instances without PatientID are now allowed
-* Support of HTTP proxy to access Orthanc peers
-
-Minor
------
-
-* Support of Tudor DICOM in Query/Retrieve
-* More flexible "/modify" and "/anonymize" for single instance
-* Access to called AET and remote AET from Lua scripts ("OnStoredInstance")
-* Option "DicomAssociationCloseDelay" to set delay before closing DICOM association
-* ZIP archives now display the accession number of the studies
-
-Plugins
--------
-
-* Introspection of plugins (cf. the "/plugins" URI)
-* Plugins can access the command-line arguments used to launch Orthanc
-* Plugins can extend Orthanc Explorer with custom JavaScript
-* Plugins can get/set global properties to save their configuration
-* Plugins can do REST calls to other plugins (cf. "xxxAfterPlugins()")
-* Scan of folders for plugins
-
-Fixes
------
-
-* Code refactorings
-* Fix issue 25 (AET with underscore not allowed)
-* Fix replacement and insertion of private DICOM tags
-* Fix anonymization generating non-portable DICOM files
-
-
-Version 0.8.5 (2014/11/04)
-==========================
-
-General
--------
-
-* Major speed-up thanks to a new database schema
-* Plugins can monitor changes through callbacks
-* Download ZIP + DICOMDIR from Orthanc Explorer
-* Sample plugin framework to serve static resources (./Plugins/Samples/WebSkeleton/)
-
-Fixes
------
-
-* Fix issue 19 (YBR_FULL are decoded incorrectly)
-* Fix issue 21 (Microsoft Visual Studio precompiled headers)
-* Fix issue 22 (Error decoding multi-frame instances)
-* Fix issue 24 (Build fails on OSX when directory has .DS_Store files)
-* Fix crash when bad HTTP credentials are provided
-
-
-Version 0.8.4 (2014/09/19)
-==========================
-
-* "/instances-tags" to get the tags of all the child instances of a
-  patient/study/series with a single REST call (bulk tags retrieval)
-* Configuration/Lua to select the accepted C-STORE SCP transfer syntaxes
-* Fix reporting of errors in Orthanc Explorer when sending images to peers/modalities
-* Installation of plugin SDK in CMake
-
-
-Version 0.8.3 (2014/09/11)
-==========================
-
-Major
------
-
-* Creation of ZIP archives for media storage, with DICOMDIR
-* URIs to get all the children of a given resource in a single REST call
-* "/tools/lookup" URI to map DICOM UIDs to Orthanc identifiers
-* Support of index-only mode (using the "StoreDicom" option)
-* Plugins can implement a custom storage area
-
-Minor
------
-
-* Configuration option to enable HTTP Keep-Alive
-* Configuration option to disable the logging of exported resources in "/exports"
-* Plugins can retrieve the path to Orthanc and to its configuration file
-* "/tools/create-dicom" now accepts the "PatientID" DICOM tag (+ updated sample)
-* Possibility to set HTTP headers from plugins
-* "LastUpdate" metadata is now always returned for patients, studies and series
-
-Maintenance
------------
-
-* Refactoring of HttpOutput ("Content-Length" header is now always sent)
-* Upgrade to Mongoose 3.8
-* Fixes for Visual Studio 2013 and Windows 64bit
-* Fix issue 16: Handling of "AT" value representations in JSON
-* Fix issue 17
-
-
-Version 0.8.2 (2014/08/07)
-==========================
-
-* Support of the standard text encodings
-* Hot restart of Orthanc by posting to "/tools/reset"
-* More fault-tolerant commands in Lua scripts
-* Parameter to set the default encoding for DICOM files without SpecificCharacterSet
-* Fix of issue #14 (support of XCode 5.1)
-* Upgrade to Google Test 1.7.0
-
-
-Version 0.8.1 (2014/07/29)
-==========================
-
-General
--------
-
-* Access patient module at the study level to cope with PatientID collisions
-* On-the-fly conversion of JSON to XML according to the HTTP Accept header
-* C-Echo SCU in the REST API
-* DICOM conformance statement available at URI "/tools/dicom-conformance"
-
-Lua scripts
------------
-
-* Lua scripts can do HTTP requests, and thus can call Web services
-* Lua scripts can invoke system commands, with CallSystem()
-
-Plugins
--------
-
-* Lookup for DICOM UIDs in the plugin SDK
-* Plugins have access to the HTTP headers and can answer with HTTP status codes
-* Callback to react to the incoming of DICOM instances
-
-Fixes
------
-
-* Fix build of Google Log with Visual Studio >= 11.0
-* Fix automated generation of the list of resource children in the REST API
-
-
-Version 0.8.0 (2014/07/10)
-==========================
-
-Major changes
--------------
-
-* Routing images with Lua scripts
-* Introduction of the Orthanc Plugin SDK
-* Official support of OS X (Darwin) 10.8
-
-Minor changes
--------------
-
-* Extraction of tags for the patient/study/series/instance DICOM modules
-* Extraction of the tags shared by all the instances of a patient/study/series
-* Options to limit the number of results for an incoming C-FIND query
-* Support of kFreeBSD
-* Several code refactorings
-* Fix OrthancCppClient::GetVoxelSizeZ()
-
-
-Version 0.7.6 (2014/06/11)
-==========================
-
-* Support of JPEG and JPEG-LS decompression
-* Download DICOM images as Matlab/Octave arrays
-* Precompiled headers for Microsoft Visual Studio
-
-
-Version 0.7.5 (2014/05/08)
-==========================
-
-* Dynamic negotiation of SOP classes for C-STORE SCU
-* Creation of DICOM instances using the REST API
-* Embedding of images within DICOM instances
-* Adding/removal/modification of remote modalities/peers through REST
-* Reuse of the previous SCU connection to avoid unnecessary handshakes
-* Fix problems with anonymization and modification
-* Fix missing licensing terms about reuse of some code from DCMTK
-* Various code refactorings
-
-
-Version 0.7.4 (2014/04/16)
-==========================
-
-* Switch to openssl-1.0.1g in static builds (cf. Heartbleed exploit)
-* Switch to boost 1.55.0 in static builds (to solve compiling errors)
-* Better logging about nonexistent tags
-* Dcm4Chee manufacturer
-* Automatic discovering of the path to the DICOM dictionaries
-* In the "DicomModalities" config, the port number can be a string
-
-
-Version 0.7.3 (2014/02/14)
-==========================
-
-Major changes
--------------
-
-* Fixes in the implementation of the C-FIND handler for Query/Retrieve
-* Custom attachment of files to patients, studies, series or instances
-* Access to lowlevel info about the attached files through the REST API
-* Recover pixel data for more transfer syntaxes (notably JPEG)
-
-Minor changes
--------------
-
-* AET comparison is now case-insensitive by default
-* Possibility to disable the HTTP server or the DICOM server
-* Automatic computation of MD5 hashes for the stored DICOM files
-* Maintenance tool to recover DICOM files compressed by Orthanc
-* The newline characters in the configuration file are fixed for GNU/Linux
-* Capture of the SIGTERM signal in GNU/Linux
-
-
-Version 0.7.2 (2013/11/08)
-==========================
-
-* Support of Query/Retrieve from medInria
-* Accept more transfer syntaxes for C-STORE SCP and SCU (notably JPEG)
-* Create the meta-header when receiving files through C-STORE SCP
-* Fixes and improvements thanks to the static analyzer cppcheck
-
-
-Version 0.7.1 (2013/10/30)
-==========================
-
-* Use ZIP64 only when required to improve compatibility (cf. issue #7)
-* Refactoring of the CMake options
-* Fix for big-endian architectures (RedHat bug #985748)
-* Use filenames with 8 characters in ZIP files for maximum compatibility
-* Possibility to build Orthanc inplace (in the source directory)
-
-
-Version 0.7.0 (2013/10/25)
-==========================
-
-Major changes
--------------
-
-* DICOM Query/Retrieve is supported
-
-Minor changes
--------------
-
-* Possibility to keep the PatientID during an anonymization
-* Check whether "unzip", "tar" and/or "7-zip" are installed from CMake
-
-
-Version 0.6.2 (2013/10/04)
-==========================
-
-* Build of the C++ client as a shared library
-* Improvements and documentation of the C++ client API
-* Fix of Debian bug #724947 (licensing issue with the SHA-1 library)
-* Switch to Boost 1.54.0 (cf. issue #9)
-* "make uninstall" is now possible
-
-
-Version 0.6.1 (2013/09/16)
-==========================
-
-* Detection of stable patients/studies/series
-* C-FIND SCU at the instance level
-* Link from modified to original resource in Orthanc Explorer
-* Fix of issue #8
-* Anonymization of the medical alerts tag (0010,2000)
-
-
-Version 0.6.0 (2013/07/16)
-==========================
-
-Major changes
--------------
-
-* Introduction of the C++ client
-* Send DICOM resources to other Orthanc instances through HTTP
-* Access to signed images (instances/.../image-int16)
-  (Closes: Debian #716958)
-
-Minor changes
--------------
-
-* Export of DICOM files to the host filesystem (instances/.../export)
-* Statistics about patients, studies, series and instances
-* Link from anonymized to original resource in Orthanc Explorer
-* Fixes for Red Hat and Debian packaging
-* Fixes for history in Orthanc Explorer
-* Fixes for boost::thread, as reported by Cyril Paulus
-* Fix licensing (Closes: Debian #712038)
-
-Metadata
---------
-
-* Access to the metadata through the REST API (.../metadata)
-* Support of user-defined metadata
-* "LastUpdate" metadata for patients, studies and series
-* "/tools/now" to be used in combination with "LastUpdate"
-* Improved support of series with temporal positions
-
-
-Version 0.5.2 (2013/05/07)
-==========================
-
-* "Bulk" Store-SCU (send several DICOM instances with the same
-  DICOM connection)
-* Store-SCU for patients and studies in Orthanc Explorer
-* Filtering of incoming DICOM instances (through Lua scripting)
-* Filtering of incoming HTTP requests (through Lua scripting)
-* Clearing of "/exports" and "/changes"
-* Check MD5 of third party downloads
-* Faking of the HTTP methods PUT and DELETE
-
-
-Version 0.5.1 (2013/04/17)
-==========================
-
-* Support of RGB images
-* Fix of store SCU in release builds
-* Possibility to store the SQLite index at another place than the
-  DICOM instances (for performance)
-
-
-Version 0.5.0 (2013/01/31)
-==========================
-
-Major changes
--------------
-
-* Download of modified or anonymized DICOM instances
-* Inplace modification and anonymization of DICOM series, studies and patients
-
-Minor changes
--------------
-
-* Support of private tags
-* Implementation of the PMSCT_RLE1 image decoding for Philips modalities
-* Generation of random DICOM UID through the REST API (/tools/generate-uid)
-
-
-Version 0.4.0 (2012/12/14)
-==========================
-
-Major changes
--------------
-
-* Recycling of disk space
-* Raw access to the value of the DICOM tags in the REST API
-
-Minor changes
--------------
-
-* Protection of patients against recycling (also in Orthanc Explorer)
-* The DICOM dictionaries are embedded in Windows builds
-
-
-Version 0.3.1 (2012/12/05)
-==========================
-
-* Download archives of patients, studies and series as ZIP files
-* Orthanc now checks the version of its database schema before starting
-
-
-Version 0.3.0 (2012/11/30)
-==========================
-
-Major changes
--------------
-
-* Transparent compression of the DICOM instances on the disk
-* The patient/study/series/instances are now indexed by SHA-1 digests
-  of their DICOM Instance IDs (and not by UUIDs anymore): The same
-  DICOM objects are thus always identified by the same Orthanc IDs
-* Log of exported instances through DICOM C-STORE SCU ("/exported" URI)
-* Full refactoring of the DB schema and of the REST API
-* Introduction of generic classes for REST APIs (in Core/RestApi)
-
-Minor changes
--------------
-
-* "/statistics" URI
-* "last" flag to retrieve the last change from the "/changes" URI
-* Generate a sample configuration file from command line
-* "CompletedSeries" event in the changes API
-* Thread to continuously flush DB to disk (SQLite checkpoints for
-  improved robustness)
-
-
-Version 0.2.3 (2012/10/26)
-==========================
-
-* Use HTTP Content-Disposition to set a filename when downloading JSON/DCM
-* URI "/system" for general information about Orthanc
-* Versioning info and help on the command line
-* Improved logging
-* Possibility of dynamic linking against jsoncpp, sqlite, boost and dmctk
-  for Debian packaging
-* Fix some bugs
-* Switch to default 8042 port for HTTP
-
-
-Version 0.2.2 (2012/10/04)
-==========================
-
-* Switch to Google Log
-* Fixes to Debian packaging
-
-
-Version 0.2.1 (2012/09/28)
-==========================
-
-* Status of series
-* Continuous Integration Server is up and running
-* Ready for Debian packaging
-
-
-Version 0.2.0 (2012/09/16)
-==========================
-
-Major changes
--------------
-
-* Renaming to "Orthanc"
-* Focus on security: Support of SSL, HTTP Basic Authentication and
-  interdiction of remote access
-* Access to multi-frame images (for nuclear medicine)
-* Access to the raw PNG images (in 8bpp and 16bpp)
-
-Minor changes
--------------
-
-* Change of the licensing of the "Core/SQLite" folder to BSD (to
-  reflect the original licensing terms of Chromium, from which the
-  code derives)
-* Standalone build for cross-compilation
-
-
-Version 0.1.1 (2012/07/20)
-==========================
-
-* Fix Windows version
-* Native Windows build with Microsoft Visual Studio 2005
-* Add path to storage in Configuration.json
-
-
-Version 0.1.0 (2012/07/19)
-==========================
-
-* Initial release
--- a/Resources/Orthanc/Plugins/Samples/Common/DicomDatasetReader.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +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-2018 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.
- *
- * 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 "DicomDatasetReader.h"
-
-#include "OrthancPluginException.h"
-
-#include <boost/lexical_cast.hpp>
-
-namespace OrthancPlugins
-{
-  // This function is copied-pasted from "../../../Core/Toolbox.cpp",
-  // in order to avoid the dependency of plugins against the Orthanc core
-  static std::string StripSpaces(const std::string& source)
-  {
-    size_t first = 0;
-
-    while (first < source.length() &&
-           isspace(source[first]))
-    {
-      first++;
-    }
-
-    if (first == source.length())
-    {
-      // String containing only spaces
-      return "";
-    }
-
-    size_t last = source.length();
-    while (last > first &&
-           isspace(source[last - 1]))
-    {
-      last--;
-    }          
-    
-    assert(first <= last);
-    return source.substr(first, last - first);
-  }
-
-
-  DicomDatasetReader::DicomDatasetReader(const IDicomDataset& dataset) :
-    dataset_(dataset)
-  {
-  }
-  
-
-  std::string DicomDatasetReader::GetStringValue(const DicomPath& path,
-                                                 const std::string& defaultValue) const
-  {
-    std::string s;
-    if (dataset_.GetStringValue(s, path))
-    {
-      return s;
-    }
-    else
-    {
-      return defaultValue;
-    }
-  }
-
-
-  std::string DicomDatasetReader::GetMandatoryStringValue(const DicomPath& path) const
-  {
-    std::string s;
-    if (dataset_.GetStringValue(s, path))
-    {
-      return s;
-    }
-    else
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(InexistentTag);
-    }
-  }
-
-
-  template <typename T>
-  static bool GetValueInternal(T& target,
-                               const IDicomDataset& dataset,
-                               const DicomPath& path)
-  {
-    try
-    {
-      std::string s;
-
-      if (dataset.GetStringValue(s, path))
-      {
-        target = boost::lexical_cast<T>(StripSpaces(s));
-        return true;
-      }
-      else
-      {
-        return false;
-      }
-    }
-    catch (boost::bad_lexical_cast&)
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);        
-    }
-  }
-
-
-  bool DicomDatasetReader::GetIntegerValue(int& target,
-                                           const DicomPath& path) const
-  {
-    return GetValueInternal<int>(target, dataset_, path);
-  }
-
-
-  bool DicomDatasetReader::GetUnsignedIntegerValue(unsigned int& target,
-                                                   const DicomPath& path) const
-  {
-    int value;
-
-    if (!GetIntegerValue(value, path))
-    {
-      return false;
-    }
-    else if (value >= 0)
-    {
-      target = static_cast<unsigned int>(value);
-      return true;
-    }
-    else
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
-    }
-  }
-
-
-  bool DicomDatasetReader::GetFloatValue(float& target,
-                                         const DicomPath& path) const
-  {
-    return GetValueInternal<float>(target, dataset_, path);
-  }
-
-
-  bool DicomDatasetReader::GetDoubleValue(double& target,
-                                          const DicomPath& path) const
-  {
-    return GetValueInternal<double>(target, dataset_, path);
-  }
-}
--- a/Resources/Orthanc/Plugins/Samples/Common/DicomDatasetReader.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "IDicomDataset.h"
-
-#include <memory>
-#include <vector>
-
-namespace OrthancPlugins
-{
-  class DicomDatasetReader : public boost::noncopyable
-  {
-  private:
-    const IDicomDataset&  dataset_;
-
-  public:
-    DicomDatasetReader(const IDicomDataset& dataset);
-
-    const IDicomDataset& GetDataset() const
-    {
-      return dataset_;
-    }
-
-    std::string GetStringValue(const DicomPath& path,
-                               const std::string& defaultValue) const;
-
-    std::string GetMandatoryStringValue(const DicomPath& path) const;
-
-    bool GetIntegerValue(int& target,
-                         const DicomPath& path) const;
-
-    bool GetUnsignedIntegerValue(unsigned int& target,
-                                 const DicomPath& path) const;
-
-    bool GetFloatValue(float& target,
-                       const DicomPath& path) const;
-
-    bool GetDoubleValue(double& target,
-                        const DicomPath& path) const;
-  };
-}
--- a/Resources/Orthanc/Plugins/Samples/Common/DicomPath.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +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-2018 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.
- *
- * 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 "DicomPath.h"
-
-#include "OrthancPluginException.h"
-
-namespace OrthancPlugins
-{
-  const DicomPath::Prefix& DicomPath::GetPrefixItem(size_t depth) const
-  {
-    if (depth >= prefix_.size())
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
-    }
-    else
-    {
-      return prefix_[depth];
-    }
-  }
-
-
-  DicomPath::DicomPath(const DicomTag& sequence,
-                       size_t index,
-                       const DicomTag& tag) :
-    finalTag_(tag)
-  {
-    AddToPrefix(sequence, index);
-  }
-
-
-  DicomPath::DicomPath(const DicomTag& sequence1,
-                       size_t index1,
-                       const DicomTag& sequence2,
-                       size_t index2,
-                       const DicomTag& tag) :
-    finalTag_(tag)
-  {
-    AddToPrefix(sequence1, index1);
-    AddToPrefix(sequence2, index2);
-  }
-
-
-  DicomPath::DicomPath(const DicomTag& sequence1,
-                       size_t index1,
-                       const DicomTag& sequence2,
-                       size_t index2,
-                       const DicomTag& sequence3,
-                       size_t index3,
-                       const DicomTag& tag) :
-    finalTag_(tag)
-  {
-    AddToPrefix(sequence1, index1);
-    AddToPrefix(sequence2, index2);
-    AddToPrefix(sequence3, index3);
-  }
-}
--- a/Resources/Orthanc/Plugins/Samples/Common/DicomPath.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "DicomTag.h"
-
-#include <vector>
-#include <stddef.h>
-
-namespace OrthancPlugins
-{
-  class DicomPath
-  {
-  private:
-    typedef std::pair<DicomTag, size_t>  Prefix;
-
-    std::vector<Prefix>  prefix_;
-    DicomTag             finalTag_;
-
-    const Prefix& GetPrefixItem(size_t depth) const;
-
-  public:
-    DicomPath(const DicomTag& finalTag) :
-    finalTag_(finalTag)
-    {
-    }
-
-    DicomPath(const DicomTag& sequence,
-              size_t index,
-              const DicomTag& tag);
-
-    DicomPath(const DicomTag& sequence1,
-              size_t index1,
-              const DicomTag& sequence2,
-              size_t index2,
-              const DicomTag& tag);
-
-    DicomPath(const DicomTag& sequence1,
-              size_t index1,
-              const DicomTag& sequence2,
-              size_t index2,
-              const DicomTag& sequence3,
-              size_t index3,
-              const DicomTag& tag);
-
-    void AddToPrefix(const DicomTag& tag,
-                     size_t position)
-    {
-      prefix_.push_back(std::make_pair(tag, position));
-    }
-
-    size_t GetPrefixLength() const
-    {
-      return prefix_.size();
-    }
-    
-    DicomTag GetPrefixTag(size_t depth) const
-    {
-      return GetPrefixItem(depth).first;
-    }
-
-    size_t GetPrefixIndex(size_t depth) const
-    {
-      return GetPrefixItem(depth).second;
-    }
-    
-    const DicomTag& GetFinalTag() const
-    {
-      return finalTag_;
-    }
-
-    void SetFinalTag(const DicomTag& tag)
-    {
-      finalTag_ = tag;
-    }
-  };
-}
--- a/Resources/Orthanc/Plugins/Samples/Common/DicomTag.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include <stdint.h>
-
-namespace OrthancPlugins
-{
-  class DicomTag
-  {
-  private:
-    uint16_t  group_;
-    uint16_t  element_;
-
-    DicomTag();  // Forbidden
-
-  public:
-    DicomTag(uint16_t group,
-             uint16_t element) :
-      group_(group),
-      element_(element)
-    {
-    }
-
-    uint16_t GetGroup() const
-    {
-      return group_;
-    }
-
-    uint16_t GetElement() const
-    {
-      return element_;
-    }
-
-    const char* GetName() const;
-
-    bool operator== (const DicomTag& other) const
-    {
-      return group_ == other.group_ && element_ == other.element_;
-    }
-
-    bool operator!= (const DicomTag& other) const
-    {
-      return !(*this == other);
-    }
-  };
-
-
-  static const DicomTag DICOM_TAG_BITS_STORED(0x0028, 0x0101);
-  static const DicomTag DICOM_TAG_COLUMNS(0x0028, 0x0011);
-  static const DicomTag DICOM_TAG_COLUMN_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021e);
-  static const DicomTag DICOM_TAG_IMAGE_ORIENTATION_PATIENT(0x0020, 0x0037);
-  static const DicomTag DICOM_TAG_IMAGE_POSITION_PATIENT(0x0020, 0x0032);
-  static const DicomTag DICOM_TAG_MODALITY(0x0008, 0x0060);
-  static const DicomTag DICOM_TAG_NUMBER_OF_FRAMES(0x0028, 0x0008);
-  static const DicomTag DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE(0x5200, 0x9230);
-  static const DicomTag DICOM_TAG_PHOTOMETRIC_INTERPRETATION(0x0028, 0x0004);
-  static const DicomTag DICOM_TAG_PIXEL_REPRESENTATION(0x0028, 0x0103);
-  static const DicomTag DICOM_TAG_PIXEL_SPACING(0x0028, 0x0030);
-  static const DicomTag DICOM_TAG_PLANE_POSITION_SLIDE_SEQUENCE(0x0048, 0x021a);
-  static const DicomTag DICOM_TAG_RESCALE_INTERCEPT(0x0028, 0x1052);
-  static const DicomTag DICOM_TAG_RESCALE_SLOPE(0x0028, 0x1053);
-  static const DicomTag DICOM_TAG_ROWS(0x0028, 0x0010);
-  static const DicomTag DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021f);
-  static const DicomTag DICOM_TAG_SAMPLES_PER_PIXEL(0x0028, 0x0002);
-  static const DicomTag DICOM_TAG_SERIES_INSTANCE_UID(0x0020, 0x000e);
-  static const DicomTag DICOM_TAG_SLICE_THICKNESS(0x0018, 0x0050);
-  static const DicomTag DICOM_TAG_SOP_CLASS_UID(0x0008, 0x0016);
-  static const DicomTag DICOM_TAG_SOP_INSTANCE_UID(0x0008, 0x0018);
-  static const DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_COLUMNS(0x0048, 0x0006);
-  static const DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_ROWS(0x0048, 0x0007);
-  static const DicomTag DICOM_TAG_TRANSFER_SYNTAX_UID(0x0002, 0x0010);
-  static const DicomTag DICOM_TAG_WINDOW_CENTER(0x0028, 0x1050);
-  static const DicomTag DICOM_TAG_WINDOW_WIDTH(0x0028, 0x1051);
-}
--- a/Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,215 +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-2018 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.
- *
- * 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 "FullOrthancDataset.h"
-
-#include "OrthancPluginException.h"
-
-#include <stdio.h>
-#include <cassert>
-
-namespace OrthancPlugins
-{
-  static const Json::Value* AccessTag(const Json::Value& dataset,
-                                      const DicomTag& tag) 
-  {
-    if (dataset.type() != Json::objectValue)
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
-    }
-
-    char name[16];
-    sprintf(name, "%04x,%04x", tag.GetGroup(), tag.GetElement());
-
-    if (!dataset.isMember(name))
-    {
-      return NULL;
-    }
-
-    const Json::Value& value = dataset[name];
-    if (value.type() != Json::objectValue ||
-        !value.isMember("Name") ||
-        !value.isMember("Type") ||
-        !value.isMember("Value") ||
-        value["Name"].type() != Json::stringValue ||
-        value["Type"].type() != Json::stringValue)
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
-    }
-
-    return &value;
-  }
-
-
-  static const Json::Value& GetSequenceContent(const Json::Value& sequence)
-  {
-    assert(sequence.type() == Json::objectValue);
-    assert(sequence.isMember("Type"));
-    assert(sequence.isMember("Value"));
-
-    const Json::Value& value = sequence["Value"];
-      
-    if (sequence["Type"].asString() != "Sequence" ||
-        value.type() != Json::arrayValue)
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
-    }
-    else
-    {
-      return value;
-    }
-  }
-
-
-  static bool GetStringInternal(std::string& result,
-                                const Json::Value& tag)
-  {
-    assert(tag.type() == Json::objectValue);
-    assert(tag.isMember("Type"));
-    assert(tag.isMember("Value"));
-
-    const Json::Value& value = tag["Value"];
-      
-    if (tag["Type"].asString() != "String" ||
-        value.type() != Json::stringValue)
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
-    }
-    else
-    {
-      result = value.asString();
-      return true;
-    }
-  }
-
-
-  const Json::Value* FullOrthancDataset::LookupPath(const DicomPath& path) const
-  {
-    const Json::Value* content = &root_;
-                                  
-    for (unsigned int depth = 0; depth < path.GetPrefixLength(); depth++)
-    {
-      const Json::Value* sequence = AccessTag(*content, path.GetPrefixTag(depth));
-      if (sequence == NULL)
-      {
-        return NULL;
-      }
-
-      const Json::Value& nextContent = GetSequenceContent(*sequence);
-
-      size_t index = path.GetPrefixIndex(depth);
-      if (index >= nextContent.size())
-      {
-        return NULL;
-      }
-      else
-      {
-        content = &nextContent[static_cast<Json::Value::ArrayIndex>(index)];
-      }
-    }
-
-    return AccessTag(*content, path.GetFinalTag());
-  }
-
-
-  void FullOrthancDataset::CheckRoot() const
-  {
-    if (root_.type() != Json::objectValue)
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
-    }
-  }
-
-
-  FullOrthancDataset::FullOrthancDataset(IOrthancConnection& orthanc,
-                                         const std::string& uri)
-  {
-    IOrthancConnection::RestApiGet(root_, orthanc, uri);
-    CheckRoot();
-  }
-
-
-  FullOrthancDataset::FullOrthancDataset(const std::string& content)
-  {
-    IOrthancConnection::ParseJson(root_, content);
-    CheckRoot();
-  }
-
-
-  FullOrthancDataset::FullOrthancDataset(const void* content,
-                                         size_t size)
-  {
-    IOrthancConnection::ParseJson(root_, content, size);
-    CheckRoot();
-  }
-
-
-  FullOrthancDataset::FullOrthancDataset(const Json::Value& root) :
-    root_(root)
-  {
-    CheckRoot();
-  }
-
-
-  bool FullOrthancDataset::GetStringValue(std::string& result,
-                                          const DicomPath& path) const
-  {
-    const Json::Value* value = LookupPath(path);
-
-    if (value == NULL)
-    {
-      return false;
-    }
-    else
-    {
-      return GetStringInternal(result, *value);
-    }
-  }
-
-
-  bool FullOrthancDataset::GetSequenceSize(size_t& size,
-                                           const DicomPath& path) const
-  {
-    const Json::Value* sequence = LookupPath(path);
-
-    if (sequence == NULL)
-    {
-      return false;
-    }
-    else
-    {
-      size = GetSequenceContent(*sequence).size();
-      return true;
-    }
-  }
-}
--- a/Resources/Orthanc/Plugins/Samples/Common/FullOrthancDataset.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "IOrthancConnection.h"
-#include "IDicomDataset.h"
-
-#include <json/value.h>
-
-namespace OrthancPlugins
-{
-  class FullOrthancDataset : public IDicomDataset
-  {
-  private:
-    Json::Value   root_;
-
-    const Json::Value* LookupPath(const DicomPath& path) const;
-
-    void CheckRoot() const;
-
-  public:
-    FullOrthancDataset(IOrthancConnection& orthanc,
-                       const std::string& uri);
-
-    FullOrthancDataset(const std::string& content);
-
-    FullOrthancDataset(const void* content,
-                       size_t size);
-
-    FullOrthancDataset(const Json::Value& root);
-
-    virtual bool GetStringValue(std::string& result,
-                                const DicomPath& path) const;
-
-    virtual bool GetSequenceSize(size_t& size,
-                                 const DicomPath& path) const;
-  };
-}
--- a/Resources/Orthanc/Plugins/Samples/Common/IDicomDataset.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "DicomPath.h"
-
-#include <boost/noncopyable.hpp>
-#include <string>
-
-namespace OrthancPlugins
-{
-  class IDicomDataset : public boost::noncopyable
-  {
-  public:
-    virtual ~IDicomDataset()
-    {
-    }
-
-    virtual bool GetStringValue(std::string& result,
-                                const DicomPath& path) const = 0;
-
-    virtual bool GetSequenceSize(size_t& size,
-                                 const DicomPath& path) const = 0;
-  };
-}
--- a/Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +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-2018 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.
- *
- * 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 "IOrthancConnection.h"
-
-#include "OrthancPluginException.h"
-
-#include <json/reader.h>
-
-namespace OrthancPlugins
-{
-  void IOrthancConnection::ParseJson(Json::Value& result,
-                                     const std::string& content)
-  {
-    Json::Reader reader;
-    
-    if (!reader.parse(content, result))
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
-    }
-  }
-
-
-  void IOrthancConnection::ParseJson(Json::Value& result,
-                                     const void* content,
-                                     size_t size)
-  {
-    Json::Reader reader;
-    
-    if (!reader.parse(reinterpret_cast<const char*>(content),
-                      reinterpret_cast<const char*>(content) + size, result))
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
-    }
-  }
-
-
-  void IOrthancConnection::RestApiGet(Json::Value& result,
-                                      IOrthancConnection& orthanc,
-                                      const std::string& uri)
-  {
-    std::string content;
-    orthanc.RestApiGet(content, uri);
-    ParseJson(result, content);
-  }
-
-
-  void IOrthancConnection::RestApiPost(Json::Value& result,
-                                       IOrthancConnection& orthanc,
-                                       const std::string& uri,
-                                       const std::string& body)
-  {
-    std::string content;
-    orthanc.RestApiPost(content, uri, body);
-    ParseJson(result, content);
-  }
-
-
-  void IOrthancConnection::RestApiPut(Json::Value& result,
-                                      IOrthancConnection& orthanc,
-                                      const std::string& uri,
-                                      const std::string& body)
-  {
-    std::string content;
-    orthanc.RestApiPut(content, uri, body);
-    ParseJson(result, content);
-  }
-}
--- a/Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "DicomPath.h"
-
-#include <boost/noncopyable.hpp>
-#include <string>
-#include <json/value.h>
-
-namespace OrthancPlugins
-{
-  class IOrthancConnection : public boost::noncopyable
-  {
-  public:
-    virtual ~IOrthancConnection()
-    {
-    }
-
-    virtual void RestApiGet(std::string& result,
-                            const std::string& uri) = 0;
-
-    virtual void RestApiPost(std::string& result,
-                             const std::string& uri,
-                             const std::string& body) = 0;
-
-    virtual void RestApiPut(std::string& result,
-                            const std::string& uri,
-                            const std::string& body) = 0;
-
-    virtual void RestApiDelete(const std::string& uri) = 0;
-
-    static void ParseJson(Json::Value& result,
-                          const std::string& content);
-
-    static void ParseJson(Json::Value& result,
-                          const void* content,
-                          size_t size);
-
-    static void RestApiGet(Json::Value& result,
-                           IOrthancConnection& orthanc,
-                           const std::string& uri);
-
-    static void RestApiPost(Json::Value& result,
-                            IOrthancConnection& orthanc,
-                            const std::string& uri,
-                            const std::string& body);
-
-    static void RestApiPut(Json::Value& result,
-                           IOrthancConnection& orthanc,
-                           const std::string& uri,
-                           const std::string& body);
-  };
-}
--- a/Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +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-2018 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.
- *
- * 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 "OrthancHttpConnection.h"
-
-namespace OrthancPlugins
-{
-  void OrthancHttpConnection::Setup()
-  {
-    url_ = client_.GetUrl();
-
-    // Don't follow 3xx HTTP (avoid redirections to "unsupported.png" in Orthanc)
-    client_.SetRedirectionFollowed(false);  
-  }
-
-
-  OrthancHttpConnection::OrthancHttpConnection() :
-    client_(Orthanc::WebServiceParameters(), "")
-  {
-    Setup();
-  }
-
-
-  OrthancHttpConnection::OrthancHttpConnection(const Orthanc::WebServiceParameters& parameters) :
-    client_(parameters, "")
-  {
-    Setup();
-  }
-
-
-  void OrthancHttpConnection::RestApiGet(std::string& result,
-                                         const std::string& uri)
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-
-    client_.SetMethod(Orthanc::HttpMethod_Get);
-    client_.SetUrl(url_ + uri);
-    client_.ApplyAndThrowException(result);
-  }
-
-
-  void OrthancHttpConnection::RestApiPost(std::string& result,
-                                          const std::string& uri,
-                                          const std::string& body)
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-
-    client_.SetMethod(Orthanc::HttpMethod_Post);
-    client_.SetUrl(url_ + uri);
-    client_.SetBody(body);
-    client_.ApplyAndThrowException(result);
-  }
-
-
-  void OrthancHttpConnection::RestApiPut(std::string& result,
-                                         const std::string& uri,
-                                         const std::string& body)
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-
-    client_.SetMethod(Orthanc::HttpMethod_Put);
-    client_.SetUrl(url_ + uri);
-    client_.SetBody(body);
-    client_.ApplyAndThrowException(result);
-  }
-
-
-  void OrthancHttpConnection::RestApiDelete(const std::string& uri)
-  {
-    boost::mutex::scoped_lock lock(mutex_);
-
-    std::string result;
-
-    client_.SetMethod(Orthanc::HttpMethod_Delete);
-    client_.SetUrl(url_ + uri);
-    client_.ApplyAndThrowException(result);
-  }
-}
--- a/Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#include "IOrthancConnection.h"
-
-#if HAS_ORTHANC_EXCEPTION != 1
-#  error The macro HAS_ORTHANC_EXCEPTION must be set to 1 if using this header
-#endif
-
-#include "../../../Core/HttpClient.h"
-
-#include <boost/thread/mutex.hpp>
-
-namespace OrthancPlugins
-{
-  // This class is thread-safe
-  class OrthancHttpConnection : public IOrthancConnection
-  {
-  private:
-    boost::mutex         mutex_;
-    Orthanc::HttpClient  client_;
-    std::string          url_;
-
-    void Setup();
-
-  public:
-    OrthancHttpConnection();
-
-    OrthancHttpConnection(const Orthanc::WebServiceParameters& parameters);
-
-    virtual void RestApiGet(std::string& result,
-                            const std::string& uri);
-
-    virtual void RestApiPost(std::string& result,
-                             const std::string& uri,
-                             const std::string& body);
-
-    virtual void RestApiPut(std::string& result,
-                            const std::string& uri,
-                            const std::string& body);
-
-    virtual void RestApiDelete(const std::string& uri);
-  };
-}
--- a/Resources/Orthanc/Plugins/Samples/Common/OrthancPluginException.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +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-2018 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.
- *
- * 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/>.
- **/
-
-
-#pragma once
-
-#if !defined(HAS_ORTHANC_EXCEPTION)
-#  error The macro HAS_ORTHANC_EXCEPTION must be defined
-#endif
-
-
-#if HAS_ORTHANC_EXCEPTION == 1
-#  include "../../../Core/OrthancException.h"
-#  define ORTHANC_PLUGINS_ERROR_ENUMERATION     ::Orthanc::ErrorCode
-#  define ORTHANC_PLUGINS_EXCEPTION_CLASS       ::Orthanc::OrthancException
-#  define ORTHANC_PLUGINS_GET_ERROR_CODE(code)  ::Orthanc::ErrorCode_ ## code
-#else
-#  include <orthanc/OrthancCPlugin.h>
-#  define ORTHANC_PLUGINS_ERROR_ENUMERATION     ::OrthancPluginErrorCode
-#  define ORTHANC_PLUGINS_EXCEPTION_CLASS       ::OrthancPlugins::PluginException
-#  define ORTHANC_PLUGINS_GET_ERROR_CODE(code)  ::OrthancPluginErrorCode_ ## code
-#endif
-
-
-#define ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code)                   \
-  throw ORTHANC_PLUGINS_EXCEPTION_CLASS(static_cast<ORTHANC_PLUGINS_ERROR_ENUMERATION>(code));
-
-
-#define ORTHANC_PLUGINS_THROW_EXCEPTION(code)                           \
-  throw ORTHANC_PLUGINS_EXCEPTION_CLASS(ORTHANC_PLUGINS_GET_ERROR_CODE(code));
-                                                  
-
-#define ORTHANC_PLUGINS_CHECK_ERROR(code)                           \
-  if (code != ORTHANC_PLUGINS_GET_ERROR_CODE(Success))              \
-  {                                                                 \
-    ORTHANC_PLUGINS_THROW_EXCEPTION(code);                          \
-  }
-
-
-namespace OrthancPlugins
-{
-#if HAS_ORTHANC_EXCEPTION == 0
-  class PluginException
-  {
-  private:
-    OrthancPluginErrorCode  code_;
-
-  public:
-    explicit PluginException(OrthancPluginErrorCode code) : code_(code)
-    {
-    }
-
-    OrthancPluginErrorCode GetErrorCode() const
-    {
-      return code_;
-    }
-
-    const char* What(OrthancPluginContext* context) const
-    {
-      const char* description = OrthancPluginGetErrorDescription(context, code_);
-      if (description)
-      {
-        return description;
-      }
-      else
-      {
-        return "No description available";
-      }
-    }
-  };
-#endif
-}
--- a/Resources/Orthanc/Resources/CMake/AutoGeneratedCode.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-set(AUTOGENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/AUTOGENERATED")
-set(AUTOGENERATED_SOURCES)
-
-file(MAKE_DIRECTORY ${AUTOGENERATED_DIR})
-include_directories(${AUTOGENERATED_DIR})
-
-macro(EmbedResources)
-  # Convert a semicolon separated list to a whitespace separated string
-  set(SCRIPT_OPTIONS)
-  set(SCRIPT_ARGUMENTS)
-  set(DEPENDENCIES)
-  set(IS_PATH_NAME false)
-
-  # Loop over the arguments of the function
-  foreach(arg ${ARGN})
-    # Extract the first character of the argument
-    string(SUBSTRING "${arg}" 0 1 FIRST_CHAR)
-    if (${FIRST_CHAR} STREQUAL "-")
-      # If the argument starts with a dash "-", this is an option to
-      # EmbedResources.py
-      list(APPEND SCRIPT_OPTIONS ${arg})
-    else()
-      if (${IS_PATH_NAME})
-        list(APPEND SCRIPT_ARGUMENTS "${arg}")
-        list(APPEND DEPENDENCIES "${arg}")
-        set(IS_PATH_NAME false)
-      else()
-        list(APPEND SCRIPT_ARGUMENTS "${arg}")
-        set(IS_PATH_NAME true)
-      endif()
-    endif()
-  endforeach()
-
-  set(TARGET_BASE "${AUTOGENERATED_DIR}/EmbeddedResources")
-  add_custom_command(
-    OUTPUT
-    "${TARGET_BASE}.h"
-    "${TARGET_BASE}.cpp"
-    COMMAND 
-    ${PYTHON_EXECUTABLE}
-    "${ORTHANC_ROOT}/Resources/EmbedResources.py"
-    ${SCRIPT_OPTIONS}
-    "${AUTOGENERATED_DIR}/EmbeddedResources"
-    ${SCRIPT_ARGUMENTS}
-    DEPENDS
-    "${ORTHANC_ROOT}/Resources/EmbedResources.py"
-    ${DEPENDENCIES}
-    )
-
-  list(APPEND AUTOGENERATED_SOURCES
-    "${AUTOGENERATED_DIR}/EmbeddedResources.cpp"
-    ) 
-endmacro()
--- a/Resources/Orthanc/Resources/CMake/BoostConfiguration.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +0,0 @@
-if (STATIC_BUILD OR NOT USE_SYSTEM_BOOST)
-  set(BOOST_STATIC 1)
-else()
-  include(FindBoost)
-
-  set(BOOST_STATIC 0)
-  #set(Boost_DEBUG 1)
-  #set(Boost_USE_STATIC_LIBS ON)
-
-  if (ENABLE_LOCALE)
-    list(APPEND ORTHANC_BOOST_COMPONENTS locale)
-  endif()
-
-  list(APPEND ORTHANC_BOOST_COMPONENTS filesystem thread system date_time regex)
-  find_package(Boost COMPONENTS "${ORTHANC_BOOST_COMPONENTS}")
-
-  if (NOT Boost_FOUND)
-    foreach (item ${ORTHANC_BOOST_COMPONENTS})
-      string(TOUPPER ${item} tmp)
-
-      if (Boost_${tmp}_FOUND)
-        set(tmp2 "found")
-      else()
-        set(tmp2 "missing")
-      endif()
-      
-      message("Boost component ${item} - ${tmp2}")
-    endforeach()
-    
-    message(FATAL_ERROR "Unable to locate Boost on this system")
-  endif()
-
-  # Boost releases 1.44 through 1.47 supply both V2 and V3 filesystem
-  # http://www.boost.org/doc/libs/1_46_1/libs/filesystem/v3/doc/index.htm
-  if (${Boost_VERSION} LESS 104400)
-    add_definitions(
-      -DBOOST_HAS_FILESYSTEM_V3=0
-      )
-  else()
-    add_definitions(
-      -DBOOST_HAS_FILESYSTEM_V3=1
-      -DBOOST_FILESYSTEM_VERSION=3
-      )
-  endif()
-
-  include_directories(${Boost_INCLUDE_DIRS})
-  link_libraries(${Boost_LIBRARIES})
-endif()
-
-
-if (BOOST_STATIC)
-  ##
-  ## Parameters for static compilation of Boost 
-  ##
-  
-  set(BOOST_NAME boost_1_66_0)
-  set(BOOST_BCP_SUFFIX bcpdigest-1.3.2)
-  set(BOOST_MD5 "e509e66140e8f2fd4d326b0052825f52")
-  set(BOOST_URL "http://www.orthanc-server.com/downloads/third-party/${BOOST_NAME}_${BOOST_BCP_SUFFIX}.tar.gz")
-  set(BOOST_SOURCES_DIR ${CMAKE_BINARY_DIR}/${BOOST_NAME})
-
-  if (IS_DIRECTORY "${BOOST_SOURCES_DIR}")
-    set(FirstRun OFF)
-  else()
-    set(FirstRun ON)
-  endif()
-
-  DownloadPackage(${BOOST_MD5} ${BOOST_URL} "${BOOST_SOURCES_DIR}")
-
-
-  ##
-  ## Generic configuration of Boost
-  ## 
-
-  if (CMAKE_COMPILER_IS_GNUCXX)
-    add_definitions(-isystem ${BOOST_SOURCES_DIR})
-  endif()
-
-  include_directories(
-    ${BOOST_SOURCES_DIR}
-    )
-
-  add_definitions(
-    # Static build of Boost
-    -DBOOST_ALL_NO_LIB 
-    -DBOOST_ALL_NOLIB 
-    -DBOOST_DATE_TIME_NO_LIB 
-    -DBOOST_THREAD_BUILD_LIB
-    -DBOOST_PROGRAM_OPTIONS_NO_LIB
-    -DBOOST_REGEX_NO_LIB
-    -DBOOST_SYSTEM_NO_LIB
-    -DBOOST_LOCALE_NO_LIB
-    )
-
-  set(BOOST_SOURCES
-    ${BOOST_SOURCES_DIR}/libs/system/src/error_code.cpp
-    )
-
-  if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase")
-    add_definitions(
-      -DBOOST_SYSTEM_USE_STRERROR=1
-      )
-    
-    execute_process(
-      COMMAND ${PATCH_EXECUTABLE} -p0 -N -i
-      ${ORTHANC_ROOT}/Resources/Patches/boost-1.66.0-linux-standard-base.patch
-      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-      RESULT_VARIABLE Failure
-      )
-
-    if (FirstRun AND Failure)
-      message(FATAL_ERROR "Error while patching a file")
-    endif()
-  endif()
-
-  
-  ##
-  ## Configuration of boost::thread
-  ##
-  
-  if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
-      CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
-      CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
-      CMAKE_SYSTEM_NAME STREQUAL "kFreeBSD" OR
-      CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR
-      CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR
-      CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR
-      CMAKE_SYSTEM_NAME STREQUAL "NaCl64")
-    list(APPEND BOOST_SOURCES
-      ${BOOST_SOURCES_DIR}/libs/atomic/src/lockpool.cpp
-      ${BOOST_SOURCES_DIR}/libs/thread/src/pthread/once.cpp
-      ${BOOST_SOURCES_DIR}/libs/thread/src/pthread/thread.cpp
-      )
-
-    if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase" OR
-        CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR
-        CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR
-        CMAKE_SYSTEM_NAME STREQUAL "NaCl64")
-      add_definitions(-DBOOST_HAS_SCHED_YIELD=1)
-    endif()
-
-  elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
-    list(APPEND BOOST_SOURCES
-      ${BOOST_SOURCES_DIR}/libs/thread/src/win32/tss_dll.cpp
-      ${BOOST_SOURCES_DIR}/libs/thread/src/win32/thread.cpp
-      ${BOOST_SOURCES_DIR}/libs/thread/src/win32/tss_pe.cpp
-      )
-
-  elseif (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
-    # No support for threads in WebAssembly
-
-  else()
-    message(FATAL_ERROR "Support your platform here")
-  endif()
-
-
-  ##
-  ## Configuration of boost::regex
-  ##
-  
-  aux_source_directory(${BOOST_SOURCES_DIR}/libs/regex/src BOOST_REGEX_SOURCES)
-
-  list(APPEND BOOST_SOURCES
-    ${BOOST_REGEX_SOURCES}
-    )
-
-
-  ##
-  ## Configuration of boost::datetime
-  ##
-  
-  list(APPEND BOOST_SOURCES
-    ${BOOST_SOURCES_DIR}/libs/date_time/src/gregorian/greg_month.cpp
-    )
-
-
-  ##
-  ## Configuration of boost::filesystem
-  ## 
-
-  if (CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR
-      CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR
-      CMAKE_SYSTEM_NAME STREQUAL "NaCl64")
-    # boost::filesystem is not available on PNaCl
-    add_definitions(
-      -DBOOST_HAS_FILESYSTEM_V3=0
-      -D__INTEGRITY=1
-      )
-  else()
-    add_definitions(
-      -DBOOST_HAS_FILESYSTEM_V3=1
-      )
-    list(APPEND BOOST_SOURCES
-      ${BOOST_NAME}/libs/filesystem/src/codecvt_error_category.cpp
-      ${BOOST_NAME}/libs/filesystem/src/operations.cpp
-      ${BOOST_NAME}/libs/filesystem/src/path.cpp
-      ${BOOST_NAME}/libs/filesystem/src/path_traits.cpp
-      )
-
-    if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
-        CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR
-        CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
-     list(APPEND BOOST_SOURCES
-        ${BOOST_SOURCES_DIR}/libs/filesystem/src/utf8_codecvt_facet.cpp
-        )
-
-    elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
-      list(APPEND BOOST_SOURCES
-        ${BOOST_NAME}/libs/filesystem/src/windows_file_codecvt.cpp
-        )
-    endif()
-  endif()
-
-
-  ##
-  ## Configuration of boost::locale
-  ## 
-
-  if (NOT ENABLE_LOCALE)
-    message("boost::locale is disabled")
-  else()
-    list(APPEND BOOST_SOURCES
-      ${BOOST_SOURCES_DIR}/libs/locale/src/encoding/codepage.cpp
-      ${BOOST_SOURCES_DIR}/libs/locale/src/shared/generator.cpp
-      ${BOOST_SOURCES_DIR}/libs/locale/src/shared/date_time.cpp
-      ${BOOST_SOURCES_DIR}/libs/locale/src/shared/formatting.cpp
-      ${BOOST_SOURCES_DIR}/libs/locale/src/shared/ids.cpp
-      ${BOOST_SOURCES_DIR}/libs/locale/src/shared/localization_backend.cpp
-      ${BOOST_SOURCES_DIR}/libs/locale/src/shared/message.cpp
-      ${BOOST_SOURCES_DIR}/libs/locale/src/shared/mo_lambda.cpp
-      ${BOOST_SOURCES_DIR}/libs/locale/src/util/codecvt_converter.cpp
-      ${BOOST_SOURCES_DIR}/libs/locale/src/util/default_locale.cpp
-      ${BOOST_SOURCES_DIR}/libs/locale/src/util/gregorian.cpp
-      ${BOOST_SOURCES_DIR}/libs/locale/src/util/info.cpp
-      ${BOOST_SOURCES_DIR}/libs/locale/src/util/locale_data.cpp
-      )        
-
-    if (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR
-        CMAKE_SYSTEM_VERSION STREQUAL "LinuxStandardBase")
-      list(APPEND BOOST_SOURCES
-        ${BOOST_SOURCES_DIR}/libs/locale/src/std/codecvt.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/std/collate.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/std/converter.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/std/numeric.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/std/std_backend.cpp
-        )
-
-      add_definitions(
-        -DBOOST_LOCALE_WITH_ICONV=1
-        -DBOOST_LOCALE_NO_WINAPI_BACKEND=1
-        -DBOOST_LOCALE_NO_POSIX_BACKEND=1
-        )
-      
-    elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
-            CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
-            CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
-            CMAKE_SYSTEM_NAME STREQUAL "kFreeBSD" OR
-            CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR
-            CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR
-            CMAKE_SYSTEM_NAME STREQUAL "NaCl64" OR
-            CMAKE_SYSTEM_NAME STREQUAL "Emscripten") # For WebAssembly or asm.js
-      list(APPEND BOOST_SOURCES
-        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/codecvt.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/collate.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/converter.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/numeric.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/posix_backend.cpp
-        )
-
-      add_definitions(
-        -DBOOST_LOCALE_WITH_ICONV=1
-        -DBOOST_LOCALE_NO_WINAPI_BACKEND=1
-        -DBOOST_LOCALE_NO_STD_BACKEND=1
-        )
-      
-    elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
-      list(APPEND BOOST_SOURCES
-        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/collate.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/converter.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/lcid.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/numeric.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/win_backend.cpp
-        )
-
-      add_definitions(
-        -DBOOST_LOCALE_NO_POSIX_BACKEND=1
-        -DBOOST_LOCALE_NO_STD_BACKEND=1
-        )
-
-      # Starting with release 0.8.2, Orthanc statically links against
-      # libiconv, even on Windows. Indeed, the "WCONV" library of
-      # Windows XP seems not to support properly several codepages
-      # (notably "Latin3", "Hebrew", and "Arabic"). Set
-      # "USE_BOOST_ICONV" to "OFF" to use WCONV anyway.
-
-      if (USE_BOOST_ICONV)
-        add_definitions(-DBOOST_LOCALE_WITH_ICONV=1)
-      else()
-        add_definitions(-DBOOST_LOCALE_WITH_WCONV=1)
-      endif()
-
-    else()
-      message(FATAL_ERROR "Support your platform here")
-    endif()
-  endif()
-
-  
-  source_group(ThirdParty\\boost REGULAR_EXPRESSION ${BOOST_SOURCES_DIR}/.*)
-
-endif()
--- a/Resources/Orthanc/Resources/CMake/Compiler.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +0,0 @@
-# This file sets all the compiler-related flags
-
-if (CMAKE_CROSSCOMPILING OR
-    "${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase")
-  # Cross-compilation necessarily implies standalone and static build
-  SET(STATIC_BUILD ON)
-  SET(STANDALONE_BUILD ON)
-endif()
-
-if (CMAKE_COMPILER_IS_GNUCXX)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-long-long")
-
-  # --std=c99 makes libcurl not to compile
-  # -pedantic gives a lot of warnings on OpenSSL 
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -Wno-variadic-macros")
-
-  if (CMAKE_CROSSCOMPILING)
-    # http://stackoverflow.com/a/3543845/881731
-    set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff -I<CMAKE_CURRENT_SOURCE_DIR> <SOURCE> <OBJECT>")
-  endif()
-
-elseif (MSVC)
-  # Use static runtime under Visual Studio
-  # http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace
-  # http://stackoverflow.com/a/6510446
-  foreach(flag_var
-    CMAKE_C_FLAGS_DEBUG
-    CMAKE_CXX_FLAGS_DEBUG
-    CMAKE_C_FLAGS_RELEASE 
-    CMAKE_CXX_FLAGS_RELEASE
-    CMAKE_C_FLAGS_MINSIZEREL 
-    CMAKE_CXX_FLAGS_MINSIZEREL 
-    CMAKE_C_FLAGS_RELWITHDEBINFO 
-    CMAKE_CXX_FLAGS_RELWITHDEBINFO) 
-    string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
-    string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
-  endforeach(flag_var)
-
-  # Add /Zm256 compiler option to Visual Studio to fix PCH errors
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zm256")
-
-  add_definitions(
-    -D_CRT_SECURE_NO_WARNINGS=1
-    -D_CRT_SECURE_NO_DEPRECATE=1
-    )
-
-  if (MSVC_VERSION LESS 1600)
-    # Starting with Visual Studio >= 2010 (i.e. macro _MSC_VER >=
-    # 1600), Microsoft ships a standard-compliant <stdint.h>
-    # header. For earlier versions of Visual Studio, give access to a
-    # compatibility header.
-    # http://stackoverflow.com/a/70630/881731
-    # https://en.wikibooks.org/wiki/C_Programming/C_Reference/stdint.h#External_links
-    include_directories(${ORTHANC_ROOT}/Resources/ThirdParty/VisualStudio)
-  endif()
-
-  link_libraries(netapi32)
-endif()
-
-
-if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
-    ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
-  # In FreeBSD/OpenBSD, the "/usr/local/" folder contains the ports and need to be imported
-  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/local/include")
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/local/include")
-  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")
-  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L/usr/local/lib")
-endif()
-
-
-if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
-    ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR
-    ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
-    ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
-
-  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
-    # The "--no-undefined" linker flag makes the shared libraries
-    # (plugins ModalityWorklists and ServeFolders) fail to compile on OpenBSD
-    set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
-    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
-  endif()
-
-  if (NOT DEFINED ENABLE_PLUGINS_VERSION_SCRIPT OR 
-      ENABLE_PLUGINS_VERSION_SCRIPT)
-    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--version-script=${ORTHANC_ROOT}/Plugins/Samples/Common/VersionScript.map")
-  endif()
-
-  # Remove the "-rdynamic" option
-  # http://www.mail-archive.com/cmake@cmake.org/msg08837.html
-  set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
-  link_libraries(pthread)
-
-  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
-    link_libraries(rt)
-  endif()
-
-  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" AND
-      NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
-    link_libraries(dl)
-  endif()
-
-  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" AND
-      NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
-    # The "--as-needed" linker flag is not available on FreeBSD and OpenBSD
-    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
-    set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--as-needed")
-    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--as-needed")
-  endif()
-
-  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" AND
-      NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
-    # FreeBSD/OpenBSD have just one single interface for file
-    # handling, which is 64bit clean, so there is no need to define macro
-    # for LFS (Large File Support).
-    # https://ohse.de/uwe/articles/lfs.html
-    add_definitions(
-      -D_LARGEFILE64_SOURCE=1 
-      -D_FILE_OFFSET_BITS=64
-      )
-  endif()
-
-elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
-  if (MSVC)
-    message("MSVC compiler version = " ${MSVC_VERSION} "\n")
-    # Starting Visual Studio 2013 (version 1800), it is not possible
-    # to target Windows XP anymore
-    if (MSVC_VERSION LESS 1800)
-      add_definitions(
-        -DWINVER=0x0501
-        -D_WIN32_WINNT=0x0501
-        )
-    endif()
-  else()
-    add_definitions(
-      -DWINVER=0x0501
-      -D_WIN32_WINNT=0x0501
-      )
-  endif()
-
-  add_definitions(
-    -D_CRT_SECURE_NO_WARNINGS=1
-    )
-  link_libraries(rpcrt4 ws2_32)
-
-  if (CMAKE_COMPILER_IS_GNUCXX)
-    # Some additional C/C++ compiler flags for MinGW
-    SET(MINGW_NO_WARNINGS "-Wno-unused-function -Wno-unused-variable")
-    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MINGW_NO_WARNINGS} -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast")
-    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MINGW_NO_WARNINGS}")
-
-    # This is a patch for MinGW64
-    SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--allow-multiple-definition -static-libgcc -static-libstdc++")
-    SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--allow-multiple-definition -static-libgcc -static-libstdc++")
-
-    CHECK_LIBRARY_EXISTS(winpthread pthread_create "" HAVE_WIN_PTHREAD)
-    if (HAVE_WIN_PTHREAD)
-      # This line is necessary to compile with recent versions of MinGW,
-      # otherwise "libwinpthread-1.dll" is not statically linked.
-      SET(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic")
-      add_definitions(-DHAVE_WIN_PTHREAD=1)
-    else()
-      add_definitions(-DHAVE_WIN_PTHREAD=0)
-    endif()
-  endif()
-
-elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
-  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -exported_symbols_list ${ORTHANC_ROOT}/Plugins/Samples/Common/ExportedSymbols.list")
-
-  add_definitions(
-    -D_XOPEN_SOURCE=1
-    )
-  link_libraries(iconv)
-
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
-  message("Building using Emscripten (for WebAssembly or asm.js targets)")
-
-  # The BINARYEN_TRAP_MODE specifies what to do when divisions per
-  # zero (and similar conditions like integer overflows) are
-  # encountered: The "clamp" mode avoids throwing errors, as they
-  # cannot be properly catched by "try {} catch (...)" constructions.
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]' -s BINARYEN_TRAP_MODE='\"clamp\"'")
-
-else()
-  message(FATAL_ERROR "Support your platform here")
-endif()
-
-
-if (DEFINED ENABLE_PROFILING AND ENABLE_PROFILING)
-  if (CMAKE_COMPILER_IS_GNUCXX)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg")
-    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
-    set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -pg")
-    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg")
-  else()
-    message(FATAL_ERROR "Don't know how to enable profiling on your configuration")
-  endif()
-endif()
-
-
-if (CMAKE_COMPILER_IS_GNUCXX)
-  # "When creating a static library using binutils (ar) and there
-  # exist a duplicate object name (e.g. a/Foo.cpp.o, b/Foo.cpp.o), the
-  # resulting static library can end up having only one of the
-  # duplicate objects. [...] This bug only happens if there are many
-  # objects." The trick consists in replacing the "r" argument
-  # ("replace") provided to "ar" (as used in CMake < 3.1) by the "q"
-  # argument ("quick append"). This is because of the fact that CMake
-  # will invoke "ar" several times with several batches of ".o"
-  # objects, and using "r" would overwrite symbols defined in
-  # preceding batches. https://cmake.org/Bug/view.php?id=14874
-  set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> <LINK_FLAGS> q <TARGET> <OBJECTS>")
-endif()
-
-
-if (STATIC_BUILD)
-  add_definitions(-DORTHANC_STATIC=1)
-else()
-  add_definitions(-DORTHANC_STATIC=0)
-endif()
--- a/Resources/Orthanc/Resources/CMake/DownloadPackage.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-macro(GetUrlFilename TargetVariable Url)
-  string(REGEX REPLACE "^.*/" "" ${TargetVariable} "${Url}")
-endmacro()
-
-
-macro(GetUrlExtension TargetVariable Url)
-  #string(REGEX REPLACE "^.*/[^.]*\\." "" TMP "${Url}")
-  string(REGEX REPLACE "^.*\\." "" TMP "${Url}")
-  string(TOLOWER "${TMP}" "${TargetVariable}")
-endmacro()
-
-
-
-##
-## Setup the patch command-line tool
-##
-
-if (NOT ORTHANC_DISABLE_PATCH)
-  if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
-    set(PATCH_EXECUTABLE ${CMAKE_CURRENT_LIST_DIR}/../ThirdParty/patch/patch.exe)
-    if (NOT EXISTS ${PATCH_EXECUTABLE})
-      message(FATAL_ERROR "Unable to find the patch.exe tool that is shipped with Orthanc")
-    endif()
-
-  else ()
-    find_program(PATCH_EXECUTABLE patch)
-    if (${PATCH_EXECUTABLE} MATCHES "PATCH_EXECUTABLE-NOTFOUND")
-      message(FATAL_ERROR "Please install the 'patch' standard command-line tool")
-    endif()
-  endif()
-endif()
-
-
-
-##
-## Check the existence of the required decompression tools
-##
-
-if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
-  find_program(ZIP_EXECUTABLE 7z 
-    PATHS 
-    "$ENV{ProgramFiles}/7-Zip"
-    "$ENV{ProgramW6432}/7-Zip"
-    )
-
-  if (${ZIP_EXECUTABLE} MATCHES "ZIP_EXECUTABLE-NOTFOUND")
-    message(FATAL_ERROR "Please install the '7-zip' software (http://www.7-zip.org/)")
-  endif()
-
-else()
-  find_program(UNZIP_EXECUTABLE unzip)
-  if (${UNZIP_EXECUTABLE} MATCHES "UNZIP_EXECUTABLE-NOTFOUND")
-    message(FATAL_ERROR "Please install the 'unzip' package")
-  endif()
-
-  find_program(TAR_EXECUTABLE tar)
-  if (${TAR_EXECUTABLE} MATCHES "TAR_EXECUTABLE-NOTFOUND")
-    message(FATAL_ERROR "Please install the 'tar' package")
-  endif()
-endif()
-
-
-macro(DownloadPackage MD5 Url TargetDirectory)
-  if (NOT IS_DIRECTORY "${TargetDirectory}")
-    GetUrlFilename(TMP_FILENAME "${Url}")
-
-    set(TMP_PATH "${CMAKE_SOURCE_DIR}/ThirdPartyDownloads/${TMP_FILENAME}")
-    if (NOT EXISTS "${TMP_PATH}")
-      message("Downloading ${Url}")
-
-      # This fixes issue 6: "I think cmake shouldn't download the
-      # packages which are not in the system, it should stop and let
-      # user know."
-      # https://code.google.com/p/orthanc/issues/detail?id=6
-      if (NOT STATIC_BUILD AND NOT ALLOW_DOWNLOADS)
-	message(FATAL_ERROR "CMake is not allowed to download from Internet. Please set the ALLOW_DOWNLOADS option to ON")
-      endif()
-
-      file(DOWNLOAD "${Url}" "${TMP_PATH}" 
-        SHOW_PROGRESS EXPECTED_MD5 "${MD5}"
-        TIMEOUT 60 INACTIVITY_TIMEOUT 60)
-    else()
-      message("Using local copy of ${Url}")
-    endif()
-
-    GetUrlExtension(TMP_EXTENSION "${Url}")
-    #message(${TMP_EXTENSION})
-    message("Uncompressing ${TMP_FILENAME}")
-
-    if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
-      # How to silently extract files using 7-zip
-      # http://superuser.com/questions/331148/7zip-command-line-extract-silently-quietly
-
-      if (("${TMP_EXTENSION}" STREQUAL "gz") OR 
-          ("${TMP_EXTENSION}" STREQUAL "tgz") OR
-          ("${TMP_EXTENSION}" STREQUAL "xz"))
-        execute_process(
-          COMMAND ${ZIP_EXECUTABLE} e -y ${TMP_PATH}
-          WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-          RESULT_VARIABLE Failure
-          OUTPUT_QUIET
-          )
-
-        if (Failure)
-          message(FATAL_ERROR "Error while running the uncompression tool")
-        endif()
-
-        if ("${TMP_EXTENSION}" STREQUAL "tgz")
-          string(REGEX REPLACE ".tgz$" ".tar" TMP_FILENAME2 "${TMP_FILENAME}")
-        elseif ("${TMP_EXTENSION}" STREQUAL "gz")
-          string(REGEX REPLACE ".gz$" "" TMP_FILENAME2 "${TMP_FILENAME}")
-        elseif ("${TMP_EXTENSION}" STREQUAL "xz")
-          string(REGEX REPLACE ".xz" "" TMP_FILENAME2 "${TMP_FILENAME}")
-        endif()
-
-        execute_process(
-          COMMAND ${ZIP_EXECUTABLE} x -y ${TMP_FILENAME2}
-          WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-          RESULT_VARIABLE Failure
-          OUTPUT_QUIET
-          )
-      elseif ("${TMP_EXTENSION}" STREQUAL "zip")
-        execute_process(
-          COMMAND ${ZIP_EXECUTABLE} x -y ${TMP_PATH}
-          WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-          RESULT_VARIABLE Failure
-          OUTPUT_QUIET
-          )
-      else()
-        message(FATAL_ERROR "Support your platform here")
-      endif()
-
-    else()
-      if ("${TMP_EXTENSION}" STREQUAL "zip")
-        execute_process(
-          COMMAND sh -c "${UNZIP_EXECUTABLE} -q ${TMP_PATH}"
-          WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-          RESULT_VARIABLE Failure
-        )
-      elseif (("${TMP_EXTENSION}" STREQUAL "gz") OR ("${TMP_EXTENSION}" STREQUAL "tgz"))
-        #message("tar xvfz ${TMP_PATH}")
-        execute_process(
-          COMMAND sh -c "${TAR_EXECUTABLE} xfz ${TMP_PATH}"
-          WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-          RESULT_VARIABLE Failure
-          )
-      elseif ("${TMP_EXTENSION}" STREQUAL "bz2")
-        execute_process(
-          COMMAND sh -c "${TAR_EXECUTABLE} xfj ${TMP_PATH}"
-          WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-          RESULT_VARIABLE Failure
-          )
-      elseif ("${TMP_EXTENSION}" STREQUAL "xz")
-        execute_process(
-          COMMAND sh -c "${TAR_EXECUTABLE} xf ${TMP_PATH}"
-          WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-          RESULT_VARIABLE Failure
-          )
-      else()
-        message(FATAL_ERROR "Unknown package format.")
-      endif()
-    endif()
-   
-    if (Failure)
-      message(FATAL_ERROR "Error while running the uncompression tool")
-    endif()
-
-    if (NOT IS_DIRECTORY "${TargetDirectory}")
-      message(FATAL_ERROR "The package was not uncompressed at the proper location. Check the CMake instructions.")
-    endif()
-  endif()
-endmacro()
--- a/Resources/Orthanc/Resources/CMake/GoogleTestConfiguration.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-if (USE_GOOGLE_TEST_DEBIAN_PACKAGE)
-  find_path(GOOGLE_TEST_DEBIAN_SOURCES_DIR
-    NAMES src/gtest-all.cc
-    PATHS
-    /usr/src/gtest
-    /usr/src/googletest/googletest
-    PATH_SUFFIXES src
-    )
-
-  find_path(GOOGLE_TEST_DEBIAN_INCLUDE_DIR
-    NAMES gtest.h
-    PATHS
-    /usr/include/gtest
-    )
-
-  message("Path to the Debian Google Test sources: ${GOOGLE_TEST_DEBIAN_SOURCES_DIR}")
-  message("Path to the Debian Google Test includes: ${GOOGLE_TEST_DEBIAN_INCLUDE_DIR}")
-
-  set(GOOGLE_TEST_SOURCES
-    ${GOOGLE_TEST_DEBIAN_SOURCES_DIR}/src/gtest-all.cc
-    )
-
-  include_directories(${GOOGLE_TEST_DEBIAN_SOURCES_DIR})
-
-  if (NOT EXISTS ${GOOGLE_TEST_SOURCES} OR
-      NOT EXISTS ${GOOGLE_TEST_DEBIAN_INCLUDE_DIR}/gtest.h)
-    message(FATAL_ERROR "Please install the libgtest-dev package")
-  endif()
-
-elseif (STATIC_BUILD OR NOT USE_SYSTEM_GOOGLE_TEST)
-  set(GOOGLE_TEST_SOURCES_DIR ${CMAKE_BINARY_DIR}/gtest-1.7.0)
-  set(GOOGLE_TEST_URL "http://www.orthanc-server.com/downloads/third-party/gtest-1.7.0.zip")
-  set(GOOGLE_TEST_MD5 "2d6ec8ccdf5c46b05ba54a9fd1d130d7")
-
-  DownloadPackage(${GOOGLE_TEST_MD5} ${GOOGLE_TEST_URL} "${GOOGLE_TEST_SOURCES_DIR}")
-
-  include_directories(
-    ${GOOGLE_TEST_SOURCES_DIR}/include
-    ${GOOGLE_TEST_SOURCES_DIR}
-    )
-
-  set(GOOGLE_TEST_SOURCES
-    ${GOOGLE_TEST_SOURCES_DIR}/src/gtest-all.cc
-    )
-
-  # https://code.google.com/p/googletest/issues/detail?id=412
-  if (MSVC) # VS2012 does not support tuples correctly yet
-    add_definitions(/D _VARIADIC_MAX=10)
-  endif()
-  
-  if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase")
-    add_definitions(-DGTEST_HAS_CLONE=0)
-  endif()
-  
-  source_group(ThirdParty\\GoogleTest REGULAR_EXPRESSION ${GOOGLE_TEST_SOURCES_DIR}/.*)
-
-else()
-  include(FindGTest)
-  if (NOT GTEST_FOUND)
-    message(FATAL_ERROR "Unable to find GoogleTest")
-  endif()
-
-  include_directories(${GTEST_INCLUDE_DIRS})
-
-  # The variable GTEST_LIBRARIES contains the shared library of
-  # Google Test, create an alias for more uniformity
-  set(GOOGLE_TEST_LIBRARIES ${GTEST_LIBRARIES})
-endif()
--- a/Resources/Orthanc/Resources/CMake/JsonCppConfiguration.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-set(JSONCPP_CXX11 OFF)
-
-if (STATIC_BUILD OR NOT USE_SYSTEM_JSONCPP)
-  if (USE_LEGACY_JSONCPP)
-    set(JSONCPP_SOURCES_DIR ${CMAKE_BINARY_DIR}/jsoncpp-0.10.6)
-    set(JSONCPP_URL "http://www.orthanc-server.com/downloads/third-party/jsoncpp-0.10.6.tar.gz")
-    set(JSONCPP_MD5 "13d1991d79697df8cadbc25c93e37c83")
-    add_definitions(-DORTHANC_LEGACY_JSONCPP=1)
-  else()
-    set(JSONCPP_SOURCES_DIR ${CMAKE_BINARY_DIR}/jsoncpp-1.8.4)
-    set(JSONCPP_URL "http://www.orthanc-server.com/downloads/third-party/jsoncpp-1.8.4.tar.gz")
-    set(JSONCPP_MD5 "fa47a3ab6b381869b6a5f20811198662")
-    add_definitions(-DORTHANC_LEGACY_JSONCPP=0)
-    set(JSONCPP_CXX11 ON)
-  endif()
-
-  DownloadPackage(${JSONCPP_MD5} ${JSONCPP_URL} "${JSONCPP_SOURCES_DIR}")
-
-  set(JSONCPP_SOURCES
-    ${JSONCPP_SOURCES_DIR}/src/lib_json/json_reader.cpp
-    ${JSONCPP_SOURCES_DIR}/src/lib_json/json_value.cpp
-    ${JSONCPP_SOURCES_DIR}/src/lib_json/json_writer.cpp
-    )
-
-  include_directories(
-    ${JSONCPP_SOURCES_DIR}/include
-    )
-
-  source_group(ThirdParty\\JsonCpp REGULAR_EXPRESSION ${JSONCPP_SOURCES_DIR}/.*)
-
-else()
-  find_path(JSONCPP_INCLUDE_DIR json/reader.h
-    /usr/include/jsoncpp
-    /usr/local/include/jsoncpp
-    )
-
-  message("JsonCpp include dir: ${JSONCPP_INCLUDE_DIR}")
-  include_directories(${JSONCPP_INCLUDE_DIR})
-  link_libraries(jsoncpp)
-
-  CHECK_INCLUDE_FILE_CXX(${JSONCPP_INCLUDE_DIR}/json/reader.h HAVE_JSONCPP_H)
-  if (NOT HAVE_JSONCPP_H)
-    message(FATAL_ERROR "Please install the libjsoncpp-dev package")
-  endif()
-
-  # Switch to the C++11 standard if the version of JsonCpp is 1.y.z
-  if (EXISTS ${JSONCPP_INCLUDE_DIR}/json/version.h)
-    file(STRINGS
-      "${JSONCPP_INCLUDE_DIR}/json/version.h" 
-      JSONCPP_VERSION_MAJOR1 REGEX
-      ".*define JSONCPP_VERSION_MAJOR.*")
-
-    if (NOT JSONCPP_VERSION_MAJOR1)
-      message(FATAL_ERROR "Unable to extract the major version of JsonCpp")
-    endif()
-    
-    string(REGEX REPLACE
-      ".*JSONCPP_VERSION_MAJOR.*([0-9]+)$" "\\1" 
-      JSONCPP_VERSION_MAJOR ${JSONCPP_VERSION_MAJOR1})
-    message("JsonCpp major version: ${JSONCPP_VERSION_MAJOR}")
-
-    if (JSONCPP_VERSION_MAJOR GREATER 0)
-      set(JSONCPP_CXX11 ON)
-    endif()
-  else()
-    message("Unable to detect the major version of JsonCpp, assuming < 1.0.0")
-  endif()
-endif()
-
-
-if (JSONCPP_CXX11)
-  # Osimis has encountered problems when this macro is left at its
-  # default value (1000), so we increase this limit
-  # https://gitlab.kitware.com/third-party/jsoncpp/commit/56df2068470241f9043b676bfae415ed62a0c172
-  add_definitions(-DJSONCPP_DEPRECATED_STACK_LIMIT=5000)
-
-  if (CMAKE_COMPILER_IS_GNUCXX OR
-      "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
-    message("Switching to C++11 standard in gcc/clang, as version of JsonCpp is >= 1.0.0")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-deprecated-declarations")
-  endif()
-endif()
--- a/Resources/Orthanc/Resources/CMake/LibCurlConfiguration.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,323 +0,0 @@
-if (STATIC_BUILD OR NOT USE_SYSTEM_CURL)
-  SET(CURL_SOURCES_DIR ${CMAKE_BINARY_DIR}/curl-7.57.0)
-  SET(CURL_URL "http://www.orthanc-server.com/downloads/third-party/curl-7.57.0.tar.gz")
-  SET(CURL_MD5 "c7aab73aaf5e883ca1d7518f93649dc2")
-
-  if (IS_DIRECTORY "${CURL_SOURCES_DIR}")
-    set(FirstRun OFF)
-  else()
-    set(FirstRun ON)
-  endif()
-  
-  DownloadPackage(${CURL_MD5} ${CURL_URL} "${CURL_SOURCES_DIR}")
-
-  if (FirstRun)
-    execute_process(
-      COMMAND ${PATCH_EXECUTABLE} -p0 -N -i
-      ${ORTHANC_ROOT}/Resources/Patches/curl-7.57.0-cmake.patch
-      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-      RESULT_VARIABLE Failure
-      )
-    
-    if (Failure)
-      message(FATAL_ERROR "Error while patching a file")
-    endif()
-  endif()
-  
-  include_directories(
-    ${CURL_SOURCES_DIR}/include
-    )
-
-  AUX_SOURCE_DIRECTORY(${CURL_SOURCES_DIR}/lib CURL_SOURCES)
-  AUX_SOURCE_DIRECTORY(${CURL_SOURCES_DIR}/lib/vauth CURL_SOURCES)
-  AUX_SOURCE_DIRECTORY(${CURL_SOURCES_DIR}/lib/vtls CURL_SOURCES)
-  source_group(ThirdParty\\LibCurl REGULAR_EXPRESSION ${CURL_SOURCES_DIR}/.*)
-
-  add_definitions(
-    -DBUILDING_LIBCURL=1
-    -DCURL_STATICLIB=1
-    -DCURL_DISABLE_LDAPS=1
-    -DCURL_DISABLE_LDAP=1
-    -DCURL_DISABLE_DICT=1
-    -DCURL_DISABLE_FILE=1
-    -DCURL_DISABLE_FTP=1
-    -DCURL_DISABLE_GOPHER=1
-    -DCURL_DISABLE_LDAP=1
-    -DCURL_DISABLE_LDAPS=1
-    -DCURL_DISABLE_POP3=1
-    #-DCURL_DISABLE_PROXY=1
-    -DCURL_DISABLE_RTSP=1
-    -DCURL_DISABLE_TELNET=1
-    -DCURL_DISABLE_TFTP=1
-    )
-
-  if (ENABLE_SSL)
-    add_definitions(
-      #-DHAVE_LIBSSL=1
-      -DUSE_OPENSSL=1
-      -DHAVE_OPENSSL_ENGINE_H=1
-      -DUSE_SSLEAY=1
-      )
-  endif()
-
-  if (NOT EXISTS "${CURL_SOURCES_DIR}/lib/curl_config.h")
-    #file(WRITE ${CURL_SOURCES_DIR}/lib/curl_config.h "")
-
-    file(WRITE ${CURL_SOURCES_DIR}/lib/vauth/vauth/vauth.h "#include \"../vauth.h\"\n")
-    file(WRITE ${CURL_SOURCES_DIR}/lib/vauth/vauth/digest.h "#include \"../digest.h\"\n")
-    file(WRITE ${CURL_SOURCES_DIR}/lib/vauth/vauth/ntlm.h "#include \"../ntlm.h\"\n")
-    file(WRITE ${CURL_SOURCES_DIR}/lib/vauth/vtls/vtls.h "#include \"../../vtls/vtls.h\"\n")
-
-    file(GLOB CURL_LIBS_HEADERS ${CURL_SOURCES_DIR}/lib/*.h)
-    foreach (header IN LISTS CURL_LIBS_HEADERS)
-      get_filename_component(filename ${header} NAME)
-      file(WRITE ${CURL_SOURCES_DIR}/lib/vauth/${filename} "#include \"../${filename}\"\n")
-      file(WRITE ${CURL_SOURCES_DIR}/lib/vtls/${filename} "#include \"../${filename}\"\n")
-    endforeach()
-  endif()
-
-  if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
-    if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
-      SET(TMP_OS "x86_64")
-    else()
-      SET(TMP_OS "x86")
-    endif()
-
-    set_property(
-      SOURCE ${CURL_SOURCES}
-      PROPERTY COMPILE_DEFINITIONS "HAVE_CONFIG_H=1;OS=\"${TMP_OS}\""
-      )
-   
-    include(${CURL_SOURCES_DIR}/CMake/Macros.cmake)
-
-    # WARNING: Do *not* reorder the "check_include_file_concat()" below!
-    check_include_file_concat("stdio.h"          HAVE_STDIO_H)
-    check_include_file_concat("inttypes.h"       HAVE_INTTYPES_H)
-    check_include_file_concat("sys/filio.h"      HAVE_SYS_FILIO_H)
-    check_include_file_concat("sys/ioctl.h"      HAVE_SYS_IOCTL_H)
-    check_include_file_concat("sys/param.h"      HAVE_SYS_PARAM_H)
-    check_include_file_concat("sys/poll.h"       HAVE_SYS_POLL_H)
-    check_include_file_concat("sys/resource.h"   HAVE_SYS_RESOURCE_H)
-    check_include_file_concat("sys/select.h"     HAVE_SYS_SELECT_H)
-    check_include_file_concat("sys/socket.h"     HAVE_SYS_SOCKET_H)
-    check_include_file_concat("sys/sockio.h"     HAVE_SYS_SOCKIO_H)
-    check_include_file_concat("sys/stat.h"       HAVE_SYS_STAT_H)
-    check_include_file_concat("sys/time.h"       HAVE_SYS_TIME_H)
-    check_include_file_concat("sys/types.h"      HAVE_SYS_TYPES_H)
-    check_include_file_concat("sys/uio.h"        HAVE_SYS_UIO_H)
-    check_include_file_concat("sys/un.h"         HAVE_SYS_UN_H)
-    check_include_file_concat("sys/utime.h"      HAVE_SYS_UTIME_H)
-    check_include_file_concat("sys/xattr.h"      HAVE_SYS_XATTR_H)
-    check_include_file_concat("alloca.h"         HAVE_ALLOCA_H)
-    check_include_file_concat("arpa/inet.h"      HAVE_ARPA_INET_H)
-    check_include_file_concat("arpa/tftp.h"      HAVE_ARPA_TFTP_H)
-    check_include_file_concat("assert.h"         HAVE_ASSERT_H)
-    check_include_file_concat("crypto.h"         HAVE_CRYPTO_H)
-    check_include_file_concat("des.h"            HAVE_DES_H)
-    check_include_file_concat("err.h"            HAVE_ERR_H)
-    check_include_file_concat("errno.h"          HAVE_ERRNO_H)
-    check_include_file_concat("fcntl.h"          HAVE_FCNTL_H)
-    check_include_file_concat("idn2.h"           HAVE_IDN2_H)
-    check_include_file_concat("ifaddrs.h"        HAVE_IFADDRS_H)
-    check_include_file_concat("io.h"             HAVE_IO_H)
-    check_include_file_concat("krb.h"            HAVE_KRB_H)
-    check_include_file_concat("libgen.h"         HAVE_LIBGEN_H)
-    check_include_file_concat("limits.h"         HAVE_LIMITS_H)
-    check_include_file_concat("locale.h"         HAVE_LOCALE_H)
-    check_include_file_concat("net/if.h"         HAVE_NET_IF_H)
-    check_include_file_concat("netdb.h"          HAVE_NETDB_H)
-    check_include_file_concat("netinet/in.h"     HAVE_NETINET_IN_H)
-    check_include_file_concat("netinet/tcp.h"    HAVE_NETINET_TCP_H)
-
-    check_include_file_concat("pem.h"            HAVE_PEM_H)
-    check_include_file_concat("poll.h"           HAVE_POLL_H)
-    check_include_file_concat("pwd.h"            HAVE_PWD_H)
-    check_include_file_concat("rsa.h"            HAVE_RSA_H)
-    check_include_file_concat("setjmp.h"         HAVE_SETJMP_H)
-    check_include_file_concat("sgtty.h"          HAVE_SGTTY_H)
-    check_include_file_concat("signal.h"         HAVE_SIGNAL_H)
-    check_include_file_concat("ssl.h"            HAVE_SSL_H)
-    check_include_file_concat("stdbool.h"        HAVE_STDBOOL_H)
-    check_include_file_concat("stdint.h"         HAVE_STDINT_H)
-    check_include_file_concat("stdio.h"          HAVE_STDIO_H)
-    check_include_file_concat("stdlib.h"         HAVE_STDLIB_H)
-    check_include_file_concat("string.h"         HAVE_STRING_H)
-    check_include_file_concat("strings.h"        HAVE_STRINGS_H)
-    check_include_file_concat("stropts.h"        HAVE_STROPTS_H)
-    check_include_file_concat("termio.h"         HAVE_TERMIO_H)
-    check_include_file_concat("termios.h"        HAVE_TERMIOS_H)
-    check_include_file_concat("time.h"           HAVE_TIME_H)
-    check_include_file_concat("unistd.h"         HAVE_UNISTD_H)
-    check_include_file_concat("utime.h"          HAVE_UTIME_H)
-    check_include_file_concat("x509.h"           HAVE_X509_H)
-
-    check_include_file_concat("process.h"        HAVE_PROCESS_H)
-    check_include_file_concat("stddef.h"         HAVE_STDDEF_H)
-    check_include_file_concat("dlfcn.h"          HAVE_DLFCN_H)
-    check_include_file_concat("malloc.h"         HAVE_MALLOC_H)
-    check_include_file_concat("memory.h"         HAVE_MEMORY_H)
-    check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H)
-    check_include_file_concat("stdint.h"        HAVE_STDINT_H)
-    check_include_file_concat("sockio.h"        HAVE_SOCKIO_H)
-    check_include_file_concat("sys/utsname.h"   HAVE_SYS_UTSNAME_H)
-
-    check_type_size("size_t"  SIZEOF_SIZE_T)
-    check_type_size("ssize_t"  SIZEOF_SSIZE_T)
-    check_type_size("long long"  SIZEOF_LONG_LONG)
-    check_type_size("long"  SIZEOF_LONG)
-    check_type_size("short"  SIZEOF_SHORT)
-    check_type_size("int"  SIZEOF_INT)
-    check_type_size("__int64"  SIZEOF___INT64)
-    check_type_size("long double"  SIZEOF_LONG_DOUBLE)
-    check_type_size("time_t"  SIZEOF_TIME_T)
-    check_type_size("off_t"  SIZEOF_OFF_T)
-    check_type_size("socklen_t" CURL_SIZEOF_CURL_SOCKLEN_T)
-
-    check_symbol_exists(basename      "${CURL_INCLUDES}" HAVE_BASENAME)
-    check_symbol_exists(socket        "${CURL_INCLUDES}" HAVE_SOCKET)
-    # poll on macOS is unreliable, it first did not exist, then was broken until
-    # fixed in 10.9 only to break again in 10.12.
-    if(NOT APPLE)
-      check_symbol_exists(poll        "${CURL_INCLUDES}" HAVE_POLL)
-    endif()
-    check_symbol_exists(select        "${CURL_INCLUDES}" HAVE_SELECT)
-    check_symbol_exists(strdup        "${CURL_INCLUDES}" HAVE_STRDUP)
-    check_symbol_exists(strstr        "${CURL_INCLUDES}" HAVE_STRSTR)
-    check_symbol_exists(strtok_r      "${CURL_INCLUDES}" HAVE_STRTOK_R)
-    check_symbol_exists(strftime      "${CURL_INCLUDES}" HAVE_STRFTIME)
-    check_symbol_exists(uname         "${CURL_INCLUDES}" HAVE_UNAME)
-    check_symbol_exists(strcasecmp    "${CURL_INCLUDES}" HAVE_STRCASECMP)
-    check_symbol_exists(stricmp       "${CURL_INCLUDES}" HAVE_STRICMP)
-    check_symbol_exists(strcmpi       "${CURL_INCLUDES}" HAVE_STRCMPI)
-    check_symbol_exists(strncmpi      "${CURL_INCLUDES}" HAVE_STRNCMPI)
-    check_symbol_exists(alarm         "${CURL_INCLUDES}" HAVE_ALARM)
-    if(NOT HAVE_STRNCMPI)
-      set(HAVE_STRCMPI)
-    endif(NOT HAVE_STRNCMPI)
-
-    check_symbol_exists(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR)
-    check_symbol_exists(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R)
-    check_symbol_exists(gettimeofday  "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
-    check_symbol_exists(inet_addr     "${CURL_INCLUDES}" HAVE_INET_ADDR)
-    check_symbol_exists(inet_ntoa     "${CURL_INCLUDES}" HAVE_INET_NTOA)
-    check_symbol_exists(inet_ntoa_r   "${CURL_INCLUDES}" HAVE_INET_NTOA_R)
-    check_symbol_exists(tcsetattr     "${CURL_INCLUDES}" HAVE_TCSETATTR)
-    check_symbol_exists(tcgetattr     "${CURL_INCLUDES}" HAVE_TCGETATTR)
-    check_symbol_exists(perror        "${CURL_INCLUDES}" HAVE_PERROR)
-    check_symbol_exists(closesocket   "${CURL_INCLUDES}" HAVE_CLOSESOCKET)
-    check_symbol_exists(setvbuf       "${CURL_INCLUDES}" HAVE_SETVBUF)
-    check_symbol_exists(sigsetjmp     "${CURL_INCLUDES}" HAVE_SIGSETJMP)
-    check_symbol_exists(getpass_r     "${CURL_INCLUDES}" HAVE_GETPASS_R)
-    check_symbol_exists(strlcat       "${CURL_INCLUDES}" HAVE_STRLCAT)
-    check_symbol_exists(getpwuid      "${CURL_INCLUDES}" HAVE_GETPWUID)
-    check_symbol_exists(geteuid       "${CURL_INCLUDES}" HAVE_GETEUID)
-    check_symbol_exists(utime         "${CURL_INCLUDES}" HAVE_UTIME)
-    check_symbol_exists(gmtime_r      "${CURL_INCLUDES}" HAVE_GMTIME_R)
-    check_symbol_exists(localtime_r   "${CURL_INCLUDES}" HAVE_LOCALTIME_R)
-
-    check_symbol_exists(gethostbyname   "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME)
-    check_symbol_exists(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R)
-
-    check_symbol_exists(signal        "${CURL_INCLUDES}" HAVE_SIGNAL_FUNC)
-    check_symbol_exists(SIGALRM       "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO)
-    if(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
-      set(HAVE_SIGNAL 1)
-    endif(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
-    check_symbol_exists(uname          "${CURL_INCLUDES}" HAVE_UNAME)
-    check_symbol_exists(strtoll        "${CURL_INCLUDES}" HAVE_STRTOLL)
-    check_symbol_exists(_strtoi64      "${CURL_INCLUDES}" HAVE__STRTOI64)
-    check_symbol_exists(strerror_r     "${CURL_INCLUDES}" HAVE_STRERROR_R)
-    check_symbol_exists(siginterrupt   "${CURL_INCLUDES}" HAVE_SIGINTERRUPT)
-    check_symbol_exists(perror         "${CURL_INCLUDES}" HAVE_PERROR)
-    check_symbol_exists(fork           "${CURL_INCLUDES}" HAVE_FORK)
-    check_symbol_exists(getaddrinfo    "${CURL_INCLUDES}" HAVE_GETADDRINFO)
-    check_symbol_exists(freeaddrinfo   "${CURL_INCLUDES}" HAVE_FREEADDRINFO)
-    check_symbol_exists(freeifaddrs    "${CURL_INCLUDES}" HAVE_FREEIFADDRS)
-    check_symbol_exists(pipe           "${CURL_INCLUDES}" HAVE_PIPE)
-    check_symbol_exists(ftruncate      "${CURL_INCLUDES}" HAVE_FTRUNCATE)
-    check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME)
-    check_symbol_exists(getrlimit      "${CURL_INCLUDES}" HAVE_GETRLIMIT)
-    check_symbol_exists(setlocale      "${CURL_INCLUDES}" HAVE_SETLOCALE)
-    check_symbol_exists(setmode        "${CURL_INCLUDES}" HAVE_SETMODE)
-    check_symbol_exists(setrlimit      "${CURL_INCLUDES}" HAVE_SETRLIMIT)
-    check_symbol_exists(fcntl          "${CURL_INCLUDES}" HAVE_FCNTL)
-    check_symbol_exists(ioctl          "${CURL_INCLUDES}" HAVE_IOCTL)
-    check_symbol_exists(setsockopt     "${CURL_INCLUDES}" HAVE_SETSOCKOPT)
-
-    if(HAVE_SIZEOF_LONG_LONG)
-      set(HAVE_LONGLONG 1)
-      set(HAVE_LL 1)
-    endif(HAVE_SIZEOF_LONG_LONG)
-
-    check_function_exists(mach_absolute_time HAVE_MACH_ABSOLUTE_TIME)
-    check_function_exists(gethostname HAVE_GETHOSTNAME)
-
-    check_include_file_concat("pthread.h" HAVE_PTHREAD_H)
-    check_symbol_exists(recv "sys/socket.h" HAVE_RECV)
-    check_symbol_exists(send "sys/socket.h" HAVE_SEND)
-
-    check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS)
-
-    set(CMAKE_REQUIRED_INCLUDES "${CURL_SOURCES_DIR}/include")
-    set(CMAKE_EXTRA_INCLUDE_FILES "curl/system.h")
-    check_type_size("curl_off_t"  SIZEOF_CURL_OFF_T)
-
-    add_definitions(-DHAVE_GLIBC_STRERROR_R=1)
-
-    include(${CURL_SOURCES_DIR}/CMake/OtherTests.cmake)
-
-    foreach(CURL_TEST
-        HAVE_FCNTL_O_NONBLOCK
-        HAVE_IOCTLSOCKET
-        HAVE_IOCTLSOCKET_CAMEL
-        HAVE_IOCTLSOCKET_CAMEL_FIONBIO
-        HAVE_IOCTLSOCKET_FIONBIO
-        HAVE_IOCTL_FIONBIO
-        HAVE_IOCTL_SIOCGIFADDR
-        HAVE_SETSOCKOPT_SO_NONBLOCK
-        HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
-        TIME_WITH_SYS_TIME
-        HAVE_O_NONBLOCK
-        HAVE_GETHOSTBYADDR_R_5
-        HAVE_GETHOSTBYADDR_R_7
-        HAVE_GETHOSTBYADDR_R_8
-        HAVE_GETHOSTBYADDR_R_5_REENTRANT
-        HAVE_GETHOSTBYADDR_R_7_REENTRANT
-        HAVE_GETHOSTBYADDR_R_8_REENTRANT
-        HAVE_GETHOSTBYNAME_R_3
-        HAVE_GETHOSTBYNAME_R_5
-        HAVE_GETHOSTBYNAME_R_6
-        HAVE_GETHOSTBYNAME_R_3_REENTRANT
-        HAVE_GETHOSTBYNAME_R_5_REENTRANT
-        HAVE_GETHOSTBYNAME_R_6_REENTRANT
-        HAVE_SOCKLEN_T
-        HAVE_IN_ADDR_T
-        HAVE_BOOL_T
-        STDC_HEADERS
-        RETSIGTYPE_TEST
-        HAVE_INET_NTOA_R_DECL
-        HAVE_INET_NTOA_R_DECL_REENTRANT
-        HAVE_GETADDRINFO
-        HAVE_FILE_OFFSET_BITS
-        )
-      curl_internal_test(${CURL_TEST})
-    endforeach(CURL_TEST)
-
-    configure_file(
-      ${CURL_SOURCES_DIR}/lib/curl_config.h.cmake
-      ${CURL_SOURCES_DIR}/lib/curl_config.h
-      )
-  endif()
-else()
-  include(FindCURL)
-  include_directories(${CURL_INCLUDE_DIRS})
-  link_libraries(${CURL_LIBRARIES})
-
-  if (NOT ${CURL_FOUND})
-    message(FATAL_ERROR "Unable to find LibCurl")
-  endif()
-endif()
--- a/Resources/Orthanc/Resources/CMake/LibJpegConfiguration.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-if (STATIC_BUILD OR NOT USE_SYSTEM_LIBJPEG)
-  set(LIBJPEG_SOURCES_DIR ${CMAKE_BINARY_DIR}/jpeg-9a)
-  DownloadPackage(
-    "3353992aecaee1805ef4109aadd433e7"
-    "http://www.orthanc-server.com/downloads/third-party/jpegsrc.v9a.tar.gz"
-    "${LIBJPEG_SOURCES_DIR}")
-
-  include_directories(
-    ${LIBJPEG_SOURCES_DIR}
-    )
-
-  list(APPEND LIBJPEG_SOURCES 
-    ${LIBJPEG_SOURCES_DIR}/jaricom.c
-    ${LIBJPEG_SOURCES_DIR}/jcapimin.c
-    ${LIBJPEG_SOURCES_DIR}/jcapistd.c
-    ${LIBJPEG_SOURCES_DIR}/jcarith.c
-    ${LIBJPEG_SOURCES_DIR}/jccoefct.c
-    ${LIBJPEG_SOURCES_DIR}/jccolor.c
-    ${LIBJPEG_SOURCES_DIR}/jcdctmgr.c
-    ${LIBJPEG_SOURCES_DIR}/jchuff.c
-    ${LIBJPEG_SOURCES_DIR}/jcinit.c
-    ${LIBJPEG_SOURCES_DIR}/jcmarker.c
-    ${LIBJPEG_SOURCES_DIR}/jcmaster.c
-    ${LIBJPEG_SOURCES_DIR}/jcomapi.c
-    ${LIBJPEG_SOURCES_DIR}/jcparam.c
-    ${LIBJPEG_SOURCES_DIR}/jcprepct.c
-    ${LIBJPEG_SOURCES_DIR}/jcsample.c
-    ${LIBJPEG_SOURCES_DIR}/jctrans.c
-    ${LIBJPEG_SOURCES_DIR}/jdapimin.c
-    ${LIBJPEG_SOURCES_DIR}/jdapistd.c
-    ${LIBJPEG_SOURCES_DIR}/jdarith.c
-    ${LIBJPEG_SOURCES_DIR}/jdatadst.c
-    ${LIBJPEG_SOURCES_DIR}/jdatasrc.c
-    ${LIBJPEG_SOURCES_DIR}/jdcoefct.c
-    ${LIBJPEG_SOURCES_DIR}/jdcolor.c
-    ${LIBJPEG_SOURCES_DIR}/jddctmgr.c
-    ${LIBJPEG_SOURCES_DIR}/jdhuff.c
-    ${LIBJPEG_SOURCES_DIR}/jdinput.c
-    ${LIBJPEG_SOURCES_DIR}/jcmainct.c
-    ${LIBJPEG_SOURCES_DIR}/jdmainct.c
-    ${LIBJPEG_SOURCES_DIR}/jdmarker.c
-    ${LIBJPEG_SOURCES_DIR}/jdmaster.c
-    ${LIBJPEG_SOURCES_DIR}/jdmerge.c
-    ${LIBJPEG_SOURCES_DIR}/jdpostct.c
-    ${LIBJPEG_SOURCES_DIR}/jdsample.c
-    ${LIBJPEG_SOURCES_DIR}/jdtrans.c
-    ${LIBJPEG_SOURCES_DIR}/jerror.c
-    ${LIBJPEG_SOURCES_DIR}/jfdctflt.c
-    ${LIBJPEG_SOURCES_DIR}/jfdctfst.c
-    ${LIBJPEG_SOURCES_DIR}/jfdctint.c
-    ${LIBJPEG_SOURCES_DIR}/jidctflt.c
-    ${LIBJPEG_SOURCES_DIR}/jidctfst.c
-    ${LIBJPEG_SOURCES_DIR}/jidctint.c
-    #${LIBJPEG_SOURCES_DIR}/jmemansi.c
-    #${LIBJPEG_SOURCES_DIR}/jmemdos.c
-    #${LIBJPEG_SOURCES_DIR}/jmemmac.c
-    ${LIBJPEG_SOURCES_DIR}/jmemmgr.c
-    #${LIBJPEG_SOURCES_DIR}/jmemname.c
-    ${LIBJPEG_SOURCES_DIR}/jmemnobs.c
-    ${LIBJPEG_SOURCES_DIR}/jquant1.c
-    ${LIBJPEG_SOURCES_DIR}/jquant2.c
-    ${LIBJPEG_SOURCES_DIR}/jutils.c
-
-    # ${LIBJPEG_SOURCES_DIR}/rdbmp.c
-    # ${LIBJPEG_SOURCES_DIR}/rdcolmap.c
-    # ${LIBJPEG_SOURCES_DIR}/rdgif.c
-    # ${LIBJPEG_SOURCES_DIR}/rdppm.c
-    # ${LIBJPEG_SOURCES_DIR}/rdrle.c
-    # ${LIBJPEG_SOURCES_DIR}/rdswitch.c
-    # ${LIBJPEG_SOURCES_DIR}/rdtarga.c
-    # ${LIBJPEG_SOURCES_DIR}/transupp.c
-    # ${LIBJPEG_SOURCES_DIR}/wrbmp.c
-    # ${LIBJPEG_SOURCES_DIR}/wrgif.c
-    # ${LIBJPEG_SOURCES_DIR}/wrppm.c
-    # ${LIBJPEG_SOURCES_DIR}/wrrle.c
-    # ${LIBJPEG_SOURCES_DIR}/wrtarga.c
-    )
-
-  configure_file(
-    ${LIBJPEG_SOURCES_DIR}/jconfig.txt
-    ${LIBJPEG_SOURCES_DIR}/jconfig.h COPYONLY
-    )
-
-  source_group(ThirdParty\\libjpeg REGULAR_EXPRESSION ${LIBJPEG_SOURCES_DIR}/.*)
-
-else()
-  include(FindJPEG)
-
-  if (NOT ${JPEG_FOUND})
-    message(FATAL_ERROR "Unable to find libjpeg")
-  endif()
-
-  include_directories(${JPEG_INCLUDE_DIR})
-  link_libraries(${JPEG_LIBRARIES})
-endif()
--- a/Resources/Orthanc/Resources/CMake/LibPngConfiguration.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-if (STATIC_BUILD OR NOT USE_SYSTEM_LIBPNG)
-  SET(LIBPNG_SOURCES_DIR ${CMAKE_BINARY_DIR}/libpng-1.5.12)
-  SET(LIBPNG_URL "http://www.orthanc-server.com/downloads/third-party/libpng-1.5.12.tar.gz")
-  SET(LIBPNG_MD5 "8ea7f60347a306c5faf70b977fa80e28")
-
-  DownloadPackage(${LIBPNG_MD5} ${LIBPNG_URL} "${LIBPNG_SOURCES_DIR}")
-
-  include_directories(
-    ${LIBPNG_SOURCES_DIR}
-    )
-
-  configure_file(
-    ${LIBPNG_SOURCES_DIR}/scripts/pnglibconf.h.prebuilt
-    ${LIBPNG_SOURCES_DIR}/pnglibconf.h
-    )
-
-  set(LIBPNG_SOURCES
-    #${LIBPNG_SOURCES_DIR}/example.c
-    ${LIBPNG_SOURCES_DIR}/png.c
-    ${LIBPNG_SOURCES_DIR}/pngerror.c
-    ${LIBPNG_SOURCES_DIR}/pngget.c
-    ${LIBPNG_SOURCES_DIR}/pngmem.c
-    ${LIBPNG_SOURCES_DIR}/pngpread.c
-    ${LIBPNG_SOURCES_DIR}/pngread.c
-    ${LIBPNG_SOURCES_DIR}/pngrio.c
-    ${LIBPNG_SOURCES_DIR}/pngrtran.c
-    ${LIBPNG_SOURCES_DIR}/pngrutil.c
-    ${LIBPNG_SOURCES_DIR}/pngset.c
-    #${LIBPNG_SOURCES_DIR}/pngtest.c
-    ${LIBPNG_SOURCES_DIR}/pngtrans.c
-    ${LIBPNG_SOURCES_DIR}/pngwio.c
-    ${LIBPNG_SOURCES_DIR}/pngwrite.c
-    ${LIBPNG_SOURCES_DIR}/pngwtran.c
-    ${LIBPNG_SOURCES_DIR}/pngwutil.c
-    )
-
-  #set_property(
-  #  SOURCE ${LIBPNG_SOURCES}
-  #  PROPERTY COMPILE_FLAGS -UHAVE_CONFIG_H)
-
-  add_definitions(
-    -DPNG_NO_CONSOLE_IO=1
-    -DPNG_NO_STDIO=1
-    # The following declaration avoids "__declspec(dllexport)" in
-    # libpng to prevent publicly exposing its symbols by the DLLs
-    -DPNG_IMPEXP=
-    )
-
-  source_group(ThirdParty\\libpng REGULAR_EXPRESSION ${LIBPNG_SOURCES_DIR}/.*)
-
-else()
-  include(FindPNG)
-
-  if (NOT ${PNG_FOUND})
-    message(FATAL_ERROR "Unable to find libpng")
-  endif()
-
-  include_directories(${PNG_INCLUDE_DIRS})
-  link_libraries(${PNG_LIBRARIES})
-  add_definitions(${PNG_DEFINITIONS})
-endif()
--- a/Resources/Orthanc/Resources/CMake/OpenSslConfiguration.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,219 +0,0 @@
-if (STATIC_BUILD OR NOT USE_SYSTEM_OPENSSL)
-  # WARNING - We had to repack the upstream ".tar.gz" file to a ZIP
-  # file, as the upstream distribution ships symbolic links that are
-  # not always properly handled when uncompressing on Windows.
-
-  SET(OPENSSL_SOURCES_DIR ${CMAKE_BINARY_DIR}/openssl-1.0.2d)
-  SET(OPENSSL_URL "http://www.orthanc-server.com/downloads/third-party/openssl-1.0.2d.zip")
-  SET(OPENSSL_MD5 "4b2ac15fc6db17f3dadc54482d3eee85")
-
-  if (IS_DIRECTORY "${OPENSSL_SOURCES_DIR}")
-    set(FirstRun OFF)
-  else()
-    set(FirstRun ON)
-  endif()
-
-  DownloadPackage(${OPENSSL_MD5} ${OPENSSL_URL} "${OPENSSL_SOURCES_DIR}")
-
-  add_definitions(
-    -DOPENSSL_THREADS
-    -DOPENSSL_IA32_SSE2
-    -DOPENSSL_NO_ASM
-    -DOPENSSL_NO_DYNAMIC_ENGINE
-    -DNO_WINDOWS_BRAINDEATH
-
-    -DOPENSSL_NO_BF 
-    -DOPENSSL_NO_CAMELLIA
-    -DOPENSSL_NO_CAST 
-    -DOPENSSL_NO_EC_NISTP_64_GCC_128
-    -DOPENSSL_NO_GMP
-    -DOPENSSL_NO_GOST
-    -DOPENSSL_NO_HW
-    -DOPENSSL_NO_JPAKE
-    -DOPENSSL_NO_IDEA
-    -DOPENSSL_NO_KRB5 
-    -DOPENSSL_NO_MD2 
-    -DOPENSSL_NO_MDC2 
-    -DOPENSSL_NO_MD4
-    -DOPENSSL_NO_RC2 
-    -DOPENSSL_NO_RC4 
-    -DOPENSSL_NO_RC5 
-    -DOPENSSL_NO_RFC3779
-    -DOPENSSL_NO_SCTP
-    -DOPENSSL_NO_STORE
-    -DOPENSSL_NO_SEED
-    -DOPENSSL_NO_WHIRLPOOL
-    -DOPENSSL_NO_RIPEMD
-    )
-
-  include_directories(
-    ${OPENSSL_SOURCES_DIR}
-    ${OPENSSL_SOURCES_DIR}/crypto
-    ${OPENSSL_SOURCES_DIR}/crypto/asn1
-    ${OPENSSL_SOURCES_DIR}/crypto/modes
-    ${OPENSSL_SOURCES_DIR}/crypto/evp
-    ${OPENSSL_SOURCES_DIR}/include
-    )
-
-  set(OPENSSL_SOURCES_SUBDIRS
-    ${OPENSSL_SOURCES_DIR}/crypto
-    ${OPENSSL_SOURCES_DIR}/crypto/aes
-    ${OPENSSL_SOURCES_DIR}/crypto/asn1
-    ${OPENSSL_SOURCES_DIR}/crypto/bio
-    ${OPENSSL_SOURCES_DIR}/crypto/bn
-    ${OPENSSL_SOURCES_DIR}/crypto/buffer
-    ${OPENSSL_SOURCES_DIR}/crypto/cmac
-    ${OPENSSL_SOURCES_DIR}/crypto/cms
-    ${OPENSSL_SOURCES_DIR}/crypto/comp
-    ${OPENSSL_SOURCES_DIR}/crypto/conf
-    ${OPENSSL_SOURCES_DIR}/crypto/des
-    ${OPENSSL_SOURCES_DIR}/crypto/dh
-    ${OPENSSL_SOURCES_DIR}/crypto/dsa
-    ${OPENSSL_SOURCES_DIR}/crypto/dso
-    ${OPENSSL_SOURCES_DIR}/crypto/engine
-    ${OPENSSL_SOURCES_DIR}/crypto/err
-    ${OPENSSL_SOURCES_DIR}/crypto/evp
-    ${OPENSSL_SOURCES_DIR}/crypto/hmac
-    ${OPENSSL_SOURCES_DIR}/crypto/lhash
-    ${OPENSSL_SOURCES_DIR}/crypto/md5
-    ${OPENSSL_SOURCES_DIR}/crypto/modes
-    ${OPENSSL_SOURCES_DIR}/crypto/objects
-    ${OPENSSL_SOURCES_DIR}/crypto/ocsp
-    ${OPENSSL_SOURCES_DIR}/crypto/pem
-    ${OPENSSL_SOURCES_DIR}/crypto/pkcs12
-    ${OPENSSL_SOURCES_DIR}/crypto/pkcs7
-    ${OPENSSL_SOURCES_DIR}/crypto/pqueue
-    ${OPENSSL_SOURCES_DIR}/crypto/rand
-    ${OPENSSL_SOURCES_DIR}/crypto/rsa
-    ${OPENSSL_SOURCES_DIR}/crypto/sha
-    ${OPENSSL_SOURCES_DIR}/crypto/srp
-    ${OPENSSL_SOURCES_DIR}/crypto/stack
-    ${OPENSSL_SOURCES_DIR}/crypto/ts
-    ${OPENSSL_SOURCES_DIR}/crypto/txt_db
-    ${OPENSSL_SOURCES_DIR}/crypto/ui
-    ${OPENSSL_SOURCES_DIR}/crypto/x509
-    ${OPENSSL_SOURCES_DIR}/crypto/x509v3
-    ${OPENSSL_SOURCES_DIR}/ssl
-    )
-
-  if (ENABLE_PKCS11)
-    list(APPEND OPENSSL_SOURCES_SUBDIRS
-      # EC, ECDH and ECDSA are necessary for PKCS11
-      ${OPENSSL_SOURCES_DIR}/crypto/ec
-      ${OPENSSL_SOURCES_DIR}/crypto/ecdh
-      ${OPENSSL_SOURCES_DIR}/crypto/ecdsa
-      )
-  else()
-    add_definitions(
-      -DOPENSSL_NO_EC
-      -DOPENSSL_NO_ECDH
-      -DOPENSSL_NO_ECDSA
-      )
-  endif()
-
-  foreach(d ${OPENSSL_SOURCES_SUBDIRS})
-    AUX_SOURCE_DIRECTORY(${d} OPENSSL_SOURCES)
-  endforeach()
-
-  list(REMOVE_ITEM OPENSSL_SOURCES
-    ${OPENSSL_SOURCES_DIR}/crypto/LPdir_unix.c
-    ${OPENSSL_SOURCES_DIR}/crypto/LPdir_vms.c
-    ${OPENSSL_SOURCES_DIR}/crypto/LPdir_win.c
-    ${OPENSSL_SOURCES_DIR}/crypto/LPdir_win32.c
-    ${OPENSSL_SOURCES_DIR}/crypto/LPdir_wince.c
-    ${OPENSSL_SOURCES_DIR}/crypto/armcap.c
-    ${OPENSSL_SOURCES_DIR}/crypto/bf/bfs.cpp
-    ${OPENSSL_SOURCES_DIR}/crypto/bio/bss_rtcp.c
-    ${OPENSSL_SOURCES_DIR}/crypto/bn/exp.c
-    ${OPENSSL_SOURCES_DIR}/crypto/conf/cnf_save.c
-    ${OPENSSL_SOURCES_DIR}/crypto/conf/test.c
-    ${OPENSSL_SOURCES_DIR}/crypto/des/des.c
-    ${OPENSSL_SOURCES_DIR}/crypto/des/des3s.cpp
-    ${OPENSSL_SOURCES_DIR}/crypto/des/des_opts.c
-    ${OPENSSL_SOURCES_DIR}/crypto/des/dess.cpp
-    ${OPENSSL_SOURCES_DIR}/crypto/des/read_pwd.c
-    ${OPENSSL_SOURCES_DIR}/crypto/des/speed.c
-    ${OPENSSL_SOURCES_DIR}/crypto/evp/e_dsa.c
-    ${OPENSSL_SOURCES_DIR}/crypto/evp/m_ripemd.c
-    ${OPENSSL_SOURCES_DIR}/crypto/lhash/lh_test.c
-    ${OPENSSL_SOURCES_DIR}/crypto/md5/md5s.cpp
-    ${OPENSSL_SOURCES_DIR}/crypto/pkcs7/bio_ber.c
-    ${OPENSSL_SOURCES_DIR}/crypto/pkcs7/pk7_enc.c
-    ${OPENSSL_SOURCES_DIR}/crypto/ppccap.c
-    ${OPENSSL_SOURCES_DIR}/crypto/rand/randtest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/s390xcap.c
-    ${OPENSSL_SOURCES_DIR}/crypto/sparcv9cap.c
-    ${OPENSSL_SOURCES_DIR}/crypto/x509v3/tabtest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/x509v3/v3conf.c
-    ${OPENSSL_SOURCES_DIR}/ssl/ssl_task.c
-    ${OPENSSL_SOURCES_DIR}/crypto/LPdir_nyi.c
-    ${OPENSSL_SOURCES_DIR}/crypto/aes/aes_x86core.c
-    ${OPENSSL_SOURCES_DIR}/crypto/bio/bss_dgram.c
-    ${OPENSSL_SOURCES_DIR}/crypto/bn/bntest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/bn/expspeed.c
-    ${OPENSSL_SOURCES_DIR}/crypto/bn/exptest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/engine/enginetest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/evp/evp_test.c
-    ${OPENSSL_SOURCES_DIR}/crypto/hmac/hmactest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/md5/md5.c
-    ${OPENSSL_SOURCES_DIR}/crypto/md5/md5test.c
-    ${OPENSSL_SOURCES_DIR}/crypto/o_dir_test.c
-    ${OPENSSL_SOURCES_DIR}/crypto/pkcs7/dec.c
-    ${OPENSSL_SOURCES_DIR}/crypto/pkcs7/enc.c
-    ${OPENSSL_SOURCES_DIR}/crypto/pkcs7/sign.c
-    ${OPENSSL_SOURCES_DIR}/crypto/pkcs7/verify.c
-    ${OPENSSL_SOURCES_DIR}/crypto/rsa/rsa_test.c
-    ${OPENSSL_SOURCES_DIR}/crypto/sha/sha.c
-    ${OPENSSL_SOURCES_DIR}/crypto/sha/sha1.c
-    ${OPENSSL_SOURCES_DIR}/crypto/sha/sha1t.c
-    ${OPENSSL_SOURCES_DIR}/crypto/sha/sha1test.c
-    ${OPENSSL_SOURCES_DIR}/crypto/sha/sha256t.c
-    ${OPENSSL_SOURCES_DIR}/crypto/sha/sha512t.c
-    ${OPENSSL_SOURCES_DIR}/crypto/sha/shatest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/srp/srptest.c
-
-    ${OPENSSL_SOURCES_DIR}/crypto/bn/divtest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/bn/bnspeed.c
-    ${OPENSSL_SOURCES_DIR}/crypto/des/destest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/dh/p192.c
-    ${OPENSSL_SOURCES_DIR}/crypto/dh/p512.c
-    ${OPENSSL_SOURCES_DIR}/crypto/dh/p1024.c
-    ${OPENSSL_SOURCES_DIR}/crypto/des/rpw.c
-    ${OPENSSL_SOURCES_DIR}/ssl/ssltest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/dsa/dsagen.c
-    ${OPENSSL_SOURCES_DIR}/crypto/dsa/dsatest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/dh/dhtest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/pqueue/pq_test.c
-    ${OPENSSL_SOURCES_DIR}/crypto/des/ncbc_enc.c
-
-    ${OPENSSL_SOURCES_DIR}/crypto/evp/evp_extra_test.c
-    ${OPENSSL_SOURCES_DIR}/crypto/evp/verify_extra_test.c
-    ${OPENSSL_SOURCES_DIR}/crypto/x509/verify_extra_test.c
-    ${OPENSSL_SOURCES_DIR}/crypto/x509v3/v3prin.c
-    ${OPENSSL_SOURCES_DIR}/crypto/x509v3/v3nametest.c
-    ${OPENSSL_SOURCES_DIR}/crypto/constant_time_test.c
-    ${OPENSSL_SOURCES_DIR}/crypto/ec/ecp_nistz256_table.c
-
-    ${OPENSSL_SOURCES_DIR}/ssl/heartbeat_test.c
-    )
-
-
-  if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
-    set_source_files_properties(
-      ${OPENSSL_SOURCES}
-      PROPERTIES COMPILE_DEFINITIONS
-      "OPENSSL_SYSNAME_WIN32;SO_WIN32;WIN32_LEAN_AND_MEAN;L_ENDIAN")
-  endif()
-
-  source_group(ThirdParty\\OpenSSL REGULAR_EXPRESSION ${OPENSSL_SOURCES_DIR}/.*)
-
-else()
-  include(FindOpenSSL)
-
-  if (NOT ${OPENSSL_FOUND})
-    message(FATAL_ERROR "Unable to find OpenSSL")
-  endif()
-
-  include_directories(${OPENSSL_INCLUDE_DIR})
-  link_libraries(${OPENSSL_LIBRARIES})
-endif()
--- a/Resources/Orthanc/Resources/CMake/OrthancFrameworkConfiguration.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,568 +0,0 @@
-##
-## This is a CMake configuration file that configures the core
-## libraries of Orthanc. This file can be used by external projects so
-## as to gain access to the Orthanc APIs (the most prominent examples
-## are currently "Stone of Orthanc" and "Orthanc for whole-slide
-## imaging plugin").
-##
-
-
-#####################################################################
-## Configuration of the components
-#####################################################################
-
-# Path to the root folder of the Orthanc distribution
-set(ORTHANC_ROOT ${CMAKE_CURRENT_LIST_DIR}/../..)
-
-# Some basic inclusions
-include(CMakePushCheckState)
-include(CheckFunctionExists)
-include(CheckIncludeFile)
-include(CheckIncludeFileCXX)
-include(CheckIncludeFiles)
-include(CheckLibraryExists)
-include(CheckStructHasMember)
-include(CheckSymbolExists)
-include(CheckTypeSize)
-include(FindPythonInterp)
-  
-include(${CMAKE_CURRENT_LIST_DIR}/AutoGeneratedCode.cmake)
-include(${CMAKE_CURRENT_LIST_DIR}/DownloadPackage.cmake)
-include(${CMAKE_CURRENT_LIST_DIR}/Compiler.cmake)
-
-
-#####################################################################
-## Disable unneeded macros
-#####################################################################
-
-if (NOT ENABLE_SQLITE)
-  unset(USE_SYSTEM_SQLITE CACHE)
-  add_definitions(-DORTHANC_ENABLE_SQLITE=0)
-endif()
-
-if (NOT ENABLE_CRYPTO_OPTIONS)
-  unset(ENABLE_SSL CACHE)
-  unset(ENABLE_PKCS11 CACHE)
-  unset(USE_SYSTEM_OPENSSL CACHE)
-  unset(USE_SYSTEM_LIBP11 CACHE)
-  add_definitions(
-    -DORTHANC_ENABLE_SSL=0
-    -DORTHANC_ENABLE_PKCS11=0
-    )
-endif()
-
-if (NOT ENABLE_WEB_CLIENT)
-  unset(USE_SYSTEM_CURL CACHE)
-  add_definitions(-DORTHANC_ENABLE_CURL=0)
-endif()
-
-if (NOT ENABLE_WEB_SERVER)
-  unset(ENABLE_CIVETWEB CACHE)
-  unset(USE_SYSTEM_CIVETWEB CACHE)
-  unset(USE_SYSTEM_MONGOOSE CACHE)
-  add_definitions(
-    -DORTHANC_ENABLE_CIVETWEB=0
-    -DORTHANC_ENABLE_MONGOOSE=0
-    )
-endif()
-
-if (NOT ENABLE_JPEG)
-  unset(USE_SYSTEM_LIBJPEG CACHE)
-  add_definitions(-DORTHANC_ENABLE_JPEG=0)
-endif()
-
-if (NOT ENABLE_ZLIB)
-  unset(USE_SYSTEM_ZLIB CACHE)
-  add_definitions(-DORTHANC_ENABLE_ZLIB=0)
-endif()
-
-if (NOT ENABLE_PNG)
-  unset(USE_SYSTEM_LIBPNG CACHE)
-  add_definitions(-DORTHANC_ENABLE_PNG=0)
-endif()
-
-if (NOT ENABLE_LUA)
-  unset(USE_SYSTEM_LUA CACHE)
-  add_definitions(-DORTHANC_ENABLE_LUA=0)
-endif()
-
-if (NOT ENABLE_PUGIXML)
-  unset(USE_SYSTEM_PUGIXML CACHE)
-  add_definitions(-DORTHANC_ENABLE_PUGIXML=0)
-endif()
-
-if (NOT ENABLE_LOCALE)
-  unset(USE_SYSTEM_LIBICONV CACHE)
-  add_definitions(-DORTHANC_ENABLE_LOCALE=0)
-endif()
-
-if (NOT ENABLE_GOOGLE_TEST)
-  unset(USE_SYSTEM_GOOGLE_TEST CACHE)
-  unset(USE_GOOGLE_TEST_DEBIAN_PACKAGE CACHE)
-endif()
-
-if (NOT ENABLE_DCMTK)
-  add_definitions(
-    -DORTHANC_ENABLE_DCMTK=0
-    -DORTHANC_ENABLE_DCMTK_NETWORKING=0
-    )
-  unset(DCMTK_DICTIONARY_DIR CACHE)
-  unset(USE_DCMTK_360 CACHE)
-  unset(USE_DCMTK_362_PRIVATE_DIC CACHE)
-  unset(USE_SYSTEM_DCMTK CACHE)
-  unset(ENABLE_DCMTK_JPEG CACHE)
-  unset(ENABLE_DCMTK_JPEG_LOSSLESS CACHE)
-endif()
-
-
-#####################################################################
-## List of source files
-#####################################################################
-
-set(ORTHANC_CORE_SOURCES_INTERNAL
-  ${ORTHANC_ROOT}/Core/Cache/MemoryCache.cpp
-  ${ORTHANC_ROOT}/Core/ChunkedBuffer.cpp
-  ${ORTHANC_ROOT}/Core/DicomFormat/DicomArray.cpp
-  ${ORTHANC_ROOT}/Core/DicomFormat/DicomImageInformation.cpp
-  ${ORTHANC_ROOT}/Core/DicomFormat/DicomInstanceHasher.cpp
-  ${ORTHANC_ROOT}/Core/DicomFormat/DicomIntegerPixelAccessor.cpp
-  ${ORTHANC_ROOT}/Core/DicomFormat/DicomMap.cpp
-  ${ORTHANC_ROOT}/Core/DicomFormat/DicomTag.cpp
-  ${ORTHANC_ROOT}/Core/DicomFormat/DicomValue.cpp
-  ${ORTHANC_ROOT}/Core/Enumerations.cpp
-  ${ORTHANC_ROOT}/Core/Images/Font.cpp
-  ${ORTHANC_ROOT}/Core/Images/FontRegistry.cpp
-  ${ORTHANC_ROOT}/Core/Images/IImageWriter.cpp
-  ${ORTHANC_ROOT}/Core/Images/Image.cpp
-  ${ORTHANC_ROOT}/Core/Images/ImageAccessor.cpp
-  ${ORTHANC_ROOT}/Core/Images/ImageBuffer.cpp
-  ${ORTHANC_ROOT}/Core/Images/ImageProcessing.cpp
-  ${ORTHANC_ROOT}/Core/Logging.cpp
-  ${ORTHANC_ROOT}/Core/Toolbox.cpp
-  ${ORTHANC_ROOT}/Core/WebServiceParameters.cpp
-  )
-
-
-#####################################################################
-## Configuration of optional third-party dependencies
-#####################################################################
-
-
-##
-## Embedded database: SQLite
-##
-
-if (ENABLE_SQLITE)
-  include(${CMAKE_CURRENT_LIST_DIR}/SQLiteConfiguration.cmake)
-  add_definitions(-DORTHANC_ENABLE_SQLITE=1)
-
-  list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
-    ${ORTHANC_ROOT}/Core/SQLite/Connection.cpp
-    ${ORTHANC_ROOT}/Core/SQLite/FunctionContext.cpp
-    ${ORTHANC_ROOT}/Core/SQLite/Statement.cpp
-    ${ORTHANC_ROOT}/Core/SQLite/StatementId.cpp
-    ${ORTHANC_ROOT}/Core/SQLite/StatementReference.cpp
-    ${ORTHANC_ROOT}/Core/SQLite/Transaction.cpp
-    )
-endif()
-
-
-##
-## Cryptography: OpenSSL and libp11
-## Must be above "ENABLE_WEB_CLIENT" and "ENABLE_WEB_SERVER"
-##
-
-if (ENABLE_CRYPTO_OPTIONS)
-  if (ENABLE_SSL)
-    include(${CMAKE_CURRENT_LIST_DIR}/OpenSslConfiguration.cmake)
-    add_definitions(-DORTHANC_ENABLE_SSL=1)
-  else()
-    unset(USE_SYSTEM_OPENSSL CACHE)
-    add_definitions(-DORTHANC_ENABLE_SSL=0)
-  endif()
-
-  if (ENABLE_PKCS11)
-    if (ENABLE_SSL)
-      include(${CMAKE_CURRENT_LIST_DIR}/LibP11Configuration.cmake)
-
-      add_definitions(-DORTHANC_ENABLE_PKCS11=1)
-      list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
-        ${ORTHANC_ROOT}/Core/Pkcs11.cpp
-        )
-    else()
-      message(FATAL_ERROR "OpenSSL is required to enable PKCS#11 support")
-    endif()
-  else()
-    add_definitions(-DORTHANC_ENABLE_PKCS11=0)  
-  endif()
-endif()
-
-
-##
-## HTTP client: libcurl
-##
-
-if (ENABLE_WEB_CLIENT)
-  include(${CMAKE_CURRENT_LIST_DIR}/LibCurlConfiguration.cmake)
-  add_definitions(-DORTHANC_ENABLE_CURL=1)
-
-  list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
-    ${ORTHANC_ROOT}/Core/HttpClient.cpp
-    )
-endif()
-
-
-##
-## HTTP server: Mongoose 3.8 or Civetweb
-##
-
-if (ENABLE_WEB_SERVER)
-  if (ENABLE_CIVETWEB)
-    include(${CMAKE_CURRENT_LIST_DIR}/CivetwebConfiguration.cmake)
-    add_definitions(
-      -DORTHANC_ENABLE_CIVETWEB=1
-      -DORTHANC_ENABLE_MONGOOSE=0
-      )
-  else()
-    include(${CMAKE_CURRENT_LIST_DIR}/MongooseConfiguration.cmake)
-    add_definitions(
-      -DORTHANC_ENABLE_CIVETWEB=0
-      -DORTHANC_ENABLE_MONGOOSE=1
-      )
-  endif()
-
-  list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
-    ${ORTHANC_ROOT}/Core/HttpServer/BufferHttpSender.cpp
-    ${ORTHANC_ROOT}/Core/HttpServer/FilesystemHttpHandler.cpp
-    ${ORTHANC_ROOT}/Core/HttpServer/FilesystemHttpSender.cpp
-    ${ORTHANC_ROOT}/Core/HttpServer/HttpContentNegociation.cpp
-    ${ORTHANC_ROOT}/Core/HttpServer/HttpFileSender.cpp
-    ${ORTHANC_ROOT}/Core/HttpServer/HttpOutput.cpp
-    ${ORTHANC_ROOT}/Core/HttpServer/HttpStreamTranscoder.cpp
-    ${ORTHANC_ROOT}/Core/HttpServer/HttpToolbox.cpp
-    ${ORTHANC_ROOT}/Core/HttpServer/MongooseServer.cpp
-    ${ORTHANC_ROOT}/Core/HttpServer/StringHttpOutput.cpp
-    ${ORTHANC_ROOT}/Core/RestApi/RestApi.cpp
-    ${ORTHANC_ROOT}/Core/RestApi/RestApiCall.cpp
-    ${ORTHANC_ROOT}/Core/RestApi/RestApiGetCall.cpp
-    ${ORTHANC_ROOT}/Core/RestApi/RestApiHierarchy.cpp
-    ${ORTHANC_ROOT}/Core/RestApi/RestApiOutput.cpp
-    ${ORTHANC_ROOT}/Core/RestApi/RestApiPath.cpp
-    )
-endif()
-
-
-##
-## JPEG support: libjpeg
-##
-
-if (ENABLE_JPEG)
-  include(${CMAKE_CURRENT_LIST_DIR}/LibJpegConfiguration.cmake)
-  add_definitions(-DORTHANC_ENABLE_JPEG=1)
-
-  list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
-    ${ORTHANC_ROOT}/Core/Images/JpegErrorManager.cpp
-    ${ORTHANC_ROOT}/Core/Images/JpegReader.cpp
-    ${ORTHANC_ROOT}/Core/Images/JpegWriter.cpp
-    )
-endif()
-
-
-##
-## zlib support
-##
-
-if (ENABLE_ZLIB)
-  include(${CMAKE_CURRENT_LIST_DIR}/ZlibConfiguration.cmake)
-  add_definitions(-DORTHANC_ENABLE_ZLIB=1)
-
-  list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
-    ${ORTHANC_ROOT}/Core/Compression/DeflateBaseCompressor.cpp
-    ${ORTHANC_ROOT}/Core/Compression/HierarchicalZipWriter.cpp
-    ${ORTHANC_ROOT}/Core/Compression/GzipCompressor.cpp
-    ${ORTHANC_ROOT}/Core/Compression/ZipWriter.cpp
-    ${ORTHANC_ROOT}/Core/Compression/ZlibCompressor.cpp
-    )
-endif()
-
-
-##
-## PNG support: libpng (in conjunction with zlib)
-##
-
-if (ENABLE_PNG)
-  if (NOT ENABLE_ZLIB)
-    message(FATAL_ERROR "Support for zlib must be enabled if enabling libpng support")
-  endif()
-
-  include(${CMAKE_CURRENT_LIST_DIR}/LibPngConfiguration.cmake)
-  add_definitions(-DORTHANC_ENABLE_PNG=1)
-
-  list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
-    ${ORTHANC_ROOT}/Core/Images/PngReader.cpp
-    ${ORTHANC_ROOT}/Core/Images/PngWriter.cpp
-    )
-endif()
-
-
-##
-## Lua support
-##
-
-if (ENABLE_LUA)
-  include(${CMAKE_CURRENT_LIST_DIR}/LuaConfiguration.cmake)
-  add_definitions(-DORTHANC_ENABLE_LUA=1)
-
-  list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
-    ${ORTHANC_ROOT}/Core/Lua/LuaContext.cpp
-    ${ORTHANC_ROOT}/Core/Lua/LuaFunctionCall.cpp
-    )
-endif()
-
-
-##
-## XML support: pugixml
-##
-
-if (ENABLE_PUGIXML)
-  include(${CMAKE_CURRENT_LIST_DIR}/PugixmlConfiguration.cmake)
-  add_definitions(-DORTHANC_ENABLE_PUGIXML=1)
-endif()
-
-
-##
-## Locale support: libiconv
-##
-
-if (ENABLE_LOCALE)
-  if (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
-    # In WebAssembly or asm.js, we rely on the version of iconv that
-    # is shipped with the stdlib
-    unset(USE_BOOST_ICONV CACHE)
-  else()
-    include(${CMAKE_CURRENT_LIST_DIR}/LibIconvConfiguration.cmake)
-  endif()
-  
-  add_definitions(-DORTHANC_ENABLE_LOCALE=1)
-endif()
-
-
-##
-## Google Test for unit testing
-##
-
-if (ENABLE_GOOGLE_TEST)
-  include(${CMAKE_CURRENT_LIST_DIR}/GoogleTestConfiguration.cmake)
-endif()
-
-
-
-#####################################################################
-## Inclusion of mandatory third-party dependencies
-#####################################################################
-
-include(${CMAKE_CURRENT_LIST_DIR}/JsonCppConfiguration.cmake)
-include(${CMAKE_CURRENT_LIST_DIR}/UuidConfiguration.cmake)
-
-# We put Boost as the last dependency, as it is the heaviest to
-# configure, which allows to quickly spot problems when configuring
-# static builds in other dependencies
-include(${CMAKE_CURRENT_LIST_DIR}/BoostConfiguration.cmake)
-
-
-#####################################################################
-## Optional configuration of DCMTK
-#####################################################################
-
-if (ENABLE_DCMTK)
-  if (NOT ENABLE_LOCALE)
-    message(FATAL_ERROR "Support for locales must be enabled if enabling DICOM support")
-  endif()
-
-  include(${CMAKE_CURRENT_LIST_DIR}/DcmtkConfiguration.cmake)
-
-  add_definitions(-DORTHANC_ENABLE_DCMTK=1)
-
-  if (ENABLE_DCMTK_JPEG)
-    add_definitions(-DORTHANC_ENABLE_DCMTK_JPEG=1)
-  else()
-    add_definitions(-DORTHANC_ENABLE_DCMTK_JPEG=0)
-  endif()
-
-  if (ENABLE_DCMTK_JPEG_LOSSLESS)
-    add_definitions(-DORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS=1)
-  else()
-    add_definitions(-DORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS=0)
-  endif()
-
-  set(ORTHANC_DICOM_SOURCES_INTERNAL
-    ${ORTHANC_ROOT}/Core/DicomParsing/DicomModification.cpp
-    ${ORTHANC_ROOT}/Core/DicomParsing/FromDcmtkBridge.cpp
-    ${ORTHANC_ROOT}/Core/DicomParsing/ParsedDicomFile.cpp
-    ${ORTHANC_ROOT}/Core/DicomParsing/ToDcmtkBridge.cpp
-
-    ${ORTHANC_ROOT}/Core/DicomParsing/Internals/DicomFrameIndex.cpp
-    ${ORTHANC_ROOT}/Core/DicomParsing/Internals/DicomImageDecoder.cpp
-    )
-
-  if (NOT ORTHANC_SANDBOXED)
-    list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
-      ${ORTHANC_ROOT}/Core/DicomParsing/DicomDirWriter.cpp
-      )
-  endif()
-
-  if (ENABLE_DCMTK_NETWORKING)
-    add_definitions(-DORTHANC_ENABLE_DCMTK_NETWORKING=1)
-    list(APPEND ORTHANC_DICOM_SOURCES_INTERNAL
-      ${ORTHANC_ROOT}/Core/DicomNetworking/DicomFindAnswers.cpp
-      ${ORTHANC_ROOT}/Core/DicomNetworking/DicomServer.cpp
-      ${ORTHANC_ROOT}/Core/DicomNetworking/DicomUserConnection.cpp
-      ${ORTHANC_ROOT}/Core/DicomNetworking/RemoteModalityParameters.cpp
-      ${ORTHANC_ROOT}/Core/DicomNetworking/ReusableDicomUserConnection.cpp
-
-      ${ORTHANC_ROOT}/Core/DicomNetworking/Internals/CommandDispatcher.cpp
-      ${ORTHANC_ROOT}/Core/DicomNetworking/Internals/FindScp.cpp
-      ${ORTHANC_ROOT}/Core/DicomNetworking/Internals/MoveScp.cpp
-      ${ORTHANC_ROOT}/Core/DicomNetworking/Internals/StoreScp.cpp
-      )
-  else()
-    add_definitions(-DORTHANC_ENABLE_DCMTK_NETWORKING=0)
-  endif()
-
-  if (STANDALONE_BUILD AND NOT HAS_EMBEDDED_RESOURCES)
-    EmbedResources(
-      ${DCMTK_DICTIONARIES}
-      )
-    list(APPEND ORTHANC_DICOM_SOURCES_DEPENDENCIES
-      ${AUTOGENERATED_SOURCES}
-      )
-  endif()
-endif()
-
-
-#####################################################################
-## Configuration of the C/C++ macros
-#####################################################################
-
-add_definitions(
-  -DORTHANC_API_VERSION="${ORTHANC_API_VERSION}"
-  -DORTHANC_DATABASE_VERSION=${ORTHANC_DATABASE_VERSION}
-  -DORTHANC_DEFAULT_DICOM_ENCODING=Encoding_Latin1
-  -DORTHANC_ENABLE_BASE64=1
-  -DORTHANC_ENABLE_MD5=1
-  -DORTHANC_MAXIMUM_TAG_LENGTH=256
-  -DORTHANC_VERSION="${ORTHANC_VERSION}"
-  )
-
-
-if (ORTHANC_SANDBOXED)
-  add_definitions(
-    -DORTHANC_SANDBOXED=1
-    -DORTHANC_ENABLE_LOGGING_PLUGIN=0
-    )
-
-  if (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
-    add_definitions(
-      -DORTHANC_ENABLE_LOGGING=1
-      -DORTHANC_ENABLE_LOGGING_STDIO=1
-      )
-  else()
-    add_definitions(
-      -DORTHANC_ENABLE_LOGGING=0
-      )
-  endif()
-  
-else()
-  add_definitions(
-    -DORTHANC_SANDBOXED=0
-    -DORTHANC_ENABLE_LOGGING=1
-    -DORTHANC_ENABLE_LOGGING_PLUGIN=0
-    -DORTHANC_ENABLE_LOGGING_STDIO=0
-    )
-  
-  list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
-    ${ORTHANC_ROOT}/Core/Cache/SharedArchive.cpp
-    ${ORTHANC_ROOT}/Core/FileStorage/FilesystemStorage.cpp
-    ${ORTHANC_ROOT}/Core/FileStorage/StorageAccessor.cpp
-    ${ORTHANC_ROOT}/Core/MultiThreading/BagOfTasksProcessor.cpp
-    ${ORTHANC_ROOT}/Core/MultiThreading/Mutex.cpp
-    ${ORTHANC_ROOT}/Core/MultiThreading/ReaderWriterLock.cpp
-    ${ORTHANC_ROOT}/Core/MultiThreading/RunnableWorkersPool.cpp
-    ${ORTHANC_ROOT}/Core/MultiThreading/Semaphore.cpp
-    ${ORTHANC_ROOT}/Core/MultiThreading/SharedMessageQueue.cpp
-    ${ORTHANC_ROOT}/Core/SharedLibrary.cpp
-    ${ORTHANC_ROOT}/Core/SystemToolbox.cpp
-    ${ORTHANC_ROOT}/Core/TemporaryFile.cpp
-    )
-endif()
-
-
-if (HAS_EMBEDDED_RESOURCES)
-  add_definitions(-DORTHANC_HAS_EMBEDDED_RESOURCES=1)
-
-  list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
-    ${ORTHANC_ROOT}/Core/HttpServer/EmbeddedResourceHttpHandler.cpp
-    )
-else()
-  add_definitions(-DORTHANC_HAS_EMBEDDED_RESOURCES=0)
-endif()
-
-
-#####################################################################
-## Gathering of all the source code
-#####################################################################
-
-# The "xxx_INTERNAL" variables list the source code that belongs to
-# the Orthanc project. It can be used to configure precompiled headers
-# if using Microsoft Visual Studio.
-
-# The "xxx_DEPENDENCIES" variables list the source code coming from
-# third-party dependencies.
-
-
-set(ORTHANC_CORE_SOURCES_DEPENDENCIES
-  ${BOOST_SOURCES}
-  ${CIVETWEB_SOURCES}
-  ${CURL_SOURCES}
-  ${JSONCPP_SOURCES}
-  ${LIBICONV_SOURCES}
-  ${LIBJPEG_SOURCES}
-  ${LIBP11_SOURCES}
-  ${LIBPNG_SOURCES}
-  ${LUA_SOURCES}
-  ${MONGOOSE_SOURCES}
-  ${OPENSSL_SOURCES}
-  ${PUGIXML_SOURCES}
-  ${SQLITE_SOURCES}
-  ${UUID_SOURCES}
-  ${ZLIB_SOURCES}
-
-  ${ORTHANC_ROOT}/Resources/ThirdParty/md5/md5.c
-  ${ORTHANC_ROOT}/Resources/ThirdParty/base64/base64.cpp
-  )  
-
-
-if (ENABLE_ZLIB)
-  list(APPEND ORTHANC_CORE_SOURCES_DEPENDENCIES
-    # This is the minizip distribution to create ZIP files using zlib
-    ${ORTHANC_ROOT}/Resources/ThirdParty/minizip/ioapi.c
-    ${ORTHANC_ROOT}/Resources/ThirdParty/minizip/zip.c
-    )
-endif()
-
-
-set(ORTHANC_CORE_SOURCES
-  ${ORTHANC_CORE_SOURCES_INTERNAL}
-  ${ORTHANC_CORE_SOURCES_DEPENDENCIES}
-  )
-
-if (ENABLE_DCMTK)
-  list(APPEND ORTHANC_DICOM_SOURCES_DEPENDENCIES
-    ${DCMTK_SOURCES}
-    )
-  
-  set(ORTHANC_DICOM_SOURCES
-    ${ORTHANC_DICOM_SOURCES_INTERNAL}
-    ${ORTHANC_DICOM_SOURCES_DEPENDENCIES}
-    )
-endif()
--- a/Resources/Orthanc/Resources/CMake/OrthancFrameworkParameters.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-#####################################################################
-## Versioning information
-#####################################################################
-
-# Version of the build, should always be "mainline" except in release branches
-set(ORTHANC_VERSION "mainline")
-
-# Version of the database schema. History:
-#   * Orthanc 0.1.0 -> Orthanc 0.3.0 = no versioning
-#   * Orthanc 0.3.1                  = version 2
-#   * Orthanc 0.4.0 -> Orthanc 0.7.2 = version 3
-#   * Orthanc 0.7.3 -> Orthanc 0.8.4 = version 4
-#   * Orthanc 0.8.5 -> Orthanc 0.9.4 = version 5
-#   * Orthanc 0.9.5 -> mainline      = version 6
-set(ORTHANC_DATABASE_VERSION 6)
-
-# Version of the Orthanc API, can be retrieved from "/system" URI in
-# order to check whether new URI endpoints are available even if using
-# the mainline version of Orthanc
-set(ORTHANC_API_VERSION "1.0")
-
-
-#####################################################################
-## CMake parameters tunable by the user
-#####################################################################
-
-# Support of static compilation
-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(STANDALONE_BUILD ON CACHE BOOL "Standalone build (all the resources are embedded, necessary for releases)")
-
-# Generic parameters of the build
-set(ENABLE_CIVETWEB OFF CACHE BOOL "Use Civetweb instead of Mongoose (experimental)")
-set(ENABLE_PKCS11 OFF CACHE BOOL "Enable PKCS#11 for HTTPS client authentication using hardware security modules and smart cards")
-set(ENABLE_PROFILING OFF CACHE BOOL "Whether to enable the generation of profiling information with gprof")
-set(ENABLE_SSL ON CACHE BOOL "Include support for SSL")
-set(ENABLE_LUA_MODULES OFF CACHE BOOL "Enable support for loading external Lua modules (only meaningful if using static version of the Lua engine)")
-
-# Parameters to fine-tune linking against system libraries
-set(USE_SYSTEM_BOOST ON CACHE BOOL "Use the system version of Boost")
-set(USE_SYSTEM_CIVETWEB ON CACHE BOOL "Use the system version of Civetweb (experimental)")
-set(USE_SYSTEM_CURL ON CACHE BOOL "Use the system version of LibCurl")
-set(USE_SYSTEM_GOOGLE_TEST ON CACHE BOOL "Use the system version of Google Test")
-set(USE_SYSTEM_JSONCPP ON CACHE BOOL "Use the system version of JsonCpp")
-set(USE_SYSTEM_LIBICONV ON CACHE BOOL "Use the system version of libiconv")
-set(USE_SYSTEM_LIBJPEG ON CACHE BOOL "Use the system version of libjpeg")
-set(USE_SYSTEM_LIBP11 OFF CACHE BOOL "Use the system version of libp11 (PKCS#11 wrapper library)")
-set(USE_SYSTEM_LIBPNG ON CACHE BOOL "Use the system version of libpng")
-set(USE_SYSTEM_LUA ON CACHE BOOL "Use the system version of Lua")
-set(USE_SYSTEM_MONGOOSE ON CACHE BOOL "Use the system version of Mongoose")
-set(USE_SYSTEM_OPENSSL ON CACHE BOOL "Use the system version of OpenSSL")
-set(USE_SYSTEM_PUGIXML ON CACHE BOOL "Use the system version of Pugixml")
-set(USE_SYSTEM_SQLITE ON CACHE BOOL "Use the system version of SQLite")
-set(USE_SYSTEM_UUID ON CACHE BOOL "Use the system version of the uuid library from e2fsprogs")
-set(USE_SYSTEM_ZLIB ON CACHE BOOL "Use the system version of ZLib")
-
-# Parameters specific to DCMTK
-set(DCMTK_DICTIONARY_DIR "" CACHE PATH "Directory containing the DCMTK dictionaries \"dicom.dic\" and \"private.dic\" (only when using system version of DCMTK)") 
-set(USE_DCMTK_360 OFF CACHE BOOL "Use older DCMTK version 3.6.0 in static builds (instead of default 3.6.2)")
-set(USE_DCMTK_362_PRIVATE_DIC ON CACHE BOOL "Use the dictionary of private tags from DCMTK 3.6.2 if using DCMTK 3.6.0")
-set(USE_SYSTEM_DCMTK ON CACHE BOOL "Use the system version of DCMTK")
-set(ENABLE_DCMTK_JPEG ON CACHE BOOL "Enable JPEG-LS (Lossless) decompression")
-set(ENABLE_DCMTK_JPEG_LOSSLESS ON CACHE BOOL "Enable JPEG-LS (Lossless) decompression")
-
-# Advanced and distribution-specific parameters
-set(USE_GOOGLE_TEST_DEBIAN_PACKAGE OFF CACHE BOOL "Use the sources of Google Test shipped with libgtest-dev (Debian only)")
-set(SYSTEM_MONGOOSE_USE_CALLBACKS ON CACHE BOOL "The system version of Mongoose uses callbacks (version >= 3.7)")
-set(USE_BOOST_ICONV ON CACHE BOOL "Use iconv instead of wconv (Windows only)")
-set(USE_PUGIXML ON CACHE BOOL "Use the Pugixml parser (turn off only for debug)")
-set(USE_LEGACY_JSONCPP OFF CACHE BOOL "Use the old branch 0.x.y of JsonCpp, that does not require a C++11 compiler (for old versions of Visual Studio)")
-
-mark_as_advanced(USE_GOOGLE_TEST_DEBIAN_PACKAGE)
-mark_as_advanced(SYSTEM_MONGOOSE_USE_CALLBACKS)
-mark_as_advanced(USE_BOOST_ICONV)
-mark_as_advanced(USE_PUGIXML)
-mark_as_advanced(USE_LEGACY_JSONCPP)
-
-
-#####################################################################
-## Internal CMake parameters to enable the optional subcomponents of
-## the Orthanc framework
-#####################################################################
-
-# These options must be set to "ON" if compiling Orthanc, but might be
-# set to "OFF" by third-party projects if their associated features
-# are not required
-
-set(ENABLE_CRYPTO_OPTIONS OFF CACHE INTERNAL "Show options related to cryptography")
-set(ENABLE_JPEG OFF CACHE INTERNAL "Enable support of JPEG")
-set(ENABLE_GOOGLE_TEST OFF CACHE INTERNAL "Enable support of Google Test")
-set(ENABLE_LOCALE OFF CACHE INTERNAL "Enable support for locales (notably in Boost)")
-set(ENABLE_LUA OFF CACHE INTERNAL "Enable support of Lua scripting")
-set(ENABLE_PNG OFF CACHE INTERNAL "Enable support of PNG")
-set(ENABLE_PUGIXML OFF CACHE INTERNAL "Enable support of XML through Pugixml")
-set(ENABLE_SQLITE OFF CACHE INTERNAL "Enable support of SQLite databases")
-set(ENABLE_ZLIB OFF CACHE INTERNAL "Enable support of zlib")
-set(ENABLE_WEB_CLIENT OFF CACHE INTERNAL "Enable Web client")
-set(ENABLE_WEB_SERVER OFF CACHE INTERNAL "Enable embedded Web server")
-set(ENABLE_DCMTK OFF CACHE INTERNAL "Enable DCMTK")
-set(ENABLE_DCMTK_NETWORKING OFF CACHE INTERNAL "Enable DICOM networking in DCMTK")
-
-set(HAS_EMBEDDED_RESOURCES OFF CACHE INTERNAL
-  "Whether resources are auto-generated using EmbedResources.py")
-
-set(ORTHANC_SANDBOXED OFF CACHE INTERNAL
-  "Whether Orthanc runs inside a sandboxed environment (such as Google NaCl or WebAssembly)")
--- a/Resources/Orthanc/Resources/CMake/UuidConfiguration.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
-
-  if (STATIC_BUILD OR NOT USE_SYSTEM_UUID)
-    SET(E2FSPROGS_SOURCES_DIR ${CMAKE_BINARY_DIR}/e2fsprogs-1.43.8)
-    SET(E2FSPROGS_URL "http://www.orthanc-server.com/downloads/third-party/e2fsprogs-1.43.8.tar.gz")
-    SET(E2FSPROGS_MD5 "670b7a74a8ead5333acf21b9afc92b3c")
-
-    DownloadPackage(${E2FSPROGS_MD5} ${E2FSPROGS_URL} "${E2FSPROGS_SOURCES_DIR}")
-
-    include_directories(
-      ${E2FSPROGS_SOURCES_DIR}/lib
-      )
-
-    set(UUID_SOURCES
-      #${E2FSPROGS_SOURCES_DIR}/lib/uuid/tst_uuid.c
-      #${E2FSPROGS_SOURCES_DIR}/lib/uuid/uuid_time.c
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/clear.c
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/compare.c
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/copy.c
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/gen_uuid.c
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/isnull.c
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/pack.c
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/parse.c
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/unpack.c
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/unparse.c
-      )
-
-    check_include_file("net/if.h"       HAVE_NET_IF_H)
-    check_include_file("net/if_dl.h"    HAVE_NET_IF_DL_H)
-    check_include_file("netinet/in.h"   HAVE_NETINET_IN_H)
-    check_include_file("stdlib.h"       HAVE_STDLIB_H)
-    check_include_file("sys/file.h"     HAVE_SYS_FILE_H)
-    check_include_file("sys/ioctl.h"    HAVE_SYS_IOCTL_H)
-    check_include_file("sys/resource.h" HAVE_SYS_RESOURCE_H)
-    check_include_file("sys/socket.h"   HAVE_SYS_SOCKET_H)
-    check_include_file("sys/sockio.h"   HAVE_SYS_SOCKIO_H)
-    check_include_file("sys/syscall.h"  HAVE_SYS_SYSCALL_H)
-    check_include_file("sys/time.h"     HAVE_SYS_TIME_H)
-    check_include_file("sys/un.h"       HAVE_SYS_UN_H)
-    check_include_file("unistd.h"       HAVE_UNISTD_H)
-
-    if (NOT HAVE_NET_IF_H)  # This is the case of OpenBSD
-      unset(HAVE_NET_IF_H CACHE)
-      check_include_files("sys/socket.h;net/if.h" HAVE_NET_IF_H)
-    endif()
-
-    if (NOT HAVE_NETINET_TCP_H)  # This is the case of OpenBSD
-      unset(HAVE_NETINET_TCP_H CACHE)
-      check_include_files("sys/socket.h;netinet/tcp.h" HAVE_NETINET_TCP_H)
-    endif()
-
-    if (NOT EXISTS ${E2FSPROGS_SOURCES_DIR}/lib/uuid/config.h)
-      file(WRITE ${E2FSPROGS_SOURCES_DIR}/lib/uuid/config.h.cmake "
-#cmakedefine HAVE_NET_IF_H \@HAVE_NET_IF_H\@
-#cmakedefine HAVE_NET_IF_DL_H \@HAVE_NET_IF_DL_H\@
-#cmakedefine HAVE_NETINET_IN_H \@HAVE_NETINET_IN_H\@
-#cmakedefine HAVE_STDLIB_H \@HAVE_STDLIB_H \@
-#cmakedefine HAVE_SYS_FILE_H \@HAVE_SYS_FILE_H\@
-#cmakedefine HAVE_SYS_IOCTL_H \@HAVE_SYS_IOCTL_H\@
-#cmakedefine HAVE_SYS_RESOURCE_H \@HAVE_SYS_RESOURCE_H\@
-#cmakedefine HAVE_SYS_SOCKET_H \@HAVE_SYS_SOCKET_H\@
-#cmakedefine HAVE_SYS_SOCKIO_H \@HAVE_SYS_SOCKIO_H\@
-#cmakedefine HAVE_SYS_SYSCALL_H \@HAVE_SYS_SYSCALL_H\@
-#cmakedefine HAVE_SYS_TIME_H \@HAVE_SYS_TIME_H\@
-#cmakedefine HAVE_SYS_UN_H \@HAVE_SYS_UN_H\@
-#cmakedefine HAVE_UNISTD_H \@HAVE_UNISTD_H\@
-")
-    endif()
-      
-    configure_file(
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/config.h.cmake
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/config.h
-      )
-      
-    configure_file(
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/uuid.h.in
-      ${E2FSPROGS_SOURCES_DIR}/lib/uuid/uuid.h
-      )
-
-    if (NOT EXISTS ${E2FSPROGS_SOURCES_DIR}/lib/uuid/uuid_types.h)
-      file(WRITE
-        ${E2FSPROGS_SOURCES_DIR}/lib/uuid/uuid_types.h
-        "#include <stdint.h>\n")
-    endif()
-    
-    source_group(ThirdParty\\uuid REGULAR_EXPRESSION ${E2FSPROGS_SOURCES_DIR}/.*)
-
-  else()
-    CHECK_INCLUDE_FILE(uuid/uuid.h HAVE_UUID_H)
-    if (NOT HAVE_UUID_H)
-      message(FATAL_ERROR "Please install uuid-dev, e2fsprogs (OpenBSD) or e2fsprogs-libuuid (FreeBSD)")
-    endif()
-
-    check_library_exists(uuid uuid_generate_random "" HAVE_UUID_LIB)
-    if (NOT HAVE_UUID_LIB)
-      message(FATAL_ERROR "Unable to find the uuid library")
-    endif()
-    
-    link_libraries(uuid)
-  endif()
-
-endif()
--- a/Resources/Orthanc/Resources/CMake/ZlibConfiguration.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-if (STATIC_BUILD OR NOT USE_SYSTEM_ZLIB)
-  SET(ZLIB_SOURCES_DIR ${CMAKE_BINARY_DIR}/zlib-1.2.11)
-  SET(ZLIB_URL "http://www.orthanc-server.com/downloads/third-party/zlib-1.2.11.tar.gz")
-  SET(ZLIB_MD5 "1c9f62f0778697a09d36121ead88e08e")
-
-  DownloadPackage(${ZLIB_MD5} ${ZLIB_URL} "${ZLIB_SOURCES_DIR}")
-
-  include_directories(
-    ${ZLIB_SOURCES_DIR}
-    )
-
-  list(APPEND ZLIB_SOURCES 
-    ${ZLIB_SOURCES_DIR}/adler32.c
-    ${ZLIB_SOURCES_DIR}/compress.c
-    ${ZLIB_SOURCES_DIR}/crc32.c 
-    ${ZLIB_SOURCES_DIR}/deflate.c 
-    ${ZLIB_SOURCES_DIR}/gzclose.c 
-    ${ZLIB_SOURCES_DIR}/gzlib.c 
-    ${ZLIB_SOURCES_DIR}/gzread.c 
-    ${ZLIB_SOURCES_DIR}/gzwrite.c 
-    ${ZLIB_SOURCES_DIR}/infback.c 
-    ${ZLIB_SOURCES_DIR}/inffast.c 
-    ${ZLIB_SOURCES_DIR}/inflate.c 
-    ${ZLIB_SOURCES_DIR}/inftrees.c 
-    ${ZLIB_SOURCES_DIR}/trees.c 
-    ${ZLIB_SOURCES_DIR}/uncompr.c 
-    ${ZLIB_SOURCES_DIR}/zutil.c
-    )
-
-  source_group(ThirdParty\\zlib REGULAR_EXPRESSION ${ZLIB_SOURCES_DIR}/.*)
-
-  if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
-    # "ioapi.c" from zlib (minizip) expects the "IOAPI_NO_64" macro to be set to "true"
-    # https://ohse.de/uwe/articles/lfs.html
-    add_definitions(
-      -DIOAPI_NO_64=1
-      )
-  endif()
-
-else()
-  include(FindZLIB)
-  include_directories(${ZLIB_INCLUDE_DIRS})
-  link_libraries(${ZLIB_LIBRARIES})
-endif()
--- a/Resources/Orthanc/Resources/EmbedResources.py	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,431 +0,0 @@
-#!/usr/bin/python
-
-# Orthanc - A Lightweight, RESTful DICOM Store
-# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
-# Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2018 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.
-#
-# 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/>.
-
-
-import sys
-import os
-import os.path
-import pprint
-import re
-
-UPCASE_CHECK = True
-USE_SYSTEM_EXCEPTION = False
-EXCEPTION_CLASS = 'OrthancException'
-OUT_OF_RANGE_EXCEPTION = 'OrthancException(ErrorCode_ParameterOutOfRange)'
-INEXISTENT_PATH_EXCEPTION = 'OrthancException(ErrorCode_InexistentItem)'
-NAMESPACE = 'Orthanc'
-
-ARGS = []
-for i in range(len(sys.argv)):
-    if not sys.argv[i].startswith('--'):
-        ARGS.append(sys.argv[i])
-    elif sys.argv[i].lower() == '--no-upcase-check':
-        UPCASE_CHECK = False
-    elif sys.argv[i].lower() == '--system-exception':
-        USE_SYSTEM_EXCEPTION = True
-        EXCEPTION_CLASS = '::std::runtime_error'
-        OUT_OF_RANGE_EXCEPTION = '%s("Parameter out of range")' % EXCEPTION_CLASS
-        INEXISTENT_PATH_EXCEPTION = '%s("Unknown path in a directory resource")' % EXCEPTION_CLASS
-    elif sys.argv[i].startswith('--namespace='):
-        NAMESPACE = sys.argv[i][sys.argv[i].find('=') + 1 : ]
-
-if len(ARGS) < 2 or len(ARGS) % 2 != 0:
-    print ('Usage:')
-    print ('python %s [--no-upcase-check] [--system-exception] [--namespace=<Namespace>] <TargetBaseFilename> [ <Name> <Source> ]*' % sys.argv[0])
-    exit(-1)
-
-TARGET_BASE_FILENAME = ARGS[1]
-SOURCES = ARGS[2:]
-
-try:
-    # Make sure the destination directory exists
-    os.makedirs(os.path.normpath(os.path.join(TARGET_BASE_FILENAME, '..')))
-except:
-    pass
-
-
-#####################################################################
-## Read each resource file
-#####################################################################
-
-def CheckNoUpcase(s):
-    global UPCASE_CHECK
-    if (UPCASE_CHECK and
-        re.search('[A-Z]', s) != None):
-        raise Exception("Path in a directory with an upcase letter: %s" % s)
-
-resources = {}
-
-counter = 0
-i = 0
-while i < len(SOURCES):
-    resourceName = SOURCES[i].upper()
-    pathName = SOURCES[i + 1]
-
-    if not os.path.exists(pathName):
-        raise Exception("Non existing path: %s" % pathName)
-
-    if resourceName in resources:
-        raise Exception("Twice the same resource: " + resourceName)
-    
-    if os.path.isdir(pathName):
-        # The resource is a directory: Recursively explore its files
-        content = {}
-        for root, dirs, files in os.walk(pathName):
-            base = os.path.relpath(root, pathName)
-
-            # Fix issue #24 (Build fails on OSX when directory has .DS_Store files):
-            # Ignore folders whose name starts with a dot (".")
-            if base.find('/.') != -1:
-                print('Ignoring folder: %s' % root)
-                continue
-
-            for f in files:
-                if f.find('~') == -1:  # Ignore Emacs backup files
-                    if base == '.':
-                        r = f
-                    else:
-                        r = os.path.join(base, f)
-
-                    CheckNoUpcase(r)
-                    r = '/' + r.replace('\\', '/')
-                    if r in content:
-                        raise Exception("Twice the same filename (check case): " + r)
-
-                    content[r] = {
-                        'Filename' : os.path.join(root, f),
-                        'Index' : counter
-                        }
-                    counter += 1
-
-        resources[resourceName] = {
-            'Type' : 'Directory',
-            'Files' : content
-            }
-
-    elif os.path.isfile(pathName):
-        resources[resourceName] = {
-            'Type' : 'File',
-            'Index' : counter,
-            'Filename' : pathName
-            }
-        counter += 1
-
-    else:
-        raise Exception("Not a regular file, nor a directory: " + pathName)
-
-    i += 2
-
-#pprint.pprint(resources)
-
-
-#####################################################################
-## Write .h header
-#####################################################################
-
-header = open(TARGET_BASE_FILENAME + '.h', 'w')
-
-header.write("""
-#pragma once
-
-#include <string>
-#include <list>
-
-#if defined(_MSC_VER)
-#  pragma warning(disable: 4065)  // "Switch statement contains 'default' but no 'case' labels"
-#endif
-
-namespace %s
-{
-  namespace EmbeddedResources
-  {
-    enum FileResourceId
-    {
-""" % NAMESPACE)
-
-isFirst = True
-for name in resources:
-    if resources[name]['Type'] == 'File':
-        if isFirst:
-            isFirst = False
-        else:    
-            header.write(',\n')
-        header.write('      %s' % name)
-
-header.write("""
-    };
-
-    enum DirectoryResourceId
-    {
-""")
-
-isFirst = True
-for name in resources:
-    if resources[name]['Type'] == 'Directory':
-        if isFirst:
-            isFirst = False
-        else:    
-            header.write(',\n')
-        header.write('      %s' % name)
-
-header.write("""
-    };
-
-    const void* GetFileResourceBuffer(FileResourceId id);
-    size_t GetFileResourceSize(FileResourceId id);
-    void GetFileResource(std::string& result, FileResourceId id);
-
-    const void* GetDirectoryResourceBuffer(DirectoryResourceId id, const char* path);
-    size_t GetDirectoryResourceSize(DirectoryResourceId id, const char* path);
-    void GetDirectoryResource(std::string& result, DirectoryResourceId id, const char* path);
-
-    void ListResources(std::list<std::string>& result, DirectoryResourceId id);
-  }
-}
-""")
-header.close()
-
-
-
-#####################################################################
-## Write the resource content in the .cpp source
-#####################################################################
-
-PYTHON_MAJOR_VERSION = sys.version_info[0]
-
-def WriteResource(cpp, item):
-    cpp.write('    static const uint8_t resource%dBuffer[] = {' % item['Index'])
-
-    f = open(item['Filename'], "rb")
-    content = f.read()
-    f.close()
-
-    # http://stackoverflow.com/a/1035360
-    pos = 0
-    for b in content:
-        if PYTHON_MAJOR_VERSION == 2:
-            c = ord(b[0])
-        else:
-            c = b
-
-        if pos > 0:
-            cpp.write(', ')
-
-        if (pos % 16) == 0:
-            cpp.write('\n    ')
-
-        if c < 0:
-            raise Exception("Internal error")
-
-        cpp.write("0x%02x" % c)
-        pos += 1
-
-    # Zero-size array are disallowed, so we put one single void character in it.
-    if pos == 0:
-        cpp.write('  0')
-
-    cpp.write('  };\n')
-    cpp.write('    static const size_t resource%dSize = %d;\n' % (item['Index'], pos))
-
-
-cpp = open(TARGET_BASE_FILENAME + '.cpp', 'w')
-
-cpp.write('#include "%s.h"\n' % os.path.basename(TARGET_BASE_FILENAME))
-
-if USE_SYSTEM_EXCEPTION:
-    cpp.write('#include <stdexcept>')
-else:
-    cpp.write('#include "%s/Core/OrthancException.h"' % os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
-
-cpp.write("""
-#include <stdint.h>
-#include <string.h>
-
-namespace %s
-{
-  namespace EmbeddedResources
-  {
-""" % NAMESPACE)
-
-
-for name in resources:
-    if resources[name]['Type'] == 'File':
-        WriteResource(cpp, resources[name])
-    else:
-        for f in resources[name]['Files']:
-            WriteResource(cpp, resources[name]['Files'][f])
-
-
-
-#####################################################################
-## Write the accessors to the file resources in .cpp
-#####################################################################
-
-cpp.write("""
-    const void* GetFileResourceBuffer(FileResourceId id)
-    {
-      switch (id)
-      {
-""")
-for name in resources:
-    if resources[name]['Type'] == 'File':
-        cpp.write('      case %s:\n' % name)
-        cpp.write('        return resource%dBuffer;\n' % resources[name]['Index'])
-
-cpp.write("""
-      default:
-        throw %s;
-      }
-    }
-
-    size_t GetFileResourceSize(FileResourceId id)
-    {
-      switch (id)
-      {
-""" % OUT_OF_RANGE_EXCEPTION)
-
-for name in resources:
-    if resources[name]['Type'] == 'File':
-        cpp.write('      case %s:\n' % name)
-        cpp.write('        return resource%dSize;\n' % resources[name]['Index'])
-
-cpp.write("""
-      default:
-        throw %s;
-      }
-    }
-""" % OUT_OF_RANGE_EXCEPTION)
-
-
-
-#####################################################################
-## Write the accessors to the directory resources in .cpp
-#####################################################################
-
-cpp.write("""
-    const void* GetDirectoryResourceBuffer(DirectoryResourceId id, const char* path)
-    {
-      switch (id)
-      {
-""")
-
-for name in resources:
-    if resources[name]['Type'] == 'Directory':
-        cpp.write('      case %s:\n' % name)
-        isFirst = True
-        for path in resources[name]['Files']:
-            cpp.write('        if (!strcmp(path, "%s"))\n' % path)
-            cpp.write('          return resource%dBuffer;\n' % resources[name]['Files'][path]['Index'])
-        cpp.write('        throw %s;\n\n' % INEXISTENT_PATH_EXCEPTION)
-
-cpp.write("""      default:
-        throw %s;
-      }
-    }
-
-    size_t GetDirectoryResourceSize(DirectoryResourceId id, const char* path)
-    {
-      switch (id)
-      {
-""" % OUT_OF_RANGE_EXCEPTION)
-
-for name in resources:
-    if resources[name]['Type'] == 'Directory':
-        cpp.write('      case %s:\n' % name)
-        isFirst = True
-        for path in resources[name]['Files']:
-            cpp.write('        if (!strcmp(path, "%s"))\n' % path)
-            cpp.write('          return resource%dSize;\n' % resources[name]['Files'][path]['Index'])
-        cpp.write('        throw %s;\n\n' % INEXISTENT_PATH_EXCEPTION)
-
-cpp.write("""      default:
-        throw %s;
-      }
-    }
-""" % OUT_OF_RANGE_EXCEPTION)
-
-
-
-
-#####################################################################
-## List the resources in a directory
-#####################################################################
-
-cpp.write("""
-    void ListResources(std::list<std::string>& result, DirectoryResourceId id)
-    {
-      result.clear();
-
-      switch (id)
-      {
-""")
-
-for name in resources:
-    if resources[name]['Type'] == 'Directory':
-        cpp.write('      case %s:\n' % name)
-        for path in sorted(resources[name]['Files']):
-            cpp.write('        result.push_back("%s");\n' % path)
-        cpp.write('        break;\n\n')
-
-cpp.write("""      default:
-        throw %s;
-      }
-    }
-""" % OUT_OF_RANGE_EXCEPTION)
-
-
-
-
-#####################################################################
-## Write the convenience wrappers in .cpp
-#####################################################################
-
-cpp.write("""
-    void GetFileResource(std::string& result, FileResourceId id)
-    {
-      size_t size = GetFileResourceSize(id);
-      result.resize(size);
-      if (size > 0)
-        memcpy(&result[0], GetFileResourceBuffer(id), size);
-    }
-
-    void GetDirectoryResource(std::string& result, DirectoryResourceId id, const char* path)
-    {
-      size_t size = GetDirectoryResourceSize(id, path);
-      result.resize(size);
-      if (size > 0)
-        memcpy(&result[0], GetDirectoryResourceBuffer(id, path), size);
-    }
-  }
-}
-""")
-cpp.close()
--- a/Resources/Orthanc/Resources/LinuxStandardBaseToolchain.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-# LSB_CC=gcc-4.8 LSB_CXX=g++-4.8 cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../Resources/LinuxStandardBaseToolchain.cmake -DUSE_LEGACY_JSONCPP=ON
-
-INCLUDE(CMakeForceCompiler)
-
-SET(LSB_PATH $ENV{LSB_PATH})
-SET(LSB_CC $ENV{LSB_CC})
-SET(LSB_CXX $ENV{LSB_CXX})
-SET(LSB_TARGET_VERSION "4.0")
-
-IF ("${LSB_PATH}" STREQUAL "")
-  SET(LSB_PATH "/opt/lsb")
-ENDIF()
-
-IF (EXISTS ${LSB_PATH}/lib64)
-  SET(LSB_TARGET_PROCESSOR "x86_64")
-  SET(LSB_LIBPATH ${LSB_PATH}/lib64-${LSB_TARGET_VERSION})
-ELSEIF (EXISTS ${LSB_PATH}/lib)
-  SET(LSB_TARGET_PROCESSOR "x86")
-  SET(LSB_LIBPATH ${LSB_PATH}/lib-${LSB_TARGET_VERSION})
-ELSE()
-  MESSAGE(FATAL_ERROR "Unable to detect the target processor architecture. Check the LSB_PATH environment variable.")
-ENDIF()
-
-SET(LSB_CPPPATH ${LSB_PATH}/include)
-SET(PKG_CONFIG_PATH ${LSB_LIBPATH}/pkgconfig/)
-
-# the name of the target operating system
-SET(CMAKE_SYSTEM_NAME Linux)
-SET(CMAKE_SYSTEM_VERSION LinuxStandardBase)
-SET(CMAKE_SYSTEM_PROCESSOR ${LSB_TARGET_PROCESSOR})
-
-# which compilers to use for C and C++
-SET(CMAKE_C_COMPILER ${LSB_PATH}/bin/lsbcc)
-CMAKE_FORCE_CXX_COMPILER(${LSB_PATH}/bin/lsbc++ GNU)
-
-# here is the target environment located
-SET(CMAKE_FIND_ROOT_PATH ${LSB_PATH})
-
-# adjust the default behaviour of the FIND_XXX() commands:
-# search headers and libraries in the target environment, search 
-# programs in the host environment
-SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER)
-SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER)
-
-SET(CMAKE_CROSSCOMPILING OFF)
-
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -I${LSB_PATH}/include" CACHE INTERNAL "" FORCE)
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -nostdinc++ -I${LSB_PATH}/include -I${LSB_PATH}/include/c++ -I${LSB_PATH}/include/c++/backward" CACHE INTERNAL "" FORCE)
-SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -L${LSB_LIBPATH} --lsb-besteffort" CACHE INTERNAL "" FORCE)
-SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -L${LSB_LIBPATH} --lsb-besteffort" CACHE INTERNAL "" FORCE)
-
-if (NOT "${LSB_CXX}" STREQUAL "")
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --lsb-cxx=${LSB_CXX}")
-  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --lsb-cxx=${LSB_CXX}")
-  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --lsb-cxx=${LSB_CXX}")
-endif()
-
-if (NOT "${LSB_CC}" STREQUAL "")
-  SET(CMAKE_C_FLAGS "${CMAKE_CC_FLAGS} --lsb-cc=${LSB_CC}")
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --lsb-cc=${LSB_CC}")
-  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --lsb-cc=${LSB_CC}")
-  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --lsb-cc=${LSB_CC}")
-endif()
-
--- a/Resources/Orthanc/Resources/MinGW-W64-Toolchain32.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Windows)
-
-# which compilers to use for C and C++
-set(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
-set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
-set(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
-
-# here is the target environment located
-set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
-
-# adjust the default behaviour of the FIND_XXX() commands:
-# search headers and libraries in the target environment, search 
-# programs in the host environment
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
--- a/Resources/Orthanc/Resources/MinGW-W64-Toolchain64.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Windows)
-
-# which compilers to use for C and C++
-set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
-set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
-set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
-
-# here is the target environment located
-set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
-
-# adjust the default behaviour of the FIND_XXX() commands:
-# search headers and libraries in the target environment, search 
-# programs in the host environment
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
--- a/Resources/Orthanc/Resources/MinGWToolchain.cmake	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Windows)
-
-# which compilers to use for C and C++
-set(CMAKE_C_COMPILER i586-mingw32msvc-gcc)
-set(CMAKE_CXX_COMPILER i586-mingw32msvc-g++)
-set(CMAKE_RC_COMPILER i586-mingw32msvc-windres)
-
-# here is the target environment located
-set(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc)
-
-# adjust the default behaviour of the FIND_XXX() commands:
-# search headers and libraries in the target environment, search 
-# programs in the host environment
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
--- a/Resources/Orthanc/Resources/Patches/boost-1.66.0-linux-standard-base.patch	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-diff -urEb boost_1_66_0.orig/boost/move/adl_move_swap.hpp boost_1_66_0/boost/move/adl_move_swap.hpp
---- boost_1_66_0.orig/boost/move/adl_move_swap.hpp	2018-04-11 11:56:16.761768726 +0200
-+++ boost_1_66_0/boost/move/adl_move_swap.hpp	2018-04-11 11:57:01.073881330 +0200
-@@ -28,6 +28,8 @@
- //Try to avoid including <algorithm>, as it's quite big
- #if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB)
-    #include <utility>   //Dinkum libraries define std::swap in utility which is lighter than algorithm
-+#elif defined(__LSB_VERSION__)
-+#  include <utility>
- #elif defined(BOOST_GNU_STDLIB)
-    //For non-GCC compilers, where GNUC version is not very reliable, or old GCC versions
-    //use the good old stl_algobase header, which is quite lightweight
-Only in boost_1_66_0/boost/move: adl_move_swap.hpp~
--- a/Resources/Orthanc/Resources/Patches/curl-7.57.0-cmake.patch	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-diff -urEb curl-7.57.0.orig/CMake/Macros.cmake curl-7.57.0/CMake/Macros.cmake
---- curl-7.57.0.orig/CMake/Macros.cmake	2017-11-09 23:40:36.000000000 +0100
-+++ curl-7.57.0/CMake/Macros.cmake	2018-01-03 10:39:15.589520034 +0100
-@@ -38,7 +38,7 @@
-     message(STATUS "Performing Curl Test ${CURL_TEST}")
-     try_compile(${CURL_TEST}
-       ${CMAKE_BINARY_DIR}
--      ${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
-+      ${CURL_SOURCES_DIR}/CMake/CurlTests.c
-       CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
-       "${CURL_TEST_ADD_LIBRARIES}"
-       OUTPUT_VARIABLE OUTPUT)
--- a/Resources/Orthanc/Resources/Patches/dcmtk-3.6.2-linux-standard-base.patch	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-diff -urEb dcmtk-3.6.2.orig/ofstd/include/dcmtk/ofstd/offile.h dcmtk-3.6.2/ofstd/include/dcmtk/ofstd/offile.h
---- dcmtk-3.6.2.orig/ofstd/include/dcmtk/ofstd/offile.h	2017-07-14 17:41:11.000000000 +0200
-+++ dcmtk-3.6.2/ofstd/include/dcmtk/ofstd/offile.h	2018-01-02 13:56:04.075293459 +0100
-@@ -551,7 +551,7 @@
-    */
-   void setlinebuf()
-   {
--#if defined(_WIN32) || defined(__hpux)
-+#if defined(_WIN32) || defined(__hpux) || defined(__LSB_VERSION__)
-     this->setvbuf(NULL, _IOLBF, 0);
- #else
-     :: setlinebuf(file_);
--- a/Resources/Orthanc/Resources/ThirdParty/VisualStudio/stdint.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +0,0 @@
-// ISO C9x  compliant stdint.h for Microsoft Visual Studio
-// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
-// 
-//  Copyright (c) 2006-2013 Alexander Chemeris
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 
-//   1. Redistributions of source code must retain the above copyright notice,
-//      this list of conditions and the following disclaimer.
-// 
-//   2. Redistributions in binary form must reproduce the above copyright
-//      notice, this list of conditions and the following disclaimer in the
-//      documentation and/or other materials provided with the distribution.
-// 
-//   3. Neither the name of the product nor the names of its contributors may
-//      be used to endorse or promote products derived from this software
-//      without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef _MSC_VER // [
-#error "Use this header only with Microsoft Visual C++ compilers!"
-#endif // _MSC_VER ]
-
-#ifndef _MSC_STDINT_H_ // [
-#define _MSC_STDINT_H_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#if _MSC_VER >= 1600 // [
-#include <stdint.h>
-#else // ] _MSC_VER >= 1600 [
-
-#include <limits.h>
-
-// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
-// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
-// or compiler give many errors like this:
-//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
-#ifdef __cplusplus
-extern "C" {
-#endif
-#  include <wchar.h>
-#ifdef __cplusplus
-}
-#endif
-
-// Define _W64 macros to mark types changing their size, like intptr_t.
-#ifndef _W64
-#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
-#     define _W64 __w64
-#  else
-#     define _W64
-#  endif
-#endif
-
-
-// 7.18.1 Integer types
-
-// 7.18.1.1 Exact-width integer types
-
-// Visual Studio 6 and Embedded Visual C++ 4 doesn't
-// realize that, e.g. char has the same size as __int8
-// so we give up on __intX for them.
-#if (_MSC_VER < 1300)
-   typedef signed char       int8_t;
-   typedef signed short      int16_t;
-   typedef signed int        int32_t;
-   typedef unsigned char     uint8_t;
-   typedef unsigned short    uint16_t;
-   typedef unsigned int      uint32_t;
-#else
-   typedef signed __int8     int8_t;
-   typedef signed __int16    int16_t;
-   typedef signed __int32    int32_t;
-   typedef unsigned __int8   uint8_t;
-   typedef unsigned __int16  uint16_t;
-   typedef unsigned __int32  uint32_t;
-#endif
-typedef signed __int64       int64_t;
-typedef unsigned __int64     uint64_t;
-
-
-// 7.18.1.2 Minimum-width integer types
-typedef int8_t    int_least8_t;
-typedef int16_t   int_least16_t;
-typedef int32_t   int_least32_t;
-typedef int64_t   int_least64_t;
-typedef uint8_t   uint_least8_t;
-typedef uint16_t  uint_least16_t;
-typedef uint32_t  uint_least32_t;
-typedef uint64_t  uint_least64_t;
-
-// 7.18.1.3 Fastest minimum-width integer types
-typedef int8_t    int_fast8_t;
-typedef int16_t   int_fast16_t;
-typedef int32_t   int_fast32_t;
-typedef int64_t   int_fast64_t;
-typedef uint8_t   uint_fast8_t;
-typedef uint16_t  uint_fast16_t;
-typedef uint32_t  uint_fast32_t;
-typedef uint64_t  uint_fast64_t;
-
-// 7.18.1.4 Integer types capable of holding object pointers
-#ifdef _WIN64 // [
-   typedef signed __int64    intptr_t;
-   typedef unsigned __int64  uintptr_t;
-#else // _WIN64 ][
-   typedef _W64 signed int   intptr_t;
-   typedef _W64 unsigned int uintptr_t;
-#endif // _WIN64 ]
-
-// 7.18.1.5 Greatest-width integer types
-typedef int64_t   intmax_t;
-typedef uint64_t  uintmax_t;
-
-
-// 7.18.2 Limits of specified-width integer types
-
-#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
-
-// 7.18.2.1 Limits of exact-width integer types
-#define INT8_MIN     ((int8_t)_I8_MIN)
-#define INT8_MAX     _I8_MAX
-#define INT16_MIN    ((int16_t)_I16_MIN)
-#define INT16_MAX    _I16_MAX
-#define INT32_MIN    ((int32_t)_I32_MIN)
-#define INT32_MAX    _I32_MAX
-#define INT64_MIN    ((int64_t)_I64_MIN)
-#define INT64_MAX    _I64_MAX
-#define UINT8_MAX    _UI8_MAX
-#define UINT16_MAX   _UI16_MAX
-#define UINT32_MAX   _UI32_MAX
-#define UINT64_MAX   _UI64_MAX
-
-// 7.18.2.2 Limits of minimum-width integer types
-#define INT_LEAST8_MIN    INT8_MIN
-#define INT_LEAST8_MAX    INT8_MAX
-#define INT_LEAST16_MIN   INT16_MIN
-#define INT_LEAST16_MAX   INT16_MAX
-#define INT_LEAST32_MIN   INT32_MIN
-#define INT_LEAST32_MAX   INT32_MAX
-#define INT_LEAST64_MIN   INT64_MIN
-#define INT_LEAST64_MAX   INT64_MAX
-#define UINT_LEAST8_MAX   UINT8_MAX
-#define UINT_LEAST16_MAX  UINT16_MAX
-#define UINT_LEAST32_MAX  UINT32_MAX
-#define UINT_LEAST64_MAX  UINT64_MAX
-
-// 7.18.2.3 Limits of fastest minimum-width integer types
-#define INT_FAST8_MIN    INT8_MIN
-#define INT_FAST8_MAX    INT8_MAX
-#define INT_FAST16_MIN   INT16_MIN
-#define INT_FAST16_MAX   INT16_MAX
-#define INT_FAST32_MIN   INT32_MIN
-#define INT_FAST32_MAX   INT32_MAX
-#define INT_FAST64_MIN   INT64_MIN
-#define INT_FAST64_MAX   INT64_MAX
-#define UINT_FAST8_MAX   UINT8_MAX
-#define UINT_FAST16_MAX  UINT16_MAX
-#define UINT_FAST32_MAX  UINT32_MAX
-#define UINT_FAST64_MAX  UINT64_MAX
-
-// 7.18.2.4 Limits of integer types capable of holding object pointers
-#ifdef _WIN64 // [
-#  define INTPTR_MIN   INT64_MIN
-#  define INTPTR_MAX   INT64_MAX
-#  define UINTPTR_MAX  UINT64_MAX
-#else // _WIN64 ][
-#  define INTPTR_MIN   INT32_MIN
-#  define INTPTR_MAX   INT32_MAX
-#  define UINTPTR_MAX  UINT32_MAX
-#endif // _WIN64 ]
-
-// 7.18.2.5 Limits of greatest-width integer types
-#define INTMAX_MIN   INT64_MIN
-#define INTMAX_MAX   INT64_MAX
-#define UINTMAX_MAX  UINT64_MAX
-
-// 7.18.3 Limits of other integer types
-
-#ifdef _WIN64 // [
-#  define PTRDIFF_MIN  _I64_MIN
-#  define PTRDIFF_MAX  _I64_MAX
-#else  // _WIN64 ][
-#  define PTRDIFF_MIN  _I32_MIN
-#  define PTRDIFF_MAX  _I32_MAX
-#endif  // _WIN64 ]
-
-#define SIG_ATOMIC_MIN  INT_MIN
-#define SIG_ATOMIC_MAX  INT_MAX
-
-#ifndef SIZE_MAX // [
-#  ifdef _WIN64 // [
-#     define SIZE_MAX  _UI64_MAX
-#  else // _WIN64 ][
-#     define SIZE_MAX  _UI32_MAX
-#  endif // _WIN64 ]
-#endif // SIZE_MAX ]
-
-// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
-#ifndef WCHAR_MIN // [
-#  define WCHAR_MIN  0
-#endif  // WCHAR_MIN ]
-#ifndef WCHAR_MAX // [
-#  define WCHAR_MAX  _UI16_MAX
-#endif  // WCHAR_MAX ]
-
-#define WINT_MIN  0
-#define WINT_MAX  _UI16_MAX
-
-#endif // __STDC_LIMIT_MACROS ]
-
-
-// 7.18.4 Limits of other integer types
-
-#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
-
-// 7.18.4.1 Macros for minimum-width integer constants
-
-#define INT8_C(val)  val##i8
-#define INT16_C(val) val##i16
-#define INT32_C(val) val##i32
-#define INT64_C(val) val##i64
-
-#define UINT8_C(val)  val##ui8
-#define UINT16_C(val) val##ui16
-#define UINT32_C(val) val##ui32
-#define UINT64_C(val) val##ui64
-
-// 7.18.4.2 Macros for greatest-width integer constants
-// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
-// Check out Issue 9 for the details.
-#ifndef INTMAX_C //   [
-#  define INTMAX_C   INT64_C
-#endif // INTMAX_C    ]
-#ifndef UINTMAX_C //  [
-#  define UINTMAX_C  UINT64_C
-#endif // UINTMAX_C   ]
-
-#endif // __STDC_CONSTANT_MACROS ]
-
-#endif // _MSC_VER >= 1600 ]
-
-#endif // _MSC_STDINT_H_ ]
--- a/Resources/Orthanc/Resources/ThirdParty/base64/base64.cpp	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/* 
-   base64.cpp and base64.h
-
-   Copyright (C) 2004-2008 René Nyffenegger
-
-   This source code is provided 'as-is', without any express or implied
-   warranty. In no event will the author be held liable for any damages
-   arising from the use of this software.
-
-   Permission is granted to anyone to use this software for any purpose,
-   including commercial applications, and to alter it and redistribute it
-   freely, subject to the following restrictions:
-
-   1. The origin of this source code must not be misrepresented; you must not
-      claim that you wrote the original source code. If you use this source code
-      in a product, an acknowledgment in the product documentation would be
-      appreciated but is not required.
-
-   2. Altered source versions must be plainly marked as such, and must not be
-      misrepresented as being the original source code.
-
-   3. This notice may not be removed or altered from any source distribution.
-
-   René Nyffenegger rene.nyffenegger@adp-gmbh.ch
-
-*/
-
-#include "base64.h"
-#include <string.h>
-
-static const std::string base64_chars = 
-             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-             "abcdefghijklmnopqrstuvwxyz"
-             "0123456789+/";
-
-
-static inline bool is_base64(unsigned char c) {
-  return (isalnum(c) || (c == '+') || (c == '/'));
-}
-
-std::string base64_encode(const std::string& stringToEncode) 
-{
-  const unsigned char* bytes_to_encode = reinterpret_cast<const unsigned char*>
-    (stringToEncode.size() > 0 ? &stringToEncode[0] : NULL);
-  unsigned int in_len = stringToEncode.size();
-  
-  std::string ret;
-  int i = 0;
-  int j = 0;
-  unsigned char char_array_3[3];
-  unsigned char char_array_4[4];
-
-  while (in_len--) {
-    char_array_3[i++] = *(bytes_to_encode++);
-    if (i == 3) {
-      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
-      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
-      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
-      char_array_4[3] = char_array_3[2] & 0x3f;
-
-      for(i = 0; (i <4) ; i++)
-        ret += base64_chars[char_array_4[i]];
-      i = 0;
-    }
-  }
-
-  if (i)
-  {
-    for(j = i; j < 3; j++)
-      char_array_3[j] = '\0';
-
-    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
-    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
-    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
-    char_array_4[3] = char_array_3[2] & 0x3f;
-
-    for (j = 0; (j < i + 1); j++)
-      ret += base64_chars[char_array_4[j]];
-
-    while((i++ < 3))
-      ret += '=';
-
-  }
-
-  return ret;
-}
-
-
-std::string base64_decode(const std::string& encoded_string) {
-  int in_len = encoded_string.size();
-  int i = 0;
-  int j = 0;
-  int in_ = 0;
-  unsigned char char_array_4[4], char_array_3[3];
-  std::string ret;
-
-  while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
-    char_array_4[i++] = encoded_string[in_]; in_++;
-    if (i ==4) {
-      for (i = 0; i <4; i++)
-        char_array_4[i] = base64_chars.find(char_array_4[i]);
-
-      char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
-      char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
-      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
-
-      for (i = 0; (i < 3); i++)
-        ret += char_array_3[i];
-      i = 0;
-    }
-  }
-
-  if (i) {
-    for (j = i; j <4; j++)
-      char_array_4[j] = 0;
-
-    for (j = 0; j <4; j++)
-      char_array_4[j] = base64_chars.find(char_array_4[j]);
-
-    char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
-    char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
-    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
-
-    for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
-  }
-
-  return ret;
-}
--- a/Resources/Orthanc/Resources/ThirdParty/base64/base64.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-#include <string>
-
-std::string base64_encode(const std::string& stringToEncode);
-std::string base64_decode(const std::string& s);
--- a/Resources/Orthanc/Resources/ThirdParty/md5/md5.c	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,381 +0,0 @@
-/*
-  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  L. Peter Deutsch
-  ghost@aladdin.com
-
- */
-/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
-/*
-  Independent implementation of MD5 (RFC 1321).
-
-  This code implements the MD5 Algorithm defined in RFC 1321, whose
-  text is available at
-	http://www.ietf.org/rfc/rfc1321.txt
-  The code is derived from the text of the RFC, including the test suite
-  (section A.5) but excluding the rest of Appendix A.  It does not include
-  any code or documentation that is identified in the RFC as being
-  copyrighted.
-
-  The original and principal author of md5.c is L. Peter Deutsch
-  <ghost@aladdin.com>.  Other authors are noted in the change history
-  that follows (in reverse chronological order):
-
-  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
-	either statically or dynamically; added missing #include <string.h>
-	in library.
-  2002-03-11 lpd Corrected argument list for main(), and added int return
-	type, in test program and T value program.
-  2002-02-21 lpd Added missing #include <stdio.h> in test program.
-  2000-07-03 lpd Patched to eliminate warnings about "constant is
-	unsigned in ANSI C, signed in traditional"; made test program
-	self-checking.
-  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
-  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
-  1999-05-03 lpd Original version.
- */
-
-#include "md5.h"
-#include <string.h>
-
-#undef BYTE_ORDER	/* 1 = big-endian, -1 = little-endian, 0 = unknown */
-#ifdef ARCH_IS_BIG_ENDIAN
-#  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
-#else
-#  define BYTE_ORDER 0
-#endif
-
-#define T_MASK ((md5_word_t)~0)
-#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
-#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
-#define T3    0x242070db
-#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
-#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
-#define T6    0x4787c62a
-#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
-#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
-#define T9    0x698098d8
-#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
-#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
-#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
-#define T13    0x6b901122
-#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
-#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
-#define T16    0x49b40821
-#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
-#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
-#define T19    0x265e5a51
-#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
-#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
-#define T22    0x02441453
-#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
-#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
-#define T25    0x21e1cde6
-#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
-#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
-#define T28    0x455a14ed
-#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
-#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
-#define T31    0x676f02d9
-#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
-#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
-#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
-#define T35    0x6d9d6122
-#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
-#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
-#define T38    0x4bdecfa9
-#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
-#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
-#define T41    0x289b7ec6
-#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
-#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
-#define T44    0x04881d05
-#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
-#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
-#define T47    0x1fa27cf8
-#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
-#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
-#define T50    0x432aff97
-#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
-#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
-#define T53    0x655b59c3
-#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
-#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
-#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
-#define T57    0x6fa87e4f
-#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
-#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
-#define T60    0x4e0811a1
-#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
-#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
-#define T63    0x2ad7d2bb
-#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
-
-
-static void
-md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
-{
-    md5_word_t
-	a = pms->abcd[0], b = pms->abcd[1],
-	c = pms->abcd[2], d = pms->abcd[3];
-    md5_word_t t;
-#if BYTE_ORDER > 0
-    /* Define storage only for big-endian CPUs. */
-    md5_word_t X[16];
-#else
-    /* Define storage for little-endian or both types of CPUs. */
-    md5_word_t xbuf[16];
-    const md5_word_t *X;
-#endif
-
-    {
-#if BYTE_ORDER == 0
-	/*
-	 * Determine dynamically whether this is a big-endian or
-	 * little-endian machine, since we can use a more efficient
-	 * algorithm on the latter.
-	 */
-	static const int w = 1;
-
-	if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
-#endif
-#if BYTE_ORDER <= 0		/* little-endian */
-	{
-	    /*
-	     * On little-endian machines, we can process properly aligned
-	     * data without copying it.
-	     */
-	    if (!((data - (const md5_byte_t *)0) & 3)) {
-		/* data are properly aligned */
-		X = (const md5_word_t *)data;
-	    } else {
-		/* not aligned */
-		memcpy(xbuf, data, 64);
-		X = xbuf;
-	    }
-	}
-#endif
-#if BYTE_ORDER == 0
-	else			/* dynamic big-endian */
-#endif
-#if BYTE_ORDER >= 0		/* big-endian */
-	{
-	    /*
-	     * On big-endian machines, we must arrange the bytes in the
-	     * right order.
-	     */
-	    const md5_byte_t *xp = data;
-	    int i;
-
-#  if BYTE_ORDER == 0
-	    X = xbuf;		/* (dynamic only) */
-#  else
-#    define xbuf X		/* (static only) */
-#  endif
-	    for (i = 0; i < 16; ++i, xp += 4)
-		xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
-	}
-#endif
-    }
-
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
-
-    /* Round 1. */
-    /* Let [abcd k s i] denote the operation
-       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
-#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + F(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-    /* Do the following 16 operations. */
-    SET(a, b, c, d,  0,  7,  T1);
-    SET(d, a, b, c,  1, 12,  T2);
-    SET(c, d, a, b,  2, 17,  T3);
-    SET(b, c, d, a,  3, 22,  T4);
-    SET(a, b, c, d,  4,  7,  T5);
-    SET(d, a, b, c,  5, 12,  T6);
-    SET(c, d, a, b,  6, 17,  T7);
-    SET(b, c, d, a,  7, 22,  T8);
-    SET(a, b, c, d,  8,  7,  T9);
-    SET(d, a, b, c,  9, 12, T10);
-    SET(c, d, a, b, 10, 17, T11);
-    SET(b, c, d, a, 11, 22, T12);
-    SET(a, b, c, d, 12,  7, T13);
-    SET(d, a, b, c, 13, 12, T14);
-    SET(c, d, a, b, 14, 17, T15);
-    SET(b, c, d, a, 15, 22, T16);
-#undef SET
-
-     /* Round 2. */
-     /* Let [abcd k s i] denote the operation
-          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
-#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + G(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-     /* Do the following 16 operations. */
-    SET(a, b, c, d,  1,  5, T17);
-    SET(d, a, b, c,  6,  9, T18);
-    SET(c, d, a, b, 11, 14, T19);
-    SET(b, c, d, a,  0, 20, T20);
-    SET(a, b, c, d,  5,  5, T21);
-    SET(d, a, b, c, 10,  9, T22);
-    SET(c, d, a, b, 15, 14, T23);
-    SET(b, c, d, a,  4, 20, T24);
-    SET(a, b, c, d,  9,  5, T25);
-    SET(d, a, b, c, 14,  9, T26);
-    SET(c, d, a, b,  3, 14, T27);
-    SET(b, c, d, a,  8, 20, T28);
-    SET(a, b, c, d, 13,  5, T29);
-    SET(d, a, b, c,  2,  9, T30);
-    SET(c, d, a, b,  7, 14, T31);
-    SET(b, c, d, a, 12, 20, T32);
-#undef SET
-
-     /* Round 3. */
-     /* Let [abcd k s t] denote the operation
-          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + H(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-     /* Do the following 16 operations. */
-    SET(a, b, c, d,  5,  4, T33);
-    SET(d, a, b, c,  8, 11, T34);
-    SET(c, d, a, b, 11, 16, T35);
-    SET(b, c, d, a, 14, 23, T36);
-    SET(a, b, c, d,  1,  4, T37);
-    SET(d, a, b, c,  4, 11, T38);
-    SET(c, d, a, b,  7, 16, T39);
-    SET(b, c, d, a, 10, 23, T40);
-    SET(a, b, c, d, 13,  4, T41);
-    SET(d, a, b, c,  0, 11, T42);
-    SET(c, d, a, b,  3, 16, T43);
-    SET(b, c, d, a,  6, 23, T44);
-    SET(a, b, c, d,  9,  4, T45);
-    SET(d, a, b, c, 12, 11, T46);
-    SET(c, d, a, b, 15, 16, T47);
-    SET(b, c, d, a,  2, 23, T48);
-#undef SET
-
-     /* Round 4. */
-     /* Let [abcd k s t] denote the operation
-          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + I(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-     /* Do the following 16 operations. */
-    SET(a, b, c, d,  0,  6, T49);
-    SET(d, a, b, c,  7, 10, T50);
-    SET(c, d, a, b, 14, 15, T51);
-    SET(b, c, d, a,  5, 21, T52);
-    SET(a, b, c, d, 12,  6, T53);
-    SET(d, a, b, c,  3, 10, T54);
-    SET(c, d, a, b, 10, 15, T55);
-    SET(b, c, d, a,  1, 21, T56);
-    SET(a, b, c, d,  8,  6, T57);
-    SET(d, a, b, c, 15, 10, T58);
-    SET(c, d, a, b,  6, 15, T59);
-    SET(b, c, d, a, 13, 21, T60);
-    SET(a, b, c, d,  4,  6, T61);
-    SET(d, a, b, c, 11, 10, T62);
-    SET(c, d, a, b,  2, 15, T63);
-    SET(b, c, d, a,  9, 21, T64);
-#undef SET
-
-     /* Then perform the following additions. (That is increment each
-        of the four registers by the value it had before this block
-        was started.) */
-    pms->abcd[0] += a;
-    pms->abcd[1] += b;
-    pms->abcd[2] += c;
-    pms->abcd[3] += d;
-}
-
-void
-md5_init(md5_state_t *pms)
-{
-    pms->count[0] = pms->count[1] = 0;
-    pms->abcd[0] = 0x67452301;
-    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
-    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
-    pms->abcd[3] = 0x10325476;
-}
-
-void
-md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
-{
-    const md5_byte_t *p = data;
-    int left = nbytes;
-    int offset = (pms->count[0] >> 3) & 63;
-    md5_word_t nbits = (md5_word_t)(nbytes << 3);
-
-    if (nbytes <= 0)
-	return;
-
-    /* Update the message length. */
-    pms->count[1] += nbytes >> 29;
-    pms->count[0] += nbits;
-    if (pms->count[0] < nbits)
-	pms->count[1]++;
-
-    /* Process an initial partial block. */
-    if (offset) {
-	int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
-
-	memcpy(pms->buf + offset, p, copy);
-	if (offset + copy < 64)
-	    return;
-	p += copy;
-	left -= copy;
-	md5_process(pms, pms->buf);
-    }
-
-    /* Process full blocks. */
-    for (; left >= 64; p += 64, left -= 64)
-	md5_process(pms, p);
-
-    /* Process a final partial block. */
-    if (left)
-	memcpy(pms->buf, p, left);
-}
-
-void
-md5_finish(md5_state_t *pms, md5_byte_t digest[16])
-{
-    static const md5_byte_t pad[64] = {
-	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
-    md5_byte_t data[8];
-    int i;
-
-    /* Save the length before padding. */
-    for (i = 0; i < 8; ++i)
-	data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
-    /* Pad to 56 bytes mod 64. */
-    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
-    /* Append the length. */
-    md5_append(pms, data, 8);
-    for (i = 0; i < 16; ++i)
-	digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
-}
--- a/Resources/Orthanc/Resources/ThirdParty/md5/md5.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
-  Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved.
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  L. Peter Deutsch
-  ghost@aladdin.com
-
- */
-/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
-/*
-  Independent implementation of MD5 (RFC 1321).
-
-  This code implements the MD5 Algorithm defined in RFC 1321, whose
-  text is available at
-	http://www.ietf.org/rfc/rfc1321.txt
-  The code is derived from the text of the RFC, including the test suite
-  (section A.5) but excluding the rest of Appendix A.  It does not include
-  any code or documentation that is identified in the RFC as being
-  copyrighted.
-
-  The original and principal author of md5.h is L. Peter Deutsch
-  <ghost@aladdin.com>.  Other authors are noted in the change history
-  that follows (in reverse chronological order):
-
-  2002-04-13 lpd Removed support for non-ANSI compilers; removed
-	references to Ghostscript; clarified derivation from RFC 1321;
-	now handles byte order either statically or dynamically.
-  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
-  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
-	added conditionalization for C++ compilation from Martin
-	Purschke <purschke@bnl.gov>.
-  1999-05-03 lpd Original version.
- */
-
-#ifndef md5_INCLUDED
-#  define md5_INCLUDED
-
-/*
- * This package supports both compile-time and run-time determination of CPU
- * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
- * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
- * defined as non-zero, the code will be compiled to run only on big-endian
- * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
- * run on either big- or little-endian CPUs, but will run slightly less
- * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
- */
-
-typedef unsigned char md5_byte_t; /* 8-bit byte */
-typedef unsigned int md5_word_t; /* 32-bit word */
-
-/* Define the state of the MD5 Algorithm. */
-typedef struct md5_state_s {
-    md5_word_t count[2];	/* message length in bits, lsw first */
-    md5_word_t abcd[4];		/* digest buffer */
-    md5_byte_t buf[64];		/* accumulate block */
-} md5_state_t;
-
-#ifdef __cplusplus
-extern "C" 
-{
-#endif
-
-/* Initialize the algorithm. */
-void md5_init(md5_state_t *pms);
-
-/* Append a string to the message. */
-void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
-
-/* Finish the message and return the digest. */
-void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
-
-#ifdef __cplusplus
-}  /* end extern "C" */
-#endif
-
-#endif /* md5_INCLUDED */
--- a/Resources/Orthanc/Resources/ThirdParty/minizip/NOTES	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-These files come from the "contrib/minizip" directory in zlib 1.2.7.
--- a/Resources/Orthanc/Resources/ThirdParty/minizip/crypt.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/* crypt.h -- base code for crypt/uncrypt ZIPfile
-
-
-   Version 1.01e, February 12th, 2005
-
-   Copyright (C) 1998-2005 Gilles Vollant
-
-   This code is a modified version of crypting code in Infozip distribution
-
-   The encryption/decryption parts of this source code (as opposed to the
-   non-echoing password parts) were originally written in Europe.  The
-   whole source package can be freely distributed, including from the USA.
-   (Prior to January 2000, re-export from the US was a violation of US law.)
-
-   This encryption code is a direct transcription of the algorithm from
-   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
-   file (appnote.txt) is distributed with the PKZIP program (even in the
-   version without encryption capabilities).
-
-   If you don't need crypting in your application, just define symbols
-   NOCRYPT and NOUNCRYPT.
-
-   This code support the "Traditional PKWARE Encryption".
-
-   The new AES encryption added on Zip format by Winzip (see the page
-   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
-   Encryption is not supported.
-*/
-
-#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
-
-/***********************************************************************
- * Return the next byte in the pseudo-random sequence
- */
-static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
-{
-    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
-                     * unpredictable manner on 16-bit systems; not a problem
-                     * with any known compiler so far, though */
-
-    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
-    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
-}
-
-/***********************************************************************
- * Update the encryption keys with the next byte of plain text
- */
-static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
-{
-    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
-    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
-    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
-    {
-      register int keyshift = (int)((*(pkeys+1)) >> 24);
-      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
-    }
-    return c;
-}
-
-
-/***********************************************************************
- * Initialize the encryption keys and the random header according to
- * the given password.
- */
-static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
-{
-    *(pkeys+0) = 305419896L;
-    *(pkeys+1) = 591751049L;
-    *(pkeys+2) = 878082192L;
-    while (*passwd != '\0') {
-        update_keys(pkeys,pcrc_32_tab,(int)*passwd);
-        passwd++;
-    }
-}
-
-#define zdecode(pkeys,pcrc_32_tab,c) \
-    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
-
-#define zencode(pkeys,pcrc_32_tab,c,t) \
-    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
-
-#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-
-#define RAND_HEAD_LEN  12
-   /* "last resort" source for second part of crypt seed pattern */
-#  ifndef ZCR_SEED2
-#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */
-#  endif
-
-static int crypthead(const char* passwd,      /* password string */
-                     unsigned char* buf,      /* where to write header */
-                     int bufSize,
-                     unsigned long* pkeys,
-                     const unsigned long* pcrc_32_tab,
-                     unsigned long crcForCrypting)
-{
-    int n;                       /* index in random header */
-    int t;                       /* temporary */
-    int c;                       /* random byte */
-    unsigned char header[RAND_HEAD_LEN-2]; /* random header */
-    static unsigned calls = 0;   /* ensure different random header each time */
-
-    if (bufSize<RAND_HEAD_LEN)
-      return 0;
-
-    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
-     * output of rand() to get less predictability, since rand() is
-     * often poorly implemented.
-     */
-    if (++calls == 1)
-    {
-        srand((unsigned)(time(NULL) ^ ZCR_SEED2));
-    }
-    init_keys(passwd, pkeys, pcrc_32_tab);
-    for (n = 0; n < RAND_HEAD_LEN-2; n++)
-    {
-        c = (rand() >> 7) & 0xff;
-        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
-    }
-    /* Encrypt random header (last two bytes is high word of crc) */
-    init_keys(passwd, pkeys, pcrc_32_tab);
-    for (n = 0; n < RAND_HEAD_LEN-2; n++)
-    {
-        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
-    }
-    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
-    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
-    return n;
-}
-
-#endif
--- a/Resources/Orthanc/Resources/ThirdParty/minizip/ioapi.c	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,247 +0,0 @@
-/* ioapi.h -- IO base function header for compress/uncompress .zip
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-*/
-
-#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS)))
-        #define _CRT_SECURE_NO_WARNINGS
-#endif
-
-#if defined(__APPLE__) || defined(IOAPI_NO_64)
-// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
-#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
-#define FTELLO_FUNC(stream) ftello(stream)
-#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
-#else
-#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
-#define FTELLO_FUNC(stream) ftello64(stream)
-#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
-#endif
-
-
-#include "ioapi.h"
-
-voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
-{
-    if (pfilefunc->zfile_func64.zopen64_file != NULL)
-        return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
-    else
-    {
-        return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
-    }
-}
-
-long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
-{
-    if (pfilefunc->zfile_func64.zseek64_file != NULL)
-        return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
-    else
-    {
-        uLong offsetTruncated = (uLong)offset;
-        if (offsetTruncated != offset)
-            return -1;
-        else
-            return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
-    }
-}
-
-ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
-{
-    if (pfilefunc->zfile_func64.zseek64_file != NULL)
-        return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
-    else
-    {
-        uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
-        if ((tell_uLong) == MAXU32)
-            return (ZPOS64_T)-1;
-        else
-            return tell_uLong;
-    }
-}
-
-void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
-{
-    p_filefunc64_32->zfile_func64.zopen64_file = NULL;
-    p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
-    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
-    p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
-    p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
-    p_filefunc64_32->zfile_func64.ztell64_file = NULL;
-    p_filefunc64_32->zfile_func64.zseek64_file = NULL;
-    p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
-    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
-    p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
-    p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
-    p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
-}
-
-
-
-static voidpf  ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
-static uLong   ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-static uLong   ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
-static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
-static long    ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
-static int     ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
-static int     ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
-
-static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
-{
-    FILE* file = NULL;
-    const char* mode_fopen = NULL;
-    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
-        mode_fopen = "rb";
-    else
-    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
-        mode_fopen = "r+b";
-    else
-    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
-        mode_fopen = "wb";
-
-    if ((filename!=NULL) && (mode_fopen != NULL))
-        file = fopen(filename, mode_fopen);
-    return file;
-}
-
-static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
-{
-    FILE* file = NULL;
-    const char* mode_fopen = NULL;
-    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
-        mode_fopen = "rb";
-    else
-    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
-        mode_fopen = "r+b";
-    else
-    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
-        mode_fopen = "wb";
-
-    if ((filename!=NULL) && (mode_fopen != NULL))
-        file = FOPEN_FUNC((const char*)filename, mode_fopen);
-    return file;
-}
-
-
-static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
-{
-    uLong ret;
-    ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
-    return ret;
-}
-
-static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
-{
-    uLong ret;
-    ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
-    return ret;
-}
-
-static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
-{
-    long ret;
-    ret = ftell((FILE *)stream);
-    return ret;
-}
-
-
-static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
-{
-    ZPOS64_T ret;
-    ret = FTELLO_FUNC((FILE *)stream);
-    return ret;
-}
-
-static long ZCALLBACK fseek_file_func (voidpf  opaque, voidpf stream, uLong offset, int origin)
-{
-    int fseek_origin=0;
-    long ret;
-    switch (origin)
-    {
-    case ZLIB_FILEFUNC_SEEK_CUR :
-        fseek_origin = SEEK_CUR;
-        break;
-    case ZLIB_FILEFUNC_SEEK_END :
-        fseek_origin = SEEK_END;
-        break;
-    case ZLIB_FILEFUNC_SEEK_SET :
-        fseek_origin = SEEK_SET;
-        break;
-    default: return -1;
-    }
-    ret = 0;
-    if (fseek((FILE *)stream, offset, fseek_origin) != 0)
-        ret = -1;
-    return ret;
-}
-
-static long ZCALLBACK fseek64_file_func (voidpf  opaque, voidpf stream, ZPOS64_T offset, int origin)
-{
-    int fseek_origin=0;
-    long ret;
-    switch (origin)
-    {
-    case ZLIB_FILEFUNC_SEEK_CUR :
-        fseek_origin = SEEK_CUR;
-        break;
-    case ZLIB_FILEFUNC_SEEK_END :
-        fseek_origin = SEEK_END;
-        break;
-    case ZLIB_FILEFUNC_SEEK_SET :
-        fseek_origin = SEEK_SET;
-        break;
-    default: return -1;
-    }
-    ret = 0;
-
-    if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0)
-                        ret = -1;
-
-    return ret;
-}
-
-
-static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
-{
-    int ret;
-    ret = fclose((FILE *)stream);
-    return ret;
-}
-
-static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
-{
-    int ret;
-    ret = ferror((FILE *)stream);
-    return ret;
-}
-
-void fill_fopen_filefunc (pzlib_filefunc_def)
-  zlib_filefunc_def* pzlib_filefunc_def;
-{
-    pzlib_filefunc_def->zopen_file = fopen_file_func;
-    pzlib_filefunc_def->zread_file = fread_file_func;
-    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
-    pzlib_filefunc_def->ztell_file = ftell_file_func;
-    pzlib_filefunc_def->zseek_file = fseek_file_func;
-    pzlib_filefunc_def->zclose_file = fclose_file_func;
-    pzlib_filefunc_def->zerror_file = ferror_file_func;
-    pzlib_filefunc_def->opaque = NULL;
-}
-
-void fill_fopen64_filefunc (zlib_filefunc64_def*  pzlib_filefunc_def)
-{
-    pzlib_filefunc_def->zopen64_file = fopen64_file_func;
-    pzlib_filefunc_def->zread_file = fread_file_func;
-    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
-    pzlib_filefunc_def->ztell64_file = ftell64_file_func;
-    pzlib_filefunc_def->zseek64_file = fseek64_file_func;
-    pzlib_filefunc_def->zclose_file = fclose_file_func;
-    pzlib_filefunc_def->zerror_file = ferror_file_func;
-    pzlib_filefunc_def->opaque = NULL;
-}
--- a/Resources/Orthanc/Resources/ThirdParty/minizip/ioapi.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-/* ioapi.h -- IO base function header for compress/uncompress .zip
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-         Changes
-
-    Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
-    Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
-               More if/def section may be needed to support other platforms
-    Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
-                          (but you should use iowin32.c for windows instead)
-
-*/
-
-#ifndef _ZLIBIOAPI64_H
-#define _ZLIBIOAPI64_H
-
-#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
-
-  // Linux needs this to support file operation on files larger then 4+GB
-  // But might need better if/def to select just the platforms that needs them.
-
-        #ifndef __USE_FILE_OFFSET64
-                #define __USE_FILE_OFFSET64
-        #endif
-        #ifndef __USE_LARGEFILE64
-                #define __USE_LARGEFILE64
-        #endif
-        #ifndef _LARGEFILE64_SOURCE
-                #define _LARGEFILE64_SOURCE
-        #endif
-        #ifndef _FILE_OFFSET_BIT
-                #define _FILE_OFFSET_BIT 64
-        #endif
-
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "zlib.h"
-
-#if defined(USE_FILE32API)
-#define fopen64 fopen
-#define ftello64 ftell
-#define fseeko64 fseek
-#else
-#ifdef __FreeBSD__
-#define fopen64 fopen
-#define ftello64 ftello
-#define fseeko64 fseeko
-#endif
-#ifdef _MSC_VER
- #define fopen64 fopen
- #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
-  #define ftello64 _ftelli64
-  #define fseeko64 _fseeki64
- #else // old MSC
-  #define ftello64 ftell
-  #define fseeko64 fseek
- #endif
-#endif
-#endif
-
-/*
-#ifndef ZPOS64_T
-  #ifdef _WIN32
-                #define ZPOS64_T fpos_t
-  #else
-    #include <stdint.h>
-    #define ZPOS64_T uint64_t
-  #endif
-#endif
-*/
-
-#ifdef HAVE_MINIZIP64_CONF_H
-#include "mz64conf.h"
-#endif
-
-/* a type choosen by DEFINE */
-#ifdef HAVE_64BIT_INT_CUSTOM
-typedef  64BIT_INT_CUSTOM_TYPE ZPOS64_T;
-#else
-#ifdef HAS_STDINT_H
-#include "stdint.h"
-typedef uint64_t ZPOS64_T;
-#else
-
-/* Maximum unsigned 32-bit value used as placeholder for zip64 */
-#define MAXU32 0xffffffff
-
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef unsigned __int64 ZPOS64_T;
-#else
-typedef unsigned long long int ZPOS64_T;
-#endif
-#endif
-#endif
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#define ZLIB_FILEFUNC_SEEK_CUR (1)
-#define ZLIB_FILEFUNC_SEEK_END (2)
-#define ZLIB_FILEFUNC_SEEK_SET (0)
-
-#define ZLIB_FILEFUNC_MODE_READ      (1)
-#define ZLIB_FILEFUNC_MODE_WRITE     (2)
-#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
-
-#define ZLIB_FILEFUNC_MODE_EXISTING (4)
-#define ZLIB_FILEFUNC_MODE_CREATE   (8)
-
-
-#ifndef ZCALLBACK
- #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
-   #define ZCALLBACK CALLBACK
- #else
-   #define ZCALLBACK
- #endif
-#endif
-
-
-
-
-typedef voidpf   (ZCALLBACK *open_file_func)      OF((voidpf opaque, const char* filename, int mode));
-typedef uLong    (ZCALLBACK *read_file_func)      OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-typedef uLong    (ZCALLBACK *write_file_func)     OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-typedef int      (ZCALLBACK *close_file_func)     OF((voidpf opaque, voidpf stream));
-typedef int      (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
-
-typedef long     (ZCALLBACK *tell_file_func)      OF((voidpf opaque, voidpf stream));
-typedef long     (ZCALLBACK *seek_file_func)      OF((voidpf opaque, voidpf stream, uLong offset, int origin));
-
-
-/* here is the "old" 32 bits structure structure */
-typedef struct zlib_filefunc_def_s
-{
-    open_file_func      zopen_file;
-    read_file_func      zread_file;
-    write_file_func     zwrite_file;
-    tell_file_func      ztell_file;
-    seek_file_func      zseek_file;
-    close_file_func     zclose_file;
-    testerror_file_func zerror_file;
-    voidpf              opaque;
-} zlib_filefunc_def;
-
-typedef ZPOS64_T (ZCALLBACK *tell64_file_func)    OF((voidpf opaque, voidpf stream));
-typedef long     (ZCALLBACK *seek64_file_func)    OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
-typedef voidpf   (ZCALLBACK *open64_file_func)    OF((voidpf opaque, const void* filename, int mode));
-
-typedef struct zlib_filefunc64_def_s
-{
-    open64_file_func    zopen64_file;
-    read_file_func      zread_file;
-    write_file_func     zwrite_file;
-    tell64_file_func    ztell64_file;
-    seek64_file_func    zseek64_file;
-    close_file_func     zclose_file;
-    testerror_file_func zerror_file;
-    voidpf              opaque;
-} zlib_filefunc64_def;
-
-void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
-void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-/* now internal definition, only for zip.c and unzip.h */
-typedef struct zlib_filefunc64_32_def_s
-{
-    zlib_filefunc64_def zfile_func64;
-    open_file_func      zopen32_file;
-    tell_file_func      ztell32_file;
-    seek_file_func      zseek32_file;
-} zlib_filefunc64_32_def;
-
-
-#define ZREAD64(filefunc,filestream,buf,size)     ((*((filefunc).zfile_func64.zread_file))   ((filefunc).zfile_func64.opaque,filestream,buf,size))
-#define ZWRITE64(filefunc,filestream,buf,size)    ((*((filefunc).zfile_func64.zwrite_file))  ((filefunc).zfile_func64.opaque,filestream,buf,size))
-//#define ZTELL64(filefunc,filestream)            ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
-//#define ZSEEK64(filefunc,filestream,pos,mode)   ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
-#define ZCLOSE64(filefunc,filestream)             ((*((filefunc).zfile_func64.zclose_file))  ((filefunc).zfile_func64.opaque,filestream))
-#define ZERROR64(filefunc,filestream)             ((*((filefunc).zfile_func64.zerror_file))  ((filefunc).zfile_func64.opaque,filestream))
-
-voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
-long    call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
-ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
-
-void    fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
-
-#define ZOPEN64(filefunc,filename,mode)         (call_zopen64((&(filefunc)),(filename),(mode)))
-#define ZTELL64(filefunc,filestream)            (call_ztell64((&(filefunc)),(filestream)))
-#define ZSEEK64(filefunc,filestream,pos,mode)   (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--- a/Resources/Orthanc/Resources/ThirdParty/minizip/zip.c	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2007 +0,0 @@
-/* zip.c -- IO on .zip files using zlib
-   Version 1.1, February 14h, 2010
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-         Changes
-   Oct-2009 - Mathias Svensson - Remove old C style function prototypes
-   Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
-   Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
-   Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
-                                 It is used when recreting zip archive with RAW when deleting items from a zip.
-                                 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
-   Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
-   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
-
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "zlib.h"
-#include "zip.h"
-
-#ifdef STDC
-#  include <stddef.h>
-#  include <string.h>
-#  include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
-    extern int errno;
-#else
-#   include <errno.h>
-#endif
-
-
-#ifndef local
-#  define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-#ifndef VERSIONMADEBY
-# define VERSIONMADEBY   (0x0) /* platform depedent */
-#endif
-
-#ifndef Z_BUFSIZE
-#define Z_BUFSIZE (64*1024) //(16384)
-#endif
-
-#ifndef Z_MAXFILENAMEINZIP
-#define Z_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-/*
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-*/
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-
-// NOT sure that this work on ALL platform
-#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
-
-#ifndef SEEK_CUR
-#define SEEK_CUR    1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END    2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET    0
-#endif
-
-#ifndef DEF_MEM_LEVEL
-#if MAX_MEM_LEVEL >= 8
-#  define DEF_MEM_LEVEL 8
-#else
-#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#endif
-#endif
-const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
-
-
-#define SIZEDATA_INDATABLOCK (4096-(4*4))
-
-#define LOCALHEADERMAGIC    (0x04034b50)
-#define CENTRALHEADERMAGIC  (0x02014b50)
-#define ENDHEADERMAGIC      (0x06054b50)
-#define ZIP64ENDHEADERMAGIC      (0x6064b50)
-#define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)
-
-#define FLAG_LOCALHEADER_OFFSET (0x06)
-#define CRC_LOCALHEADER_OFFSET  (0x0e)
-
-#define SIZECENTRALHEADER (0x2e) /* 46 */
-
-typedef struct linkedlist_datablock_internal_s
-{
-  struct linkedlist_datablock_internal_s* next_datablock;
-  uLong  avail_in_this_block;
-  uLong  filled_in_this_block;
-  uLong  unused; /* for future use and alignement */
-  unsigned char data[SIZEDATA_INDATABLOCK];
-} linkedlist_datablock_internal;
-
-typedef struct linkedlist_data_s
-{
-    linkedlist_datablock_internal* first_block;
-    linkedlist_datablock_internal* last_block;
-} linkedlist_data;
-
-
-typedef struct
-{
-    z_stream stream;            /* zLib stream structure for inflate */
-#ifdef HAVE_BZIP2
-    bz_stream bstream;          /* bzLib stream structure for bziped */
-#endif
-
-    int  stream_initialised;    /* 1 is stream is initialised */
-    uInt pos_in_buffered_data;  /* last written byte in buffered_data */
-
-    ZPOS64_T pos_local_header;     /* offset of the local header of the file
-                                     currenty writing */
-    char* central_header;       /* central header data for the current file */
-    uLong size_centralExtra;
-    uLong size_centralheader;   /* size of the central header for cur file */
-    uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
-    uLong flag;                 /* flag of the file currently writing */
-
-    int  method;                /* compression method of file currenty wr.*/
-    int  raw;                   /* 1 for directly writing raw data */
-    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
-    uLong dosDate;
-    uLong crc32;
-    int  encrypt;
-    int  zip64;               /* Add ZIP64 extened information in the extra field */
-    ZPOS64_T pos_zip64extrainfo;
-    ZPOS64_T totalCompressedData;
-    ZPOS64_T totalUncompressedData;
-#ifndef NOCRYPT
-    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
-    const unsigned long* pcrc_32_tab;
-    int crypt_header_size;
-#endif
-} curfile64_info;
-
-typedef struct
-{
-    zlib_filefunc64_32_def z_filefunc;
-    voidpf filestream;        /* io structore of the zipfile */
-    linkedlist_data central_dir;/* datablock with central dir in construction*/
-    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
-    curfile64_info ci;            /* info on the file curretly writing */
-
-    ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */
-    ZPOS64_T add_position_when_writting_offset;
-    ZPOS64_T number_entry;
-
-#ifndef NO_ADDFILEINEXISTINGZIP
-    char *globalcomment;
-#endif
-
-} zip64_internal;
-
-
-#ifndef NOCRYPT
-#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-#include "crypt.h"
-#endif
-
-local linkedlist_datablock_internal* allocate_new_datablock()
-{
-    linkedlist_datablock_internal* ldi;
-    ldi = (linkedlist_datablock_internal*)
-                 ALLOC(sizeof(linkedlist_datablock_internal));
-    if (ldi!=NULL)
-    {
-        ldi->next_datablock = NULL ;
-        ldi->filled_in_this_block = 0 ;
-        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
-    }
-    return ldi;
-}
-
-local void free_datablock(linkedlist_datablock_internal* ldi)
-{
-    while (ldi!=NULL)
-    {
-        linkedlist_datablock_internal* ldinext = ldi->next_datablock;
-        TRYFREE(ldi);
-        ldi = ldinext;
-    }
-}
-
-local void init_linkedlist(linkedlist_data* ll)
-{
-    ll->first_block = ll->last_block = NULL;
-}
-
-local void free_linkedlist(linkedlist_data* ll)
-{
-    free_datablock(ll->first_block);
-    ll->first_block = ll->last_block = NULL;
-}
-
-
-local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
-{
-    linkedlist_datablock_internal* ldi;
-    const unsigned char* from_copy;
-
-    if (ll==NULL)
-        return ZIP_INTERNALERROR;
-
-    if (ll->last_block == NULL)
-    {
-        ll->first_block = ll->last_block = allocate_new_datablock();
-        if (ll->first_block == NULL)
-            return ZIP_INTERNALERROR;
-    }
-
-    ldi = ll->last_block;
-    from_copy = (unsigned char*)buf;
-
-    while (len>0)
-    {
-        uInt copy_this;
-        uInt i;
-        unsigned char* to_copy;
-
-        if (ldi->avail_in_this_block==0)
-        {
-            ldi->next_datablock = allocate_new_datablock();
-            if (ldi->next_datablock == NULL)
-                return ZIP_INTERNALERROR;
-            ldi = ldi->next_datablock ;
-            ll->last_block = ldi;
-        }
-
-        if (ldi->avail_in_this_block < len)
-            copy_this = (uInt)ldi->avail_in_this_block;
-        else
-            copy_this = (uInt)len;
-
-        to_copy = &(ldi->data[ldi->filled_in_this_block]);
-
-        for (i=0;i<copy_this;i++)
-            *(to_copy+i)=*(from_copy+i);
-
-        ldi->filled_in_this_block += copy_this;
-        ldi->avail_in_this_block -= copy_this;
-        from_copy += copy_this ;
-        len -= copy_this;
-    }
-    return ZIP_OK;
-}
-
-
-
-/****************************************************************************/
-
-#ifndef NO_ADDFILEINEXISTINGZIP
-/* ===========================================================================
-   Inputs a long in LSB order to the given file
-   nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
-*/
-
-local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
-local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
-{
-    unsigned char buf[8];
-    int n;
-    for (n = 0; n < nbByte; n++)
-    {
-        buf[n] = (unsigned char)(x & 0xff);
-        x >>= 8;
-    }
-    if (x != 0)
-      {     /* data overflow - hack for ZIP64 (X Roche) */
-      for (n = 0; n < nbByte; n++)
-        {
-          buf[n] = 0xff;
-        }
-      }
-
-    if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
-        return ZIP_ERRNO;
-    else
-        return ZIP_OK;
-}
-
-local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
-local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
-{
-    unsigned char* buf=(unsigned char*)dest;
-    int n;
-    for (n = 0; n < nbByte; n++) {
-        buf[n] = (unsigned char)(x & 0xff);
-        x >>= 8;
-    }
-
-    if (x != 0)
-    {     /* data overflow - hack for ZIP64 */
-       for (n = 0; n < nbByte; n++)
-       {
-          buf[n] = 0xff;
-       }
-    }
-}
-
-/****************************************************************************/
-
-
-local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
-{
-    uLong year = (uLong)ptm->tm_year;
-    if (year>=1980)
-        year-=1980;
-    else if (year>=80)
-        year-=80;
-    return
-      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
-        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
-}
-
-
-/****************************************************************************/
-
-local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
-
-local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
-{
-    unsigned char c;
-    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
-    if (err==1)
-    {
-        *pi = (int)c;
-        return ZIP_OK;
-    }
-    else
-    {
-        if (ZERROR64(*pzlib_filefunc_def,filestream))
-            return ZIP_ERRNO;
-        else
-            return ZIP_EOF;
-    }
-}
-
-
-/* ===========================================================================
-   Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
-
-local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
-{
-    uLong x ;
-    int i = 0;
-    int err;
-
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x = (uLong)i;
-
-    if (err==ZIP_OK)
-        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<8;
-
-    if (err==ZIP_OK)
-        *pX = x;
-    else
-        *pX = 0;
-    return err;
-}
-
-local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
-
-local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
-{
-    uLong x ;
-    int i = 0;
-    int err;
-
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x = (uLong)i;
-
-    if (err==ZIP_OK)
-        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<8;
-
-    if (err==ZIP_OK)
-        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<16;
-
-    if (err==ZIP_OK)
-        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<24;
-
-    if (err==ZIP_OK)
-        *pX = x;
-    else
-        *pX = 0;
-    return err;
-}
-
-local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
-
-
-local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
-{
-  ZPOS64_T x;
-  int i = 0;
-  int err;
-
-  err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x = (ZPOS64_T)i;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<8;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<16;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<24;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<32;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<40;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<48;
-
-  if (err==ZIP_OK)
-    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
-  x += ((ZPOS64_T)i)<<56;
-
-  if (err==ZIP_OK)
-    *pX = x;
-  else
-    *pX = 0;
-
-  return err;
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-/*
-  Locate the Central directory of a zipfile (at the end, just before
-    the global comment)
-*/
-local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
-
-local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
-{
-  unsigned char* buf;
-  ZPOS64_T uSizeFile;
-  ZPOS64_T uBackRead;
-  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
-  ZPOS64_T uPosFound=0;
-
-  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
-    return 0;
-
-
-  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
-
-  if (uMaxBack>uSizeFile)
-    uMaxBack = uSizeFile;
-
-  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
-  if (buf==NULL)
-    return 0;
-
-  uBackRead = 4;
-  while (uBackRead<uMaxBack)
-  {
-    uLong uReadSize;
-    ZPOS64_T uReadPos ;
-    int i;
-    if (uBackRead+BUFREADCOMMENT>uMaxBack)
-      uBackRead = uMaxBack;
-    else
-      uBackRead+=BUFREADCOMMENT;
-    uReadPos = uSizeFile-uBackRead ;
-
-    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
-      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
-    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-      break;
-
-    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
-      break;
-
-    for (i=(int)uReadSize-3; (i--)>0;)
-      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
-        ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
-      {
-        uPosFound = uReadPos+i;
-        break;
-      }
-
-      if (uPosFound!=0)
-        break;
-  }
-  TRYFREE(buf);
-  return uPosFound;
-}
-
-/*
-Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
-the global comment)
-*/
-local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
-
-local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
-{
-  unsigned char* buf;
-  ZPOS64_T uSizeFile;
-  ZPOS64_T uBackRead;
-  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
-  ZPOS64_T uPosFound=0;
-  uLong uL;
-  ZPOS64_T relativeOffset;
-
-  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
-    return 0;
-
-  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
-
-  if (uMaxBack>uSizeFile)
-    uMaxBack = uSizeFile;
-
-  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
-  if (buf==NULL)
-    return 0;
-
-  uBackRead = 4;
-  while (uBackRead<uMaxBack)
-  {
-    uLong uReadSize;
-    ZPOS64_T uReadPos;
-    int i;
-    if (uBackRead+BUFREADCOMMENT>uMaxBack)
-      uBackRead = uMaxBack;
-    else
-      uBackRead+=BUFREADCOMMENT;
-    uReadPos = uSizeFile-uBackRead ;
-
-    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
-      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
-    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-      break;
-
-    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
-      break;
-
-    for (i=(int)uReadSize-3; (i--)>0;)
-    {
-      // Signature "0x07064b50" Zip64 end of central directory locater
-      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
-      {
-        uPosFound = uReadPos+i;
-        break;
-      }
-    }
-
-      if (uPosFound!=0)
-        break;
-  }
-
-  TRYFREE(buf);
-  if (uPosFound == 0)
-    return 0;
-
-  /* Zip64 end of central directory locator */
-  if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
-    return 0;
-
-  /* the signature, already checked */
-  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
-    return 0;
-
-  /* number of the disk with the start of the zip64 end of  central directory */
-  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
-    return 0;
-  if (uL != 0)
-    return 0;
-
-  /* relative offset of the zip64 end of central directory record */
-  if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
-    return 0;
-
-  /* total number of disks */
-  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
-    return 0;
-  if (uL != 1)
-    return 0;
-
-  /* Goto Zip64 end of central directory record */
-  if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
-    return 0;
-
-  /* the signature */
-  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
-    return 0;
-
-  if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
-    return 0;
-
-  return relativeOffset;
-}
-
-int LoadCentralDirectoryRecord(zip64_internal* pziinit)
-{
-  int err=ZIP_OK;
-  ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
-
-  ZPOS64_T size_central_dir;     /* size of the central directory  */
-  ZPOS64_T offset_central_dir;   /* offset of start of central directory */
-  ZPOS64_T central_pos;
-  uLong uL;
-
-  uLong number_disk;          /* number of the current dist, used for
-                              spaning ZIP, unsupported, always 0*/
-  uLong number_disk_with_CD;  /* number the the disk with central dir, used
-                              for spaning ZIP, unsupported, always 0*/
-  ZPOS64_T number_entry;
-  ZPOS64_T number_entry_CD;      /* total number of entries in
-                                the central dir
-                                (same than number_entry on nospan) */
-  uLong VersionMadeBy;
-  uLong VersionNeeded;
-  uLong size_comment;
-
-  int hasZIP64Record = 0;
-
-  // check first if we find a ZIP64 record
-  central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
-  if(central_pos > 0)
-  {
-    hasZIP64Record = 1;
-  }
-  else if(central_pos == 0)
-  {
-    central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
-  }
-
-/* disable to allow appending to empty ZIP archive
-        if (central_pos==0)
-            err=ZIP_ERRNO;
-*/
-
-  if(hasZIP64Record)
-  {
-    ZPOS64_T sizeEndOfCentralDirectory;
-    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
-      err=ZIP_ERRNO;
-
-    /* the signature, already checked */
-    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* size of zip64 end of central directory record */
-    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* version made by */
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* version needed to extract */
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* number of this disk */
-    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* number of the disk with the start of the central directory */
-    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* total number of entries in the central directory on this disk */
-    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* total number of entries in the central directory */
-    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
-      err=ZIP_BADZIPFILE;
-
-    /* size of the central directory */
-    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* offset of start of central directory with respect to the
-    starting disk number */
-    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    // TODO..
-    // read the comment from the standard central header.
-    size_comment = 0;
-  }
-  else
-  {
-    // Read End of central Directory info
-    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-      err=ZIP_ERRNO;
-
-    /* the signature, already checked */
-    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* number of this disk */
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* number of the disk with the start of the central directory */
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
-      err=ZIP_ERRNO;
-
-    /* total number of entries in the central dir on this disk */
-    number_entry = 0;
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
-      err=ZIP_ERRNO;
-    else
-      number_entry = uL;
-
-    /* total number of entries in the central dir */
-    number_entry_CD = 0;
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
-      err=ZIP_ERRNO;
-    else
-      number_entry_CD = uL;
-
-    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
-      err=ZIP_BADZIPFILE;
-
-    /* size of the central directory */
-    size_central_dir = 0;
-    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
-      err=ZIP_ERRNO;
-    else
-      size_central_dir = uL;
-
-    /* offset of start of central directory with respect to the starting disk number */
-    offset_central_dir = 0;
-    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
-      err=ZIP_ERRNO;
-    else
-      offset_central_dir = uL;
-
-
-    /* zipfile global comment length */
-    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
-      err=ZIP_ERRNO;
-  }
-
-  if ((central_pos<offset_central_dir+size_central_dir) &&
-    (err==ZIP_OK))
-    err=ZIP_BADZIPFILE;
-
-  if (err!=ZIP_OK)
-  {
-    ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
-    return ZIP_ERRNO;
-  }
-
-  if (size_comment>0)
-  {
-    pziinit->globalcomment = (char*)ALLOC(size_comment+1);
-    if (pziinit->globalcomment)
-    {
-      size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
-      pziinit->globalcomment[size_comment]=0;
-    }
-  }
-
-  byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
-  pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
-
-  {
-    ZPOS64_T size_central_dir_to_read = size_central_dir;
-    size_t buf_size = SIZEDATA_INDATABLOCK;
-    void* buf_read = (void*)ALLOC(buf_size);
-    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
-      err=ZIP_ERRNO;
-
-    while ((size_central_dir_to_read>0) && (err==ZIP_OK))
-    {
-      ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
-      if (read_this > size_central_dir_to_read)
-        read_this = size_central_dir_to_read;
-
-      if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
-        err=ZIP_ERRNO;
-
-      if (err==ZIP_OK)
-        err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
-
-      size_central_dir_to_read-=read_this;
-    }
-    TRYFREE(buf_read);
-  }
-  pziinit->begin_pos = byte_before_the_zipfile;
-  pziinit->number_entry = number_entry_CD;
-
-  if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
-    err=ZIP_ERRNO;
-
-  return err;
-}
-
-
-#endif /* !NO_ADDFILEINEXISTINGZIP*/
-
-
-/************************************************************/
-extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
-{
-    zip64_internal ziinit;
-    zip64_internal* zi;
-    int err=ZIP_OK;
-
-    ziinit.z_filefunc.zseek32_file = NULL;
-    ziinit.z_filefunc.ztell32_file = NULL;
-    if (pzlib_filefunc64_32_def==NULL)
-        fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
-    else
-        ziinit.z_filefunc = *pzlib_filefunc64_32_def;
-
-    ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
-                  pathname,
-                  (append == APPEND_STATUS_CREATE) ?
-                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
-                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
-
-    if (ziinit.filestream == NULL)
-        return NULL;
-
-    if (append == APPEND_STATUS_CREATEAFTER)
-        ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
-
-    ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
-    ziinit.in_opened_file_inzip = 0;
-    ziinit.ci.stream_initialised = 0;
-    ziinit.number_entry = 0;
-    ziinit.add_position_when_writting_offset = 0;
-    init_linkedlist(&(ziinit.central_dir));
-
-
-
-    zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
-    if (zi==NULL)
-    {
-        ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
-        return NULL;
-    }
-
-    /* now we add file in a zipfile */
-#    ifndef NO_ADDFILEINEXISTINGZIP
-    ziinit.globalcomment = NULL;
-    if (append == APPEND_STATUS_ADDINZIP)
-    {
-      // Read and Cache Central Directory Records
-      err = LoadCentralDirectoryRecord(&ziinit);
-    }
-
-    if (globalcomment)
-    {
-      *globalcomment = ziinit.globalcomment;
-    }
-#    endif /* !NO_ADDFILEINEXISTINGZIP*/
-
-    if (err != ZIP_OK)
-    {
-#    ifndef NO_ADDFILEINEXISTINGZIP
-        TRYFREE(ziinit.globalcomment);
-#    endif /* !NO_ADDFILEINEXISTINGZIP*/
-        TRYFREE(zi);
-        return NULL;
-    }
-    else
-    {
-        *zi = ziinit;
-        return (zipFile)zi;
-    }
-}
-
-extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
-{
-    if (pzlib_filefunc32_def != NULL)
-    {
-        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
-        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
-        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
-    }
-    else
-        return zipOpen3(pathname, append, globalcomment, NULL);
-}
-
-extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
-{
-    if (pzlib_filefunc_def != NULL)
-    {
-        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
-        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
-        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
-        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
-        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
-    }
-    else
-        return zipOpen3(pathname, append, globalcomment, NULL);
-}
-
-
-
-extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
-{
-    return zipOpen3((const void*)pathname,append,NULL,NULL);
-}
-
-extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
-{
-    return zipOpen3(pathname,append,NULL,NULL);
-}
-
-int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
-{
-  /* write the local header */
-  int err;
-  uInt size_filename = (uInt)strlen(filename);
-  uInt size_extrafield = size_extrafield_local;
-
-  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
-
-  if (err==ZIP_OK)
-  {
-    if(zi->ci.zip64)
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
-    else
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
-  }
-
-  if (err==ZIP_OK)
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
-
-  if (err==ZIP_OK)
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
-
-  if (err==ZIP_OK)
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
-
-  // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
-  if (err==ZIP_OK)
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
-  if (err==ZIP_OK)
-  {
-    if(zi->ci.zip64)
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
-    else
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
-  }
-  if (err==ZIP_OK)
-  {
-    if(zi->ci.zip64)
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
-    else
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
-  }
-
-  if (err==ZIP_OK)
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
-
-  if(zi->ci.zip64)
-  {
-    size_extrafield += 20;
-  }
-
-  if (err==ZIP_OK)
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
-
-  if ((err==ZIP_OK) && (size_filename > 0))
-  {
-    if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
-      err = ZIP_ERRNO;
-  }
-
-  if ((err==ZIP_OK) && (size_extrafield_local > 0))
-  {
-    if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
-      err = ZIP_ERRNO;
-  }
-
-
-  if ((err==ZIP_OK) && (zi->ci.zip64))
-  {
-      // write the Zip64 extended info
-      short HeaderID = 1;
-      short DataSize = 16;
-      ZPOS64_T CompressedSize = 0;
-      ZPOS64_T UncompressedSize = 0;
-
-      // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
-      zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
-
-      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
-      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
-
-      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
-      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
-  }
-
-  return err;
-}
-
-/*
- NOTE.
- When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
- before calling this function it can be done with zipRemoveExtraInfoBlock
-
- It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
- unnecessary allocations.
- */
-extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                         const void* extrafield_local, uInt size_extrafield_local,
-                                         const void* extrafield_global, uInt size_extrafield_global,
-                                         const char* comment, int method, int level, int raw,
-                                         int windowBits,int memLevel, int strategy,
-                                         const char* password, uLong crcForCrypting,
-                                         uLong versionMadeBy, uLong flagBase, int zip64)
-{
-    zip64_internal* zi;
-    uInt size_filename;
-    uInt size_comment;
-    uInt i;
-    int err = ZIP_OK;
-
-#    ifdef NOCRYPT
-    (crcForCrypting);
-    if (password != NULL)
-        return ZIP_PARAMERROR;
-#    endif
-
-    if (file == NULL)
-        return ZIP_PARAMERROR;
-
-#ifdef HAVE_BZIP2
-    if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
-      return ZIP_PARAMERROR;
-#else
-    if ((method!=0) && (method!=Z_DEFLATED))
-      return ZIP_PARAMERROR;
-#endif
-
-    zi = (zip64_internal*)file;
-
-    if (zi->in_opened_file_inzip == 1)
-    {
-        err = zipCloseFileInZip (file);
-        if (err != ZIP_OK)
-            return err;
-    }
-
-    if (filename==NULL)
-        filename="-";
-
-    if (comment==NULL)
-        size_comment = 0;
-    else
-        size_comment = (uInt)strlen(comment);
-
-    size_filename = (uInt)strlen(filename);
-
-    if (zipfi == NULL)
-        zi->ci.dosDate = 0;
-    else
-    {
-        if (zipfi->dosDate != 0)
-            zi->ci.dosDate = zipfi->dosDate;
-        else
-          zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
-    }
-
-    zi->ci.flag = flagBase;
-    if ((level==8) || (level==9))
-      zi->ci.flag |= 2;
-    if (level==2)
-      zi->ci.flag |= 4;
-    if (level==1)
-      zi->ci.flag |= 6;
-    if (password != NULL)
-      zi->ci.flag |= 1;
-
-    zi->ci.crc32 = 0;
-    zi->ci.method = method;
-    zi->ci.encrypt = 0;
-    zi->ci.stream_initialised = 0;
-    zi->ci.pos_in_buffered_data = 0;
-    zi->ci.raw = raw;
-    zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
-
-    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
-    zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
-
-    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
-
-    zi->ci.size_centralExtra = size_extrafield_global;
-    zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
-    /* version info */
-    zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
-    zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
-    zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
-    zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
-    zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
-    zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
-
-    if (zipfi==NULL)
-        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
-    else
-        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
-
-    if (zipfi==NULL)
-        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
-    else
-        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
-
-    if(zi->ci.pos_local_header >= 0xffffffff)
-      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
-    else
-      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
-
-    for (i=0;i<size_filename;i++)
-        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
-
-    for (i=0;i<size_extrafield_global;i++)
-        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
-              *(((const char*)extrafield_global)+i);
-
-    for (i=0;i<size_comment;i++)
-        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
-              size_extrafield_global+i) = *(comment+i);
-    if (zi->ci.central_header == NULL)
-        return ZIP_INTERNALERROR;
-
-    zi->ci.zip64 = zip64;
-    zi->ci.totalCompressedData = 0;
-    zi->ci.totalUncompressedData = 0;
-    zi->ci.pos_zip64extrainfo = 0;
-
-    err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
-
-#ifdef HAVE_BZIP2
-    zi->ci.bstream.avail_in = (uInt)0;
-    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
-    zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
-    zi->ci.bstream.total_in_hi32 = 0;
-    zi->ci.bstream.total_in_lo32 = 0;
-    zi->ci.bstream.total_out_hi32 = 0;
-    zi->ci.bstream.total_out_lo32 = 0;
-#endif
-
-    zi->ci.stream.avail_in = (uInt)0;
-    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
-    zi->ci.stream.next_out = zi->ci.buffered_data;
-    zi->ci.stream.total_in = 0;
-    zi->ci.stream.total_out = 0;
-    zi->ci.stream.data_type = Z_BINARY;
-
-#ifdef HAVE_BZIP2
-    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
-#else
-    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
-#endif
-    {
-        if(zi->ci.method == Z_DEFLATED)
-        {
-          zi->ci.stream.zalloc = (alloc_func)0;
-          zi->ci.stream.zfree = (free_func)0;
-          zi->ci.stream.opaque = (voidpf)0;
-
-          if (windowBits>0)
-              windowBits = -windowBits;
-
-          err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
-
-          if (err==Z_OK)
-              zi->ci.stream_initialised = Z_DEFLATED;
-        }
-        else if(zi->ci.method == Z_BZIP2ED)
-        {
-#ifdef HAVE_BZIP2
-            // Init BZip stuff here
-          zi->ci.bstream.bzalloc = 0;
-          zi->ci.bstream.bzfree = 0;
-          zi->ci.bstream.opaque = (voidpf)0;
-
-          err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
-          if(err == BZ_OK)
-            zi->ci.stream_initialised = Z_BZIP2ED;
-#endif
-        }
-
-    }
-
-#    ifndef NOCRYPT
-    zi->ci.crypt_header_size = 0;
-    if ((err==Z_OK) && (password != NULL))
-    {
-        unsigned char bufHead[RAND_HEAD_LEN];
-        unsigned int sizeHead;
-        zi->ci.encrypt = 1;
-        zi->ci.pcrc_32_tab = get_crc_table();
-        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
-
-        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
-        zi->ci.crypt_header_size = sizeHead;
-
-        if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
-                err = ZIP_ERRNO;
-    }
-#    endif
-
-    if (err==Z_OK)
-        zi->in_opened_file_inzip = 1;
-    return err;
-}
-
-extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                         const void* extrafield_local, uInt size_extrafield_local,
-                                         const void* extrafield_global, uInt size_extrafield_global,
-                                         const char* comment, int method, int level, int raw,
-                                         int windowBits,int memLevel, int strategy,
-                                         const char* password, uLong crcForCrypting,
-                                         uLong versionMadeBy, uLong flagBase)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, raw,
-                                 windowBits, memLevel, strategy,
-                                 password, crcForCrypting, versionMadeBy, flagBase, 0);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                         const void* extrafield_local, uInt size_extrafield_local,
-                                         const void* extrafield_global, uInt size_extrafield_global,
-                                         const char* comment, int method, int level, int raw,
-                                         int windowBits,int memLevel, int strategy,
-                                         const char* password, uLong crcForCrypting)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, raw,
-                                 windowBits, memLevel, strategy,
-                                 password, crcForCrypting, VERSIONMADEBY, 0, 0);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                         const void* extrafield_local, uInt size_extrafield_local,
-                                         const void* extrafield_global, uInt size_extrafield_global,
-                                         const char* comment, int method, int level, int raw,
-                                         int windowBits,int memLevel, int strategy,
-                                         const char* password, uLong crcForCrypting, int zip64)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, raw,
-                                 windowBits, memLevel, strategy,
-                                 password, crcForCrypting, VERSIONMADEBY, 0, zip64);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                        const void* extrafield_local, uInt size_extrafield_local,
-                                        const void* extrafield_global, uInt size_extrafield_global,
-                                        const char* comment, int method, int level, int raw)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, raw,
-                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
-                                 NULL, 0, VERSIONMADEBY, 0, 0);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                        const void* extrafield_local, uInt size_extrafield_local,
-                                        const void* extrafield_global, uInt size_extrafield_global,
-                                        const char* comment, int method, int level, int raw, int zip64)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, raw,
-                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
-                                 NULL, 0, VERSIONMADEBY, 0, zip64);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                        const void* extrafield_local, uInt size_extrafield_local,
-                                        const void*extrafield_global, uInt size_extrafield_global,
-                                        const char* comment, int method, int level, int zip64)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, 0,
-                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
-                                 NULL, 0, VERSIONMADEBY, 0, zip64);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
-                                        const void* extrafield_local, uInt size_extrafield_local,
-                                        const void*extrafield_global, uInt size_extrafield_global,
-                                        const char* comment, int method, int level)
-{
-    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, 0,
-                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
-                                 NULL, 0, VERSIONMADEBY, 0, 0);
-}
-
-local int zip64FlushWriteBuffer(zip64_internal* zi)
-{
-    int err=ZIP_OK;
-
-    if (zi->ci.encrypt != 0)
-    {
-#ifndef NOCRYPT
-        uInt i;
-        int t;
-        for (i=0;i<zi->ci.pos_in_buffered_data;i++)
-            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
-#endif
-    }
-
-    if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
-      err = ZIP_ERRNO;
-
-    zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
-
-#ifdef HAVE_BZIP2
-    if(zi->ci.method == Z_BZIP2ED)
-    {
-      zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
-      zi->ci.bstream.total_in_lo32 = 0;
-      zi->ci.bstream.total_in_hi32 = 0;
-    }
-    else
-#endif
-    {
-      zi->ci.totalUncompressedData += zi->ci.stream.total_in;
-      zi->ci.stream.total_in = 0;
-    }
-
-
-    zi->ci.pos_in_buffered_data = 0;
-
-    return err;
-}
-
-extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
-{
-    zip64_internal* zi;
-    int err=ZIP_OK;
-
-    if (file == NULL)
-        return ZIP_PARAMERROR;
-    zi = (zip64_internal*)file;
-
-    if (zi->in_opened_file_inzip == 0)
-        return ZIP_PARAMERROR;
-
-    zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
-
-#ifdef HAVE_BZIP2
-    if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
-    {
-      zi->ci.bstream.next_in = (void*)buf;
-      zi->ci.bstream.avail_in = len;
-      err = BZ_RUN_OK;
-
-      while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
-      {
-        if (zi->ci.bstream.avail_out == 0)
-        {
-          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
-            err = ZIP_ERRNO;
-          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
-          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
-        }
-
-
-        if(err != BZ_RUN_OK)
-          break;
-
-        if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
-        {
-          uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
-//          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
-          err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);
-
-          zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
-        }
-      }
-
-      if(err == BZ_RUN_OK)
-        err = ZIP_OK;
-    }
-    else
-#endif
-    {
-      zi->ci.stream.next_in = (Bytef*)buf;
-      zi->ci.stream.avail_in = len;
-
-      while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
-      {
-          if (zi->ci.stream.avail_out == 0)
-          {
-              if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
-                  err = ZIP_ERRNO;
-              zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
-              zi->ci.stream.next_out = zi->ci.buffered_data;
-          }
-
-
-          if(err != ZIP_OK)
-              break;
-
-          if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
-          {
-              uLong uTotalOutBefore = zi->ci.stream.total_out;
-              err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
-              if(uTotalOutBefore > zi->ci.stream.total_out)
-              {
-                int bBreak = 0;
-                bBreak++;
-              }
-
-              zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
-          }
-          else
-          {
-              uInt copy_this,i;
-              if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
-                  copy_this = zi->ci.stream.avail_in;
-              else
-                  copy_this = zi->ci.stream.avail_out;
-
-              for (i = 0; i < copy_this; i++)
-                  *(((char*)zi->ci.stream.next_out)+i) =
-                      *(((const char*)zi->ci.stream.next_in)+i);
-              {
-                  zi->ci.stream.avail_in -= copy_this;
-                  zi->ci.stream.avail_out-= copy_this;
-                  zi->ci.stream.next_in+= copy_this;
-                  zi->ci.stream.next_out+= copy_this;
-                  zi->ci.stream.total_in+= copy_this;
-                  zi->ci.stream.total_out+= copy_this;
-                  zi->ci.pos_in_buffered_data += copy_this;
-              }
-          }
-      }// while(...)
-    }
-
-    return err;
-}
-
-extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
-{
-    return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
-}
-
-extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
-{
-    zip64_internal* zi;
-    ZPOS64_T compressed_size;
-    uLong invalidValue = 0xffffffff;
-    short datasize = 0;
-    int err=ZIP_OK;
-
-    if (file == NULL)
-        return ZIP_PARAMERROR;
-    zi = (zip64_internal*)file;
-
-    if (zi->in_opened_file_inzip == 0)
-        return ZIP_PARAMERROR;
-    zi->ci.stream.avail_in = 0;
-
-    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
-                {
-                        while (err==ZIP_OK)
-                        {
-                                uLong uTotalOutBefore;
-                                if (zi->ci.stream.avail_out == 0)
-                                {
-                                        if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
-                                                err = ZIP_ERRNO;
-                                        zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
-                                        zi->ci.stream.next_out = zi->ci.buffered_data;
-                                }
-                                uTotalOutBefore = zi->ci.stream.total_out;
-                                err=deflate(&zi->ci.stream,  Z_FINISH);
-                                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
-                        }
-                }
-    else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
-    {
-#ifdef HAVE_BZIP2
-      err = BZ_FINISH_OK;
-      while (err==BZ_FINISH_OK)
-      {
-        uLong uTotalOutBefore;
-        if (zi->ci.bstream.avail_out == 0)
-        {
-          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
-            err = ZIP_ERRNO;
-          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
-          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
-        }
-        uTotalOutBefore = zi->ci.bstream.total_out_lo32;
-        err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);
-        if(err == BZ_STREAM_END)
-          err = Z_STREAM_END;
-
-        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
-      }
-
-      if(err == BZ_FINISH_OK)
-        err = ZIP_OK;
-#endif
-    }
-
-    if (err==Z_STREAM_END)
-        err=ZIP_OK; /* this is normal */
-
-    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
-                {
-        if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
-            err = ZIP_ERRNO;
-                }
-
-    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
-    {
-        int tmp_err = deflateEnd(&zi->ci.stream);
-        if (err == ZIP_OK)
-            err = tmp_err;
-        zi->ci.stream_initialised = 0;
-    }
-#ifdef HAVE_BZIP2
-    else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
-    {
-      int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
-                        if (err==ZIP_OK)
-                                err = tmperr;
-                        zi->ci.stream_initialised = 0;
-    }
-#endif
-
-    if (!zi->ci.raw)
-    {
-        crc32 = (uLong)zi->ci.crc32;
-        uncompressed_size = zi->ci.totalUncompressedData;
-    }
-    compressed_size = zi->ci.totalCompressedData;
-
-#    ifndef NOCRYPT
-    compressed_size += zi->ci.crypt_header_size;
-#    endif
-
-    // update Current Item crc and sizes,
-    if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
-    {
-      /*version Made by*/
-      zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
-      /*version needed*/
-      zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
-
-    }
-
-    zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
-
-
-    if(compressed_size >= 0xffffffff)
-      zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
-    else
-      zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
-
-    /// set internal file attributes field
-    if (zi->ci.stream.data_type == Z_ASCII)
-        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
-
-    if(uncompressed_size >= 0xffffffff)
-      zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
-    else
-      zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
-
-    // Add ZIP64 extra info field for uncompressed size
-    if(uncompressed_size >= 0xffffffff)
-      datasize += 8;
-
-    // Add ZIP64 extra info field for compressed size
-    if(compressed_size >= 0xffffffff)
-      datasize += 8;
-
-    // Add ZIP64 extra info field for relative offset to local file header of current file
-    if(zi->ci.pos_local_header >= 0xffffffff)
-      datasize += 8;
-
-    if(datasize > 0)
-    {
-      char* p = NULL;
-
-      if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
-      {
-        // we can not write more data to the buffer that we have room for.
-        return ZIP_BADZIPFILE;
-      }
-
-      p = zi->ci.central_header + zi->ci.size_centralheader;
-
-      // Add Extra Information Header for 'ZIP64 information'
-      zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
-      p += 2;
-      zip64local_putValue_inmemory(p, datasize, 2); // DataSize
-      p += 2;
-
-      if(uncompressed_size >= 0xffffffff)
-      {
-        zip64local_putValue_inmemory(p, uncompressed_size, 8);
-        p += 8;
-      }
-
-      if(compressed_size >= 0xffffffff)
-      {
-        zip64local_putValue_inmemory(p, compressed_size, 8);
-        p += 8;
-      }
-
-      if(zi->ci.pos_local_header >= 0xffffffff)
-      {
-        zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
-        p += 8;
-      }
-
-      // Update how much extra free space we got in the memory buffer
-      // and increase the centralheader size so the new ZIP64 fields are included
-      // ( 4 below is the size of HeaderID and DataSize field )
-      zi->ci.size_centralExtraFree -= datasize + 4;
-      zi->ci.size_centralheader += datasize + 4;
-
-      // Update the extra info size field
-      zi->ci.size_centralExtra += datasize + 4;
-      zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
-    }
-
-    if (err==ZIP_OK)
-        err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
-
-    free(zi->ci.central_header);
-
-    if (err==ZIP_OK)
-    {
-        // Update the LocalFileHeader with the new values.
-
-        ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
-
-        if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            err = ZIP_ERRNO;
-
-        if (err==ZIP_OK)
-            err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
-
-        if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
-        {
-          if(zi->ci.pos_zip64extrainfo > 0)
-          {
-            // Update the size in the ZIP64 extended field.
-            if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
-              err = ZIP_ERRNO;
-
-            if (err==ZIP_OK) /* compressed size, unknown */
-              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
-
-            if (err==ZIP_OK) /* uncompressed size, unknown */
-              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
-          }
-          else
-              err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
-        }
-        else
-        {
-          if (err==ZIP_OK) /* compressed size, unknown */
-              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
-
-          if (err==ZIP_OK) /* uncompressed size, unknown */
-              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
-        }
-
-        if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            err = ZIP_ERRNO;
-    }
-
-    zi->number_entry ++;
-    zi->in_opened_file_inzip = 0;
-
-    return err;
-}
-
-extern int ZEXPORT zipCloseFileInZip (zipFile file)
-{
-    return zipCloseFileInZipRaw (file,0,0);
-}
-
-int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
-{
-  int err = ZIP_OK;
-  ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
-
-  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
-
-  /*num disks*/
-    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
-
-  /*relative offset*/
-    if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
-
-  /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
-    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
-
-    return err;
-}
-
-int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
-{
-  int err = ZIP_OK;
-
-  uLong Zip64DataSize = 44;
-
-  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
-
-  if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
-
-  if (err==ZIP_OK) /* version made by */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
-
-  if (err==ZIP_OK) /* version needed */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
-
-  if (err==ZIP_OK) /* number of this disk */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
-
-  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
-
-  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
-    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
-
-  if (err==ZIP_OK) /* total number of entries in the central dir */
-    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
-
-  if (err==ZIP_OK) /* size of the central directory */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
-
-  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
-  {
-    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
-  }
-  return err;
-}
-int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
-{
-  int err = ZIP_OK;
-
-  /*signature*/
-  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
-
-  if (err==ZIP_OK) /* number of this disk */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
-
-  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
-
-  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
-  {
-    {
-      if(zi->number_entry >= 0xFFFF)
-        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
-      else
-        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
-    }
-  }
-
-  if (err==ZIP_OK) /* total number of entries in the central dir */
-  {
-    if(zi->number_entry >= 0xFFFF)
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
-    else
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
-  }
-
-  if (err==ZIP_OK) /* size of the central directory */
-    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
-
-  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
-  {
-    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
-    if(pos >= 0xffffffff)
-    {
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
-    }
-    else
-      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
-  }
-
-   return err;
-}
-
-int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
-{
-  int err = ZIP_OK;
-  uInt size_global_comment = 0;
-
-  if(global_comment != NULL)
-    size_global_comment = (uInt)strlen(global_comment);
-
-  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
-
-  if (err == ZIP_OK && size_global_comment > 0)
-  {
-    if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
-      err = ZIP_ERRNO;
-  }
-  return err;
-}
-
-extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
-{
-    zip64_internal* zi;
-    int err = 0;
-    uLong size_centraldir = 0;
-    ZPOS64_T centraldir_pos_inzip;
-    ZPOS64_T pos;
-
-    if (file == NULL)
-        return ZIP_PARAMERROR;
-
-    zi = (zip64_internal*)file;
-
-    if (zi->in_opened_file_inzip == 1)
-    {
-        err = zipCloseFileInZip (file);
-    }
-
-#ifndef NO_ADDFILEINEXISTINGZIP
-    if (global_comment==NULL)
-        global_comment = zi->globalcomment;
-#endif
-
-    centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
-
-    if (err==ZIP_OK)
-    {
-        linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
-        while (ldi!=NULL)
-        {
-            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
-            {
-                if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
-                    err = ZIP_ERRNO;
-            }
-
-            size_centraldir += ldi->filled_in_this_block;
-            ldi = ldi->next_datablock;
-        }
-    }
-    free_linkedlist(&(zi->central_dir));
-
-    pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
-    if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
-    {
-      ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
-      Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
-
-      Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
-    }
-
-    if (err==ZIP_OK)
-      err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
-
-    if(err == ZIP_OK)
-      err = Write_GlobalComment(zi, global_comment);
-
-    if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
-        if (err == ZIP_OK)
-            err = ZIP_ERRNO;
-
-#ifndef NO_ADDFILEINEXISTINGZIP
-    TRYFREE(zi->globalcomment);
-#endif
-    TRYFREE(zi);
-
-    return err;
-}
-
-extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
-{
-  char* p = pData;
-  int size = 0;
-  char* pNewHeader;
-  char* pTmp;
-  short header;
-  short dataSize;
-
-  int retVal = ZIP_OK;
-
-  if(pData == NULL || *dataLen < 4)
-    return ZIP_PARAMERROR;
-
-  pNewHeader = (char*)ALLOC(*dataLen);
-  pTmp = pNewHeader;
-
-  while(p < (pData + *dataLen))
-  {
-    header = *(short*)p;
-    dataSize = *(((short*)p)+1);
-
-    if( header == sHeader ) // Header found.
-    {
-      p += dataSize + 4; // skip it. do not copy to temp buffer
-    }
-    else
-    {
-      // Extra Info block should not be removed, So copy it to the temp buffer.
-      memcpy(pTmp, p, dataSize + 4);
-      p += dataSize + 4;
-      size += dataSize + 4;
-    }
-
-  }
-
-  if(size < *dataLen)
-  {
-    // clean old extra info block.
-    memset(pData,0, *dataLen);
-
-    // copy the new extra info block over the old
-    if(size > 0)
-      memcpy(pData, pNewHeader, size);
-
-    // set the new extra info size
-    *dataLen = size;
-
-    retVal = ZIP_OK;
-  }
-  else
-    retVal = ZIP_ERRNO;
-
-  TRYFREE(pNewHeader);
-
-  return retVal;
-}
--- a/Resources/Orthanc/Resources/ThirdParty/minizip/zip.h	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,362 +0,0 @@
-/* zip.h -- IO on .zip files using zlib
-   Version 1.1, February 14h, 2010
-   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
-
-         Modifications for Zip64 support
-         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
-
-         For more info read MiniZip_info.txt
-
-         ---------------------------------------------------------------------------
-
-   Condition of use and distribution are the same than zlib :
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-        ---------------------------------------------------------------------------
-
-        Changes
-
-        See header of zip.h
-
-*/
-
-#ifndef _zip12_H
-#define _zip12_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//#define HAVE_BZIP2
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#ifdef HAVE_BZIP2
-#include "bzlib.h"
-#endif
-
-#define Z_BZIP2ED 12
-
-#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
-    from (void*) without cast */
-typedef struct TagzipFile__ { int unused; } zipFile__;
-typedef zipFile__ *zipFile;
-#else
-typedef voidp zipFile;
-#endif
-
-#define ZIP_OK                          (0)
-#define ZIP_EOF                         (0)
-#define ZIP_ERRNO                       (Z_ERRNO)
-#define ZIP_PARAMERROR                  (-102)
-#define ZIP_BADZIPFILE                  (-103)
-#define ZIP_INTERNALERROR               (-104)
-
-#ifndef DEF_MEM_LEVEL
-#  if MAX_MEM_LEVEL >= 8
-#    define DEF_MEM_LEVEL 8
-#  else
-#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#  endif
-#endif
-/* default memLevel */
-
-/* tm_zip contain date/time info */
-typedef struct tm_zip_s
-{
-    uInt tm_sec;            /* seconds after the minute - [0,59] */
-    uInt tm_min;            /* minutes after the hour - [0,59] */
-    uInt tm_hour;           /* hours since midnight - [0,23] */
-    uInt tm_mday;           /* day of the month - [1,31] */
-    uInt tm_mon;            /* months since January - [0,11] */
-    uInt tm_year;           /* years - [1980..2044] */
-} tm_zip;
-
-typedef struct
-{
-    tm_zip      tmz_date;       /* date in understandable format           */
-    uLong       dosDate;       /* if dos_date == 0, tmu_date is used      */
-/*    uLong       flag;        */   /* general purpose bit flag        2 bytes */
-
-    uLong       internal_fa;    /* internal file attributes        2 bytes */
-    uLong       external_fa;    /* external file attributes        4 bytes */
-} zip_fileinfo;
-
-typedef const char* zipcharpc;
-
-
-#define APPEND_STATUS_CREATE        (0)
-#define APPEND_STATUS_CREATEAFTER   (1)
-#define APPEND_STATUS_ADDINZIP      (2)
-
-extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
-extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));
-/*
-  Create a zipfile.
-     pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
-       an Unix computer "zlib/zlib113.zip".
-     if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
-       will be created at the end of the file.
-         (useful if the file contain a self extractor code)
-     if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
-       add files in existing zip (be sure you don't add file that doesn't exist)
-     If the zipfile cannot be opened, the return value is NULL.
-     Else, the return value is a zipFile Handle, usable with other function
-       of this zip package.
-*/
-
-/* Note : there is no delete function into a zipfile.
-   If you want delete file into a zipfile, you must open a zipfile, and create another
-   Of couse, you can use RAW reading and writing to copy the file you did not want delte
-*/
-
-extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
-                                   int append,
-                                   zipcharpc* globalcomment,
-                                   zlib_filefunc_def* pzlib_filefunc_def));
-
-extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
-                                   int append,
-                                   zipcharpc* globalcomment,
-                                   zlib_filefunc64_def* pzlib_filefunc_def));
-
-extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
-                       const char* filename,
-                       const zip_fileinfo* zipfi,
-                       const void* extrafield_local,
-                       uInt size_extrafield_local,
-                       const void* extrafield_global,
-                       uInt size_extrafield_global,
-                       const char* comment,
-                       int method,
-                       int level));
-
-extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
-                       const char* filename,
-                       const zip_fileinfo* zipfi,
-                       const void* extrafield_local,
-                       uInt size_extrafield_local,
-                       const void* extrafield_global,
-                       uInt size_extrafield_global,
-                       const char* comment,
-                       int method,
-                       int level,
-                       int zip64));
-
-/*
-  Open a file in the ZIP for writing.
-  filename : the filename in zip (if NULL, '-' without quote will be used
-  *zipfi contain supplemental information
-  if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
-    contains the extrafield data the the local header
-  if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
-    contains the extrafield data the the local header
-  if comment != NULL, comment contain the comment string
-  method contain the compression method (0 for store, Z_DEFLATED for deflate)
-  level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
-  zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
-                    this MUST be '1' if the uncompressed size is >= 0xffffffff.
-
-*/
-
-
-extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw));
-
-
-extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int zip64));
-/*
-  Same than zipOpenNewFileInZip, except if raw=1, we write raw file
- */
-
-extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting));
-
-extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting,
-                                            int zip64
-                                            ));
-
-/*
-  Same than zipOpenNewFileInZip2, except
-    windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
-    password : crypting password (NULL for no crypting)
-    crcForCrypting : crc of file to compress (needed for crypting)
- */
-
-extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting,
-                                            uLong versionMadeBy,
-                                            uLong flagBase
-                                            ));
-
-
-extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCrypting,
-                                            uLong versionMadeBy,
-                                            uLong flagBase,
-                                            int zip64
-                                            ));
-/*
-  Same than zipOpenNewFileInZip4, except
-    versionMadeBy : value for Version made by field
-    flag : value for flag field (compression level info will be added)
- */
-
-
-extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
-                       const void* buf,
-                       unsigned len));
-/*
-  Write data in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
-/*
-  Close the current file in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
-                                            uLong uncompressed_size,
-                                            uLong crc32));
-
-extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
-                                            ZPOS64_T uncompressed_size,
-                                            uLong crc32));
-
-/*
-  Close the current file in the zipfile, for file opened with
-    parameter raw=1 in zipOpenNewFileInZip2
-  uncompressed_size and crc32 are value for the uncompressed size
-*/
-
-extern int ZEXPORT zipClose OF((zipFile file,
-                const char* global_comment));
-/*
-  Close the zipfile
-*/
-
-
-extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
-/*
-  zipRemoveExtraInfoBlock -  Added by Mathias Svensson
-
-  Remove extra information block from a extra information data for the local file header or central directory header
-
-  It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.
-
-  0x0001 is the signature header for the ZIP64 extra information blocks
-
-  usage.
-                        Remove ZIP64 Extra information from a central director extra field data
-              zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);
-
-                        Remove ZIP64 Extra information from a Local File Header extra field data
-        zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _zip64_H */
--- a/Resources/Orthanc/Resources/ThirdParty/patch/NOTES.txt	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-===========
-INFORMATION
-===========
-
-This is a precompiled version of the "patch" standard tool for
-Windows. It was compiled using the MSYS framework.
-
-The binaries originate from the "Git for Windows 1.9.5" package
-(https://msysgit.github.io/). The build instructions have been
-provided on the discussion group of Git for Windows [1]. They are
-copied/pasted below for reference.
-
-
-
-================
-UPSTREAM PROJECT
-================
-
-URL to the upstream project:
-http://savannah.gnu.org/projects/patch/
-
-License of patch: GPLv2 (GNU General Public License v2)
-
-Copyright (C) 1988 Larry Wall "with lots o' patches by Paul Eggert"
-Copyright (C) 1997 Free Software Foundation, Inc.
-
-
-
-======================
-BUILD INSTRUCTIONS [1]
-======================
-
-The easiest way to find out about this is to install the Git SDK, then 
-run 
-
-     pacman -Qu $(which patch.exe) 
-
-to find out which package contains the `patch.exe` binary. It so happens 
-to be patch.2.7.5-1 at the moment. Since this is an MSys2 package (not a 
-MinGW one, otherwise the patch utility would be in /mingw64/bin/, not 
-/usr/bin/), this package is built from the recipes in 
-
-     https://github.com/msys2/MSYS2-packages 
-
-The `patch` package is obviously built from the subdirectory 
-
-     https://github.com/Alexpux/MSYS2-packages/tree/master/patch 
-
-and the PKGBUILD file specifies that the source is fetched from 
-ftp://ftp.gnu.org/gnu/patch/patch-2.7.5.tar.xz: 
-
-https://github.com/Alexpux/MSYS2-packages/blob/900744becd072f687029b0f830ab6fe95cf533d6/patch/PKGBUILD#L14 
-
-and then these two patches are applied before building: 
-     
-https://github.com/Alexpux/MSYS2-packages/blob/900744becd072f687029b0f830ab6fe95cf533d6/patch/msys2-patch-2.7.1.patch 
-
-and 
-      
-https://github.com/Alexpux/MSYS2-packages/blob/900744becd072f687029b0f830ab6fe95cf533d6/patch/msys2-patch-manifest.patch 
-
-As you can see, some light changes are applied, i.e. `patch.exe` will 
-always write in binary mode with MSys2, and the executable will have a 
-manifest embedded that allows it to run as non-administrator. 
-
-Ciao, 
-Johannes Schindelin
-
-
-[1] https://groups.google.com/d/msg/git-for-windows/xWyVr4z6Ri0/6RKeV028EAAJ
Binary file Resources/Orthanc/Resources/ThirdParty/patch/msys-1.0.dll has changed
Binary file Resources/Orthanc/Resources/ThirdParty/patch/patch.exe has changed
--- a/Resources/Orthanc/Resources/ThirdParty/patch/patch.exe.manifest	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
-  <assemblyIdentity version="7.95.0.0"
-     processorArchitecture="X86"
-     name="patch.exe"
-     type="win32"/>
-
-  <!-- Identify the application security requirements. -->
-  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
-    <security>
-      <requestedPrivileges>
-        <requestedExecutionLevel
-          level="asInvoker"
-          uiAccess="false"/>
-        </requestedPrivileges>
-       </security>
-  </trustInfo>
-</assembly>
-
--- a/Resources/Orthanc/Resources/WindowsResources.py	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-#!/usr/bin/python
-
-# Orthanc - A Lightweight, RESTful DICOM Store
-# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
-# Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2018 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.
-#
-# 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/>.
-
-
-import os
-import sys
-import datetime
-
-if len(sys.argv) != 5:
-    sys.stderr.write('Usage: %s <Version> <ProductName> <Filename> <Description>\n\n' % sys.argv[0])
-    sys.stderr.write('Example: %s 0.9.1 Orthanc Orthanc.exe "Lightweight, RESTful DICOM server for medical imaging"\n' % sys.argv[0])
-    sys.exit(-1)
-
-SOURCE = os.path.join(os.path.dirname(__file__), 'WindowsResources.rc')
-
-VERSION = sys.argv[1]
-PRODUCT = sys.argv[2]
-FILENAME = sys.argv[3]
-DESCRIPTION = sys.argv[4]
-
-if VERSION == 'mainline':
-    VERSION = '999.999.999'
-    RELEASE = 'This is a mainline build, not an official release'
-else:
-    RELEASE = 'Release %s' % VERSION
-
-v = VERSION.split('.')
-if len(v) != 2 and len(v) != 3:
-    sys.stderr.write('Bad version number: %s\n' % VERSION)
-    sys.exit(-1)
-
-if len(v) == 2:
-    v.append('0')
-
-extension = os.path.splitext(FILENAME)[1]
-if extension.lower() == '.dll':
-    BLOCK = '040904E4'
-    TYPE = 'VFT_DLL'
-elif extension.lower() == '.exe':
-    #BLOCK = '040904B0'   # LANG_ENGLISH/SUBLANG_ENGLISH_US,
-    BLOCK = '040904E4'   # Lang=US English, CharSet=Windows Multilingual
-    TYPE = 'VFT_APP'
-else:
-    sys.stderr.write('Unsupported extension (.EXE or .DLL only): %s\n' % extension)
-    sys.exit(-1)
-
-
-with open(SOURCE, 'r') as source:
-    content = source.read()
-    content = content.replace('${VERSION_MAJOR}', v[0])
-    content = content.replace('${VERSION_MINOR}', v[1])
-    content = content.replace('${VERSION_PATCH}', v[2])
-    content = content.replace('${RELEASE}', RELEASE)
-    content = content.replace('${DESCRIPTION}', DESCRIPTION)
-    content = content.replace('${PRODUCT}', PRODUCT)   
-    content = content.replace('${FILENAME}', FILENAME)   
-    content = content.replace('${YEAR}', str(datetime.datetime.now().year))
-    content = content.replace('${BLOCK}', BLOCK)
-    content = content.replace('${TYPE}', TYPE)
-
-    sys.stdout.write(content)
--- a/Resources/Orthanc/Resources/WindowsResources.rc	Mon May 21 09:02:03 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#include <winver.h>
-
-VS_VERSION_INFO VERSIONINFO
-   FILEVERSION ${VERSION_MAJOR},${VERSION_MINOR},0,${VERSION_PATCH}
-   PRODUCTVERSION ${VERSION_MAJOR},${VERSION_MINOR},0,0
-   FILEOS VOS_NT_WINDOWS32
-   FILETYPE ${TYPE}
-   BEGIN
-      BLOCK "StringFileInfo"
-      BEGIN
-         BLOCK "${BLOCK}"
-         BEGIN
-            VALUE "Comments", "${RELEASE}"
-            VALUE "CompanyName", "University Hospital of Liege, Belgium"
-            VALUE "FileDescription", "${DESCRIPTION}"
-            VALUE "FileVersion", "${VERSION_MAJOR}.${VERSION_MINOR}.0.${VERSION_PATCH}"
-            VALUE "InternalName", "${PRODUCT}"
-            VALUE "LegalCopyright", "(c) 2012-${YEAR}, Sebastien Jodogne, University Hospital of Liege, Belgium"
-            VALUE "LegalTrademarks", "Licensing information is available at http://www.orthanc-server.com/"
-            VALUE "OriginalFilename", "${FILENAME}"
-            VALUE "ProductName", "${PRODUCT}"
-            VALUE "ProductVersion", "${VERSION_MAJOR}.${VERSION_MINOR}"
-         END
-      END
-
-      BLOCK "VarFileInfo"
-      BEGIN
-        VALUE "Translation", 0x409, 1252  // U.S. English
-      END
-   END
--- a/Resources/SyncOrthancFolder.py	Mon May 21 09:02:03 2018 +0200
+++ b/Resources/SyncOrthancFolder.py	Fri Jun 01 17:48:47 2018 +0200
@@ -8,175 +8,17 @@
 import multiprocessing
 import os
 import stat
-import sys
 import urllib2
 
 TARGET = os.path.join(os.path.dirname(__file__), 'Orthanc')
-BRANCH = 'default'
 REPOSITORY = 'https://bitbucket.org/sjodogne/orthanc/raw'
 
 FILES = [
-    'Core/Cache/ICachePageProvider.h',
-    'Core/Cache/LeastRecentlyUsedIndex.h',
-    'Core/Cache/MemoryCache.cpp',
-    'Core/Cache/MemoryCache.h',
-    'Core/Cache/SharedArchive.cpp',
-    'Core/Cache/SharedArchive.h',
-    'Core/ChunkedBuffer.cpp',
-    'Core/ChunkedBuffer.h',
-    'Core/Compression/DeflateBaseCompressor.cpp',
-    'Core/Compression/DeflateBaseCompressor.h',
-    'Core/Compression/GzipCompressor.cpp',
-    'Core/Compression/GzipCompressor.h',
-    'Core/Compression/HierarchicalZipWriter.cpp',
-    'Core/Compression/HierarchicalZipWriter.h',
-    'Core/Compression/IBufferCompressor.h',
-    'Core/Compression/ZipWriter.cpp',
-    'Core/Compression/ZipWriter.h',
-    'Core/Compression/ZlibCompressor.cpp',
-    'Core/Compression/ZlibCompressor.h',
-    'Core/DicomFormat/DicomArray.cpp',
-    'Core/DicomFormat/DicomArray.h',
-    'Core/DicomFormat/DicomElement.h',
-    'Core/DicomFormat/DicomImageInformation.cpp',
-    'Core/DicomFormat/DicomImageInformation.h',
-    'Core/DicomFormat/DicomInstanceHasher.cpp',
-    'Core/DicomFormat/DicomInstanceHasher.h',
-    'Core/DicomFormat/DicomIntegerPixelAccessor.cpp',
-    'Core/DicomFormat/DicomIntegerPixelAccessor.h',
-    'Core/DicomFormat/DicomMap.cpp',
-    'Core/DicomFormat/DicomMap.h',
-    'Core/DicomFormat/DicomTag.cpp',
-    'Core/DicomFormat/DicomTag.h',
-    'Core/DicomFormat/DicomValue.cpp',
-    'Core/DicomFormat/DicomValue.h',
-    'Core/Endianness.h',
-    'Core/Enumerations.cpp',
-    'Core/Enumerations.h',
-    'Core/FileStorage/FileInfo.h',
-    'Core/FileStorage/FilesystemStorage.cpp',
-    'Core/FileStorage/FilesystemStorage.h',
-    'Core/FileStorage/IStorageArea.h',
-    'Core/FileStorage/StorageAccessor.cpp',
-    'Core/FileStorage/StorageAccessor.h',
-    'Core/HttpClient.cpp',
-    'Core/HttpClient.h',
-    'Core/ICommand.h',
-    'Core/IDynamicObject.h',
-    'Core/Images/Font.cpp',
-    'Core/Images/Font.h',
-    'Core/Images/FontRegistry.cpp',
-    'Core/Images/FontRegistry.h',
-    'Core/Images/IImageWriter.cpp',
-    'Core/Images/IImageWriter.h',
-    'Core/Images/Image.cpp',
-    'Core/Images/Image.h',
-    'Core/Images/ImageAccessor.cpp',
-    'Core/Images/ImageAccessor.h',
-    'Core/Images/ImageBuffer.cpp',
-    'Core/Images/ImageBuffer.h',
-    'Core/Images/ImageProcessing.cpp',
-    'Core/Images/ImageProcessing.h',
-    'Core/Images/ImageTraits.h',
-    'Core/Images/JpegErrorManager.cpp',
-    'Core/Images/JpegErrorManager.h',
-    'Core/Images/JpegReader.cpp',
-    'Core/Images/JpegReader.h',
-    'Core/Images/JpegWriter.cpp',
-    'Core/Images/JpegWriter.h',
-    'Core/Images/PixelTraits.h',
-    'Core/Images/PngReader.cpp',
-    'Core/Images/PngReader.h',
-    'Core/Images/PngWriter.cpp',
-    'Core/Images/PngWriter.h',
-    'Core/Logging.cpp',
-    'Core/Logging.h',
-    'Core/MultiThreading/BagOfTasks.h',
-    'Core/MultiThreading/BagOfTasksProcessor.cpp',
-    'Core/MultiThreading/BagOfTasksProcessor.h',
-    'Core/MultiThreading/ILockable.h',
-    'Core/MultiThreading/IRunnableBySteps.h',
-    'Core/MultiThreading/Mutex.cpp',
-    'Core/MultiThreading/Mutex.h',
-    'Core/MultiThreading/ReaderWriterLock.cpp',
-    'Core/MultiThreading/ReaderWriterLock.h',
-    'Core/MultiThreading/RunnableWorkersPool.cpp',
-    'Core/MultiThreading/RunnableWorkersPool.h',
-    'Core/MultiThreading/Semaphore.cpp',
-    'Core/MultiThreading/Semaphore.h',
-    'Core/MultiThreading/SharedMessageQueue.cpp',
-    'Core/MultiThreading/SharedMessageQueue.h',
-    'Core/OrthancException.h',
-    'Core/PrecompiledHeaders.cpp',
-    'Core/PrecompiledHeaders.h',
-    'Core/SharedLibrary.cpp',
-    'Core/SharedLibrary.h',
-    'Core/SystemToolbox.cpp',
-    'Core/SystemToolbox.h',
-    'Core/TemporaryFile.cpp',
-    'Core/TemporaryFile.h',
-    'Core/Toolbox.cpp',
-    'Core/Toolbox.h',
-    'Core/WebServiceParameters.cpp',
-    'Core/WebServiceParameters.h',
-    'NEWS',
-    'Plugins/Samples/Common/DicomDatasetReader.cpp',
-    'Plugins/Samples/Common/DicomDatasetReader.h',
-    'Plugins/Samples/Common/DicomPath.cpp',
-    'Plugins/Samples/Common/DicomPath.h',
-    'Plugins/Samples/Common/DicomTag.h',
-    'Plugins/Samples/Common/FullOrthancDataset.cpp',
-    'Plugins/Samples/Common/FullOrthancDataset.h',
-    'Plugins/Samples/Common/IDicomDataset.h',
-    'Plugins/Samples/Common/IOrthancConnection.cpp',
-    'Plugins/Samples/Common/IOrthancConnection.h',
-    'Plugins/Samples/Common/OrthancHttpConnection.cpp',
-    'Plugins/Samples/Common/OrthancHttpConnection.h',
-    'Plugins/Samples/Common/OrthancPluginException.h',
-    'Resources/CMake/AutoGeneratedCode.cmake',
-    'Resources/CMake/BoostConfiguration.cmake',
-    'Resources/CMake/Compiler.cmake',
-    'Resources/CMake/DownloadPackage.cmake',
-    'Resources/CMake/GoogleTestConfiguration.cmake',
-    'Resources/CMake/JsonCppConfiguration.cmake',
-    'Resources/CMake/LibCurlConfiguration.cmake',
-    'Resources/CMake/LibJpegConfiguration.cmake',
-    'Resources/CMake/LibPngConfiguration.cmake',
-    'Resources/CMake/OpenSslConfiguration.cmake',
-    'Resources/CMake/OrthancFrameworkConfiguration.cmake',
-    'Resources/CMake/OrthancFrameworkParameters.cmake',
-    'Resources/CMake/UuidConfiguration.cmake',
-    'Resources/CMake/ZlibConfiguration.cmake',
-    'Resources/EmbedResources.py',
-    'Resources/LinuxStandardBaseToolchain.cmake',
-    'Resources/MinGW-W64-Toolchain32.cmake',
-    'Resources/MinGW-W64-Toolchain64.cmake',
-    'Resources/MinGWToolchain.cmake',
-    'Resources/Patches/boost-1.66.0-linux-standard-base.patch',
-    'Resources/Patches/curl-7.57.0-cmake.patch',
-    'Resources/Patches/dcmtk-3.6.2-linux-standard-base.patch',
-    'Resources/ThirdParty/VisualStudio/stdint.h',
-    'Resources/ThirdParty/base64/base64.cpp',
-    'Resources/ThirdParty/base64/base64.h',
-    'Resources/ThirdParty/md5/md5.c',
-    'Resources/ThirdParty/md5/md5.h',
-    'Resources/ThirdParty/minizip/NOTES',
-    'Resources/ThirdParty/minizip/crypt.h',
-    'Resources/ThirdParty/minizip/ioapi.c',
-    'Resources/ThirdParty/minizip/ioapi.h',
-    'Resources/ThirdParty/minizip/zip.c',
-    'Resources/ThirdParty/minizip/zip.h',
-    'Resources/ThirdParty/patch/NOTES.txt',
-    'Resources/ThirdParty/patch/msys-1.0.dll',
-    'Resources/ThirdParty/patch/patch.exe',
-    'Resources/ThirdParty/patch/patch.exe.manifest',
-    'Resources/WindowsResources.py',
-    'Resources/WindowsResources.rc',
-]
-
-EXE = [
-    'Resources/EmbedResources.py',
-    'Resources/WindowsResources.py',
+    'DownloadOrthancFramework.cmake',
+    'LinuxStandardBaseToolchain.cmake',
+    'MinGW-W64-Toolchain32.cmake',
+    'MinGW-W64-Toolchain64.cmake',
+    'MinGWToolchain.cmake',
 ]
 
 
@@ -193,26 +35,16 @@
 
     url = '%s/%s/%s' % (REPOSITORY, branch, source)
 
-    try:
-        with open(target, 'w') as f:
-            f.write(urllib2.urlopen(url).read())
-    except:
-        sys.stderr.write('Cannot download: %s\n' % url)
-        raise
+    with open(target, 'w') as f:
+        f.write(urllib2.urlopen(url).read())
 
 
 commands = []
 
 for f in FILES:
-    commands.append([ BRANCH, f, f ])
+    commands.append([ 'default',
+                      os.path.join('Resources', f),
+                      f ])
 
 pool = multiprocessing.Pool(10)  # simultaneous downloads
-
-# https://stackoverflow.com/a/1408476/881731
-pool.map_async(Download, commands).get(timeout = 20)
-
-
-for exe in EXE:
-    path = os.path.join(TARGET, exe)
-    st = os.stat(path)
-    os.chmod(path, st.st_mode | stat.S_IEXEC)
+pool.map(Download, commands)
--- a/UnitTestsSources/UnitTestsMain.cpp	Mon May 21 09:02:03 2018 +0200
+++ b/UnitTestsSources/UnitTestsMain.cpp	Fri Jun 01 17:48:47 2018 +0200
@@ -31,11 +31,11 @@
 #include "../Framework/Volumes/SlicedVolumeBase.h"
 #include "../Platforms/Generic/OracleWebService.h"
 
-#include "../Resources/Orthanc/Core/HttpClient.h"
-#include "../Resources/Orthanc/Core/Images/ImageProcessing.h"
-#include "../Resources/Orthanc/Core/Logging.h"
-#include "../Resources/Orthanc/Core/MultiThreading/SharedMessageQueue.h"
-#include "../Resources/Orthanc/Core/OrthancException.h"
+#include <Core/HttpClient.h>
+#include <Core/Images/ImageProcessing.h>
+#include <Core/Logging.h>
+#include <Core/MultiThreading/SharedMessageQueue.h>
+#include <Core/OrthancException.h>
 
 #include <boost/lexical_cast.hpp>
 #include <boost/date_time/posix_time/posix_time.hpp>