changeset 4899:3ab57510f6dd proto-filter-instance-returning-error-code

integration mainline->proto-filter-instance-returning-error-code
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sun, 20 Feb 2022 12:59:30 +0100
parents 656784ac6759 (current diff) 181e67f9d129 (diff)
children 260377d84e9f
files OrthancFramework/Resources/CMake/OpenSslConfigurationStatic-1.0.2.cmake OrthancFramework/Resources/CMake/OpenSslConfigurationStatic-1.1.1.cmake OrthancFramework/Resources/Patches/openssl-1.1.1-conf.h.in OrthancFramework/Resources/Patches/openssl-1.1.1k.patch OrthancFramework/Sources/DicomNetworking/IStoreRequestHandler.h OrthancFramework/Sources/DicomNetworking/Internals/StoreScp.cpp OrthancServer/Sources/main.cpp
diffstat 641 files changed, 6687 insertions(+), 3854 deletions(-) [+]
line wrap: on
line diff
--- a/AUTHORS	Wed Sep 29 10:32:23 2021 +0200
+++ b/AUTHORS	Sun Feb 20 12:59:30 2022 +0100
@@ -14,8 +14,13 @@
   4000 Liege
   Belgium
 
-* Osimis S.A.
+* Osimis S.A. <info@osimis.io>
   Quai Banning 6
   4000 Liege
   Belgium
   http://www.osimis.io/
+
+* ICTEAM, UCLouvain
+  Place de l'Universite 1
+  1348 Ottignies-Louvain-la-Neuve
+  Belgium
--- a/NEWS	Wed Sep 29 10:32:23 2021 +0200
+++ b/NEWS	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,74 @@
 Pending changes in the mainline
 ===============================
 
+General
+-------
+
+* Removed the OpenSSL license exception, as binary versions of Orthanc are now
+  designed to use OpenSSL 3.x, that was re-licensed under Apache 2.0, making
+  it compatible with the GPL/AGPL licenses used by the Orthanc project:
+  https://en.wikipedia.org/wiki/OpenSSL#Licensing
+  https://people.gnome.org/~markmc/openssl-and-the-gpl.html
+* New configuration "DicomAlwaysAllowFindWorklist" to complement the existing
+  "DicomAlwaysAllowFind" configuration.  "DicomAlwaysAllowFind" applies now 
+  only to C-Find for Patients/Studies/Series/Instances while C-Find for worklists are
+  covered by "DicomAlwaysAllowFindWorklist".  The same changes applies to new 
+  configurations in "DicomModalities": "AllowFind" is now complemented by 
+  "AllowFindWorklist".
+  This new option allows improved security management.  E.g: a modality might have
+  only "AllowStore" and "AllowFindWorklist" enabled but might have "AllowFind"
+  disabled to prevent listing past patient studies.
+  Possible BREAKING-CHANGE: if you relied on "DicomAlwaysAllowFind" or "AllowFind"
+  to specifically authorize C-Find for worklist, you now need to explicitly enable
+  "DicomAlwaysAllowFindWorklist" and/or "AllowFindWorklist"
+* Added a storage cache in RAM to avoid reading the same files multiple times from 
+  the storage.  This greatly improves, among other things, the performance of WADO-RS
+  retrieval of individual frames of multiframe instances.
+* New configuration option "MaximumStorageCacheSize" to configure the size of
+  the new storage cache.
+* New configuration option "ZipLoaderThreads" to configure the number of threads used
+  to read instances from storage when creating a Zip archive/media.
+* Support decoding of black-and-white images (with 1 bit per pixel), notably DICOM SEG
+* Added links to download attachments from the Orthanc Explorer
+
+REST API
+--------
+
+* API version upgraded to 16
+* If an image can not be decoded, ../preview and ../rendered routes are now returning 
+  unsupported.png only if the ?returnUnsupportedImage option is specified; otherwise, 
+  it raises a 415 error code.
+* Archive jobs response now contains a header Content-Disposition:filename='archive.zip'
+* "/instances/{...}/frames/{...}/numpy": Download the frame as a Python numpy array
+* "/instances/{...}/numpy": Download the instance as a Python numpy array
+* "/series/{...}/numpy": Download the series as a Python numpy array
+* Added a ?full option to "/patients|studies|series|instances/{...}/attachments" route
+  to show the mapping alias<->numerical id.
+* Added "/patients|studies|series|instances/{...}/attachments/{...}/info" route to retrieve
+  the full information about an attachment (size, type, MD5 and UUID)
+
+Lua
+---
+
+* New "ReceivedCStoreInstanceFilter" Lua callback to filter instances received
+  through C-Store and return a specific C-Store status code.
+
+Plugins
+-------
+
+* New function in the SDK: OrthancPluginRegisterIncomingCStoreInstanceFilter()
+
+Maintenance
+-----------
+
 * Fix handling of option "DeidentifyLogs", notably for tags (0010,0010) and (0010,0020)
+* New configuration options:
+  - "DicomThreadsCount" to set the number of threads in the embedded DICOM server
+* Fix instances accumulating in DB while their attachments were not stored because of 
+  MaximumStorageSize limit reached with a single patient in DB.
+* Dropped support for static compilation of OpenSSL 1.0.2 and 1.1.1
+* Upgraded dependencies for static builds (notably on Windows and LSB):
+  - openssl 3.0.1
 
 
 Version 1.9.7 (2021-08-31)
--- a/OrthancFramework/Resources/CMake/AutoGeneratedCode.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/AutoGeneratedCode.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/BoostConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/BoostConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/CivetwebConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/CivetwebConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/Compiler.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/Compiler.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/DcmtkConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/DcmtkConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.0.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.0.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.2.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.2.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.4.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.4.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.5.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.5.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.6.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/DcmtkConfigurationStatic-3.6.6.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/DownloadOrthancFramework.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/DownloadOrthancFramework.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
@@ -71,7 +72,10 @@
       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}")
+        message("Bad version of the Orthanc framework, assuming a pre-release: ${ORTHANC_FRAMEWORK_VERSION}")
+        set(ORTHANC_FRAMEWORK_MAJOR 999)
+        set(ORTHANC_FRAMEWORK_MINOR 999)
+        set(ORTHANC_FRAMEWORK_REVISION 999)
       endif()
 
       if (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.3.1")
@@ -158,6 +162,9 @@
       elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "23ad1b9c7800")
         # For "Toolbox::ReadJson()" and "Toolbox::Write{...}Json()" (pre-1.9.0)
         set(ORTHANC_FRAMEWORK_MD5 "9af92080e57c60dd288eba46ce606c00")
+      elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "b2e08d83e21d")
+        # WSI 1.1 (framework pre-1.9.8), to remove "-std=c++11"
+        set(ORTHANC_FRAMEWORK_MD5 "2eaa073cbb4b44ffba199ad93393b2b1")
       endif()
     endif()
   endif()
@@ -500,35 +507,6 @@
     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
-  # (same as variable JSONCPP_CXX11 in the source code of Orthanc)
-  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)
-      message("Switching to C++11 standard, as version of JsonCpp is >= 1.0.0")
-      if (CMAKE_COMPILER_IS_GNUCXX)
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
-      elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-      endif()
-    endif()
-  else()
-    message("Unable to detect the major version of JsonCpp, assuming < 1.0.0")
-  endif()
-  
   # Look for Orthanc framework shared library
   include(CheckCXXSymbolExists)
 
--- a/OrthancFramework/Resources/CMake/DownloadPackage.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/DownloadPackage.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/EmscriptenParameters.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/EmscriptenParameters.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/GoogleTestConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/GoogleTestConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/JsonCppConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/JsonCppConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
@@ -67,7 +68,7 @@
     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
+  # Detect if the version of JsonCpp is >= 1.0.0
   if (EXISTS ${JSONCPP_INCLUDE_DIR}/json/version.h)
     file(STRINGS
       "${JSONCPP_INCLUDE_DIR}/json/version.h" 
@@ -98,11 +99,9 @@
   # https://gitlab.kitware.com/third-party/jsoncpp/commit/56df2068470241f9043b676bfae415ed62a0c172
   add_definitions(-DJSONCPP_DEPRECATED_STACK_LIMIT=5000)
 
-  if (CMAKE_COMPILER_IS_GNUCXX)
-    message("Switching to C++11 standard in gcc, as version of JsonCpp is >= 1.0.0")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
-  elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
-    message("Switching to C++11 standard in clang, as version of JsonCpp is >= 1.0.0")
+  if (APPLE AND
+      "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+    # Explicitly adding "-std=c++11" is needed on XCode
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
   endif()
 endif()
--- a/OrthancFramework/Resources/CMake/LibCurlConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/LibCurlConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/LibIconvConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/LibIconvConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/LibIcuConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/LibIcuConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/LibJpegConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/LibJpegConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/LibP11Configuration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/LibP11Configuration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/LibPngConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/LibPngConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/LuaConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/LuaConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/MongooseConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/MongooseConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/OpenSslConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/OpenSslConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
@@ -19,10 +20,8 @@
 
 
 if (STATIC_BUILD OR NOT USE_SYSTEM_OPENSSL)
-  if (OPENSSL_STATIC_VERSION STREQUAL "1.0.2")
-    include(${CMAKE_CURRENT_LIST_DIR}/OpenSslConfigurationStatic-1.0.2.cmake)
-  elseif (OPENSSL_STATIC_VERSION STREQUAL "1.1.1")
-    include(${CMAKE_CURRENT_LIST_DIR}/OpenSslConfigurationStatic-1.1.1.cmake)
+  if (OPENSSL_STATIC_VERSION STREQUAL "3.0")
+    include(${CMAKE_CURRENT_LIST_DIR}/OpenSslConfigurationStatic-3.0.cmake)
   else()
     message(FATAL_ERROR "Unsupported version of OpenSSL: ${OPENSSL_STATIC_VERSION}")
   endif()
--- a/OrthancFramework/Resources/CMake/OpenSslConfigurationStatic-1.0.2.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,352 +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-2021 Osimis S.A., Belgium
-#
-# This program is free software: you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public License
-# as published by the Free Software Foundation, either version 3 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program. If not, see
-# <http://www.gnu.org/licenses/>.
-
-
-SET(OPENSSL_SOURCES_DIR ${CMAKE_BINARY_DIR}/openssl-1.0.2p)
-SET(OPENSSL_URL "http://orthanc.osimis.io/ThirdPartyDownloads/openssl-1.0.2p.tar.gz")
-SET(OPENSSL_MD5 "ac5eb30bf5798aa14b1ae6d0e7da58df")
-
-if (IS_DIRECTORY "${OPENSSL_SOURCES_DIR}")
-  set(FirstRun OFF)
-else()
-  set(FirstRun ON)
-endif()
-
-DownloadPackage(${OPENSSL_MD5} ${OPENSSL_URL} "${OPENSSL_SOURCES_DIR}")
-
-if (FirstRun)
-  file(MAKE_DIRECTORY ${OPENSSL_SOURCES_DIR}/include/openssl)
-
-  foreach(header
-      ${OPENSSL_SOURCES_DIR}/crypto/aes/aes.h
-      ${OPENSSL_SOURCES_DIR}/crypto/asn1/asn1.h
-      ${OPENSSL_SOURCES_DIR}/crypto/asn1/asn1_mac.h
-      ${OPENSSL_SOURCES_DIR}/crypto/asn1/asn1t.h
-      ${OPENSSL_SOURCES_DIR}/crypto/bf/blowfish.h
-      ${OPENSSL_SOURCES_DIR}/crypto/bio/bio.h
-      ${OPENSSL_SOURCES_DIR}/crypto/bn/bn.h
-      ${OPENSSL_SOURCES_DIR}/crypto/buffer/buffer.h
-      ${OPENSSL_SOURCES_DIR}/crypto/camellia/camellia.h
-      ${OPENSSL_SOURCES_DIR}/crypto/cast/cast.h
-      ${OPENSSL_SOURCES_DIR}/crypto/cmac/cmac.h
-      ${OPENSSL_SOURCES_DIR}/crypto/cms/cms.h
-      ${OPENSSL_SOURCES_DIR}/crypto/comp/comp.h
-      ${OPENSSL_SOURCES_DIR}/crypto/conf/conf.h
-      ${OPENSSL_SOURCES_DIR}/crypto/conf/conf_api.h
-      ${OPENSSL_SOURCES_DIR}/crypto/crypto.h
-      ${OPENSSL_SOURCES_DIR}/crypto/des/des.h
-      ${OPENSSL_SOURCES_DIR}/crypto/des/des_old.h
-      ${OPENSSL_SOURCES_DIR}/crypto/dh/dh.h
-      ${OPENSSL_SOURCES_DIR}/crypto/dsa/dsa.h
-      ${OPENSSL_SOURCES_DIR}/crypto/dso/dso.h
-      ${OPENSSL_SOURCES_DIR}/crypto/ebcdic.h
-      ${OPENSSL_SOURCES_DIR}/crypto/ec/ec.h
-      ${OPENSSL_SOURCES_DIR}/crypto/ecdh/ecdh.h
-      ${OPENSSL_SOURCES_DIR}/crypto/ecdsa/ecdsa.h
-      ${OPENSSL_SOURCES_DIR}/crypto/engine/engine.h
-      ${OPENSSL_SOURCES_DIR}/crypto/err/err.h
-      ${OPENSSL_SOURCES_DIR}/crypto/evp/evp.h
-      ${OPENSSL_SOURCES_DIR}/crypto/hmac/hmac.h
-      ${OPENSSL_SOURCES_DIR}/crypto/idea/idea.h
-      ${OPENSSL_SOURCES_DIR}/crypto/jpake/jpake.h
-      ${OPENSSL_SOURCES_DIR}/crypto/krb5/krb5_asn.h
-      ${OPENSSL_SOURCES_DIR}/crypto/lhash/lhash.h
-      ${OPENSSL_SOURCES_DIR}/crypto/md2/md2.h
-      ${OPENSSL_SOURCES_DIR}/crypto/md4/md4.h
-      ${OPENSSL_SOURCES_DIR}/crypto/md5/md5.h
-      ${OPENSSL_SOURCES_DIR}/crypto/mdc2/mdc2.h
-      ${OPENSSL_SOURCES_DIR}/crypto/modes/modes.h
-      ${OPENSSL_SOURCES_DIR}/crypto/objects/obj_mac.h
-      ${OPENSSL_SOURCES_DIR}/crypto/objects/objects.h
-      ${OPENSSL_SOURCES_DIR}/crypto/ocsp/ocsp.h
-      ${OPENSSL_SOURCES_DIR}/crypto/opensslconf.h
-      ${OPENSSL_SOURCES_DIR}/crypto/opensslv.h
-      ${OPENSSL_SOURCES_DIR}/crypto/ossl_typ.h
-      ${OPENSSL_SOURCES_DIR}/crypto/pem/pem.h
-      ${OPENSSL_SOURCES_DIR}/crypto/pem/pem2.h
-      ${OPENSSL_SOURCES_DIR}/crypto/pkcs12/pkcs12.h
-      ${OPENSSL_SOURCES_DIR}/crypto/pkcs7/pkcs7.h
-      ${OPENSSL_SOURCES_DIR}/crypto/pqueue/pqueue.h
-      ${OPENSSL_SOURCES_DIR}/crypto/rand/rand.h
-      ${OPENSSL_SOURCES_DIR}/crypto/rc2/rc2.h
-      ${OPENSSL_SOURCES_DIR}/crypto/rc4/rc4.h
-      ${OPENSSL_SOURCES_DIR}/crypto/rc5/rc5.h
-      ${OPENSSL_SOURCES_DIR}/crypto/ripemd/ripemd.h
-      ${OPENSSL_SOURCES_DIR}/crypto/rsa/rsa.h
-      ${OPENSSL_SOURCES_DIR}/crypto/seed/seed.h
-      ${OPENSSL_SOURCES_DIR}/crypto/sha/sha.h
-      ${OPENSSL_SOURCES_DIR}/crypto/srp/srp.h
-      ${OPENSSL_SOURCES_DIR}/crypto/stack/safestack.h
-      ${OPENSSL_SOURCES_DIR}/crypto/stack/stack.h
-      ${OPENSSL_SOURCES_DIR}/crypto/store/store.h
-      ${OPENSSL_SOURCES_DIR}/crypto/symhacks.h
-      ${OPENSSL_SOURCES_DIR}/crypto/ts/ts.h
-      ${OPENSSL_SOURCES_DIR}/crypto/txt_db/txt_db.h
-      ${OPENSSL_SOURCES_DIR}/crypto/ui/ui.h
-      ${OPENSSL_SOURCES_DIR}/crypto/ui/ui_compat.h
-      ${OPENSSL_SOURCES_DIR}/crypto/whrlpool/whrlpool.h
-      ${OPENSSL_SOURCES_DIR}/crypto/x509/x509.h
-      ${OPENSSL_SOURCES_DIR}/crypto/x509/x509_vfy.h
-      ${OPENSSL_SOURCES_DIR}/crypto/x509v3/x509v3.h
-      ${OPENSSL_SOURCES_DIR}/e_os2.h
-      ${OPENSSL_SOURCES_DIR}/ssl/dtls1.h
-      ${OPENSSL_SOURCES_DIR}/ssl/kssl.h
-      ${OPENSSL_SOURCES_DIR}/ssl/srtp.h
-      ${OPENSSL_SOURCES_DIR}/ssl/ssl.h
-      ${OPENSSL_SOURCES_DIR}/ssl/ssl2.h
-      ${OPENSSL_SOURCES_DIR}/ssl/ssl23.h
-      ${OPENSSL_SOURCES_DIR}/ssl/ssl3.h
-      ${OPENSSL_SOURCES_DIR}/ssl/tls1.h
-      )
-    file(COPY ${header} DESTINATION ${OPENSSL_SOURCES_DIR}/include/openssl)
-  endforeach()
-
-  file(RENAME
-    ${OPENSSL_SOURCES_DIR}/include/openssl/e_os2.h
-    ${OPENSSL_SOURCES_DIR}/include/openssl/e_os2_source.h)
-
-  # The following patch of "e_os2.h" prevents from building OpenSSL
-  # as a DLL under Windows. Otherwise, symbols have inconsistent
-  # linkage if ${OPENSSL_SOURCES} is used to create a DLL (notably
-  # if building an Orthanc plugin such as PostgreSQL or MySQL).
-  file(WRITE ${OPENSSL_SOURCES_DIR}/include/openssl/e_os2.h "
-#include \"e_os2_source.h\"
-#if defined(_WIN32)
-#  undef OPENSSL_EXPORT
-#  undef OPENSSL_IMPORT
-#  undef OPENSSL_EXTERN
-#  undef OPENSSL_GLOBAL
-#  define OPENSSL_EXPORT
-#  define OPENSSL_IMPORT
-#  define OPENSSL_EXTERN extern
-#  define OPENSSL_GLOBAL
-#endif
-")
-endif()
-
-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   # MD4 is necessary for MariaDB/MySQL client
-  -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/md4
-  ${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_OPENSSL_ENGINES)
-  list(APPEND OPENSSL_SOURCES_SUBDIRS
-    ${OPENSSL_SOURCES_DIR}/engines
-    )
-endif()
-
-list(APPEND OPENSSL_SOURCES_SUBDIRS
-  # EC, ECDH and ECDSA are necessary for PKCS11, and for contacting
-  # HTTPS servers that use TLS certificate encrypted with ECDSA
-  # (check the output of a recent version of the "sslscan"
-  # command). Until Orthanc <= 1.4.1, these features were only
-  # enabled if ENABLE_PKCS11 support was set to "ON".
-  # https://groups.google.com/d/msg/orthanc-users/2l-bhYIMEWg/oMmK33bYBgAJ
-  ${OPENSSL_SOURCES_DIR}/crypto/ec
-  ${OPENSSL_SOURCES_DIR}/crypto/ecdh
-  ${OPENSSL_SOURCES_DIR}/crypto/ecdsa
-  )
-
-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/md4/md4.c
-  ${OPENSSL_SOURCES_DIR}/crypto/md4/md4s.cpp
-  ${OPENSSL_SOURCES_DIR}/crypto/md4/md4test.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}/ssl/heartbeat_test.c
-  ${OPENSSL_SOURCES_DIR}/ssl/fatalerrtest.c
-  ${OPENSSL_SOURCES_DIR}/ssl/dtlstest.c
-  ${OPENSSL_SOURCES_DIR}/ssl/bad_dtls_test.c
-  ${OPENSSL_SOURCES_DIR}/ssl/clienthellotest.c
-  ${OPENSSL_SOURCES_DIR}/ssl/sslv2conftest.c
-
-  ${OPENSSL_SOURCES_DIR}/crypto/ec/ecp_nistz256.c
-  ${OPENSSL_SOURCES_DIR}/crypto/ec/ecp_nistz256_table.c
-  ${OPENSSL_SOURCES_DIR}/crypto/ec/ectest.c
-  ${OPENSSL_SOURCES_DIR}/crypto/ecdh/ecdhtest.c
-  ${OPENSSL_SOURCES_DIR}/crypto/ecdsa/ecdsatest.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")
-
-  if (ENABLE_OPENSSL_ENGINES)
-    link_libraries(crypt32)
-  endif()
-endif()
--- a/OrthancFramework/Resources/CMake/OpenSslConfigurationStatic-1.1.1.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,308 +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-2021 Osimis S.A., Belgium
-#
-# This program is free software: you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public License
-# as published by the Free Software Foundation, either version 3 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program. If not, see
-# <http://www.gnu.org/licenses/>.
-
-
-SET(OPENSSL_SOURCES_DIR ${CMAKE_BINARY_DIR}/openssl-1.1.1k)
-SET(OPENSSL_URL "http://orthanc.osimis.io/ThirdPartyDownloads/openssl-1.1.1k.tar.gz")
-SET(OPENSSL_MD5 "c4e7d95f782b08116afa27b30393dd27")
-
-if (IS_DIRECTORY "${OPENSSL_SOURCES_DIR}")
-  set(FirstRun OFF)
-else()
-  set(FirstRun ON)
-endif()
-
-DownloadPackage(${OPENSSL_MD5} ${OPENSSL_URL} "${OPENSSL_SOURCES_DIR}")
-
-if (FirstRun)
-  file(WRITE ${OPENSSL_SOURCES_DIR}/crypto/buildinf.h "
-#define DATE \"\"
-#define PLATFORM \"\"
-#define compiler_flags \"\"
-")
-  file(WRITE ${OPENSSL_SOURCES_DIR}/crypto/bn_conf.h "")
-  file(WRITE ${OPENSSL_SOURCES_DIR}/crypto/dso_conf.h "")
-
-  configure_file(
-    ${CMAKE_CURRENT_LIST_DIR}/../Patches/openssl-1.1.1-conf.h.in
-    ${OPENSSL_SOURCES_DIR}/include/openssl/opensslconf.h
-    )
-
-  # Apply the patches
-  execute_process(
-    COMMAND ${PATCH_EXECUTABLE} -p0 -N -i
-    ${CMAKE_CURRENT_LIST_DIR}/../Patches/openssl-1.1.1k.patch
-    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-    RESULT_VARIABLE Failure
-    )
-
-  if (Failure)
-    message(FATAL_ERROR "Error while patching a file")
-  endif()
-
-  file(RENAME
-    ${OPENSSL_SOURCES_DIR}/include/openssl/e_os2.h
-    ${OPENSSL_SOURCES_DIR}/include/openssl/e_os2_source.h)
-
-  # The following patch of "e_os2.h" prevents from building OpenSSL
-  # as a DLL under Windows. Otherwise, symbols have inconsistent
-  # linkage if ${OPENSSL_SOURCES} is used to create a DLL (notably
-  # if building an Orthanc plugin such as PostgreSQL or MySQL).
-  file(WRITE ${OPENSSL_SOURCES_DIR}/include/openssl/e_os2.h "
-#include \"e_os2_source.h\"
-#if defined(_WIN32)
-#  undef OPENSSL_EXPORT
-#  undef OPENSSL_IMPORT
-#  undef OPENSSL_EXTERN
-#  undef OPENSSL_GLOBAL
-#  define OPENSSL_EXPORT
-#  define OPENSSL_IMPORT
-#  define OPENSSL_EXTERN extern
-#  define OPENSSL_GLOBAL
-#endif
-")
-
-else()
-  message("The patches for OpenSSL have already been applied")
-endif()
-
-add_definitions(
-  -DOPENSSL_THREADS
-  -DOPENSSL_IA32_SSE2
-  -DOPENSSL_NO_ASM
-  -DOPENSSL_NO_DYNAMIC_ENGINE
-  -DOPENSSL_NO_DEVCRYPTOENG
-
-  -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   # MD4 is necessary for MariaDB/MySQL client
-  -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
-  -DOPENSSL_NO_AFALGENG
-
-  -DOPENSSLDIR="/usr/local/ssl"
-  )
-
-
-include_directories(
-  ${OPENSSL_SOURCES_DIR}
-  ${OPENSSL_SOURCES_DIR}/crypto
-  ${OPENSSL_SOURCES_DIR}/crypto/asn1
-  ${OPENSSL_SOURCES_DIR}/crypto/ec/curve448
-  ${OPENSSL_SOURCES_DIR}/crypto/ec/curve448/arch_32
-  ${OPENSSL_SOURCES_DIR}/crypto/evp
-  ${OPENSSL_SOURCES_DIR}/crypto/include
-  ${OPENSSL_SOURCES_DIR}/crypto/modes
-  ${OPENSSL_SOURCES_DIR}/include
-  )
-
-
-set(OPENSSL_SOURCES_SUBDIRS
-  ${OPENSSL_SOURCES_DIR}/crypto
-  ${OPENSSL_SOURCES_DIR}/crypto/aes
-  ${OPENSSL_SOURCES_DIR}/crypto/aria
-  ${OPENSSL_SOURCES_DIR}/crypto/asn1
-  ${OPENSSL_SOURCES_DIR}/crypto/async
-  ${OPENSSL_SOURCES_DIR}/crypto/async/arch
-  ${OPENSSL_SOURCES_DIR}/crypto/bio
-  ${OPENSSL_SOURCES_DIR}/crypto/blake2
-  ${OPENSSL_SOURCES_DIR}/crypto/bn
-  ${OPENSSL_SOURCES_DIR}/crypto/buffer
-  ${OPENSSL_SOURCES_DIR}/crypto/chacha
-  ${OPENSSL_SOURCES_DIR}/crypto/cmac
-  ${OPENSSL_SOURCES_DIR}/crypto/cms
-  ${OPENSSL_SOURCES_DIR}/crypto/comp
-  ${OPENSSL_SOURCES_DIR}/crypto/conf
-  ${OPENSSL_SOURCES_DIR}/crypto/ct
-  ${OPENSSL_SOURCES_DIR}/crypto/des
-  ${OPENSSL_SOURCES_DIR}/crypto/dh
-  ${OPENSSL_SOURCES_DIR}/crypto/dsa
-  ${OPENSSL_SOURCES_DIR}/crypto/dso
-  ${OPENSSL_SOURCES_DIR}/crypto/ec
-  ${OPENSSL_SOURCES_DIR}/crypto/ec/curve448
-  ${OPENSSL_SOURCES_DIR}/crypto/ec/curve448/arch_32
-  ${OPENSSL_SOURCES_DIR}/crypto/err
-  ${OPENSSL_SOURCES_DIR}/crypto/evp
-  ${OPENSSL_SOURCES_DIR}/crypto/hmac
-  ${OPENSSL_SOURCES_DIR}/crypto/kdf
-  ${OPENSSL_SOURCES_DIR}/crypto/lhash
-  ${OPENSSL_SOURCES_DIR}/crypto/md4
-  ${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/poly1305
-  ${OPENSSL_SOURCES_DIR}/crypto/pqueue
-  ${OPENSSL_SOURCES_DIR}/crypto/rand
-  ${OPENSSL_SOURCES_DIR}/crypto/ripemd
-  ${OPENSSL_SOURCES_DIR}/crypto/rsa
-  ${OPENSSL_SOURCES_DIR}/crypto/sha
-  ${OPENSSL_SOURCES_DIR}/crypto/siphash
-  ${OPENSSL_SOURCES_DIR}/crypto/sm2
-  ${OPENSSL_SOURCES_DIR}/crypto/sm3
-  ${OPENSSL_SOURCES_DIR}/crypto/sm4
-  ${OPENSSL_SOURCES_DIR}/crypto/srp
-  ${OPENSSL_SOURCES_DIR}/crypto/stack
-  ${OPENSSL_SOURCES_DIR}/crypto/store
-  ${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
-  ${OPENSSL_SOURCES_DIR}/ssl/record
-  ${OPENSSL_SOURCES_DIR}/ssl/statem
-  )
-
-if (ENABLE_OPENSSL_ENGINES)
-  add_definitions(
-    #-DENGINESDIR="/usr/local/lib/engines-1.1"  # On GNU/Linux
-    -DENGINESDIR="."
-    )
-
-  list(APPEND OPENSSL_SOURCES_SUBDIRS
-    ${OPENSSL_SOURCES_DIR}/engines
-    ${OPENSSL_SOURCES_DIR}/crypto/engine
-    )
-else()
-  add_definitions(-DOPENSSL_NO_ENGINE)
-endif()
-
-list(APPEND OPENSSL_SOURCES_SUBDIRS
-  # EC, ECDH and ECDSA are necessary for PKCS11, and for contacting
-  # HTTPS servers that use TLS certificate encrypted with ECDSA
-  # (check the output of a recent version of the "sslscan"
-  # command). Until Orthanc <= 1.4.1, these features were only
-  # enabled if ENABLE_PKCS11 support was set to "ON".
-  # https://groups.google.com/d/msg/orthanc-users/2l-bhYIMEWg/oMmK33bYBgAJ
-  ${OPENSSL_SOURCES_DIR}/crypto/ec
-  ${OPENSSL_SOURCES_DIR}/crypto/ecdh
-  ${OPENSSL_SOURCES_DIR}/crypto/ecdsa
-  )
-
-foreach(d ${OPENSSL_SOURCES_SUBDIRS})
-  AUX_SOURCE_DIRECTORY(${d} OPENSSL_SOURCES)
-endforeach()
-
-list(REMOVE_ITEM OPENSSL_SOURCES
-  ${OPENSSL_SOURCES_DIR}/crypto/LPdir_nyi.c
-  ${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/aes/aes_x86core.c
-  ${OPENSSL_SOURCES_DIR}/crypto/armcap.c
-  ${OPENSSL_SOURCES_DIR}/crypto/bio/bss_dgram.c
-  ${OPENSSL_SOURCES_DIR}/crypto/des/ncbc_enc.c
-  ${OPENSSL_SOURCES_DIR}/crypto/ec/ecp_nistz256.c
-  ${OPENSSL_SOURCES_DIR}/crypto/ec/ecp_nistz256_table.c
-  ${OPENSSL_SOURCES_DIR}/crypto/engine/eng_devcrypto.c
-  ${OPENSSL_SOURCES_DIR}/crypto/poly1305/poly1305_base2_44.c  # Cannot be compiled with MinGW
-  ${OPENSSL_SOURCES_DIR}/crypto/poly1305/poly1305_ieee754.c  # Cannot be compiled with MinGW
-  ${OPENSSL_SOURCES_DIR}/crypto/ppccap.c
-  ${OPENSSL_SOURCES_DIR}/crypto/s390xcap.c
-  ${OPENSSL_SOURCES_DIR}/crypto/sparcv9cap.c
-  ${OPENSSL_SOURCES_DIR}/engines/e_afalg.c  # Cannot be compiled with MinGW
-  )
-
-# Check out "${OPENSSL_SOURCES_DIR}/Configurations/README": "This is
-# default if no option is specified, it works on any supported
-# system." It is mandatory to define it as a macro, as it is used by
-# all the source files that include OpenSSL (e.g. "Core/Toolbox.cpp"
-# or curl)
-add_definitions(-DTHIRTY_TWO_BIT)
-
-
-if (NOT CMAKE_COMPILER_IS_GNUCXX OR
-    "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows" OR
-    "${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase")
-  # Disable the use of a gcc extension, that is neither available on
-  # MinGW, nor on LSB
-  add_definitions(
-    -DOPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
-    )
-endif()
-
-
-if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
-  set(OPENSSL_DEFINITIONS
-    "${OPENSSL_DEFINITIONS};OPENSSL_SYSNAME_WIN32;SO_WIN32;WIN32_LEAN_AND_MEAN;L_ENDIAN;NO_WINDOWS_BRAINDEATH")
-  
-  if (ENABLE_OPENSSL_ENGINES)
-    link_libraries(crypt32)
-  endif()
-
-  add_definitions(
-    -DOPENSSL_RAND_SEED_OS  # ${OPENSSL_SOURCES_DIR}/crypto/rand/rand_win.c
-    )
- 
-elseif ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase")
-  add_definitions(
-    # In order for "crypto/mem_sec.c" to compile on LSB
-    -DOPENSSL_NO_SECURE_MEMORY
-
-    # The "OPENSSL_RAND_SEED_OS" value implies a syscall() to
-    # "__NR_getrandom" (i.e. system call "getentropy(2)") in
-    # "rand_unix.c", which is not available in LSB.
-    -DOPENSSL_RAND_SEED_DEVRANDOM
-
-    # If "OPENSSL_NO_ERR" is not defined, the PostgreSQL plugin
-    # crashes with segmentation fault in function
-    # "build_SYS_str_reasons()", that is called from
-    # "OPENSSL_init_ssl()"
-    # https://bugs.orthanc-server.com/show_bug.cgi?id=193
-    -DOPENSSL_NO_ERR
-    )
-
-else()
-  # Fixes error "OpenSSL error: error:2406C06E:random number
-  # generator:RAND_DRBG_instantiate:error retrieving entropy" that was
-  # present in Orthanc 1.6.0, if statically linking on Ubuntu 18.04
-  add_definitions(
-    -DOPENSSL_RAND_SEED_OS
-    )
-endif()
-
-
-set_source_files_properties(
-  ${OPENSSL_SOURCES}
-    PROPERTIES COMPILE_DEFINITIONS
-    "${OPENSSL_DEFINITIONS};DSO_NONE"
-    )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Resources/CMake/OpenSslConfigurationStatic-3.0.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -0,0 +1,409 @@
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2021-2021 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+set(OPENSSL_VERSION_MAJOR 3)
+set(OPENSSL_VERSION_MINOR 0)
+set(OPENSSL_VERSION_PATCH 1)
+set(OPENSSL_VERSION_PRE_RELEASE "")
+set(OPENSSL_VERSION_FULL "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_PATCH}${OPENSSL_VERSION_PRE_RELEASE}")
+SET(OPENSSL_SOURCES_DIR ${CMAKE_BINARY_DIR}/openssl-${OPENSSL_VERSION_FULL})
+SET(OPENSSL_URL "http://orthanc.osimis.io/ThirdPartyDownloads/openssl-${OPENSSL_VERSION_FULL}.tar.gz")
+SET(OPENSSL_MD5 "7d07e849d77d276891edd579a8832bb3")
+
+if (IS_DIRECTORY "${OPENSSL_SOURCES_DIR}")
+  set(FirstRun OFF)
+else()
+  set(FirstRun ON)
+endif()
+
+DownloadPackage(${OPENSSL_MD5} ${OPENSSL_URL} "${OPENSSL_SOURCES_DIR}")
+
+
+if (FirstRun)
+  # Apply the patches
+  execute_process(
+    COMMAND ${PATCH_EXECUTABLE} -p0 -N -i
+    ${CMAKE_CURRENT_LIST_DIR}/../Patches/openssl-${OPENSSL_VERSION_FULL}.patch
+    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+    RESULT_VARIABLE Failure
+    )
+
+  if (Failure)
+    message(FATAL_ERROR "Error while patching a file")
+  endif()
+
+  execute_process(
+    COMMAND ${PYTHON_EXECUTABLE}
+    ${CMAKE_CURRENT_LIST_DIR}/../Patches/OpenSSL-ConfigureHeaders.py
+    "${OPENSSL_SOURCES_DIR}"
+    RESULT_VARIABLE Failure
+    )
+
+  if (Failure)
+    message(FATAL_ERROR "Error while configuring the OpenSSL headers")
+  endif()
+
+  file(WRITE ${OPENSSL_SOURCES_DIR}/include/openssl/opensslv.h "")
+  file(WRITE ${OPENSSL_SOURCES_DIR}/include/crypto/bn_conf.h "")
+  file(WRITE ${OPENSSL_SOURCES_DIR}/include/crypto/dso_conf.h "")
+
+  file(WRITE ${OPENSSL_SOURCES_DIR}/crypto/buildinf.h "
+#define DATE \"\"
+#define PLATFORM \"\"
+#define compiler_flags \"\"
+")
+
+else()
+  message("The patches for OpenSSL have already been applied")
+endif()
+
+
+if (OPENSSL_VERSION_PRE_RELEASE STREQUAL "")
+  set(VERSION_VERSION_OFFSET 0)
+else()
+  set(VERSION_VERSION_OFFSET 15)
+endif()
+
+math(EXPR OPENSSL_CONFIGURED_API "${OPENSSL_VERSION_MAJOR} * 10000 + ${OPENSSL_VERSION_MINOR} * 100")
+
+# This macro is normally defined in "opensslv.h.in"
+math(EXPR OPENSSL_VERSION_NUMBER "(${OPENSSL_VERSION_MAJOR} << 28) + (${OPENSSL_VERSION_MINOR} << 20) + (${OPENSSL_VERSION_PATCH} << 4) + ${VERSION_VERSION_OFFSET}")
+
+list(GET CMAKE_FIND_LIBRARY_SUFFIXES 0 OPENSSL_DSO_EXTENSION)
+
+add_definitions(
+  -DOPENSSL_VERSION_MAJOR=${OPENSSL_VERSION_MAJOR}
+  -DOPENSSL_VERSION_MINOR=${OPENSSL_VERSION_MINOR}
+  -DOPENSSL_VERSION_PATCH=${OPENSSL_VERSION_PATCH}
+  -DOPENSSL_CONFIGURED_API=${OPENSSL_CONFIGURED_API}
+  -DOPENSSL_VERSION_NUMBER=${OPENSSL_VERSION_NUMBER}
+  -DOPENSSL_VERSION_PRE_RELEASE="${OPENSSL_VERSION_PRE_RELEASE}"
+  -DOPENSSL_VERSION_BUILD_METADATA=""
+  -DOPENSSL_VERSION_TEXT="OpenSSL ${OPENSSL_VERSION_FULL}"
+  -DOPENSSL_VERSION_STR="${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_PATCH}"
+  -DOPENSSL_FULL_VERSION_STR="${OPENSSL_VERSION_FULL}"
+  -DDSO_EXTENSION="${OPENSSL_DSO_EXTENSION}"
+
+  -DOPENSSLDIR="/usr/local/ssl"
+  -DMODULESDIR=""  # TODO
+  
+  -DOPENSSL_BUILDING_OPENSSL
+  -DOPENSSL_THREADS
+  -DOPENSSL_IA32_SSE2
+  
+  -DOPENSSL_NO_AFALGENG
+  -DOPENSSL_NO_ASM
+  -DOPENSSL_NO_CHACHA  # Necessary for VC2015-64 since openssl-3.0.1
+  -DOPENSSL_NO_DEVCRYPTOENG
+  -DOPENSSL_NO_DYNAMIC_ENGINE
+  -DOPENSSL_NO_EC_NISTP_64_GCC_128
+  -DOPENSSL_NO_GOST
+  -DOPENSSL_NO_RFC3779
+  -DOPENSSL_NO_SCTP
+
+  -DOPENSSL_NO_KTLS  # TODO ?
+  )
+
+
+include_directories(
+  ${OPENSSL_SOURCES_DIR}
+  ${OPENSSL_SOURCES_DIR}/crypto/asn1
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/curve448
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/curve448/arch_32
+  ${OPENSSL_SOURCES_DIR}/crypto/evp
+  ${OPENSSL_SOURCES_DIR}/crypto/include
+  ${OPENSSL_SOURCES_DIR}/crypto/modes
+  ${OPENSSL_SOURCES_DIR}/include
+  ${OPENSSL_SOURCES_DIR}/providers/common/include
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/include
+  )
+
+
+set(OPENSSL_SOURCES_SUBDIRS
+  ## Assembly is disabled
+  # ${OPENSSL_SOURCES_DIR}/crypto/aes/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/bf/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/bn/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/camellia/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/cast/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/chacha/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/des/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/ec/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/md5/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/modes/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/poly1305/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/rc4/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/rc5/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/ripemd/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/sha/asm
+  # ${OPENSSL_SOURCES_DIR}/crypto/whrlpool/asm
+
+  ${OPENSSL_SOURCES_DIR}/crypto
+  ${OPENSSL_SOURCES_DIR}/crypto/aes
+  ${OPENSSL_SOURCES_DIR}/crypto/aria
+  ${OPENSSL_SOURCES_DIR}/crypto/asn1
+  ${OPENSSL_SOURCES_DIR}/crypto/async
+  ${OPENSSL_SOURCES_DIR}/crypto/async/arch
+  ${OPENSSL_SOURCES_DIR}/crypto/bf
+  ${OPENSSL_SOURCES_DIR}/crypto/bio
+  ${OPENSSL_SOURCES_DIR}/crypto/bn
+  ${OPENSSL_SOURCES_DIR}/crypto/buffer
+  ${OPENSSL_SOURCES_DIR}/crypto/camellia
+  ${OPENSSL_SOURCES_DIR}/crypto/cast
+  ${OPENSSL_SOURCES_DIR}/crypto/chacha
+  ${OPENSSL_SOURCES_DIR}/crypto/cmac
+  ${OPENSSL_SOURCES_DIR}/crypto/cmp
+  ${OPENSSL_SOURCES_DIR}/crypto/cms
+  ${OPENSSL_SOURCES_DIR}/crypto/comp
+  ${OPENSSL_SOURCES_DIR}/crypto/conf
+  ${OPENSSL_SOURCES_DIR}/crypto/crmf
+  ${OPENSSL_SOURCES_DIR}/crypto/ct
+  ${OPENSSL_SOURCES_DIR}/crypto/des
+  ${OPENSSL_SOURCES_DIR}/crypto/dh
+  ${OPENSSL_SOURCES_DIR}/crypto/dsa
+  ${OPENSSL_SOURCES_DIR}/crypto/dso
+  ${OPENSSL_SOURCES_DIR}/crypto/ec
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/curve448
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/curve448/arch_32
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/curve448/arch_64
+  ${OPENSSL_SOURCES_DIR}/crypto/encode_decode
+  ${OPENSSL_SOURCES_DIR}/crypto/engine
+  ${OPENSSL_SOURCES_DIR}/crypto/err
+  ${OPENSSL_SOURCES_DIR}/crypto/ess
+  ${OPENSSL_SOURCES_DIR}/crypto/evp
+  ${OPENSSL_SOURCES_DIR}/crypto/ffc
+  ${OPENSSL_SOURCES_DIR}/crypto/hmac
+  ${OPENSSL_SOURCES_DIR}/crypto/http
+  ${OPENSSL_SOURCES_DIR}/crypto/idea
+  ${OPENSSL_SOURCES_DIR}/crypto/kdf
+  ${OPENSSL_SOURCES_DIR}/crypto/lhash
+  ${OPENSSL_SOURCES_DIR}/crypto/md2
+  ${OPENSSL_SOURCES_DIR}/crypto/md4
+  ${OPENSSL_SOURCES_DIR}/crypto/md5
+  ${OPENSSL_SOURCES_DIR}/crypto/mdc2
+  ${OPENSSL_SOURCES_DIR}/crypto/modes
+  ${OPENSSL_SOURCES_DIR}/crypto/objects
+  ${OPENSSL_SOURCES_DIR}/crypto/ocsp
+  ${OPENSSL_SOURCES_DIR}/crypto/pem
+  ${OPENSSL_SOURCES_DIR}/crypto/perlasm
+  ${OPENSSL_SOURCES_DIR}/crypto/pkcs12
+  ${OPENSSL_SOURCES_DIR}/crypto/pkcs7
+  ${OPENSSL_SOURCES_DIR}/crypto/poly1305
+  ${OPENSSL_SOURCES_DIR}/crypto/property
+  ${OPENSSL_SOURCES_DIR}/crypto/rand
+  ${OPENSSL_SOURCES_DIR}/crypto/rc2
+  ${OPENSSL_SOURCES_DIR}/crypto/rc4
+  ${OPENSSL_SOURCES_DIR}/crypto/rc5
+  ${OPENSSL_SOURCES_DIR}/crypto/ripemd
+  ${OPENSSL_SOURCES_DIR}/crypto/rsa
+  ${OPENSSL_SOURCES_DIR}/crypto/seed
+  ${OPENSSL_SOURCES_DIR}/crypto/sha
+  ${OPENSSL_SOURCES_DIR}/crypto/siphash
+  ${OPENSSL_SOURCES_DIR}/crypto/sm2
+  ${OPENSSL_SOURCES_DIR}/crypto/sm3
+  ${OPENSSL_SOURCES_DIR}/crypto/sm4
+  ${OPENSSL_SOURCES_DIR}/crypto/srp
+  ${OPENSSL_SOURCES_DIR}/crypto/stack
+  ${OPENSSL_SOURCES_DIR}/crypto/store
+  ${OPENSSL_SOURCES_DIR}/crypto/ts
+  ${OPENSSL_SOURCES_DIR}/crypto/txt_db
+  ${OPENSSL_SOURCES_DIR}/crypto/ui
+  ${OPENSSL_SOURCES_DIR}/crypto/whrlpool
+  ${OPENSSL_SOURCES_DIR}/crypto/x509
+
+  # ${OPENSSL_SOURCES_DIR}/providers/implementations/rands/seeding  # OS-specific
+  ${OPENSSL_SOURCES_DIR}/providers
+  ${OPENSSL_SOURCES_DIR}/providers/common
+  ${OPENSSL_SOURCES_DIR}/providers/common/der
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/asymciphers
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/ciphers
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/digests
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/encode_decode
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/exchange
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/kdfs
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/kem
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/keymgmt
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/macs
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/rands
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/signature
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/storemgmt
+
+  ${OPENSSL_SOURCES_DIR}/ssl
+  ${OPENSSL_SOURCES_DIR}/ssl/record
+  ${OPENSSL_SOURCES_DIR}/ssl/statem
+  )
+
+if (ENABLE_OPENSSL_ENGINES)
+  add_definitions(
+    #-DENGINESDIR="/usr/local/lib/engines-1.1"  # On GNU/Linux
+    -DENGINESDIR="."
+    )
+
+  list(APPEND OPENSSL_SOURCES_SUBDIRS
+    ${OPENSSL_SOURCES_DIR}/engines
+    ${OPENSSL_SOURCES_DIR}/crypto/engine
+    )
+else()
+  add_definitions(-DOPENSSL_NO_ENGINE)
+endif()
+
+list(APPEND OPENSSL_SOURCES_SUBDIRS
+  # EC, ECDH and ECDSA are necessary for PKCS11, and for contacting
+  # HTTPS servers that use TLS certificate encrypted with ECDSA
+  # (check the output of a recent version of the "sslscan"
+  # command). Until Orthanc <= 1.4.1, these features were only
+  # enabled if ENABLE_PKCS11 support was set to "ON".
+  # https://groups.google.com/d/msg/orthanc-users/2l-bhYIMEWg/oMmK33bYBgAJ
+  ${OPENSSL_SOURCES_DIR}/crypto/ec
+  ${OPENSSL_SOURCES_DIR}/crypto/ecdh
+  ${OPENSSL_SOURCES_DIR}/crypto/ecdsa
+  )
+
+foreach(d ${OPENSSL_SOURCES_SUBDIRS})
+  AUX_SOURCE_DIRECTORY(${d} OPENSSL_SOURCES)
+endforeach()
+
+
+list(REMOVE_ITEM OPENSSL_SOURCES
+  # Files below are not part of the "libcrypto.a" and "libssl.a" that
+  # are created by compiling OpenSSL from sources
+  ${OPENSSL_SOURCES_DIR}/crypto/LPdir_nyi.c
+  ${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/aes/aes_x86core.c
+  ${OPENSSL_SOURCES_DIR}/crypto/armcap.c
+  ${OPENSSL_SOURCES_DIR}/crypto/des/ncbc_enc.c
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/ecp_nistp224.c
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/ecp_nistp256.c
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/ecp_nistp521.c
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/ecp_nistz256.c
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/ecp_nistz256_table.c
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/ecp_s390x_nistp.c
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/ecx_s390x.c
+  ${OPENSSL_SOURCES_DIR}/crypto/poly1305/poly1305_base2_44.c
+  ${OPENSSL_SOURCES_DIR}/crypto/rsa/rsa_acvp_test_params.c
+  ${OPENSSL_SOURCES_DIR}/crypto/s390xcap.c
+  ${OPENSSL_SOURCES_DIR}/engines/e_devcrypto.c
+  ${OPENSSL_SOURCES_DIR}/engines/e_loader_attic.c
+  ${OPENSSL_SOURCES_DIR}/providers/common/securitycheck_fips.c
+  ${OPENSSL_SOURCES_DIR}/providers/implementations/macs/blake2_mac_impl.c
+  
+  ${OPENSSL_SOURCES_DIR}/engines/e_afalg.c  # Fails on OS X and Visual Studio
+  ${OPENSSL_SOURCES_DIR}/crypto/poly1305/poly1305_ieee754.c  # Fails on Visual Studio
+
+  ${OPENSSL_SOURCES_DIR}/ssl/ktls.c   # TODO ?
+
+  # Disable PowerPC sources
+  ${OPENSSL_SOURCES_DIR}/crypto/bn/bn_ppc.c
+  ${OPENSSL_SOURCES_DIR}/crypto/chacha/chacha_ppc.c
+  ${OPENSSL_SOURCES_DIR}/crypto/ec/ecp_ppc.c
+  ${OPENSSL_SOURCES_DIR}/crypto/poly1305/poly1305_ppc.c
+  ${OPENSSL_SOURCES_DIR}/crypto/ppccap.c
+  ${OPENSSL_SOURCES_DIR}/crypto/sha/sha_ppc.c
+
+  # Disable SPARC sources
+  ${OPENSSL_SOURCES_DIR}/crypto/bn/bn_sparc.c
+  ${OPENSSL_SOURCES_DIR}/crypto/sparcv9cap.c
+  )
+
+
+if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
+    ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR
+    ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
+    ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" OR
+    APPLE)
+  list(APPEND OPENSSL_SOURCES
+    ${OPENSSL_SOURCES_DIR}/providers/implementations/rands/seeding/rand_unix.c
+    )
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
+  list(APPEND OPENSSL_SOURCES
+    ${OPENSSL_SOURCES_DIR}/providers/implementations/rands/seeding/rand_win.c
+    )  
+endif()
+  
+
+# Check out "${OPENSSL_SOURCES_DIR}/Configurations/README.md": "This
+# is default if no option is specified, it works on any supported
+# system." It is mandatory to define it as a macro, as it is used by
+# all the source files that include OpenSSL (e.g. "Core/Toolbox.cpp"
+# or curl)
+add_definitions(-DTHIRTY_TWO_BIT)
+
+
+if (NOT CMAKE_COMPILER_IS_GNUCXX OR
+    "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows" OR
+    "${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase")
+  # Disable the use of a gcc extension, that is neither available on
+  # MinGW, nor on LSB
+  add_definitions(
+    -DOPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
+    )
+endif()
+
+
+if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
+  set(OPENSSL_DEFINITIONS
+    "${OPENSSL_DEFINITIONS};OPENSSL_SYSNAME_WIN32;SO_WIN32;WIN32_LEAN_AND_MEAN;L_ENDIAN;NO_WINDOWS_BRAINDEATH")
+  
+  if (ENABLE_OPENSSL_ENGINES)
+    link_libraries(crypt32)
+  endif()
+
+  add_definitions(
+    -DOPENSSL_RAND_SEED_OS  # ${OPENSSL_SOURCES_DIR}/crypto/rand/rand_win.c
+    )
+ 
+elseif ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase")
+  add_definitions(
+    # In order for "crypto/mem_sec.c" to compile on LSB
+    -DOPENSSL_NO_SECURE_MEMORY
+
+    # The "OPENSSL_RAND_SEED_OS" value implies a syscall() to
+    # "__NR_getrandom" (i.e. system call "getentropy(2)") in
+    # "rand_unix.c", which is not available in LSB.
+    -DOPENSSL_RAND_SEED_DEVRANDOM
+
+    # If "OPENSSL_NO_ERR" is not defined, the PostgreSQL plugin
+    # crashes with segmentation fault in function
+    # "build_SYS_str_reasons()", that is called from
+    # "OPENSSL_init_ssl()"
+    # https://bugs.orthanc-server.com/show_bug.cgi?id=193
+    -DOPENSSL_NO_ERR
+    )
+
+else()
+  # Fixes error "OpenSSL error: error:2406C06E:random number
+  # generator:RAND_DRBG_instantiate:error retrieving entropy" that was
+  # present in Orthanc 1.6.0, if statically linking on Ubuntu 18.04
+  add_definitions(
+    -DOPENSSL_RAND_SEED_OS
+    )
+endif()
+
+
+set_source_files_properties(
+  ${OPENSSL_SOURCES}
+    PROPERTIES COMPILE_DEFINITIONS
+    "${OPENSSL_DEFINITIONS};DSO_NONE"
+    )
--- a/OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
@@ -182,6 +183,7 @@
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/Images/ImageAccessor.cpp
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/Images/ImageBuffer.cpp
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/Images/ImageProcessing.cpp
+    ${CMAKE_CURRENT_LIST_DIR}/../../Sources/Images/NumpyWriter.cpp
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/Images/PamReader.cpp
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/Images/PamWriter.cpp
     )
@@ -385,6 +387,7 @@
       ${CMAKE_CURRENT_LIST_DIR}/../../Sources/Compression/HierarchicalZipWriter.cpp
       ${CMAKE_CURRENT_LIST_DIR}/../../Sources/Compression/ZipWriter.cpp
       ${CMAKE_CURRENT_LIST_DIR}/../../Sources/FileStorage/StorageAccessor.cpp
+      ${CMAKE_CURRENT_LIST_DIR}/../../Sources/FileStorage/StorageCache.cpp
       )
   endif()
 endif()
--- a/OrthancFramework/Resources/CMake/OrthancFrameworkParameters.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/OrthancFrameworkParameters.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
@@ -37,7 +38,7 @@
 # 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 "15")
+set(ORTHANC_API_VERSION "16")
 
 
 #####################################################################
@@ -93,7 +94,7 @@
 set(MSVC_MULTIPLE_PROCESSES OFF CACHE BOOL "Add the /MP option to build with multiple processes if using Visual Studio")
 set(EMSCRIPTEN_TARGET_MODE "wasm" CACHE STRING "Sets the target mode for Emscripten (can be \"wasm\" or \"asm.js\")")
 set(EMSCRIPTEN_TRAP_MODE "" CACHE STRING "Sets the trap mode for Emscripten for numeric errors (can notably be empty, or \"clamp\")")
-set(OPENSSL_STATIC_VERSION "1.1.1" CACHE STRING "Version of OpenSSL to be used in static builds (can be \"1.0.2\", or \"1.1.1\")")
+set(OPENSSL_STATIC_VERSION "3.0" CACHE STRING "Version of OpenSSL to be used in static builds (can be \"3.0\")")
 set(CIVETWEB_OPENSSL_API "1.1" CACHE STRING "Version of the OpenSSL API to be used in civetweb in static builds (can be \"1.0\" or \"1.1\"")
 set(ORTHANC_LUA_VERSION "" CACHE STRING "Force the version of Lua to be used by Orthanc (for instance \"5.3\"), if empty, this will be autodetected")
 
--- a/OrthancFramework/Resources/CMake/PugixmlConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/PugixmlConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/SQLiteConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/SQLiteConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/UuidConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/UuidConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/VisualStudioPrecompiledHeaders.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/VisualStudioPrecompiledHeaders.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/WebAssembly/ArithmeticTests/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/WebAssembly/ArithmeticTests/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CMake/ZlibConfiguration.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CMake/ZlibConfiguration.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CheckOrthancFrameworkSymbols.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CheckOrthancFrameworkSymbols.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CodeGeneration/CheckDcmtkTransferSyntaxes.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CodeGeneration/CheckDcmtkTransferSyntaxes.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CodeGeneration/GenerateErrorCodes.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CodeGeneration/GenerateErrorCodes.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CodeGeneration/GenerateTransferSyntaxes.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CodeGeneration/GenerateTransferSyntaxes.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CodeGeneration/GenerateTransferSyntaxesDcmtk.mustache	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CodeGeneration/GenerateTransferSyntaxesDcmtk.mustache	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/CodeGeneration/GenerateTransferSyntaxesEnumerations.mustache	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/CodeGeneration/GenerateTransferSyntaxesEnumerations.mustache	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/DcmtkTools/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/DcmtkTools/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/DcmtkTools/dummy.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/DcmtkTools/dummy.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/EmbedResources.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/EmbedResources.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Graveyard/FromDcmtkBridge.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Graveyard/FromDcmtkBridge.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Graveyard/Multithreading/BagOfTasks.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Graveyard/Multithreading/BagOfTasks.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Graveyard/Multithreading/BagOfTasksProcessor.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Graveyard/Multithreading/BagOfTasksProcessor.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Graveyard/Multithreading/BagOfTasksProcessor.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Graveyard/Multithreading/BagOfTasksProcessor.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Graveyard/Multithreading/ICommand.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Graveyard/Multithreading/ICommand.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Graveyard/Multithreading/ILockable.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Graveyard/Multithreading/ILockable.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Graveyard/Multithreading/Locker.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Graveyard/Multithreading/Locker.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Graveyard/Multithreading/Mutex.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Graveyard/Multithreading/Mutex.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Graveyard/Multithreading/Mutex.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Graveyard/Multithreading/Mutex.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Graveyard/Multithreading/ReaderWriterLock.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Graveyard/Multithreading/ReaderWriterLock.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Graveyard/Multithreading/ReaderWriterLock.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Graveyard/Multithreading/ReaderWriterLock.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Graveyard/TestTranscoding.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Graveyard/TestTranscoding.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Resources/Patches/OpenSSL-ConfigureHeaders.py	Sun Feb 20 12:59:30 2022 +0100
@@ -0,0 +1,165 @@
+#!/usr/bin/env python
+
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2021-2021 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+import json
+import os
+import re
+import sys
+
+if len(sys.argv) != 2:
+    raise Exception('Bad number of arguments')
+
+
+# This emulates "util/perl/OpenSSL/stackhash.pm"
+
+GENERATE_STACK_MACROS = '''
+SKM_DEFINE_STACK_OF_INTERNAL(${nametype}, ${realtype}, ${plaintype})
+#define sk_${nametype}_num(sk) OPENSSL_sk_num(ossl_check_const_${nametype}_sk_type(sk))
+#define sk_${nametype}_value(sk, idx) ((${realtype} *)OPENSSL_sk_value(ossl_check_const_${nametype}_sk_type(sk), (idx)))
+#define sk_${nametype}_new(cmp) ((STACK_OF(${nametype}) *)OPENSSL_sk_new(ossl_check_${nametype}_compfunc_type(cmp)))
+#define sk_${nametype}_new_null() ((STACK_OF(${nametype}) *)OPENSSL_sk_new_null())
+#define sk_${nametype}_new_reserve(cmp, n) ((STACK_OF(${nametype}) *)OPENSSL_sk_new_reserve(ossl_check_${nametype}_compfunc_type(cmp), (n)))
+#define sk_${nametype}_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_${nametype}_sk_type(sk), (n))
+#define sk_${nametype}_free(sk) OPENSSL_sk_free(ossl_check_${nametype}_sk_type(sk))
+#define sk_${nametype}_zero(sk) OPENSSL_sk_zero(ossl_check_${nametype}_sk_type(sk))
+#define sk_${nametype}_delete(sk, i) ((${realtype} *)OPENSSL_sk_delete(ossl_check_${nametype}_sk_type(sk), (i)))
+#define sk_${nametype}_delete_ptr(sk, ptr) ((${realtype} *)OPENSSL_sk_delete_ptr(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr)))
+#define sk_${nametype}_push(sk, ptr) OPENSSL_sk_push(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr))
+#define sk_${nametype}_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr))
+#define sk_${nametype}_pop(sk) ((${realtype} *)OPENSSL_sk_pop(ossl_check_${nametype}_sk_type(sk)))
+#define sk_${nametype}_shift(sk) ((${realtype} *)OPENSSL_sk_shift(ossl_check_${nametype}_sk_type(sk)))
+#define sk_${nametype}_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_${nametype}_sk_type(sk),ossl_check_${nametype}_freefunc_type(freefunc))
+#define sk_${nametype}_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr), (idx))
+#define sk_${nametype}_set(sk, idx, ptr) ((${realtype} *)OPENSSL_sk_set(ossl_check_${nametype}_sk_type(sk), (idx), ossl_check_${nametype}_type(ptr)))
+#define sk_${nametype}_find(sk, ptr) OPENSSL_sk_find(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr))
+#define sk_${nametype}_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr))
+#define sk_${nametype}_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_type(ptr), pnum)
+#define sk_${nametype}_sort(sk) OPENSSL_sk_sort(ossl_check_${nametype}_sk_type(sk))
+#define sk_${nametype}_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_${nametype}_sk_type(sk))
+#define sk_${nametype}_dup(sk) ((STACK_OF(${nametype}) *)OPENSSL_sk_dup(ossl_check_const_${nametype}_sk_type(sk)))
+#define sk_${nametype}_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(${nametype}) *)OPENSSL_sk_deep_copy(ossl_check_const_${nametype}_sk_type(sk), ossl_check_${nametype}_copyfunc_type(copyfunc), ossl_check_${nametype}_freefunc_type(freefunc)))
+#define sk_${nametype}_set_cmp_func(sk, cmp) ((sk_${nametype}_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_${nametype}_sk_type(sk), ossl_check_${nametype}_compfunc_type(cmp)))
+'''
+
+
+GENERATE_LHASH_MACROS = '''
+DEFINE_LHASH_OF_INTERNAL(${type});
+#define lh_${type}_new(hfn, cmp) ((LHASH_OF(${type}) *)OPENSSL_LH_new(ossl_check_${type}_lh_hashfunc_type(hfn), ossl_check_${type}_lh_compfunc_type(cmp)))
+#define lh_${type}_free(lh) OPENSSL_LH_free(ossl_check_${type}_lh_type(lh))
+#define lh_${type}_flush(lh) OPENSSL_LH_flush(ossl_check_${type}_lh_type(lh))
+#define lh_${type}_insert(lh, ptr) ((${type} *)OPENSSL_LH_insert(ossl_check_${type}_lh_type(lh), ossl_check_${type}_lh_plain_type(ptr)))
+#define lh_${type}_delete(lh, ptr) ((${type} *)OPENSSL_LH_delete(ossl_check_${type}_lh_type(lh), ossl_check_const_${type}_lh_plain_type(ptr)))
+#define lh_${type}_retrieve(lh, ptr) ((${type} *)OPENSSL_LH_retrieve(ossl_check_${type}_lh_type(lh), ossl_check_const_${type}_lh_plain_type(ptr)))
+#define lh_${type}_error(lh) OPENSSL_LH_error(ossl_check_${type}_lh_type(lh))
+#define lh_${type}_num_items(lh) OPENSSL_LH_num_items(ossl_check_${type}_lh_type(lh))
+#define lh_${type}_node_stats_bio(lh, out) OPENSSL_LH_node_stats_bio(ossl_check_const_${type}_lh_type(lh), out)
+#define lh_${type}_node_usage_stats_bio(lh, out) OPENSSL_LH_node_usage_stats_bio(ossl_check_const_${type}_lh_type(lh), out)
+#define lh_${type}_stats_bio(lh, out) OPENSSL_LH_stats_bio(ossl_check_const_${type}_lh_type(lh), out)
+#define lh_${type}_get_down_load(lh) OPENSSL_LH_get_down_load(ossl_check_${type}_lh_type(lh))
+#define lh_${type}_set_down_load(lh, dl) OPENSSL_LH_set_down_load(ossl_check_${type}_lh_type(lh), dl)
+#define lh_${type}_doall(lh, dfn) OPENSSL_LH_doall(ossl_check_${type}_lh_type(lh), ossl_check_${type}_lh_doallfunc_type(dfn))
+'''
+
+
+with open(os.path.join(os.path.dirname(os.path.realpath(__file__)),
+                       'OpenSSL-ExtractProvidersOIDs.json'), 'r') as f:
+    OIDS = json.loads(f.read())
+
+
+CURRENT_HEADER = ''
+    
+def Parse(match):
+    s = ''
+    
+    for t in re.findall('generate_stack_macros\("(.+?)"\)', match.group(1)):
+        s += (GENERATE_STACK_MACROS
+              .replace('${nametype}', t)
+              .replace('${realtype}', t)
+              .replace('${plaintype}', t))
+        
+    for t in re.findall('generate_const_stack_macros\("(.+?)"\)', match.group(1)):
+        s += (GENERATE_STACK_MACROS
+              .replace('${nametype}', t)
+              .replace('${realtype}', 'const %s' % t)
+              .replace('${plaintype}', t))
+
+    for t in re.findall('generate_stack_string_macros\(\)', match.group(1)):
+        s += (GENERATE_STACK_MACROS
+              .replace('${nametype}', 'OPENSSL_STRING')
+              .replace('${realtype}', 'char')
+              .replace('${plaintype}', 'char'))
+
+    for t in re.findall('generate_stack_const_string_macros\(\)', match.group(1)):
+        s += (GENERATE_STACK_MACROS
+              .replace('${nametype}', 'OPENSSL_CSTRING')
+              .replace('${realtype}', 'const char')
+              .replace('${plaintype}', 'char'))
+
+    for t in re.findall('generate_stack_block_macros\(\)', match.group(1)):
+        s += (GENERATE_STACK_MACROS
+              .replace('${nametype}', 'OPENSSL_BLOCK')
+              .replace('${realtype}', 'void')
+              .replace('${plaintype}', 'void'))
+        
+    for t in re.findall('generate_lhash_macros\("(.+?)"\)', match.group(1)):
+        s += GENERATE_LHASH_MACROS.replace('${type}', t)
+
+    for t in re.findall('\$config{rc4_int}', match.group(1)):
+        s += 'unsigned int'
+
+    for t in re.findall('oids_to_c::process_leaves\(.+?\)', match.group(1), re.MULTILINE | re.DOTALL):
+        if not CURRENT_HEADER in OIDS:
+            raise Exception('Unknown header: %s' % CURRENT_HEADER)
+
+        for (name, definition) in OIDS[CURRENT_HEADER].items():
+            s += '#define DER_OID_V_%s %s\n' % (name, ', '.join(definition))
+            s += '#define DER_OID_SZ_%s %d\n' % (name, len(definition))
+            s += 'extern const unsigned char ossl_der_oid_%s[DER_OID_SZ_%s];\n\n' % (name, name)
+        
+    return s
+
+
+for base in [ 'include/openssl',
+              'providers/common/include/prov' ]:
+    directory = os.path.join(sys.argv[1], base)
+    for source in os.listdir(directory):
+        if source.endswith('.h.in'):
+            target = re.sub('\.h\.in$', '.h', source)
+                            
+            with open(os.path.join(directory, source), 'r') as f:
+                with open(os.path.join(directory, target), 'w') as g:
+                    CURRENT_HEADER = source
+                    g.write(re.sub('{-(.*?)-}.*?$', Parse, f.read(),
+                                   flags = re.MULTILINE | re.DOTALL))
+
+
+with open(os.path.join(sys.argv[1], 'providers/common/der/orthanc_oids_gen.c'), 'w') as f:
+    for (header, content) in OIDS.items():
+        f.write('#include "prov/%s"\n' % re.sub('\.h\.in$', '.h', header))
+
+    f.write('\n')
+        
+    for (header, content) in OIDS.items():
+        for (name, definition) in content.items():
+            f.write('const unsigned char ossl_der_oid_%s[DER_OID_SZ_%s] = { DER_OID_V_%s };\n' % (
+                name, name, name))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Resources/Patches/OpenSSL-ExtractProvidersOIDs.json	Sun Feb 20 12:59:30 2022 +0100
@@ -0,0 +1,1225 @@
+{
+    "der_digests.h.in": {
+        "id_KMACWithSHAKE128": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x13"
+        ], 
+        "id_KMACWithSHAKE256": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x14"
+        ], 
+        "id_md2": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x02", 
+            "0x02"
+        ], 
+        "id_md5": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x02", 
+            "0x05"
+        ], 
+        "id_sha1": [
+            "DER_P_OBJECT", 
+            "5", 
+            "0x2B", 
+            "0x0E", 
+            "0x03", 
+            "0x02", 
+            "0x1A"
+        ], 
+        "id_sha224": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x04"
+        ], 
+        "id_sha256": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x01"
+        ], 
+        "id_sha384": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x02"
+        ], 
+        "id_sha3_224": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x07"
+        ], 
+        "id_sha3_256": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x08"
+        ], 
+        "id_sha3_384": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x09"
+        ], 
+        "id_sha3_512": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x0A"
+        ], 
+        "id_sha512": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x03"
+        ], 
+        "id_sha512_224": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x05"
+        ], 
+        "id_sha512_256": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x06"
+        ], 
+        "id_shake128": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x0B"
+        ], 
+        "id_shake128_len": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x11"
+        ], 
+        "id_shake256": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x0C"
+        ], 
+        "id_shake256_len": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02", 
+            "0x12"
+        ], 
+        "sigAlgs": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03"
+        ]
+    }, 
+    "der_dsa.h.in": {
+        "id_dsa": [
+            "DER_P_OBJECT", 
+            "7", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x38", 
+            "0x04", 
+            "0x01"
+        ], 
+        "id_dsa_with_sha1": [
+            "DER_P_OBJECT", 
+            "7", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x38", 
+            "0x04", 
+            "0x03"
+        ], 
+        "id_dsa_with_sha224": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x01"
+        ], 
+        "id_dsa_with_sha256": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x02"
+        ], 
+        "id_dsa_with_sha384": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x03"
+        ], 
+        "id_dsa_with_sha3_224": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x05"
+        ], 
+        "id_dsa_with_sha3_256": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x06"
+        ], 
+        "id_dsa_with_sha3_384": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x07"
+        ], 
+        "id_dsa_with_sha3_512": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x08"
+        ], 
+        "id_dsa_with_sha512": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x04"
+        ]
+    }, 
+    "der_ec.h.in": {
+        "c2onb191v4": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x08"
+        ], 
+        "c2onb191v5": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x09"
+        ], 
+        "c2onb239v4": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x0E"
+        ], 
+        "c2onb239v5": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x0F"
+        ], 
+        "c2pnb163v1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x01"
+        ], 
+        "c2pnb163v2": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x02"
+        ], 
+        "c2pnb163v3": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x03"
+        ], 
+        "c2pnb176w1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x04"
+        ], 
+        "c2pnb208w1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x0A"
+        ], 
+        "c2pnb272w1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x10"
+        ], 
+        "c2pnb304w1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x11"
+        ], 
+        "c2pnb368w1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x13"
+        ], 
+        "c2tnb191v1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x05"
+        ], 
+        "c2tnb191v2": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x06"
+        ], 
+        "c2tnb191v3": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x07"
+        ], 
+        "c2tnb239v1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x0B"
+        ], 
+        "c2tnb239v2": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x0C"
+        ], 
+        "c2tnb239v3": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x0D"
+        ], 
+        "c2tnb359v1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x12"
+        ], 
+        "c2tnb431r1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x00", 
+            "0x14"
+        ], 
+        "ecdsa_with_SHA1": [
+            "DER_P_OBJECT", 
+            "7", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x04", 
+            "0x01"
+        ], 
+        "ecdsa_with_SHA224": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x04", 
+            "0x03", 
+            "0x01"
+        ], 
+        "ecdsa_with_SHA256": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x04", 
+            "0x03", 
+            "0x02"
+        ], 
+        "ecdsa_with_SHA384": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x04", 
+            "0x03", 
+            "0x03"
+        ], 
+        "ecdsa_with_SHA512": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x04", 
+            "0x03", 
+            "0x04"
+        ], 
+        "id_ecPublicKey": [
+            "DER_P_OBJECT", 
+            "7", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x02", 
+            "0x01"
+        ], 
+        "id_ecdsa_with_sha3_224": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x09"
+        ], 
+        "id_ecdsa_with_sha3_256": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x0A"
+        ], 
+        "id_ecdsa_with_sha3_384": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x0B"
+        ], 
+        "id_ecdsa_with_sha3_512": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x0C"
+        ], 
+        "prime192v1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x01", 
+            "0x01"
+        ], 
+        "prime192v2": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x01", 
+            "0x02"
+        ], 
+        "prime192v3": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x01", 
+            "0x03"
+        ], 
+        "prime239v1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x01", 
+            "0x04"
+        ], 
+        "prime239v2": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x01", 
+            "0x05"
+        ], 
+        "prime239v3": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x01", 
+            "0x06"
+        ], 
+        "prime256v1": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0xCE", 
+            "0x3D", 
+            "0x03", 
+            "0x01", 
+            "0x07"
+        ]
+    }, 
+    "der_ecx.h.in": {
+        "id_Ed25519": [
+            "DER_P_OBJECT", 
+            "3", 
+            "0x2B", 
+            "0x65", 
+            "0x70"
+        ], 
+        "id_Ed448": [
+            "DER_P_OBJECT", 
+            "3", 
+            "0x2B", 
+            "0x65", 
+            "0x71"
+        ], 
+        "id_X25519": [
+            "DER_P_OBJECT", 
+            "3", 
+            "0x2B", 
+            "0x65", 
+            "0x6E"
+        ], 
+        "id_X448": [
+            "DER_P_OBJECT", 
+            "3", 
+            "0x2B", 
+            "0x65", 
+            "0x6F"
+        ]
+    }, 
+    "der_rsa.h.in": {
+        "hashAlgs": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x02"
+        ], 
+        "id_RSAES_OAEP": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x07"
+        ], 
+        "id_RSASSA_PSS": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x0A"
+        ], 
+        "id_mgf1": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x08"
+        ], 
+        "id_pSpecified": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x09"
+        ], 
+        "id_rsassa_pkcs1_v1_5_with_sha3_224": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x0D"
+        ], 
+        "id_rsassa_pkcs1_v1_5_with_sha3_256": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x0E"
+        ], 
+        "id_rsassa_pkcs1_v1_5_with_sha3_384": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x0F"
+        ], 
+        "id_rsassa_pkcs1_v1_5_with_sha3_512": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x03", 
+            "0x10"
+        ], 
+        "md2WithRSAEncryption": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x02"
+        ], 
+        "md4WithRSAEncryption": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x03"
+        ], 
+        "md5WithRSAEncryption": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x04"
+        ], 
+        "mdc2WithRSASignature": [
+            "DER_P_OBJECT", 
+            "5", 
+            "0x2B", 
+            "0x0E", 
+            "0x03", 
+            "0x02", 
+            "0x0E"
+        ], 
+        "ripemd160WithRSAEncryption": [
+            "DER_P_OBJECT", 
+            "6", 
+            "0x2B", 
+            "0x24", 
+            "0x03", 
+            "0x03", 
+            "0x01", 
+            "0x02"
+        ], 
+        "rsaEncryption": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x01"
+        ], 
+        "sha1WithRSAEncryption": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x05"
+        ], 
+        "sha224WithRSAEncryption": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x0E"
+        ], 
+        "sha256WithRSAEncryption": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x0B"
+        ], 
+        "sha384WithRSAEncryption": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x0C"
+        ], 
+        "sha512WithRSAEncryption": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x0D"
+        ], 
+        "sha512_224WithRSAEncryption": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x0F"
+        ], 
+        "sha512_256WithRSAEncryption": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x01", 
+            "0x10"
+        ]
+    }, 
+    "der_sm2.h.in": {
+        "curveSM2": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x81", 
+            "0x1C", 
+            "0xCF", 
+            "0x55", 
+            "0x01", 
+            "0x82", 
+            "0x2D"
+        ], 
+        "sm2_with_SM3": [
+            "DER_P_OBJECT", 
+            "8", 
+            "0x2A", 
+            "0x81", 
+            "0x1C", 
+            "0xCF", 
+            "0x55", 
+            "0x01", 
+            "0x83", 
+            "0x75"
+        ]
+    }, 
+    "der_wrap.h.in": {
+        "id_aes128_wrap": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x01", 
+            "0x05"
+        ], 
+        "id_aes192_wrap": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x01", 
+            "0x19"
+        ], 
+        "id_aes256_wrap": [
+            "DER_P_OBJECT", 
+            "9", 
+            "0x60", 
+            "0x86", 
+            "0x48", 
+            "0x01", 
+            "0x65", 
+            "0x03", 
+            "0x04", 
+            "0x01", 
+            "0x2D"
+        ], 
+        "id_alg_CMS3DESwrap": [
+            "DER_P_OBJECT", 
+            "11", 
+            "0x2A", 
+            "0x86", 
+            "0x48", 
+            "0x86", 
+            "0xF7", 
+            "0x0D", 
+            "0x01", 
+            "0x09", 
+            "0x10", 
+            "0x03", 
+            "0x06"
+        ]
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Resources/Patches/OpenSSL-ExtractProvidersOIDs.py	Sun Feb 20 12:59:30 2022 +0100
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2021-2021 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+##
+## This is a maintenance script to automatically extract the OIDs
+## generated from the ".asn1" files by the OpenSSL configuration
+## script "./Configure". This script generates the file
+## "OpenSSL-ExtractProvidersOIDs.json". The output JSON is then used
+## by "OpenSSL-ConfigureHeaders.py".
+##
+
+
+import json
+import os
+import re
+import sys
+
+if len(sys.argv) != 2:
+    raise Exception('Provide the path to your configured OpenSSL 3.x build directory')
+
+BASE = os.path.join(sys.argv[1], 'providers/common/include/prov')
+TARGET = 'OpenSSL-ExtractProvidersOIDs.json'
+RESULT = {}
+
+
+for source in os.listdir(BASE):
+    if source.endswith('.h.in'):
+        path = os.path.join(BASE, re.sub('.in$', '', source))
+
+        content = {}
+        
+        with open(path, 'r') as f:
+            for definition in re.findall('#define (DER_OID_V_.+?)#define (DER_OID_SZ_.+?)extern const(.+?)$', f.read(), re.MULTILINE | re.DOTALL):
+                oid = definition[0].strip().split(' ')
+                
+                name = oid[0].replace('DER_OID_V_', '')
+                oid = oid[1:]
+
+                sizes = definition[1].strip().split(' ')
+                if (name in content or
+                    len(sizes) != 2 or
+                    sizes[0] != 'DER_OID_SZ_%s' % name or
+                    int(sizes[1]) != len(oid)):
+                    raise Exception('Cannot parse %s, for OID %s' % (path, name))
+
+                content[name] = list(map(lambda x: x.replace(',', ''), oid))
+
+        RESULT[source] = content
+
+
+with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), TARGET), 'w') as f:
+    f.write(json.dumps(RESULT, sort_keys = True, indent = 4))
--- a/OrthancFramework/Resources/Patches/openssl-1.1.1-conf.h.in	Wed Sep 29 10:32:23 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
- * {- join("\n * ", @autowarntext) -}
- *
- * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License").  You may not use
- * this file except in compliance with the License.  You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/opensslv.h>
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-#ifdef OPENSSL_ALGORITHM_DEFINES
-# error OPENSSL_ALGORITHM_DEFINES no longer supported
-#endif
-
-/*
- * Sometimes OPENSSSL_NO_xxx ends up with an empty file and some compilers
- * don't like that.  This will hopefully silence them.
- */
-#define NON_EMPTY_TRANSLATION_UNIT static void *dummy = &dummy;
-
-/*
- * Applications should use -DOPENSSL_API_COMPAT=<version> to suppress the
- * declarations of functions deprecated in or before <version>. Otherwise, they
- * still won't see them if the library has been built to disable deprecated
- * functions.
- */
-#ifndef DECLARE_DEPRECATED
-# define DECLARE_DEPRECATED(f)   f;
-# ifdef __GNUC__
-#  if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0)
-#   undef DECLARE_DEPRECATED
-#   define DECLARE_DEPRECATED(f)    f __attribute__ ((deprecated));
-#  endif
-# elif defined(__SUNPRO_C)
-#  if (__SUNPRO_C >= 0x5130)
-#   undef DECLARE_DEPRECATED
-#   define DECLARE_DEPRECATED(f)    f __attribute__ ((deprecated));
-#  endif
-# endif
-#endif
-
-#ifndef OPENSSL_FILE
-# ifdef OPENSSL_NO_FILENAMES
-#  define OPENSSL_FILE ""
-#  define OPENSSL_LINE 0
-# else
-#  define OPENSSL_FILE __FILE__
-#  define OPENSSL_LINE __LINE__
-# endif
-#endif
-
-#ifndef OPENSSL_MIN_API
-# define OPENSSL_MIN_API 0
-#endif
-
-#if !defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT < OPENSSL_MIN_API
-# undef OPENSSL_API_COMPAT
-# define OPENSSL_API_COMPAT OPENSSL_MIN_API
-#endif
-
-/*
- * Do not deprecate things to be deprecated in version 1.2.0 before the
- * OpenSSL version number matches.
- */
-#if OPENSSL_VERSION_NUMBER < 0x10200000L
-# define DEPRECATEDIN_1_2_0(f)   f;
-#elif OPENSSL_API_COMPAT < 0x10200000L
-# define DEPRECATEDIN_1_2_0(f)   DECLARE_DEPRECATED(f)
-#else
-# define DEPRECATEDIN_1_2_0(f)
-#endif
-
-#if OPENSSL_API_COMPAT < 0x10100000L
-# define DEPRECATEDIN_1_1_0(f)   DECLARE_DEPRECATED(f)
-#else
-# define DEPRECATEDIN_1_1_0(f)
-#endif
-
-#if OPENSSL_API_COMPAT < 0x10000000L
-# define DEPRECATEDIN_1_0_0(f)   DECLARE_DEPRECATED(f)
-#else
-# define DEPRECATEDIN_1_0_0(f)
-#endif
-
-#if OPENSSL_API_COMPAT < 0x00908000L
-# define DEPRECATEDIN_0_9_8(f)   DECLARE_DEPRECATED(f)
-#else
-# define DEPRECATEDIN_0_9_8(f)
-#endif
-
-
-#define OPENSSL_UNISTD <unistd.h>
-
-#if 0
-/* Generate 80386 code? */
-{- ${processor} eq "386" ? "#define" : "#undef" -} I386_ONLY
-
-#undef OPENSSL_UNISTD
-#define OPENSSL_UNISTD {- ${unistd} -}
-
-{- ${export_var_as_fn} ? "#define" : "#undef" -} OPENSSL_EXPORT_VAR_AS_FUNCTION
-
-/*
- * The following are cipher-specific, but are part of the public API.
- */
-#if !defined(OPENSSL_SYS_UEFI)
-{- ${bn_ll} ? "# define" : "# undef" -} BN_LLONG
-/* Only one for the following should be defined */
-{- ${b64l} ? "# define" : "# undef" -} SIXTY_FOUR_BIT_LONG
-{- ${b64}  ? "# define" : "# undef" -} SIXTY_FOUR_BIT
-{- ${b32}  ? "# define" : "# undef" -} THIRTY_TWO_BIT
-#endif
-
-#define RC4_INT {- ${rc4_int} -}
-#endif
-
-#ifdef  __cplusplus
-}
-#endif
--- a/OrthancFramework/Resources/Patches/openssl-1.1.1k.patch	Wed Sep 29 10:32:23 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-diff -urEb openssl-1.1.1k.orig/crypto/rand/rand_unix.c openssl-1.1.1k/crypto/rand/rand_unix.c
---- openssl-1.1.1k.orig/crypto/rand/rand_unix.c	2021-04-21 11:33:05.241258372 +0200
-+++ openssl-1.1.1k/crypto/rand/rand_unix.c	2021-04-21 11:34:48.705287133 +0200
-@@ -455,6 +455,7 @@
-              * system call and this should always succeed which renders
-              * this alternative but essentially identical source moot.
-              */
-+#if !defined(__LSB_VERSION__)  // "syscall()" is not available in LSB
-             if (uname(&un) == 0) {
-                 kernel[0] = atoi(un.release);
-                 p = strchr(un.release, '.');
-@@ -465,6 +466,7 @@
-                     return 0;
-                 }
-             }
-+#endif
-             /* Open /dev/random and wait for it to be readable */
-             if ((fd = open(DEVRANDOM_WAIT, O_RDONLY)) != -1) {
-                 if (DEVRANDM_WAIT_USE_SELECT && fd < FD_SETSIZE) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Resources/Patches/openssl-3.0.1.patch	Sun Feb 20 12:59:30 2022 +0100
@@ -0,0 +1,53 @@
+diff -urEb openssl-3.0.1.orig/crypto/threads_win.c openssl-3.0.1/crypto/threads_win.c
+--- openssl-3.0.1.orig/crypto/threads_win.c	2021-12-24 16:56:23.016304241 +0100
++++ openssl-3.0.1/crypto/threads_win.c	2021-12-24 16:58:09.436272646 +0100
+@@ -207,13 +207,30 @@
+ int CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret,
+                      CRYPTO_RWLOCK *lock)
+ {
++#if defined(_WIN32) && !defined(_WIN64)
++    /**
++     * Prevents the following error, at least on Visual Studio 2008,
++     * but most probably on any Window 32bit system:
++     * "CoreLibrary.lib(threads_win.obj) : error LNK2019: unresolved
++     * external symbol _InterlockedOr64 referenced in function
++     * _CRYPTO_atomic_or". TODO - The lock should be locked!
++     * https://developercommunity.visualstudio.com/t/-interlockedexchangeadd64-is-unresolved-on-x86/1227636
++     **/
++    *ret = (*val) | op;
++#else
+     *ret = (uint64_t)InterlockedOr64((LONG64 volatile *)val, (LONG64)op) | op;
++#endif
+     return 1;
+ }
+ 
+ int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock)
+ {
++#if defined(_WIN32) && !defined(_WIN64)
++    /* See comment above */
++    *ret = *val;
++#else
+     *ret = (uint64_t)InterlockedOr64((LONG64 volatile *)val, 0);
++#endif
+     return 1;
+ }
+ 
+diff -urEb openssl-3.0.1.orig/providers/implementations/rands/seeding/rand_unix.c openssl-3.0.1/providers/implementations/rands/seeding/rand_unix.c
+--- openssl-3.0.1.orig/providers/implementations/rands/seeding/rand_unix.c	2021-12-24 16:56:23.056304227 +0100
++++ openssl-3.0.1/providers/implementations/rands/seeding/rand_unix.c	2021-12-24 16:57:03.408290650 +0100
+@@ -453,6 +453,7 @@
+              * system call and this should always succeed which renders
+              * this alternative but essentially identical source moot.
+              */
++#if !defined(__LSB_VERSION__)  // "syscall()" is not available in LSB
+             if (uname(&un) == 0) {
+                 kernel[0] = atoi(un.release);
+                 p = strchr(un.release, '.');
+@@ -463,6 +464,7 @@
+                     return 0;
+                 }
+             }
++#endif
+             /* Open /dev/random and wait for it to be readable */
+             if ((fd = open(DEVRANDOM_WAIT, O_RDONLY)) != -1) {
+                 if (DEVRANDM_WAIT_USE_SELECT && fd < FD_SETSIZE) {
--- a/OrthancFramework/Resources/RetrieveCACertificates.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/RetrieveCACertificates.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Samples/MicroService/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Samples/MicroService/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Samples/MicroService/Sample.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Samples/MicroService/Sample.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/ThirdParty/icu/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/ThirdParty/icu/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/ThirdParty/icu/Version.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/ThirdParty/icu/Version.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Toolchains/CrossToolchain.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Toolchains/CrossToolchain.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain32.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain32.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain64.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain64.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/Toolchains/MinGWToolchain.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/Toolchains/MinGWToolchain.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/WindowsResources.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/WindowsResources.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Resources/WindowsResources.rc	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Resources/WindowsResources.rc	Sun Feb 20 12:59:30 2022 +0100
@@ -15,7 +15,7 @@
             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, and Osimis SA, Belgium"
+            VALUE "LegalCopyright", "(c) 2012-${YEAR}, Sebastien Jodogne, University Hospital of Liege, Osimis S.A., and ICTEAM UCLouvain"
             VALUE "LegalTrademarks", "Licensing information is available at http://www.orthanc-server.com/"
             VALUE "OriginalFilename", "${FILENAME}"
             VALUE "ProductName", "${PRODUCT}"
--- a/OrthancFramework/SharedLibrary/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/SharedLibrary/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/SharedLibrary/DllMain.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/SharedLibrary/DllMain.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/SharedLibrary/OrthancFramework.h.in	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/SharedLibrary/OrthancFramework.h.in	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Cache/ICachePageProvider.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Cache/ICachePageProvider.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Cache/ICacheable.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Cache/ICacheable.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Cache/LeastRecentlyUsedIndex.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Cache/LeastRecentlyUsedIndex.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Cache/MemoryCache.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Cache/MemoryCache.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Cache/MemoryCache.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Cache/MemoryCache.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Cache/MemoryObjectCache.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Cache/MemoryObjectCache.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Cache/MemoryObjectCache.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Cache/MemoryObjectCache.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -37,6 +38,9 @@
 
 namespace Orthanc
 {
+  /**
+   *  Note: this class is thread safe
+   **/
   class ORTHANC_PUBLIC MemoryObjectCache : public boost::noncopyable
   {
   private:
--- a/OrthancFramework/Sources/Cache/MemoryStringCache.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Cache/MemoryStringCache.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -35,7 +36,12 @@
       content_(content)
     {
     }
-      
+
+    explicit StringValue(const char* buffer, size_t size) :
+      content_(buffer, size)
+    {
+    }
+
     const std::string& GetContent() const
     {
       return content_;
@@ -63,6 +69,13 @@
     cache_.Acquire(key, new StringValue(value));
   }
 
+  void MemoryStringCache::Add(const std::string& key,
+                              const void* buffer,
+                              size_t size)
+  {
+    cache_.Acquire(key, new StringValue(reinterpret_cast<const char*>(buffer), size));
+  }
+
   void MemoryStringCache::Invalidate(const std::string &key)
   {
     cache_.Invalidate(key);
--- a/OrthancFramework/Sources/Cache/MemoryStringCache.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Cache/MemoryStringCache.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -29,6 +30,8 @@
   /**
    * Facade object around "MemoryObjectCache" that caches a dictionary
    * of strings, using the "fetch/add" paradigm of memcached.
+   * 
+   * Note: this class is thread safe
    **/
   class ORTHANC_PUBLIC MemoryStringCache : public boost::noncopyable
   {
@@ -44,7 +47,11 @@
 
     void Add(const std::string& key,
              const std::string& value);
-    
+
+    void Add(const std::string& key,
+             const void* buffer,
+             size_t size);
+
     void Invalidate(const std::string& key);
 
     bool Fetch(std::string& value,
--- a/OrthancFramework/Sources/Cache/SharedArchive.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Cache/SharedArchive.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Cache/SharedArchive.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Cache/SharedArchive.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/ChunkedBuffer.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/ChunkedBuffer.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/ChunkedBuffer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/ChunkedBuffer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compatibility.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compatibility.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/DeflateBaseCompressor.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/DeflateBaseCompressor.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/DeflateBaseCompressor.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/DeflateBaseCompressor.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/GzipCompressor.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/GzipCompressor.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/GzipCompressor.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/GzipCompressor.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/HierarchicalZipWriter.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/HierarchicalZipWriter.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/HierarchicalZipWriter.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/HierarchicalZipWriter.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/IBufferCompressor.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/IBufferCompressor.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/IBufferCompressor.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/IBufferCompressor.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/ZipReader.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/ZipReader.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -353,7 +354,7 @@
         }
         else
         {
-          throw OrthancException(ErrorCode_BadFileFormat);
+          throw OrthancException(ErrorCode_BadFileFormat, "Invalid file or unsupported compression method (e.g. Deflate64)");
         }
       }
       
--- a/OrthancFramework/Sources/Compression/ZipReader.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/ZipReader.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/ZipWriter.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/ZipWriter.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/ZipWriter.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/ZipWriter.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/ZlibCompressor.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/ZlibCompressor.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Compression/ZlibCompressor.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Compression/ZlibCompressor.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomArray.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomArray.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomArray.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomArray.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomElement.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomElement.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomElement.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomElement.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomImageInformation.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomImageInformation.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -29,8 +30,10 @@
 #include "DicomImageInformation.h"
 
 #include "../Compatibility.h"
+#include "../Logging.h"
 #include "../OrthancException.h"
 #include "../Toolbox.h"
+
 #include <boost/lexical_cast.hpp>
 #include <limits>
 #include <cassert>
@@ -41,6 +44,16 @@
 {
   DicomImageInformation::DicomImageInformation(const DicomMap& values)
   {
+    std::string sopClassUid;
+    if (values.LookupStringValue(sopClassUid, DICOM_TAG_SOP_CLASS_UID, false))
+    {
+      sopClassUid = Toolbox::StripSpaces(sopClassUid);
+      if (sopClassUid == "1.2.840.10008.5.1.4.1.1.481.3" /* RT-STRUCT */)
+      {
+        LOG(WARNING) << "Orthanc::DicomImageInformation() should not be applied to SOP Class UID: " << sopClassUid;
+      }
+    }
+
     uint32_t pixelRepresentation = 0;
     uint32_t planarConfiguration = 0;
 
@@ -124,6 +137,11 @@
         bitsStored_ = bitsAllocated_;
       }
 
+      if (bitsStored_ > bitsAllocated_)
+      {
+        throw OrthancException(ErrorCode_BadFileFormat);
+      }
+
       if (!values.ParseUnsignedInteger32(highBit_, DICOM_TAG_HIGH_BIT))
       {
         highBit_ = bitsStored_ - 1;
@@ -168,7 +186,8 @@
     }
 
     if (bitsAllocated_ != 8 && bitsAllocated_ != 16 &&
-        bitsAllocated_ != 24 && bitsAllocated_ != 32)
+        bitsAllocated_ != 24 && bitsAllocated_ != 32 &&
+        bitsAllocated_ != 1 /* new in Orthanc 1.9.8 */)
     {
       throw OrthancException(ErrorCode_IncompatibleImageFormat, "Image not supported: " + boost::lexical_cast<std::string>(bitsAllocated_) + " bits allocated");
     }
@@ -186,7 +205,26 @@
       throw OrthancException(ErrorCode_IncompatibleImageFormat, "Image not supported: samples per pixel is 0");
     }
 
-    bytesPerValue_ = bitsAllocated_ / 8;
+    if (bitsStored_ == 1)
+    {
+      // This is the case of DICOM SEG, new in Orthanc 1.9.8
+      if (bitsAllocated_ != 1)
+      {
+        throw OrthancException(ErrorCode_BadFileFormat);
+      }
+      else if (width_ % 8 != 0)
+      {
+        throw OrthancException(ErrorCode_BadFileFormat, "Bad number of columns for a black-and-white image");
+      }
+      else
+      {
+        bytesPerValue_ = 0;  // Arbitrary initialization
+      }
+    }
+    else
+    {
+      bytesPerValue_ = bitsAllocated_ / 8;
+    }
 
     isPlanar_ = (planarConfiguration != 0 ? true : false);
     isSigned_ = (pixelRepresentation != 0 ? true : false);
@@ -237,7 +275,16 @@
 
   size_t DicomImageInformation::GetBytesPerValue() const
   {
-    return bytesPerValue_;
+    if (bitsStored_ == 1)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls,
+                             "This call is incompatible with black-and-white images");
+    }
+    else
+    {
+      assert(bitsAllocated_ >= 8);
+      return bytesPerValue_;
+    }
   }
 
   bool DicomImageInformation::IsSigned() const
@@ -315,6 +362,13 @@
         format = PixelFormat_Grayscale32;
         return true;
       }
+
+      if (GetBitsStored() == 1 && GetChannelCount() == 1 && !IsSigned())
+      {
+        // This is the case of DICOM SEG, new in Orthanc 1.9.8
+        format = PixelFormat_Grayscale8;
+        return true;
+      }
     }
 
     if (GetBitsStored() == 8 &&
@@ -332,10 +386,27 @@
 
   size_t DicomImageInformation::GetFrameSize() const
   {
-    return (GetHeight() *
-            GetWidth() *
-            GetBytesPerValue() *
-            GetChannelCount());
+    if (bitsStored_ == 1)
+    {
+      assert(GetWidth() % 8 == 0);
+      
+      if (GetChannelCount() == 1)
+      {
+        return GetHeight() * GetWidth() / 8;
+      }
+      else
+      {
+        throw OrthancException(ErrorCode_IncompatibleImageFormat,
+                               "Image not supported (multi-channel black-and-image image)");
+      }
+    }
+    else
+    {
+      return (GetHeight() *
+              GetWidth() *
+              GetBytesPerValue() *
+              GetChannelCount());
+    }
   }
 
 
--- a/OrthancFramework/Sources/DicomFormat/DicomImageInformation.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomImageInformation.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomInstanceHasher.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomInstanceHasher.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomInstanceHasher.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomInstanceHasher.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomIntegerPixelAccessor.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomIntegerPixelAccessor.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -88,7 +89,24 @@
        * means the order of the pixel values sent shall be R1, G1, B1,
        * R2, G2, B2, ..., etc.
        **/
-      rowOffset_ = information_.GetWidth() * information_.GetBytesPerValue() * information_.GetChannelCount();
+      if (information_.GetBitsStored() == 1)
+      {
+        if (information_.GetChannelCount() == 1 &&
+            information_.GetBitsAllocated() == 1)
+        {
+          assert(information_.GetWidth() % 8 == 0);  // Tested by DicomImageInformation
+          rowOffset_ = information_.GetWidth() / 8;
+        }
+        else
+        {
+          throw OrthancException(ErrorCode_IncompatibleImageFormat,
+                                 "Image not supported (multi-channel black-and-image image)");
+        }
+      }
+      else
+      {
+        rowOffset_ = information_.GetWidth() * information_.GetBytesPerValue() * information_.GetChannelCount();
+      }
     }
   }
 
@@ -115,7 +133,7 @@
       {
         for (unsigned int c = 0; c < channels; c++)
         {
-          int32_t v = GetValue(x, y);
+          int32_t v = GetValue(x, y, c);
           if (v < min)
             min = v;
           if (v > max)
@@ -133,53 +151,74 @@
     assert(x < information_.GetWidth() && 
            y < information_.GetHeight() && 
            channel < information_.GetChannelCount());
+
+    const uint8_t* pixel = (reinterpret_cast<const uint8_t*>(pixelData_) + 
+                            y * rowOffset_ + frame_ * frameOffset_);
     
-    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())
+    if (information_.GetBitsStored() == 1)
     {
-      /**
-       * 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();
+      // New in Orthanc 1.9.8, notably for DICOM SEG
+      assert(information_.GetBitsAllocated() == 1 &&
+             information_.GetChannelCount() == 1 &&
+             !information_.IsPlanar());
+      
+      uint8_t b = pixel[x / 8];
+
+      if (b & (1 << (x % 8)))
+      {
+        return 255;
+      }
+      else
+      {
+        return 0;
+      }
     }
     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();
-    }
+      // 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);
+      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();
+      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_);
+      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_);
+      }
     }
   }
 
--- a/OrthancFramework/Sources/DicomFormat/DicomIntegerPixelAccessor.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomIntegerPixelAccessor.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -64,7 +65,9 @@
     void GetExtremeValues(int32_t& min, 
                           int32_t& max) const;
 
-    int32_t GetValue(unsigned int x, unsigned int y, unsigned int channel = 0) const;
+    int32_t GetValue(unsigned int x,
+                     unsigned int y,
+                     unsigned int channel) const;
 
     const void* GetPixelData() const
     {
--- a/OrthancFramework/Sources/DicomFormat/DicomMap.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomMap.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomMap.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomMap.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomPath.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomPath.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomPath.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomPath.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomStreamReader.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomStreamReader.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomStreamReader.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomStreamReader.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomTag.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomTag.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomTag.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomTag.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomValue.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomValue.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/DicomValue.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomValue.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/StreamBlockReader.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/StreamBlockReader.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomFormat/StreamBlockReader.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomFormat/StreamBlockReader.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/DicomAssociation.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomAssociation.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/DicomAssociation.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomAssociation.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomAssociationParameters.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/DicomServer.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomServer.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -93,6 +94,7 @@
     port_(104),
     continue_(false),
     associationTimeout_(30),
+    threadsCount_(4),
     modalities_(NULL),
     findRequestHandlerFactory_(NULL),
     moveRequestHandlerFactory_(NULL),
@@ -424,7 +426,10 @@
 #endif
 
     continue_ = true;
-    pimpl_->workers_.reset(new RunnableWorkersPool(4));   // Use 4 workers - TODO as a parameter?
+
+    CLOG(INFO, DICOM) << "The embedded DICOM server will use " << threadsCount_ << " threads";
+
+    pimpl_->workers_.reset(new RunnableWorkersPool(threadsCount_));
     pimpl_->thread_ = boost::thread(ServerThread, this, maximumPduLength_, useDicomTls_);
   }
 
@@ -588,4 +593,16 @@
   {
     return remoteCertificateRequired_;
   }
+
+  void DicomServer::SetThreadsCount(unsigned int threads)
+  {
+    if (threads == 0)
+    {
+      throw OrthancException(ErrorCode_ParameterOutOfRange);
+    }
+    
+    Stop();
+    threadsCount_ = threads;
+  }
+
 }
--- a/OrthancFramework/Sources/DicomNetworking/DicomServer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomServer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -72,6 +73,7 @@
     uint16_t port_;
     bool continue_;
     uint32_t associationTimeout_;
+    unsigned int threadsCount_;
     IRemoteModalities* modalities_;
     IFindRequestHandlerFactory* findRequestHandlerFactory_;
     IMoveRequestHandlerFactory* moveRequestHandlerFactory_;
@@ -89,6 +91,7 @@
     unsigned int maximumPduLength_;
     bool         remoteCertificateRequired_;  // New in 1.9.3
 
+
     static void ServerThread(DicomServer* server,
                              unsigned int maximumPduLength,
                              bool useDicomTls);
@@ -163,5 +166,8 @@
 
     void SetRemoteCertificateRequired(bool required);
     bool IsRemoteCertificateRequired() const;
+
+    void SetThreadsCount(unsigned int threadsCount);
+
   };
 }
--- a/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/DicomStoreUserConnection.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/IApplicationEntityFilter.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IApplicationEntityFilter.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/IFindRequestHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IFindRequestHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/IFindRequestHandlerFactory.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IFindRequestHandlerFactory.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/IGetRequestHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IGetRequestHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/IGetRequestHandlerFactory.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IGetRequestHandlerFactory.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/IMoveRequestHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IMoveRequestHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/IMoveRequestHandlerFactory.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IMoveRequestHandlerFactory.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/IStorageCommitmentRequestHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IStorageCommitmentRequestHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/IStorageCommitmentRequestHandlerFactory.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IStorageCommitmentRequestHandlerFactory.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/IStoreRequestHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IStoreRequestHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -39,9 +40,9 @@
     {
     }
 
-    virtual int  Handle(DcmDataset& dicom,
-                        const std::string& remoteIp,
-                        const std::string& remoteAet,
-                        const std::string& calledAet) = 0;
+    virtual uint16_t Handle(DcmDataset& dicom,
+                            const std::string& remoteIp,
+                            const std::string& remoteAet,
+                            const std::string& calledAet) = 0;
   };
 }
--- a/OrthancFramework/Sources/DicomNetworking/IStoreRequestHandlerFactory.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IStoreRequestHandlerFactory.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/IWorklistRequestHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IWorklistRequestHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/IWorklistRequestHandlerFactory.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/IWorklistRequestHandlerFactory.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/Internals/CommandDispatcher.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/CommandDispatcher.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -787,10 +788,18 @@
             break;
 
           case DIMSE_C_FIND_RQ:
-            request = DicomRequestType_Find;
-            supported = true;
-            break;
-
+            {
+              std::string sopClassUid(msg.msg.CFindRQ.AffectedSOPClassUID);
+              if (sopClassUid == UID_FINDModalityWorklistInformationModel)
+              {
+                request = DicomRequestType_FindWorklist;
+              }
+              else
+              {
+                request = DicomRequestType_Find;
+              }
+              supported = true;
+            }; break;
           case DIMSE_N_ACTION_RQ:
             request = DicomRequestType_NAction;
             supported = true;
@@ -874,6 +883,7 @@
               break;
 
             case DicomRequestType_Find:
+            case DicomRequestType_FindWorklist:
               if (server_.HasFindRequestHandlerFactory() || // Should always be true
                   server_.HasWorklistRequestHandlerFactory())
               {
--- a/OrthancFramework/Sources/DicomNetworking/Internals/CommandDispatcher.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/CommandDispatcher.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/Internals/DicomTls.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/DicomTls.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/Internals/DicomTls.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/DicomTls.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/Internals/FindScp.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/FindScp.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/Internals/FindScp.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/FindScp.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/Internals/GetScp.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/GetScp.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/Internals/GetScp.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/GetScp.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/Internals/MoveScp.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/MoveScp.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/Internals/MoveScp.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/MoveScp.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/Internals/StoreScp.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/StoreScp.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -161,14 +162,14 @@
             // which SOP class and SOP instance ?
 	    
 #if DCMTK_VERSION_NUMBER >= 364
-	    if (!DU_findSOPClassAndInstanceInDataSet(*imageDataSet, sopClass, sizeof(sopClass),
-						     sopInstance, sizeof(sopInstance), /*opt_correctUIDPadding*/ OFFalse))
+	            if (!DU_findSOPClassAndInstanceInDataSet(*imageDataSet, sopClass, sizeof(sopClass),
+						      sopInstance, sizeof(sopInstance), /*opt_correctUIDPadding*/ OFFalse))
 #else
               if (!DU_findSOPClassAndInstanceInDataSet(*imageDataSet, sopClass, sopInstance, /*opt_correctUIDPadding*/ OFFalse))
 #endif
               {
-		//LOG4CPP_ERROR(Internals::GetLogger(), "bad DICOM file: " << fileName);
-		rsp->DimseStatus = STATUS_STORE_Error_CannotUnderstand;
+		            //LOG4CPP_ERROR(Internals::GetLogger(), "bad DICOM file: " << fileName);
+		            rsp->DimseStatus = STATUS_STORE_Error_CannotUnderstand;
               }
               else if (strcmp(sopClass, req->AffectedSOPClassUID) != 0)
               {
@@ -182,12 +183,7 @@
               {
                 try
                 {
-                  int status = cbdata->handler->Handle(**imageDataSet, *cbdata->remoteIp, cbdata->remoteAET, cbdata->calledAET);
-
-                  if (status != 0)
-                  {
-                    rsp->DimseStatus = static_cast<DIC_US>(status);  
-                  }
+                  rsp->DimseStatus = cbdata->handler->Handle(**imageDataSet, *cbdata->remoteIp, cbdata->remoteAET, cbdata->calledAET);
                 }
                 catch (OrthancException& e)
                 {
--- a/OrthancFramework/Sources/DicomNetworking/Internals/StoreScp.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/StoreScp.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/NetworkingCompatibility.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/NetworkingCompatibility.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -34,6 +35,7 @@
 static const char* KEY_AET = "AET";
 static const char* KEY_ALLOW_ECHO = "AllowEcho";
 static const char* KEY_ALLOW_FIND = "AllowFind";
+static const char* KEY_ALLOW_FIND_WORKLIST = "AllowFindWorklist";
 static const char* KEY_ALLOW_GET = "AllowGet";
 static const char* KEY_ALLOW_MOVE = "AllowMove";
 static const char* KEY_ALLOW_N_ACTION = "AllowNAction";
@@ -60,6 +62,7 @@
     allowEcho_ = true;
     allowStore_ = true;
     allowFind_ = true;
+    allowFindWorklist_ = true;
     allowMove_ = true;
     allowGet_ = true;
     allowNAction_ = true;  // For storage commitment
@@ -249,6 +252,11 @@
       allowFind_ = SerializationToolbox::ReadBoolean(serialized, KEY_ALLOW_FIND);
     }
 
+    if (serialized.isMember(KEY_ALLOW_FIND_WORKLIST))
+    {
+      allowFindWorklist_ = SerializationToolbox::ReadBoolean(serialized, KEY_ALLOW_FIND_WORKLIST);
+    }
+
     if (serialized.isMember(KEY_ALLOW_STORE))
     {
       allowStore_ = SerializationToolbox::ReadBoolean(serialized, KEY_ALLOW_STORE);
@@ -313,6 +321,9 @@
       case DicomRequestType_Find:
         return allowFind_;
 
+      case DicomRequestType_FindWorklist:
+        return allowFindWorklist_;
+
       case DicomRequestType_Get:
         return allowGet_;
 
@@ -347,6 +358,10 @@
         allowFind_ = allowed;
         break;
 
+      case DicomRequestType_FindWorklist:
+        allowFindWorklist_ = allowed;
+        break;
+
       case DicomRequestType_Get:
         allowGet_ = allowed;
         break;
@@ -378,6 +393,7 @@
     return (!allowEcho_ ||
             !allowStore_ ||
             !allowFind_ ||
+            !allowFindWorklist_ ||
             !allowGet_ ||
             !allowMove_ ||
             !allowNAction_ ||
@@ -402,6 +418,7 @@
       target[KEY_ALLOW_ECHO] = allowEcho_;
       target[KEY_ALLOW_STORE] = allowStore_;
       target[KEY_ALLOW_FIND] = allowFind_;
+      target[KEY_ALLOW_FIND_WORKLIST] = allowFindWorklist_;
       target[KEY_ALLOW_GET] = allowGet_;
       target[KEY_ALLOW_MOVE] = allowMove_;
       target[KEY_ALLOW_N_ACTION] = allowNAction_;
--- a/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/RemoteModalityParameters.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -40,6 +41,7 @@
     bool                  allowEcho_;
     bool                  allowStore_;
     bool                  allowFind_;
+    bool                  allowFindWorklist_;
     bool                  allowMove_;
     bool                  allowGet_;
     bool                  allowNAction_;
--- a/OrthancFramework/Sources/DicomNetworking/TimeoutDicomConnectionManager.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/TimeoutDicomConnectionManager.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomNetworking/TimeoutDicomConnectionManager.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/TimeoutDicomConnectionManager.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/DcmtkTranscoder.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/DicomDirWriter.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/DicomDirWriter.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/DicomDirWriter.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/DicomDirWriter.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/DicomModification.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/DicomModification.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/DicomModification.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/DicomModification.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -733,10 +734,15 @@
           if (!(flags & DicomToJsonFlags_ConvertBinaryToNull))
           {
             Uint8* data = NULL;
+            Uint16* data16 = NULL;
             if (element.getUint8Array(data) == EC_Normal)
             {
               return new DicomValue(reinterpret_cast<const char*>(data), element.getLength(), true);
             }
+            else if (element.getUint16Array(data16) == EC_Normal)
+            {
+              return new DicomValue(reinterpret_cast<const char*>(data16), element.getLength(), true);
+            }
           }
 
           return new DicomValue;
@@ -1850,6 +1856,23 @@
           break;
         }
 
+        case EVR_xs: // unsigned short, signed short or multiple values
+        {
+          if (decoded->find('\\') != std::string::npos)
+          {
+            ok = element.putString(decoded->c_str()).good();
+          }
+          else if (decoded->find('-') != std::string::npos)
+          {
+            ok = element.putSint16(boost::lexical_cast<Sint16>(*decoded)).good();
+          }
+          else
+          {
+            ok = element.putUint16(boost::lexical_cast<Uint16>(*decoded)).good();  
+          }
+          break;
+        }
+
         case EVR_US:  // unsigned short
         {
           ok = element.putUint16(boost::lexical_cast<Uint16>(*decoded)).good();
@@ -1901,7 +1924,6 @@
          **/ 
 
         case EVR_ox:  // OB or OW depending on context
-        case EVR_xs:  // SS or US depending on context
         case EVR_lt:  // US, SS or OW depending on context, used for LUT Data (thus the name)
         case EVR_na:  // na="not applicable", for data which has no VR
         case EVR_up:  // up="unsigned pointer", used internally for DICOMDIR suppor
--- a/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge_TransferSyntaxes.impl.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge_TransferSyntaxes.impl.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/IDicomTranscoder.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/IDicomTranscoder.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/IDicomTranscoder.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/IDicomTranscoder.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/ITagVisitor.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ITagVisitor.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/Internals/DicomFrameIndex.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/Internals/DicomFrameIndex.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/Internals/DicomFrameIndex.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/Internals/DicomFrameIndex.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -542,6 +543,7 @@
     bool fastVersionSuccess = false;
     PixelFormat sourceFormat;
     if (!info.IsPlanar() &&
+        info.GetBitsStored() != 1 &&  // Black-and-white image, notably DICOM SEG (new in Orthanc 1.9.8)
         info.ExtractPixelFormat(sourceFormat, false))
     {
       try
--- a/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomCache.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomCache.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomCache.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomCache.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomDir.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomDir.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomDir.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomDir.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -1194,6 +1195,10 @@
         EmbedImage(mime, content);
         break;
 
+      case MimeType_Binary:
+        EmbedImage(mime, content);
+        break;
+
       case MimeType_Pdf:
         EmbedPdf(content);
         break;
@@ -1253,6 +1258,12 @@
         break;
       }
 
+      case MimeType_Binary:
+      {
+        EmbedRawPixelData(content);
+        break;
+      }
+
       default:
         throw OrthancException(ErrorCode_NotImplemented);
     }
@@ -1406,7 +1417,24 @@
     }    
   }
 
-  
+  void ParsedDicomFile::EmbedRawPixelData(const std::string& content)
+  {
+    DcmTag key(DICOM_TAG_PIXEL_DATA.GetGroup(), 
+               DICOM_TAG_PIXEL_DATA.GetElement());
+
+    std::unique_ptr<DcmPixelData> pixels(new DcmPixelData(key));
+
+    Uint8* target = NULL;
+    pixels->createUint8Array(content.size(), target);
+    memcpy(target, content.c_str(), content.size());
+
+    if (!GetDcmtkObject().getDataset()->insert(pixels.release(), false, false).good())
+    {
+      throw OrthancException(ErrorCode_InternalError);
+    }
+  }
+
+
   Encoding ParsedDicomFile::DetectEncoding(bool& hasCodeExtensions) const
   {
     return FromDcmtkBridge::DetectEncoding(hasCodeExtensions,
@@ -1474,11 +1502,14 @@
 
     InvalidateCache();
 
+    // In Orthanc <= 1.9.7, the "Modality" would have always be overwritten as "OT"
+    // https://groups.google.com/g/orthanc-users/c/eNSddNrQDtM/m/wc1HahimAAAJ
+    
     ReplacePlainString(DICOM_TAG_SOP_CLASS_UID, UID_EncapsulatedPDFStorage);
-    ReplacePlainString(FromDcmtkBridge::Convert(DCM_Modality), "OT");
-    ReplacePlainString(FromDcmtkBridge::Convert(DCM_ConversionType), "WSD");
-    ReplacePlainString(FromDcmtkBridge::Convert(DCM_MIMETypeOfEncapsulatedDocument), MIME_PDF);
-    //ReplacePlainString(FromDcmtkBridge::Convert(DCM_SeriesNumber), "1");
+    SetIfAbsent(FromDcmtkBridge::Convert(DCM_Modality), "OT");
+    SetIfAbsent(FromDcmtkBridge::Convert(DCM_ConversionType), "WSD");
+    SetIfAbsent(FromDcmtkBridge::Convert(DCM_MIMETypeOfEncapsulatedDocument), MIME_PDF);
+    //SetIfAbsent(FromDcmtkBridge::Convert(DCM_SeriesNumber), "1");
 
     std::unique_ptr<DcmPolymorphOBOW> element(new DcmPolymorphOBOW(DCM_EncapsulatedDocument));
 
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -211,6 +212,8 @@
     void EmbedImage(MimeType mime,
                     const std::string& content);
 
+    void EmbedRawPixelData(const std::string& content);
+
     Encoding DetectEncoding(bool& hasCodeExtensions) const;
 
     // WARNING: This function only sets the encoding, it will not
--- a/OrthancFramework/Sources/DicomParsing/ToDcmtkBridge.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ToDcmtkBridge.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/DicomParsing/ToDcmtkBridge.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/DicomParsing/ToDcmtkBridge.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Endianness.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Endianness.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/EnumerationDictionary.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/EnumerationDictionary.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Enumerations.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Enumerations.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -51,6 +52,7 @@
   static const char* const MIME_ZIP = "application/zip";
   static const char* const MIME_DICOM_WEB_JSON = "application/dicom+json";
   static const char* const MIME_DICOM_WEB_XML = "application/dicom+xml";
+  static const char* const MIME_ICO = "image/x-icon";
 
   // This function is autogenerated by the script
   // "Resources/GenerateErrorCodes.py"
@@ -836,6 +838,10 @@
         return "Find";
         break;
 
+      case DicomRequestType_FindWorklist:
+        return "Find Worklist";
+        break;
+
       case DicomRequestType_Get:
         return "Get";
         break;
@@ -1097,7 +1103,10 @@
                 
       case MimeType_DicomWebXml:
         return MIME_DICOM_WEB_XML;
-                
+
+      case MimeType_Ico:
+        return MIME_ICO;
+
       default:
         throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
@@ -1806,6 +1815,11 @@
       target = MimeType_DicomWebXml;
       return true;
     }
+    else if (source == MIME_ICO)
+    {
+      target = MimeType_Ico;
+      return true;
+    }
     else
     {
       return false;
--- a/OrthancFramework/Sources/Enumerations.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Enumerations.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -77,7 +78,8 @@
     MimeType_Zip,
     MimeType_PrometheusText,  // Prometheus text-based exposition format (for metrics)
     MimeType_DicomWebJson,
-    MimeType_DicomWebXml
+    MimeType_DicomWebXml,
+    MimeType_Ico
   };
 
   
@@ -626,6 +628,7 @@
   {
     DicomRequestType_Echo,
     DicomRequestType_Find,
+    DicomRequestType_FindWorklist,
     DicomRequestType_Get,
     DicomRequestType_Move,
     DicomRequestType_Store,
--- a/OrthancFramework/Sources/Enumerations_TransferSyntaxes.impl.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Enumerations_TransferSyntaxes.impl.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/FileBuffer.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/FileBuffer.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/FileBuffer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/FileBuffer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/FileStorage/FileInfo.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/FileStorage/FileInfo.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/FileStorage/FileInfo.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/FileStorage/FileInfo.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/FileStorage/FilesystemStorage.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/FileStorage/FilesystemStorage.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/FileStorage/IStorageArea.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/FileStorage/IStorageArea.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/FileStorage/MemoryStorageArea.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/FileStorage/MemoryStorageArea.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/FileStorage/MemoryStorageArea.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/FileStorage/MemoryStorageArea.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/FileStorage/StorageAccessor.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/FileStorage/StorageAccessor.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -22,7 +23,10 @@
 
 #include "../PrecompiledHeaders.h"
 #include "StorageAccessor.h"
+#include "StorageCache.h"
 
+#include "../Logging.h"
+#include "../StringMemoryBuffer.h"
 #include "../Compatibility.h"
 #include "../Compression/ZlibCompressor.h"
 #include "../MetricsRegistry.h"
@@ -58,14 +62,18 @@
   };
 
 
-  StorageAccessor::StorageAccessor(IStorageArea &area) :
+  StorageAccessor::StorageAccessor(IStorageArea &area, StorageCache& cache) :
     area_(area),
+    cache_(cache),
     metrics_(NULL)
   {
   }
 
-  StorageAccessor::StorageAccessor(IStorageArea &area, MetricsRegistry &metrics) :
+  StorageAccessor::StorageAccessor(IStorageArea &area, 
+                                   StorageCache& cache,
+                                   MetricsRegistry &metrics) :
     area_(area),
+    cache_(cache),
     metrics_(&metrics)
   {
   }
@@ -93,6 +101,8 @@
         MetricsTimer timer(*this, METRICS_CREATE);
 
         area_.Create(uuid, data, size, type);
+        cache_.Add(uuid, type, data, size);
+
         return FileInfo(uuid, type, size, md5);
       }
 
@@ -123,6 +133,7 @@
           }
         }
 
+        cache_.Add(uuid, type, data, size);
         return FileInfo(uuid, type, size, md5,
                         CompressionType_ZlibWithSize, compressed.size(), compressedMD5);
       }
@@ -145,6 +156,13 @@
   void StorageAccessor::Read(std::string& content,
                              const FileInfo& info)
   {
+    if (cache_.Fetch(content, info.GetUuid(), info.GetContentType()))
+    {
+      LOG(INFO) << "Read attachment \"" << info.GetUuid() << "\" "
+                << "content type from cache";
+      return;
+    }
+
     switch (info.GetCompressionType())
     {
       case CompressionType_None:
@@ -152,7 +170,9 @@
         MetricsTimer timer(*this, METRICS_READ);
 
         std::unique_ptr<IMemoryBuffer> buffer(area_.Read(info.GetUuid(), info.GetContentType()));
-        buffer->MoveToString(content);        
+        buffer->MoveToString(content);
+
+        cache_.Add(info.GetUuid(), info.GetContentType(), content);
         break;
       }
 
@@ -168,6 +188,8 @@
         }
 
         zlib.Uncompress(content, compressed->GetData(), compressed->GetSize());
+
+        cache_.Add(info.GetUuid(), info.GetContentType(), content);
         break;
       }
 
@@ -196,6 +218,14 @@
   {
     MetricsTimer timer(*this, METRICS_REMOVE);
     area_.Remove(fileUuid, type);
+
+    cache_.Invalidate(fileUuid, type);
+    
+    // in ReadStartRange, we might have cached only the start of the file -> try to remove it
+    if (type == FileContentType_Dicom)
+    {
+      cache_.Invalidate(fileUuid, FileContentType_DicomUntilPixelData);
+    }
   }
 
   void StorageAccessor::Remove(const FileInfo &info)
@@ -203,15 +233,56 @@
     Remove(info.GetUuid(), info.GetContentType());
   }
 
+  IMemoryBuffer* StorageAccessor::ReadStartRange(const std::string& fileUuid,
+                                                 FileContentType contentType,
+                                                 uint64_t end /* exclusive */,
+                                                 FileContentType startFileContentType)
+  {
+    std::string content;
+    if (cache_.Fetch(content, fileUuid, contentType))
+    {
+      LOG(INFO) << "Read attachment \"" << fileUuid << "\" "
+                << "(range from " << 0 << " to " << end << ") from cache";
+
+      return StringMemoryBuffer::CreateFromCopy(content, 0, end);
+    }
+
+    if (cache_.Fetch(content, fileUuid, startFileContentType))
+    {
+      LOG(INFO) << "Read attachment \"" << fileUuid << "\" "
+                << "(range from " << 0 << " to " << end << ") from cache";
+
+      assert(content.size() == end);
+      return StringMemoryBuffer::CreateFromCopy(content);
+    }
+
+    std::unique_ptr<IMemoryBuffer> buffer(area_.ReadRange(fileUuid, contentType, 0, end));
+
+    // we've read only the first part of the file -> add an entry in the cache
+    // note the uuid is still the uuid of the full file but the type is the type of the start of the file !
+    assert(buffer->GetSize() == end);
+    cache_.Add(fileUuid, startFileContentType, buffer->GetData(), buffer->GetSize());
+    return buffer.release();
+  }
+
+
 #if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
   void StorageAccessor::SetupSender(BufferHttpSender& sender,
                                     const FileInfo& info,
                                     const std::string& mime)
   {
+    if (cache_.Fetch(sender.GetBuffer(), info.GetUuid(), info.GetContentType()))
+    {
+      LOG(INFO) << "Read attachment \"" << info.GetUuid() << "\" "
+                << "content type from cache";
+    }
+    else
     {
       MetricsTimer timer(*this, METRICS_READ);
       std::unique_ptr<IMemoryBuffer> buffer(area_.Read(info.GetUuid(), info.GetContentType()));
       buffer->MoveToString(sender.GetBuffer());
+
+      cache_.Add(info.GetUuid(), info.GetContentType(), sender.GetBuffer());
     }
 
     sender.SetContentType(mime);
--- a/OrthancFramework/Sources/FileStorage/StorageAccessor.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/FileStorage/StorageAccessor.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -54,6 +55,7 @@
 namespace Orthanc
 {
   class MetricsRegistry;
+  class StorageCache;
 
   /**
    * This class handles the compression/decompression of the raw files
@@ -66,6 +68,7 @@
     class MetricsTimer;
 
     IStorageArea&     area_;
+    StorageCache&     cache_;
     MetricsRegistry*  metrics_;
 
 #if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
@@ -75,9 +78,11 @@
 #endif
 
   public:
-    explicit StorageAccessor(IStorageArea& area);
+    explicit StorageAccessor(IStorageArea& area,
+                             StorageCache& cache);
 
     StorageAccessor(IStorageArea& area,
+                    StorageCache& cache,
                     MetricsRegistry& metrics);
 
     FileInfo Write(const void* data,
@@ -97,6 +102,11 @@
     void ReadRaw(std::string& content,
                  const FileInfo& info);
 
+    IMemoryBuffer* ReadStartRange(const std::string& fileUuid,
+                                  FileContentType fullFileContentType,
+                                  uint64_t end /* exclusive */,
+                                  FileContentType startFileContentType);
+
     void Remove(const std::string& fileUuid,
                 FileContentType type);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Sources/FileStorage/StorageCache.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -0,0 +1,138 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "../PrecompiledHeaders.h"
+#include "StorageCache.h"
+
+#include "../Compatibility.h"
+#include "../OrthancException.h"
+
+
+
+namespace Orthanc
+{
+  bool IsAcceptedContentType(FileContentType contentType)
+  {
+    return contentType == FileContentType_Dicom ||
+      contentType == FileContentType_DicomUntilPixelData ||
+      contentType == FileContentType_DicomAsJson;
+  }
+
+  const char* ToString(FileContentType contentType)
+  {
+    switch (contentType)
+    {
+      case FileContentType_Dicom:
+        return "dicom";
+      case FileContentType_DicomUntilPixelData:
+        return "dicom-header";
+      case FileContentType_DicomAsJson:
+        return "dicom-json";
+      default:
+        throw OrthancException(ErrorCode_InternalError,
+                               "ContentType not supported in StorageCache");
+    }
+  }
+
+  bool GetCacheKey(std::string& key, const std::string& uuid, FileContentType contentType)
+  {
+    if (contentType == FileContentType_Unknown || contentType >= FileContentType_StartUser)
+    {
+      return false;
+    }
+
+    key = uuid + ":" + std::string(ToString(contentType));
+
+    return true;
+  }
+  
+  void StorageCache::SetMaximumSize(size_t size)
+  {
+    cache_.SetMaximumSize(size);
+  }
+
+  void StorageCache::Add(const std::string& uuid, 
+                         FileContentType contentType,
+                         const std::string& value)
+  {
+    if (!IsAcceptedContentType(contentType))
+    {
+      return;
+    }
+
+    std::string key;
+
+    if (GetCacheKey(key, uuid, contentType))
+    {
+      cache_.Add(key, value);
+    }
+  }
+
+  void StorageCache::Add(const std::string& uuid, 
+                         FileContentType contentType,
+                         const void* buffer,
+                         size_t size)
+  {
+    if (!IsAcceptedContentType(contentType))
+    {
+      return;
+    }
+    
+    std::string key;
+
+    if (GetCacheKey(key, uuid, contentType))
+    {
+      cache_.Add(key, buffer, size);
+    }
+  }
+
+  void StorageCache::Invalidate(const std::string& uuid, FileContentType contentType)
+  {
+    std::string key;
+    
+    if (GetCacheKey(key, uuid, contentType))
+    {
+      cache_.Invalidate(key);
+    }
+  }
+
+  bool StorageCache::Fetch(std::string& value, 
+                           const std::string& uuid,
+                           FileContentType contentType)
+  {
+    if (!IsAcceptedContentType(contentType))
+    {
+      return false;
+    }
+
+    std::string key;
+    if (GetCacheKey(key, uuid, contentType))
+    {
+      return cache_.Fetch(value, key);
+    }
+
+    return false;
+  }
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Sources/FileStorage/StorageCache.h	Sun Feb 20 12:59:30 2022 +0100
@@ -0,0 +1,60 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "../Cache/MemoryStringCache.h"
+
+#include "../Compatibility.h"  // For ORTHANC_OVERRIDE
+
+#include <boost/thread/mutex.hpp>
+#include <map>
+
+namespace Orthanc
+{
+   /**
+   *  Note: this class is thread safe
+   **/
+   class ORTHANC_PUBLIC StorageCache : public boost::noncopyable
+    {
+      MemoryStringCache   cache_;
+    public:
+      void SetMaximumSize(size_t size);
+
+      void Add(const std::string& uuid, 
+               FileContentType contentType,
+               const std::string& value);
+
+      void Add(const std::string& uuid, 
+               FileContentType contentType,
+               const void* buffer,
+               size_t size);
+
+      void Invalidate(const std::string& uuid, FileContentType contentType);
+
+      bool Fetch(std::string& value, 
+                 const std::string& uuid,
+                 FileContentType contentType);
+
+    };
+}
--- a/OrthancFramework/Sources/HttpClient.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpClient.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpClient.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpClient.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/BufferHttpSender.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/BufferHttpSender.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/BufferHttpSender.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/BufferHttpSender.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/CStringMatcher.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/CStringMatcher.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/CStringMatcher.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/CStringMatcher.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/FilesystemHttpHandler.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/FilesystemHttpHandler.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/FilesystemHttpHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/FilesystemHttpHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/FilesystemHttpSender.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/FilesystemHttpSender.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/FilesystemHttpSender.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/FilesystemHttpSender.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/HttpContentNegociation.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpContentNegociation.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/HttpContentNegociation.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpContentNegociation.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/HttpFileSender.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpFileSender.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/HttpFileSender.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpFileSender.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/HttpOutput.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpOutput.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/HttpOutput.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpOutput.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/HttpServer.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpServer.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -72,6 +73,11 @@
 #if ORTHANC_ENABLE_SSL == 1
 #  include <openssl/opensslv.h>
 #  include <openssl/err.h>
+
+#  if OPENSSL_VERSION_NUMBER < 0x30000000L
+#    warning You are linking Orthanc against OpenSSL 1.x, whose license is incompatible with the GPLv3+ used by Orthanc >= 1.10.0. Please update to OpenSSL 3.x, that uses the Apache 2 license.
+#  endif
+
 #endif
 
 #define ORTHANC_REALM "Orthanc Secure Area"
--- a/OrthancFramework/Sources/HttpServer/HttpServer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpServer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/HttpStreamTranscoder.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpStreamTranscoder.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/HttpStreamTranscoder.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpStreamTranscoder.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/HttpToolbox.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpToolbox.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -50,8 +51,13 @@
       value = std::string(equal + 1, end);
     }
 
+#if 0
+    // These calls were present in Orthanc <= 1.9.7, but should not be
+    // used because mongoose/civetweb already implement URL decoding
+    // (cf. "mg_url_decode()")
     Toolbox::UrlDecode(name);
     Toolbox::UrlDecode(value);
+#endif
 
     result.push_back(std::make_pair(name, value));
   }
--- a/OrthancFramework/Sources/HttpServer/HttpToolbox.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpToolbox.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/IHttpHandler.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/IHttpHandler.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/IHttpHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/IHttpHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/IHttpOutputStream.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/IHttpOutputStream.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/IHttpStreamAnswer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/IHttpStreamAnswer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/IIncomingHttpRequestFilter.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/IIncomingHttpRequestFilter.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/IWebDavBucket.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/IWebDavBucket.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/MultipartStreamReader.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/MultipartStreamReader.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/StringHttpOutput.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/StringHttpOutput.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/StringHttpOutput.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/StringHttpOutput.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/StringMatcher.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/StringMatcher.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/StringMatcher.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/StringMatcher.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/WebDavStorage.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/WebDavStorage.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/HttpServer/WebDavStorage.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/HttpServer/WebDavStorage.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/IDynamicObject.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/IDynamicObject.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -63,5 +64,10 @@
     {
       return value_;
     }
+
+    void SetValue(const T& value)
+    {
+      value_ = value;
+    }
   };
 }
--- a/OrthancFramework/Sources/IMemoryBuffer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/IMemoryBuffer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/Font.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/Font.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/Font.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/Font.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/FontRegistry.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/FontRegistry.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/FontRegistry.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/FontRegistry.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/IImageWriter.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/IImageWriter.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/IImageWriter.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/IImageWriter.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/Image.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/Image.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/Image.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/Image.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/ImageAccessor.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/ImageAccessor.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/ImageAccessor.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/ImageAccessor.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/ImageBuffer.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/ImageBuffer.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/ImageBuffer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/ImageBuffer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/ImageProcessing.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/ImageProcessing.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -41,11 +42,13 @@
 
 #include <boost/math/special_functions/round.hpp>
 
+#include <algorithm>
 #include <cassert>
-#include <string.h>
 #include <limits>
+#include <list>
+#include <map>
 #include <stdint.h>
-#include <algorithm>
+#include <string.h>
 
 namespace Orthanc
 {
@@ -1859,157 +1862,388 @@
     }
   }
 
-  template <PixelFormat TargetFormat>
-  void FillPolygon_(ImageAccessor& image,
-                    const std::vector<ImageProcessing::ImagePoint>& points,
-                    int64_t value_)
+
+  namespace
   {
-    typedef typename PixelTraits<TargetFormat>::PixelType  TargetType;
-
-    TargetType value = PixelTraits<TargetFormat>::IntegerToPixel(value_);
-    int imageWidth = static_cast<int>(image.GetWidth());
-    int imageHeight = static_cast<int>(image.GetHeight());
-    int32_t left;
-    int32_t right;
-    int32_t top;
-    int32_t bottom;
-
-    // TODO: test clipping in UT (in Trello board)
-    ComputePolygonExtent(left, right, top, bottom, points);
-
-    // clip the computed extent with the target image
-    // L and R
-    left = std::max(0, left);
-    left = std::min(imageWidth, left);
-    right = std::max(0, right);
-    right = std::min(imageWidth, right);
-    if (left > right)
-      std::swap(left, right);
-
-    // T and B
-    top = std::max(0, top);
-    top = std::min(imageHeight, top);
-    bottom = std::max(0, bottom);
-    bottom = std::min(imageHeight, bottom);
-    if (top > bottom)
-      std::swap(top, bottom);
-
-    // from http://alienryderflex.com/polygon_fill/
-
-    // convert all "corner"  points to double only once
-    std::vector<double> cpx;
-    std::vector<double> cpy;
-    size_t cpSize = points.size();
-    for (size_t i = 0; i < points.size(); i++)
+#define USE_POLYGON_FRACTIONS 1
+
+    class PolygonEdge
     {
-      if (points[i].GetX() < 0 || points[i].GetX() >= imageWidth
-          || points[i].GetY() < 0 || points[i].GetY() >= imageHeight)
+    private:
+      int   yUpper;
+
+#if USE_POLYGON_FRACTIONS == 1
+      int  x;
+      int  xOffset;
+      int  dxPerScanNumerator;
+      int  dxPerScanDenominator;
+#else
+      float xIntersect;
+      float dxPerScan;
+#endif
+
+    public:
+      PolygonEdge(const ImageProcessing::ImagePoint& lower,
+                  const ImageProcessing::ImagePoint& upper,
+                  int yComp)
       {
-        throw OrthancException(ErrorCode_ParameterOutOfRange);
+        // cf. "makeEdgeRec()" in textbook
+
+        assert(upper.GetY() != lower.GetY());
+
+#if USE_POLYGON_FRACTIONS == 1
+        x = lower.GetX();
+        xOffset = 0;
+        dxPerScanNumerator = upper.GetX() - lower.GetX();
+        dxPerScanDenominator = upper.GetY() - lower.GetY();
+#else
+        dxPerScan = (static_cast<float>(upper.GetX() - lower.GetX()) /
+                     static_cast<float>(upper.GetY() - lower.GetY()));
+        xIntersect = lower.GetX();
+#endif
+    
+        if (upper.GetY() < yComp)
+        {
+          yUpper = upper.GetY() - 1;
+        }
+        else
+        {
+          yUpper = upper.GetY();
+        }
       }
-      cpx.push_back((double)points[i].GetX());
-      cpy.push_back((double)points[i].GetY());
-    }
-
-    // Draw the lines segments
-    for (size_t i = 0; i < (points.size() -1); i++)
-    {
-      ImageProcessing::DrawLineSegment(image, points[i].GetX(), points[i].GetY(), points[i+1].GetX(), points[i+1].GetY(), value_);
-    }
-    ImageProcessing::DrawLineSegment(image, points[points.size() -1].GetX(), points[points.size() -1].GetY(), points[0].GetX(), points[0].GetY(), value_);
-
-    std::vector<int32_t> nodeX;
-    nodeX.resize(cpSize);
-    int  pixelX, pixelY, i, swap ;
-
-    //  Loop through the rows of the image.
-    for (pixelY = top; pixelY < bottom; pixelY++)
-    {
-      double y = (double)pixelY;
-      //  Build a list of nodes.
-      int nodes = 0;
-      int j = static_cast<int>(cpSize) - 1;
-
-      for (i = 0; i < static_cast<int>(cpSize); i++)
+
+      void NextScanLine()
       {
-        if ((cpy[i] < y && cpy[j] >=  y) || (cpy[j] < y && cpy[i] >= y))
+#if USE_POLYGON_FRACTIONS == 1
+        xOffset += dxPerScanNumerator;
+
+        while (xOffset >= dxPerScanDenominator)
         {
-          nodeX[nodes++] = (int32_t)(cpx[i] + (y - cpy[i])/(cpy[j] - cpy[i]) * (cpx[j] - cpx[i]));
+          x++;
+          xOffset -= dxPerScanDenominator;
         }
-        j=i;
+
+        while (xOffset < 0)
+        {
+          x--;
+          xOffset += dxPerScanDenominator;
+        }
+
+#else
+        xIntersect += dxPerScan;
+#endif
       }
 
-      //  Sort the nodes, via a simple “Bubble” sort.
-      i=0;
-      while (i < nodes-1)
+
+      int GetEnterX() const
       {
-        if (nodeX[i] > nodeX[i+1])
+#if USE_POLYGON_FRACTIONS == 1
+        assert(xOffset >= 0 && xOffset < dxPerScanDenominator);
+        if (xOffset == 0)
         {
-          swap = nodeX[i];
-          nodeX[i] = nodeX[i+1];
-          nodeX[i+1] = swap;
-          if (i > 0)
-          {
-            i--;
-          }
+          return x;
         }
         else
         {
-          i++;
+          return x + 1;
+        }
+#else
+        return static_cast<int>(std::ceil(xIntersect));
+#endif
+      }
+  
+      int GetExitX() const
+      {
+#if USE_POLYGON_FRACTIONS == 1
+        assert(xOffset >= 0 && xOffset < dxPerScanDenominator);
+        return x;
+#else
+        return static_cast<int>(std::floor(xIntersect));
+#endif
+      }
+  
+      int GetUpperY() const
+      {
+        return yUpper;
+      }
+
+      bool operator< (const PolygonEdge& other) const
+      {
+#if USE_POLYGON_FRACTIONS == 1
+        assert(xOffset >= 0 && xOffset < dxPerScanDenominator);
+        assert(other.xOffset >= 0 && other.xOffset < other.dxPerScanDenominator);
+        return x < other.x;
+#else
+        // cf. "insertEdge()" in textbook
+        return (xIntersect < other.xIntersect);
+#endif
+      }
+    };
+  }
+  
+
+  // For an index, return y-coordinate of next nonhorizontal line
+  static int GetPolygonNextY(const std::vector<ImageProcessing::ImagePoint>& points,
+                             size_t k)
+  {
+    // cf. "yNext()" in textbook
+    size_t j = k;
+  
+    for (;;)
+    {
+      j++;
+      if (j == points.size())
+      {
+        j = 0;
+      }
+
+      if (points[k].GetY() != points[j].GetY())
+      {
+        return points[j].GetY();
+      }
+    }
+  }
+
+
+  static int GetPolygonPreviousY(const std::vector<ImageProcessing::ImagePoint>& points,
+                                 size_t k)
+  {
+    size_t j = k;
+
+    for (;;)
+    {
+      if (j > 0)
+      {
+        j --;
+      }
+      else
+      {
+        j = points.size() - 1;
+      }
+
+      if (points[k].GetY() != points[j].GetY())
+      {
+        return points[j].GetY();
+      }
+    }
+  }
+
+
+
+  void ImageProcessing::FillPolygon(IPolygonFiller& filler,
+                                    const std::vector<ImagePoint>& points)
+  {
+    /**
+     * This implementation is a C++ adaption of Section 3.11 (pages
+     * 117-124) of textbook "Computer Graphics - C Version (2nd
+     * Edition)" by Hearn and Baker, 1997.
+     **/
+  
+    typedef std::map<int, std::list<PolygonEdge> > EdgeTable;
+
+    if (points.size() < 2)
+    {
+      return;
+    }
+
+    bool onlyHorizontalSegments = true;
+    for (size_t i = 1; i < points.size(); i++)
+    {
+      if (points[0].GetY() != points[i].GetY())
+      {
+        onlyHorizontalSegments = false;
+        break;
+      }
+    }
+
+    if (onlyHorizontalSegments)
+    {
+      // Degenerate case: There are only horizontal lines. If this is
+      // the case, "GetPolygonPreviousY()" would be an infinite loop
+      int x1 = points[0].GetX();
+      int x2 = x1;
+      for (size_t i = 1; i < points.size(); i++)
+      {
+        assert(points[i].GetY() == points[0].GetY());
+
+        const int x = points[i].GetX();
+        x1 = std::min(x1, x);
+        x2 = std::max(x2, x);
+      }
+      filler.Fill(points[0].GetY(), x1, x2);
+      return;
+    }
+
+    EdgeTable globalEdgeTable;
+
+    // cf. "buildEdgeList()" in textbook
+
+    // Error in the textbook: we use "GetPolygonPreviousY()" instead of "points.size() - 2"
+    int yPrev = GetPolygonPreviousY(points, points.size() - 1);
+    ImagePoint v1(points[points.size() - 1]);
+
+    for (size_t i = 0; i < points.size(); i++)
+    {
+      ImagePoint v2(points[i]);
+
+      if (v1.GetY() != v2.GetY())
+      {
+        // Non-horizontal line
+        if (v1.GetY() < v2.GetY())
+        {
+          // Up-going edge
+          PolygonEdge edge(v1, v2, GetPolygonNextY(points, i));
+          globalEdgeTable[v1.GetY()].push_back(edge);
+        }
+        else if (v1.GetY() > v2.GetY())
+        {
+          // Down-going edge
+          PolygonEdge edge(v2, v1, yPrev);
+          globalEdgeTable[v2.GetY()].push_back(edge);
+        }
+
+        // Error in the textbook: "yPrev" must NOT be updated on horizontal lines
+        yPrev = v1.GetY();
+      }
+      
+      v1 = v2;
+    }
+    
+    assert(!globalEdgeTable.empty());
+
+    std::vector<PolygonEdge> activeEdges;
+
+    for (EdgeTable::const_iterator it = globalEdgeTable.begin(); it != globalEdgeTable.end(); ++it)
+    {
+      // cf. "buildActiveList()" in textbook
+      activeEdges.reserve(activeEdges.size() + it->second.size());
+      for (std::list<PolygonEdge>::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2)
+      {
+        activeEdges.push_back(*it2);
+      }
+
+      assert(!activeEdges.empty());
+
+      EdgeTable::const_iterator next = it;
+      ++next;
+
+      int rampEnd;
+      if (next == globalEdgeTable.end())
+      {
+        rampEnd = activeEdges[0].GetUpperY() + 1;
+
+        for (size_t i = 1; i < activeEdges.size(); i++)
+        {
+          rampEnd = std::max(rampEnd, activeEdges[i].GetUpperY() + 1);
         }
       }
-
-      TargetType* row = reinterpret_cast<TargetType*>(image.GetRow(pixelY));
-      //  Fill the pixels between node pairs.
-      for (i = 0; i < nodes; i += 2)
+      else
+      {
+        rampEnd = next->first;
+      }
+
+      for (int y = it->first; y < rampEnd; y++)
       {
-        if (nodeX[i] >= right)
-          break;
-
-        if (nodeX[i + 1] >= left)
+        // cf. "updateActiveList()" in textbook
+        std::vector<PolygonEdge> stillActive;
+        stillActive.reserve(activeEdges.size());
+
+        for (size_t i = 0; i < activeEdges.size(); i++)
         {
-          if (nodeX[i] < left)
+          if (y <= activeEdges[i].GetUpperY())
           {
-            nodeX[i] = left;
+            stillActive.push_back(activeEdges[i]);
           }
-
-          if (nodeX[i + 1] > right)
+        }
+
+        activeEdges.swap(stillActive);
+
+        assert(activeEdges.size() % 2 == 0);
+        std::sort(activeEdges.begin(), activeEdges.end());
+
+        // cf. "fillScan()" in textbook
+        for (size_t k = 0; k + 1 < activeEdges.size(); )
+        {
+          int a = activeEdges[k].GetExitX();
+          int b = activeEdges[k + 1].GetEnterX();
+
+          // Fix wrt. the textbook: merge overlapping segments
+          k += 2;
+          while (k + 1 < activeEdges.size() &&
+                 activeEdges[k].GetExitX() == b)
           {
-            nodeX[i + 1] = right;
+            assert(a <= b);
+            b = activeEdges[k + 1].GetEnterX();
+            k += 2;
           }
 
-          for (pixelX = nodeX[i]; pixelX <= nodeX[i + 1]; pixelX++)
-          {
-            *(row + pixelX) = value;
-          }
+          assert(a <= b);
+          filler.Fill(y, a, b);
+        }
+
+        // cf. "updateActiveList()" in textbook
+        for (size_t k = 0; k < activeEdges.size(); k++)
+        {
+          activeEdges[k].NextScanLine();
         }
       }
     }
   }
 
+  
   void ImageProcessing::FillPolygon(ImageAccessor& image,
                                     const std::vector<ImagePoint>& points,
                                     int64_t value)
   {
-    switch (image.GetFormat())
+    class Filler : public IPolygonFiller
     {
-      case PixelFormat_Grayscale8:
+    private:
+      ImageAccessor& image_;
+      int64_t        value_;
+
+    public:
+      Filler(ImageAccessor& image,
+             int64_t value) :
+        image_(image),
+        value_(value)
       {
-        FillPolygon_<PixelFormat_Grayscale8>(image, points, value);
-        break;
       }
-      case PixelFormat_Grayscale16:
+      
+      virtual void Fill(int y,
+                        int x1,
+                        int x2) ORTHANC_OVERRIDE
       {
-        FillPolygon_<PixelFormat_Grayscale16>(image, points, value);
-        break;
+        assert(x1 <= x2);
+    
+        if (x1 < static_cast<int>(image_.GetWidth()) &&
+            x2 >= 0 &&
+            y >= 0 &&
+            y < static_cast<int>(image_.GetHeight()))
+        {
+          unsigned int yy = static_cast<unsigned int>(y);
+          unsigned int a = static_cast<unsigned int>(std::max(0, x1));
+          unsigned int b = static_cast<unsigned int>(std::min(x2, static_cast<int>(image_.GetWidth()) - 1));
+
+          assert(a <= b);
+
+          ImageAccessor region;
+          image_.GetRegion(region, a, yy, b - a + 1, 1);
+          Set(region, value_);
+        }
       }
-      case PixelFormat_SignedGrayscale16:
-      {
-        FillPolygon_<PixelFormat_SignedGrayscale16>(image, points, value);
-        break;
-      }
-      default:
-        throw OrthancException(ErrorCode_NotImplemented);
+    };
+
+    
+    if (image.GetFormat() == PixelFormat_Grayscale8 ||
+        image.GetFormat() == PixelFormat_Grayscale16 ||
+        image.GetFormat() == PixelFormat_SignedGrayscale16)
+    {
+      Filler filler(image, value);
+      FillPolygon(filler, points);
+    }
+    else
+    {
+      throw OrthancException(ErrorCode_NotImplemented);
     }
   }
 
--- a/OrthancFramework/Sources/Images/ImageProcessing.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/ImageProcessing.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -63,6 +64,18 @@
                                double c) const; // where ax + by + c = 0 is the equation of the line
     };
 
+    class ORTHANC_PUBLIC IPolygonFiller : public boost::noncopyable
+    {
+    public:
+      virtual ~IPolygonFiller()
+      {
+      }
+
+      virtual void Fill(int y,
+                        int x1,
+                        int x2) = 0;
+    };
+
     static void Copy(ImageAccessor& target,
                      const ImageAccessor& source);
 
@@ -159,6 +172,9 @@
                                 uint8_t blue,
                                 uint8_t alpha);
 
+    static void FillPolygon(IPolygonFiller& filler,
+                            const std::vector<ImagePoint>& points);
+
     static void FillPolygon(ImageAccessor& image,
                             const std::vector<ImagePoint>& points,
                             int64_t value);
--- a/OrthancFramework/Sources/Images/ImageTraits.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/ImageTraits.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/JpegErrorManager.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/JpegErrorManager.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/JpegErrorManager.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/JpegErrorManager.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/JpegReader.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/JpegReader.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/JpegReader.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/JpegReader.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/JpegWriter.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/JpegWriter.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/JpegWriter.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/JpegWriter.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Sources/Images/NumpyWriter.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -0,0 +1,242 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "NumpyWriter.h"
+
+#if ORTHANC_ENABLE_ZLIB == 1
+#  include "../Compression/ZipWriter.h"
+#endif
+
+#if ORTHANC_SANDBOXED == 0
+#  include "../SystemToolbox.h"
+#endif
+
+#include "../OrthancException.h"
+#include "../Toolbox.h"
+
+#include <boost/lexical_cast.hpp>
+
+namespace Orthanc
+{
+  void NumpyWriter::WriteHeader(ChunkedBuffer& target,
+                                unsigned int depth,
+                                unsigned int width,
+                                unsigned int height,
+                                PixelFormat format)
+  {
+    // https://numpy.org/devdocs/reference/generated/numpy.lib.format.html
+    static const unsigned char VERSION[] = {
+      0x93, 'N', 'U', 'M', 'P', 'Y',
+      0x01 /* major version: 1 */,
+      0x00 /* minor version: 0 */
+    };
+
+    std::string datatype;
+
+    switch (Toolbox::DetectEndianness())
+    {
+      case Endianness_Little:
+        datatype = "<";
+        break;
+        
+      case Endianness_Big:
+        datatype = ">";
+        break;
+
+      default:
+        throw OrthancException(ErrorCode_InternalError);
+    }
+    
+    unsigned int channels;
+
+    switch (format)
+    {
+      case PixelFormat_Grayscale8:
+        datatype += "u1";
+        channels = 1;
+        break;
+
+      case PixelFormat_Grayscale16:
+        datatype += "u2";
+        channels = 1;
+        break;
+
+      case PixelFormat_SignedGrayscale16:
+        datatype += "i2";
+        channels = 1;
+        break;
+
+      case PixelFormat_RGB24:
+        datatype += "u1";
+        channels = 3;
+        break;
+
+      case PixelFormat_Float32:
+        datatype += "f4";
+        channels = 1;
+        break;
+
+      default:
+        throw OrthancException(ErrorCode_NotImplemented);
+    }
+
+    std::string depthString;
+    if (depth != 0)
+    {
+      depthString = boost::lexical_cast<std::string>(depth) + ", ";
+    }
+    
+    const std::string info = ("{'descr': '" + datatype + "', 'fortran_order': False, " +
+                              "'shape': (" + depthString + boost::lexical_cast<std::string>(height) +
+                              "," + boost::lexical_cast<std::string>(width) +
+                              "," + boost::lexical_cast<std::string>(channels) + "), }");
+
+    const uint16_t minimumLength = sizeof(VERSION) + sizeof(uint16_t) + info.size() + 1 /* trailing '\n' */;
+
+    // The length of the header must be evenly divisible by 64. This
+    // loop could be optimized by a "ceil()" operation, but we keep
+    // the code as simple as possible
+    uint16_t length = 64;
+    while (length < minimumLength)
+    {
+      length += 64;
+    }
+
+    uint16_t countZeros = length - minimumLength;
+    uint16_t headerLength = info.size() + countZeros + 1 /* trailing '\n' */;
+    uint8_t highByte = headerLength / 256;
+    uint8_t lowByte = headerLength % 256;
+    
+    target.AddChunk(VERSION, sizeof(VERSION));
+    target.AddChunk(&lowByte, 1);
+    target.AddChunk(&highByte, 1);
+    target.AddChunk(info);
+    target.AddChunk(std::string(countZeros, ' '));
+    target.AddChunk("\n");
+  }
+
+
+  void NumpyWriter::WritePixels(ChunkedBuffer& target,
+                                const ImageAccessor& image)
+  {
+    size_t rowSize = image.GetBytesPerPixel() * image.GetWidth();
+
+    for (unsigned int y = 0; y < image.GetHeight(); y++)
+    {
+      target.AddChunk(image.GetConstRow(y), rowSize);
+    }
+  }
+  
+
+  void NumpyWriter::Finalize(std::string& target,
+                             ChunkedBuffer& source,
+                             bool compress)
+  {
+    if (compress)
+    {
+#if ORTHANC_ENABLE_ZLIB == 1
+      // This is the default name of the first array if arrays are
+      // specified as positional arguments in "numpy.savez()"
+      // https://numpy.org/doc/stable/reference/generated/numpy.savez.html
+      const char* ARRAY_NAME = "arr_0";
+      
+      std::string uncompressed;
+      source.Flatten(uncompressed);
+
+      const bool isZip64 = (uncompressed.size() >= 1lu * 1024lu * 1024lu * 1024lu);
+
+      ZipWriter writer;
+      writer.SetMemoryOutput(target, isZip64);
+      writer.Open();
+      writer.OpenFile(ARRAY_NAME);
+      writer.Write(uncompressed);
+      writer.Close();
+#else
+      throw OrthancException(ErrorCode_InternalError, "Orthanc was compiled without support for zlib");
+#endif
+    }
+    else
+    {
+      source.Flatten(target);
+    }
+  }
+
+
+#if ORTHANC_SANDBOXED == 0
+  void NumpyWriter::WriteToFileInternal(const std::string& filename,
+                                        unsigned int width,
+                                        unsigned int height,
+                                        unsigned int pitch,
+                                        PixelFormat format,
+                                        const void* buffer)
+  {
+    std::string content;
+    WriteToMemoryInternal(content, width, height, pitch, format, buffer);
+    
+    SystemToolbox::WriteFile(content, filename);
+  }
+#endif
+
+  
+  void NumpyWriter::WriteToMemoryInternal(std::string& content,
+                                          unsigned int width,
+                                          unsigned int height,
+                                          unsigned int pitch,
+                                          PixelFormat format,
+                                          const void* buffer)
+  {
+    ChunkedBuffer chunks;
+    WriteHeader(chunks, 0 /* no depth */, width, height, format);
+
+    ImageAccessor image;
+    image.AssignReadOnly(format, width, height, pitch, buffer);
+    WritePixels(chunks, image);
+
+    Finalize(content, chunks, compressed_);
+  }
+
+
+  NumpyWriter::NumpyWriter()
+  {
+    compressed_ = false;
+  }
+
+  
+  void NumpyWriter::SetCompressed(bool compressed)
+  {
+#if ORTHANC_ENABLE_ZLIB == 1
+    compressed_ = compressed;
+#else
+    if (compressed)
+    {
+      throw OrthancException(ErrorCode_InternalError, "Orthanc was compiled without support for zlib");
+    }
+#endif
+  }
+
+
+  bool NumpyWriter::IsCompressed() const
+  {
+    return compressed_;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Sources/Images/NumpyWriter.h	Sun Feb 20 12:59:30 2022 +0100
@@ -0,0 +1,78 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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
+
+#include "IImageWriter.h"
+#include "../ChunkedBuffer.h"
+#include "../Compatibility.h"  // For ORTHANC_OVERRIDE
+
+namespace Orthanc
+{
+  class ORTHANC_PUBLIC NumpyWriter : public IImageWriter
+  {
+  protected:
+#if ORTHANC_SANDBOXED == 0
+    virtual void WriteToFileInternal(const std::string& filename,
+                                     unsigned int width,
+                                     unsigned int height,
+                                     unsigned int pitch,
+                                     PixelFormat format,
+                                     const void* buffer) ORTHANC_OVERRIDE;
+#endif
+
+    virtual void WriteToMemoryInternal(std::string& content,
+                                       unsigned int width,
+                                       unsigned int height,
+                                       unsigned int pitch,
+                                       PixelFormat format,
+                                       const void* buffer) ORTHANC_OVERRIDE;
+
+  private:
+    bool  compressed_;
+
+  public:
+    NumpyWriter();
+
+    void SetCompressed(bool compressed);
+
+    bool IsCompressed() const;
+
+    static void WriteHeader(ChunkedBuffer& target,
+                            unsigned int depth,  // Must be "0" for 2D images
+                            unsigned int width,
+                            unsigned int height,
+                            PixelFormat format);
+
+    static void WritePixels(ChunkedBuffer& target,
+                            const ImageAccessor& image);
+
+    static void Finalize(std::string& target,
+                         ChunkedBuffer& source,
+                         bool compress);
+  };
+}
--- a/OrthancFramework/Sources/Images/PamReader.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/PamReader.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/PamReader.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/PamReader.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/PamWriter.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/PamWriter.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/PamWriter.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/PamWriter.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/PixelTraits.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/PixelTraits.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/PngReader.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/PngReader.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/PngReader.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/PngReader.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/PngWriter.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/PngWriter.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Images/PngWriter.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Images/PngWriter.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/GenericJobUnserializer.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/GenericJobUnserializer.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/GenericJobUnserializer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/GenericJobUnserializer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/IJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/IJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -59,6 +60,7 @@
     // "success" state
     virtual bool GetOutput(std::string& output,
                            MimeType& mime,
+                           std::string& filename,
                            const std::string& key) = 0;
   };
 }
--- a/OrthancFramework/Sources/JobsEngine/IJobUnserializer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/IJobUnserializer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/JobInfo.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/JobInfo.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/JobInfo.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/JobInfo.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/JobStatus.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/JobStatus.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/JobStatus.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/JobStatus.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/JobStepResult.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/JobStepResult.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/JobStepResult.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/JobStepResult.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/JobsEngine.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/JobsEngine.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/JobsEngine.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/JobsEngine.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/JobsRegistry.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/JobsRegistry.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -650,6 +651,7 @@
 
   bool JobsRegistry::GetJobOutput(std::string& output,
                                   MimeType& mime,
+                                  std::string& filename,
                                   const std::string& job,
                                   const std::string& key)
   {
@@ -668,7 +670,7 @@
 
       if (handler.GetState() == JobState_Success)
       {
-        return handler.GetJob().GetOutput(output, mime, key);
+        return handler.GetJob().GetOutput(output, mime, filename, key);
       }
       else
       {
--- a/OrthancFramework/Sources/JobsEngine/JobsRegistry.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/JobsRegistry.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -148,6 +149,7 @@
 
     bool GetJobOutput(std::string& output,
                       MimeType& mime,
+                      std::string& filename,
                       const std::string& job,
                       const std::string& key);
 
--- a/OrthancFramework/Sources/JobsEngine/Operations/IJobOperation.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/IJobOperation.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/Operations/IJobOperationValue.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/IJobOperationValue.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/JobOperationValues.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/Operations/LogJobOperation.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/LogJobOperation.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/Operations/LogJobOperation.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/LogJobOperation.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/Operations/NullOperationValue.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/NullOperationValue.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/Operations/NullOperationValue.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/NullOperationValue.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -448,6 +449,7 @@
 
   bool SequenceOfOperationsJob::GetOutput(std::string& output,
                                           MimeType& mime,
+                                          std::string& filename,
                                           const std::string& key)
   {
     return false;
--- a/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/SequenceOfOperationsJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -125,6 +126,7 @@
 
     virtual bool GetOutput(std::string& output,
                            MimeType& mime,
+                           std::string& filename,
                            const std::string& key) ORTHANC_OVERRIDE;
 
     void AwakeTrailingSleep();
--- a/OrthancFramework/Sources/JobsEngine/Operations/StringOperationValue.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/StringOperationValue.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/Operations/StringOperationValue.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/Operations/StringOperationValue.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -270,6 +271,7 @@
 
   bool SetOfCommandsJob::GetOutput(std::string &output,
                                    MimeType &mime,
+                                   std::string& filename,
                                    const std::string &key)
   {
     return false;
--- a/OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/SetOfCommandsJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -104,6 +105,7 @@
 
     virtual bool GetOutput(std::string& output,
                            MimeType& mime,
+                           std::string& filename,
                            const std::string& key) ORTHANC_OVERRIDE;
   };
 }
--- a/OrthancFramework/Sources/JobsEngine/SetOfInstancesJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/SetOfInstancesJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/JobsEngine/SetOfInstancesJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/JobsEngine/SetOfInstancesJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Logging.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Logging.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Logging.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Logging.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Lua/LuaContext.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Lua/LuaContext.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Lua/LuaContext.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Lua/LuaContext.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Lua/LuaFunctionCall.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Lua/LuaFunctionCall.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -146,6 +147,20 @@
     }
   }
 
+  void LuaFunctionCall::ExecuteToInt(int& result)
+  {
+    ExecuteInternal(1);
+    
+    int top = lua_gettop(context_.lua_);
+    if (lua_isnumber(context_.lua_, top))
+    {
+      result = static_cast<int>(lua_tointeger(context_.lua_, top));
+    }
+    else
+    {
+      throw OrthancException(ErrorCode_LuaReturnsNoString);
+    }
+  }
 
   void LuaFunctionCall::PushStringMap(const std::map<std::string, std::string>& value)
   {
--- a/OrthancFramework/Sources/Lua/LuaFunctionCall.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Lua/LuaFunctionCall.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -78,6 +79,8 @@
 
     void ExecuteToString(std::string& result);
 
+    void ExecuteToInt(int& result);
+
 #if ORTHANC_ENABLE_DCMTK == 1
     void ExecuteToDicom(DicomMap& target);
 #endif
--- a/OrthancFramework/Sources/MallocMemoryBuffer.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/MallocMemoryBuffer.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/MallocMemoryBuffer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/MallocMemoryBuffer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/MetricsRegistry.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/MetricsRegistry.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/MetricsRegistry.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/MetricsRegistry.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/MultiThreading/IRunnableBySteps.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/MultiThreading/IRunnableBySteps.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/MultiThreading/RunnableWorkersPool.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/MultiThreading/RunnableWorkersPool.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/MultiThreading/RunnableWorkersPool.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/MultiThreading/RunnableWorkersPool.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/MultiThreading/Semaphore.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/MultiThreading/Semaphore.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -31,10 +32,6 @@
   Semaphore::Semaphore(unsigned int availableResources) :
     availableResources_(availableResources)
   {
-    if (availableResources_ == 0)
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
   }
 
   unsigned int Semaphore::GetAvailableResourcesCount() const
--- a/OrthancFramework/Sources/MultiThreading/Semaphore.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/MultiThreading/Semaphore.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -36,16 +37,16 @@
     boost::mutex mutex_;
     boost::condition_variable condition_;
 
+  public:
+    explicit Semaphore(unsigned int availableResources);
+
+    unsigned int GetAvailableResourcesCount() const;
+
     void Release(unsigned int resourceCount = 1);
 
     void Acquire(unsigned int resourceCount = 1);
 
     bool TryAcquire(unsigned int resourceCount = 1);
-  public:
-    explicit Semaphore(unsigned int availableResources);
-
-    unsigned int GetAvailableResourcesCount() const;
-
 
     class Locker : public boost::noncopyable
     {
--- a/OrthancFramework/Sources/MultiThreading/SharedMessageQueue.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/MultiThreading/SharedMessageQueue.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/MultiThreading/SharedMessageQueue.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/MultiThreading/SharedMessageQueue.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/OrthancException.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/OrthancException.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/OrthancException.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/OrthancException.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/OrthancFramework.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/OrthancFramework.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/OrthancFramework.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/OrthancFramework.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Pkcs11.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Pkcs11.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -41,6 +42,10 @@
 
 #include <openssl/engine.h>
 
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+#  warning You are linking Orthanc against OpenSSL 1.x, whose license is incompatible with the GPLv3+ used by Orthanc. Please update to OpenSSL 3.x, that uses the Apache 2 license.
+#endif
+
 
 namespace Orthanc
 {
--- a/OrthancFramework/Sources/Pkcs11.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Pkcs11.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/PrecompiledHeaders.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/PrecompiledHeaders.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/PrecompiledHeaders.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/PrecompiledHeaders.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApi.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApi.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApi.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApi.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApiCall.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiCall.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApiCall.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiCall.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApiCallDocumentation.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiCallDocumentation.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApiCallDocumentation.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiCallDocumentation.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApiDeleteCall.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiDeleteCall.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApiGetCall.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiGetCall.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -23,6 +24,9 @@
 #include "../PrecompiledHeaders.h"
 #include "RestApiGetCall.h"
 
+#include "../OrthancException.h"
+#include "../SerializationToolbox.h"
+
 namespace Orthanc
 {
   bool RestApiGetCall::ParseJsonRequest(Json::Value& result) const
@@ -37,4 +41,31 @@
 
     return true;
   }
+
+  
+  bool RestApiGetCall::GetBooleanArgument(const std::string& name,
+                                          bool defaultValue) const
+  {
+    HttpToolbox::Arguments::const_iterator found = getArguments_.find(name);
+
+    bool value;
+    
+    if (found == getArguments_.end())
+    {
+      return defaultValue;
+    }
+    else if (found->second.empty())
+    {
+      return true;
+    }
+    else if (SerializationToolbox::ParseBoolean(value, found->second))
+    {
+      return value;
+    }
+    else
+    {
+      throw OrthancException(ErrorCode_ParameterOutOfRange, "Expected a Boolean for GET argument \"" +
+                             name + "\", found: " + found->second);
+    }
+  }
 }
--- a/OrthancFramework/Sources/RestApi/RestApiGetCall.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiGetCall.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -60,6 +61,9 @@
     {
       return getArguments_.find(name) != getArguments_.end();
     }
+
+    bool GetBooleanArgument(const std::string& name,
+                            bool defaultValue) const;
     
     virtual bool ParseJsonRequest(Json::Value& result) const ORTHANC_OVERRIDE;
   };
--- a/OrthancFramework/Sources/RestApi/RestApiHierarchy.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiHierarchy.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApiHierarchy.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiHierarchy.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApiOutput.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiOutput.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -214,4 +215,9 @@
     // empty string
     SetCookie(name, "", 1);
   }
+
+  void RestApiOutput::SetContentFilename(const char* filename)
+  {
+    output_.SetContentFilename(filename);
+  }
 }
--- a/OrthancFramework/Sources/RestApi/RestApiOutput.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiOutput.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -77,6 +78,8 @@
                       size_t length,
                       MimeType contentType);
 
+    void SetContentFilename(const char* filename);
+
     void SignalError(HttpStatus status);
 
     void SignalError(HttpStatus status,
--- a/OrthancFramework/Sources/RestApi/RestApiPath.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiPath.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApiPath.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiPath.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApiPostCall.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiPostCall.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/RestApi/RestApiPutCall.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/RestApi/RestApiPutCall.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/SQLite/Connection.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/Connection.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
  *
--- a/OrthancFramework/Sources/SQLite/Connection.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/Connection.h	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
  *
--- a/OrthancFramework/Sources/SQLite/FunctionContext.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/FunctionContext.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
--- a/OrthancFramework/Sources/SQLite/FunctionContext.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/FunctionContext.h	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
--- a/OrthancFramework/Sources/SQLite/IScalarFunction.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/IScalarFunction.h	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
--- a/OrthancFramework/Sources/SQLite/ITransaction.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/ITransaction.h	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
  *
--- a/OrthancFramework/Sources/SQLite/NonCopyable.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/NonCopyable.h	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
--- a/OrthancFramework/Sources/SQLite/OrthancSQLiteException.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/OrthancSQLiteException.h	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
  *
--- a/OrthancFramework/Sources/SQLite/SQLiteTypes.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/SQLiteTypes.h	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
--- a/OrthancFramework/Sources/SQLite/Statement.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/Statement.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
  *
--- a/OrthancFramework/Sources/SQLite/Statement.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/Statement.h	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
  *
--- a/OrthancFramework/Sources/SQLite/StatementId.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/StatementId.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
  *
--- a/OrthancFramework/Sources/SQLite/StatementId.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/StatementId.h	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
  *
--- a/OrthancFramework/Sources/SQLite/StatementReference.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/StatementReference.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
  *
--- a/OrthancFramework/Sources/SQLite/StatementReference.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/StatementReference.h	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
  *
--- a/OrthancFramework/Sources/SQLite/Transaction.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/Transaction.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
  *
--- a/OrthancFramework/Sources/SQLite/Transaction.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SQLite/Transaction.h	Sun Feb 20 12:59:30 2022 +0100
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2012-2016 Sebastien Jodogne <s.jodogne@orthanc-labs.com>,
  * Medical Physics Department, CHU of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
  *
@@ -61,11 +63,11 @@
       // Returns true when there is a transaction that has been successfully begun.
       bool IsOpen() const;
 
-      virtual void Begin();
+      virtual void Begin() ORTHANC_OVERRIDE;
 
-      virtual void Rollback();
+      virtual void Rollback() ORTHANC_OVERRIDE;
 
-      virtual void Commit();
+      virtual void Commit() ORTHANC_OVERRIDE;
     };
   }
 }
--- a/OrthancFramework/Sources/SerializationToolbox.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SerializationToolbox.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -647,4 +648,26 @@
       return false;
     }
   }
+  
+
+  bool SerializationToolbox::ParseBoolean(bool& result,
+                                          const std::string& value)
+  {
+    if (value == "0" ||
+        value == "false")
+    {
+      result = false;
+      return true;
+    }
+    else if (value == "1" ||
+             value == "true")
+    {
+      result = true;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
 }
--- a/OrthancFramework/Sources/SerializationToolbox.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SerializationToolbox.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -137,5 +138,8 @@
 
     static bool ParseFirstDouble(double& result,
                                  const std::string& value);
+
+    static bool ParseBoolean(bool& result,
+                             const std::string& value);
   };
 }
--- a/OrthancFramework/Sources/SharedLibrary.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SharedLibrary.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/SharedLibrary.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SharedLibrary.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/StringMemoryBuffer.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/StringMemoryBuffer.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -47,4 +48,14 @@
     result->Copy(buffer);
     return result.release();
   }
+
+
+  IMemoryBuffer* StringMemoryBuffer::CreateFromCopy(const std::string& buffer, 
+                                                    size_t start /* inclusive */, 
+                                                    size_t end /* exclusive */)
+  {
+    std::unique_ptr<StringMemoryBuffer> result(new StringMemoryBuffer);
+    result->Copy(buffer, start, end);
+    return result.release();
+  }
 }
--- a/OrthancFramework/Sources/StringMemoryBuffer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/StringMemoryBuffer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -38,6 +39,11 @@
       buffer_ = buffer;
     }
 
+    void Copy(const std::string& buffer, size_t start /* inclusive */, size_t end /* exclusive */)
+    {
+      buffer_.assign(buffer, start, end - start);
+    }
+
     void Swap(std::string& buffer)
     {
       buffer_.swap(buffer);
@@ -58,5 +64,7 @@
     static IMemoryBuffer* CreateFromSwap(std::string& buffer);
 
     static IMemoryBuffer* CreateFromCopy(const std::string& buffer);
+
+    static IMemoryBuffer* CreateFromCopy(const std::string& buffer, size_t start /* inclusive */, size_t end /* exclusive */);
   };
 }
--- a/OrthancFramework/Sources/SystemToolbox.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SystemToolbox.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -812,6 +813,10 @@
     {
       return MimeType_Woff2;
     }
+    else if (extension == ".ico")
+    {
+      return MimeType_Ico;
+    }
 
     // Default type
     else
--- a/OrthancFramework/Sources/SystemToolbox.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/SystemToolbox.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/TemporaryFile.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/TemporaryFile.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/TemporaryFile.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/TemporaryFile.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/Toolbox.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Toolbox.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -92,6 +93,11 @@
 #  include <openssl/err.h>
 #  include <openssl/evp.h>
 #  include <openssl/ssl.h>
+
+#  if OPENSSL_VERSION_NUMBER < 0x30000000L
+#    warning You are linking Orthanc against OpenSSL 1.x, whose license is incompatible with the GPLv3+ used by Orthanc >= 1.10.0. Please update to OpenSSL 3.x, that uses the Apache 2 license.
+#  endif
+
 #endif
 
 
--- a/OrthancFramework/Sources/Toolbox.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/Toolbox.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/Sources/WebServiceParameters.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/WebServiceParameters.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -504,21 +505,19 @@
     {
       return defaultValue;
     }
-    else if (found->second == "0" ||
-             found->second == "false")
-    {
-      return false;
-    }
-    else if (found->second == "1" ||
-             found->second == "true")
-    {
-      return true;
-    }
     else
     {
-      throw OrthancException(ErrorCode_BadFileFormat, "Bad value for a Boolean user property in the parameters "
-                             "of a Web service: Property \"" + key + "\" equals: " + found->second);
-    }    
+      bool value;
+      if (SerializationToolbox::ParseBoolean(value, found->second))
+      {
+        return value;
+      }
+      else
+      {
+        throw OrthancException(ErrorCode_BadFileFormat, "Bad value for a Boolean user property in the parameters "
+                               "of a Web service: Property \"" + key + "\" equals: " + found->second);
+      }
+    }
   }
 
 
--- a/OrthancFramework/Sources/WebServiceParameters.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/Sources/WebServiceParameters.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/BitbucketCACertificates.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/BitbucketCACertificates.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/DicomMapTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/DicomMapTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -755,6 +756,15 @@
   ASSERT_FALSE(d > d);
 }
 
+TEST(ParsedDicomFile, canIncludeXsVrTags)
+{
+  Json::Value tags;
+  tags["0028,0034"] = "1\\1";         // PixelAspectRatio
+  tags["0028,1101"] = "256\\0\\16";   // RedPaletteColorLookupTableDescriptor which is declared as xs VR in dicom.dic
+
+  std::unique_ptr<ParsedDicomFile> dicom(ParsedDicomFile::CreateFromJson(tags, DicomFromJsonFlags_DecodeDataUriScheme, ""));
+  // simply make sure it does not throw !
+}
 
 
 #if ORTHANC_SANDBOXED != 1
--- a/OrthancFramework/UnitTestsSources/FileStorageTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/FileStorageTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -29,6 +30,7 @@
 
 #include "../Sources/FileStorage/FilesystemStorage.h"
 #include "../Sources/FileStorage/StorageAccessor.h"
+#include "../Sources/FileStorage/StorageCache.h"
 #include "../Sources/HttpServer/BufferHttpSender.h"
 #include "../Sources/HttpServer/FilesystemHttpSender.h"
 #include "../Sources/Logging.h"
@@ -124,7 +126,8 @@
 TEST(StorageAccessor, NoCompression)
 {
   FilesystemStorage s("UnitTestsStorage");
-  StorageAccessor accessor(s);
+  StorageCache cache;
+  StorageAccessor accessor(s, cache);
 
   std::string data = "Hello world";
   FileInfo info = accessor.Write(data, FileContentType_Dicom, CompressionType_None, true);
@@ -145,7 +148,8 @@
 TEST(StorageAccessor, Compression)
 {
   FilesystemStorage s("UnitTestsStorage");
-  StorageAccessor accessor(s);
+  StorageCache cache;
+  StorageAccessor accessor(s, cache);
 
   std::string data = "Hello world";
   FileInfo info = accessor.Write(data, FileContentType_Dicom, CompressionType_ZlibWithSize, true);
@@ -165,7 +169,8 @@
 TEST(StorageAccessor, Mix)
 {
   FilesystemStorage s("UnitTestsStorage");
-  StorageAccessor accessor(s);
+  StorageCache cache;
+  StorageAccessor accessor(s, cache);
 
   std::string r;
   std::string compressedData = "Hello";
--- a/OrthancFramework/UnitTestsSources/FrameworkTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/FrameworkTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -341,6 +342,7 @@
   ASSERT_EQ(MimeType_Svg, SystemToolbox::AutodetectMimeType("NOTES.svg"));
   ASSERT_EQ(MimeType_Woff, SystemToolbox::AutodetectMimeType("NOTES.woff"));
   ASSERT_EQ(MimeType_Woff2, SystemToolbox::AutodetectMimeType("NOTES.woff2"));
+  ASSERT_EQ(MimeType_Ico, SystemToolbox::AutodetectMimeType("NOTES.ico"));
 
   // Test primitives from the "RegisterDefaultExtensions()" that was
   // present in the sample "Serve Folders plugin" of Orthanc 1.4.2
--- a/OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/ImageProcessingTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/ImageProcessingTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -194,6 +195,7 @@
   }
 }
 
+
 TYPED_TEST(TestIntegerImageTraits, FillPolygon)
 {
   ImageAccessor& image = this->GetImage();
@@ -233,7 +235,15 @@
   points.push_back(ImageProcessing::ImagePoint(image.GetWidth(),image.GetHeight()));
   points.push_back(ImageProcessing::ImagePoint(0,image.GetHeight()));
 
-  ASSERT_THROW(ImageProcessing::FillPolygon(image, points, 255), OrthancException);
+  ImageProcessing::FillPolygon(image, points, 255);
+
+  for (unsigned int y = 0; y < image.GetHeight(); y++)
+  {
+    for (unsigned int x = 0; x < image.GetWidth(); x++)
+    {
+      ASSERT_FLOAT_EQ(255, TestFixture::ImageTraits::GetFloatPixel(image, x, y));
+    }
+  }
 }
 
 TYPED_TEST(TestIntegerImageTraits, FillPolygonFullImage)
@@ -296,9 +306,9 @@
 }
 
 static void SetSignedGrayscale16Pixel(ImageAccessor& image,
-                                unsigned int x,
-                                unsigned int y,
-                                int16_t value)
+                                      unsigned int x,
+                                      unsigned int y,
+                                      int16_t value)
 {
   ImageTraits<PixelFormat_SignedGrayscale16>::SetPixel(image, value, x, y);
 }
@@ -1081,3 +1091,274 @@
     }
   }
 }
+
+
+namespace
+{
+  class PolygonSegments : public ImageProcessing::IPolygonFiller
+  {
+  private:
+    std::vector<int> y_, x1_, x2_;
+
+  public:  
+    virtual void Fill(int y,
+                      int x1,
+                      int x2) ORTHANC_OVERRIDE
+    {
+      assert(x1 <= x2);
+      y_.push_back(y);
+      x1_.push_back(x1);
+      x2_.push_back(x2);
+    }
+
+    size_t GetSize() const
+    {
+      return y_.size();
+    }
+
+    int GetY(size_t i) const
+    {
+      return y_[i];
+    }
+
+    int GetX1(size_t i) const
+    {
+      return x1_[i];
+    }
+
+    int GetX2(size_t i) const
+    {
+      return x2_[i];
+    }
+  };
+}
+
+
+static bool LookupSegment(unsigned int& x1,
+                          unsigned int& x2,
+                          const Orthanc::ImageAccessor& image,
+                          unsigned int y)
+{
+  const uint8_t* p = reinterpret_cast<const uint8_t*>(image.GetConstRow(y));
+
+  bool allZeros = true;
+  for (unsigned int i = 0; i < image.GetWidth(); i++)
+  {
+    if (p[i] == 255)
+    {
+      allZeros = false;
+      break;
+    }
+    else if (p[i] > 0)
+    {
+      return false;  // error
+    }
+  }
+
+  if (allZeros)
+  {
+    return false;
+  }  
+
+  x1 = 0;
+  while (p[x1] == 0)
+  {
+    x1++;
+  }
+
+  x2 = image.GetWidth() - 1;
+  while (p[x2] == 0)
+  {
+    x2--;
+  }
+
+  for (unsigned int i = x1; i <= x2; i++)
+  {
+    if (p[i] != 255)
+    {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+
+TEST(ImageProcessing, FillPolygon)
+{
+  {
+    // Empty
+    std::vector<ImageProcessing::ImagePoint> polygon;
+
+    PolygonSegments segments;
+    ImageProcessing::FillPolygon(segments, polygon);
+    ASSERT_EQ(0u, segments.GetSize());
+  }
+
+  {
+    // One point
+    std::vector<ImageProcessing::ImagePoint> polygon;
+    polygon.push_back(ImageProcessing::ImagePoint(288, 208));
+
+    PolygonSegments segments;
+    ImageProcessing::FillPolygon(segments, polygon);
+    ASSERT_EQ(0u, segments.GetSize());
+  }
+
+  {
+    // One horizontal segment
+    std::vector<ImageProcessing::ImagePoint> polygon;
+    polygon.push_back(ImageProcessing::ImagePoint(10, 100));
+    polygon.push_back(ImageProcessing::ImagePoint(50, 100));
+
+    PolygonSegments segments;
+    ImageProcessing::FillPolygon(segments, polygon);
+    ASSERT_EQ(1u, segments.GetSize());
+    ASSERT_EQ(100, segments.GetY(0));
+    ASSERT_EQ(10, segments.GetX1(0));
+    ASSERT_EQ(50, segments.GetX2(0));
+  }
+
+  {
+    // Set of horizontal segments
+    std::vector<ImageProcessing::ImagePoint> polygon;
+    polygon.push_back(ImageProcessing::ImagePoint(10, 100));
+    polygon.push_back(ImageProcessing::ImagePoint(20, 100));
+    polygon.push_back(ImageProcessing::ImagePoint(30, 100));
+    polygon.push_back(ImageProcessing::ImagePoint(50, 100));
+
+    PolygonSegments segments;
+    ImageProcessing::FillPolygon(segments, polygon);
+    ASSERT_EQ(1u, segments.GetSize());
+    ASSERT_EQ(100, segments.GetY(0));
+    ASSERT_EQ(10, segments.GetX1(0));
+    ASSERT_EQ(50, segments.GetX2(0));
+  }
+
+  {
+    // Set of vertical segments
+    std::vector<ImageProcessing::ImagePoint> polygon;
+    polygon.push_back(ImageProcessing::ImagePoint(10, 100));
+    polygon.push_back(ImageProcessing::ImagePoint(10, 102));
+    polygon.push_back(ImageProcessing::ImagePoint(10, 105));
+
+    PolygonSegments segments;
+    ImageProcessing::FillPolygon(segments, polygon);
+    ASSERT_EQ(6u, segments.GetSize());
+    for (size_t i = 0; i < segments.GetSize(); i++)
+    {
+      ASSERT_EQ(100 + i, segments.GetY(i));
+      ASSERT_EQ(10, segments.GetX1(i));
+      ASSERT_EQ(10, segments.GetX2(i));
+    }
+  }
+
+  {
+    // One diagonal segment
+    std::vector<ImageProcessing::ImagePoint> polygon;
+    polygon.push_back(ImageProcessing::ImagePoint(10, 100));
+    polygon.push_back(ImageProcessing::ImagePoint(11, 101));
+    polygon.push_back(ImageProcessing::ImagePoint(13, 103));
+
+    PolygonSegments segments;
+    ImageProcessing::FillPolygon(segments, polygon);
+    ASSERT_EQ(4u, segments.GetSize());
+    ASSERT_EQ(100, segments.GetY(0));
+    ASSERT_EQ(10, segments.GetX1(0));
+    ASSERT_EQ(10, segments.GetX2(0));
+    ASSERT_EQ(101, segments.GetY(1));
+    ASSERT_EQ(11, segments.GetX1(1));
+    ASSERT_EQ(11, segments.GetX2(1));
+    ASSERT_EQ(102, segments.GetY(2));
+    ASSERT_EQ(12, segments.GetX1(2));
+    ASSERT_EQ(12, segments.GetX2(2));
+    ASSERT_EQ(103, segments.GetY(3));
+    ASSERT_EQ(13, segments.GetX1(3));
+    ASSERT_EQ(13, segments.GetX2(3));
+  }
+
+  {
+    // "M" shape
+    std::vector<ImageProcessing::ImagePoint> polygon;
+    polygon.push_back(ImageProcessing::ImagePoint(5, 5));
+    polygon.push_back(ImageProcessing::ImagePoint(7, 7));
+    polygon.push_back(ImageProcessing::ImagePoint(9, 5));
+    polygon.push_back(ImageProcessing::ImagePoint(9, 8));
+    polygon.push_back(ImageProcessing::ImagePoint(5, 8));
+
+    PolygonSegments segments;
+    ImageProcessing::FillPolygon(segments, polygon);
+    ASSERT_EQ(6u, segments.GetSize());
+    ASSERT_EQ(5, segments.GetY(0));  ASSERT_EQ(5, segments.GetX1(0));  ASSERT_EQ(5, segments.GetX2(0));
+    ASSERT_EQ(5, segments.GetY(1));  ASSERT_EQ(9, segments.GetX1(1));  ASSERT_EQ(9, segments.GetX2(1));
+    ASSERT_EQ(6, segments.GetY(2));  ASSERT_EQ(5, segments.GetX1(2));  ASSERT_EQ(6, segments.GetX2(2));
+    ASSERT_EQ(6, segments.GetY(3));  ASSERT_EQ(8, segments.GetX1(3));  ASSERT_EQ(9, segments.GetX2(3));
+    ASSERT_EQ(7, segments.GetY(4));  ASSERT_EQ(5, segments.GetX1(4));  ASSERT_EQ(9, segments.GetX2(4));
+    ASSERT_EQ(8, segments.GetY(5));  ASSERT_EQ(5, segments.GetX1(5));  ASSERT_EQ(9, segments.GetX2(5));
+  }
+
+  {
+    // Rectangle
+    std::vector<ImageProcessing::ImagePoint> polygon;
+    polygon.push_back(ImageProcessing::ImagePoint(10, 50));
+    polygon.push_back(ImageProcessing::ImagePoint(200, 50));
+    polygon.push_back(ImageProcessing::ImagePoint(200, 100));
+    polygon.push_back(ImageProcessing::ImagePoint(10, 100));
+
+    PolygonSegments segments;
+    ImageProcessing::FillPolygon(segments, polygon);
+    ASSERT_EQ(51u, segments.GetSize());
+
+    for (size_t i = 0; i < segments.GetSize(); i++)
+    {
+      ASSERT_EQ(i + 50, segments.GetY(i));
+      ASSERT_EQ(10, segments.GetX1(i));
+      ASSERT_EQ(200, segments.GetX2(i));
+    }
+  }
+
+  {
+    // Shape that goes outside of the image on the 4 borders
+    std::vector<ImageProcessing::ImagePoint> polygon;
+    polygon.push_back(ImageProcessing::ImagePoint(5, -5));
+    polygon.push_back(ImageProcessing::ImagePoint(40, 15));
+    polygon.push_back(ImageProcessing::ImagePoint(20, 32));
+    polygon.push_back(ImageProcessing::ImagePoint(-5, 27));
+
+    Image image(PixelFormat_Grayscale8, 30, 30, false);
+    ImageProcessing::Set(image, 0);
+    ImageProcessing::FillPolygon(image, polygon, 255);
+
+    unsigned int x1, x2;
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 0));   ASSERT_EQ(3u, x1);  ASSERT_EQ(14u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 1));   ASSERT_EQ(3u, x1);  ASSERT_EQ(16u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 2));   ASSERT_EQ(2u, x1);  ASSERT_EQ(18u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 3));   ASSERT_EQ(2u, x1);  ASSERT_EQ(19u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 4));   ASSERT_EQ(2u, x1);  ASSERT_EQ(21u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 5));   ASSERT_EQ(1u, x1);  ASSERT_EQ(23u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 6));   ASSERT_EQ(1u, x1);  ASSERT_EQ(25u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 7));   ASSERT_EQ(1u, x1);  ASSERT_EQ(26u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 8));   ASSERT_EQ(0u, x1);  ASSERT_EQ(28u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 9));   ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 10));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 11));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 12));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 13));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 14));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 15));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 16));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 17));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 18));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 19));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 20));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 21));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 22));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 23));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 24));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 25));  ASSERT_EQ(0u, x1);  ASSERT_EQ(29u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 26));  ASSERT_EQ(0u, x1);  ASSERT_EQ(28u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 27));  ASSERT_EQ(0u, x1);  ASSERT_EQ(26u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 28));  ASSERT_EQ(0u, x1);  ASSERT_EQ(25u, x2);
+    ASSERT_TRUE(LookupSegment(x1, x2, image, 29));  ASSERT_EQ(5u, x1);  ASSERT_EQ(24u, x2);
+  }
+}
--- a/OrthancFramework/UnitTestsSources/ImageTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/ImageTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/JobsTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/JobsTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -125,6 +126,7 @@
 
     virtual bool GetOutput(std::string& output,
                            MimeType& mime,
+                           std::string& filename,
                            const std::string& key) ORTHANC_OVERRIDE
     {
       return false;
@@ -1310,6 +1312,7 @@
     ASSERT_EQ(ModalityManufacturer_Generic, modality.GetManufacturer());
     ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Echo));
     ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Find));
+    ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_FindWorklist));
     ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Get));
     ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Store));
     ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Move));
@@ -1349,6 +1352,7 @@
     ASSERT_EQ(ModalityManufacturer_GenericNoWildcardInDates, modality.GetManufacturer());
     ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Echo));
     ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Find));
+    ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_FindWorklist));
     ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Get));
     ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Store));
     ASSERT_TRUE(modality.IsRequestAllowed(DicomRequestType_Move));
@@ -1375,13 +1379,14 @@
   std::set<DicomRequestType> operations;
   operations.insert(DicomRequestType_Echo);
   operations.insert(DicomRequestType_Find);
+  operations.insert(DicomRequestType_FindWorklist);
   operations.insert(DicomRequestType_Get);
   operations.insert(DicomRequestType_Move);
   operations.insert(DicomRequestType_Store);
   operations.insert(DicomRequestType_NAction);
   operations.insert(DicomRequestType_NEventReport);
 
-  ASSERT_EQ(7u, operations.size());
+  ASSERT_EQ(8u, operations.size());
 
   for (std::set<DicomRequestType>::const_iterator 
          it = operations.begin(); it != operations.end(); ++it)
--- a/OrthancFramework/UnitTestsSources/JpegLosslessTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/JpegLosslessTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/LoggingTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/LoggingTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/LuaTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/LuaTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/MemoryCacheTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/MemoryCacheTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/RestApiTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/RestApiTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/SQLiteChromiumTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/SQLiteChromiumTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/SQLiteTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/SQLiteTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/SharedLibraryUnitTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/SharedLibraryUnitTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/StreamTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/StreamTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/ToolboxTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/ToolboxTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancFramework/UnitTestsSources/ZipTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancFramework/UnitTestsSources/ZipTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
--- a/OrthancServer/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,24 +1,13 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/OrthancExplorer/explorer.css	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/OrthancExplorer/explorer.css	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -73,4 +62,4 @@
 
 .switch-container .ui-slider-switch {
     width: 100%;
-}
\ No newline at end of file
+}
--- a/OrthancServer/OrthancExplorer/explorer.html	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/OrthancExplorer/explorer.html	Sun Feb 20 12:59:30 2022 +0100
@@ -252,7 +252,7 @@
               <li data-icon="star"><a href="#" id="patient-anonymize">Anonymize</a></li>
             </ul>
 
-            <ul data-role="listview" data-inset="true" data-theme="d" data-divider-theme="c">
+            <ul data-role="listview" data-inset="true" data-theme="d" data-divider-theme="c" id="patient-access">
               <li data-role="list-divider">Access</li>
               <li data-icon="info" data-theme="e" style="display:none">
                 <a href="#" id="patient-anonymized-from">Before anonymization</a>
@@ -306,7 +306,7 @@
               <li data-icon="star"><a href="#" id="study-anonymize">Anonymize</a></li>
             </ul>
 
-            <ul data-role="listview" data-inset="true" data-theme="d" data-divider-theme="c">
+            <ul data-role="listview" data-inset="true" data-theme="d" data-divider-theme="c" id="study-access">
               <li data-role="list-divider">Access</li>
               <li data-icon="info" data-theme="e" style="display:none">
                 <a href="#" id="study-anonymized-from">Before anonymization</a>
@@ -361,7 +361,7 @@
               <li data-icon="star"><a href="#" id="series-anonymize">Anonymize</a></li>
             </ul>
 
-            <ul data-role="listview" data-inset="true" data-theme="d" data-divider-theme="c">
+            <ul data-role="listview" data-inset="true" data-theme="d" data-divider-theme="c" id="series-access">
               <li data-role="list-divider">Access</li>
               <li data-icon="info" data-theme="e" style="display:none">
                 <a href="#" id="series-anonymized-from">Before anonymization</a>
@@ -417,7 +417,7 @@
               <li data-icon="forward"><a href="#" id="instance-store">Send to DICOM modality</a></li>
             </ul>
 
-            <ul data-role="listview" data-inset="true" data-theme="d" data-divider-theme="c">
+            <ul data-role="listview" data-inset="true" data-theme="d" data-divider-theme="c" id="instance-access">
               <li data-role="list-divider">Access</li>
               <li data-icon="info" data-theme="e" style="display:none">
                 <a href="#" id="instance-anonymized-from">Before anonymization</a>
--- a/OrthancServer/OrthancExplorer/explorer.js	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/OrthancExplorer/explorer.js	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -700,7 +689,19 @@
   }
 }
 
+function SetupAttachments(accessSelector, liClass, resourceId, resourceType) {
+  GetResource('/' + resourceType + '/' + resourceId + '/attachments?full', function(attachments) {
+    target = $(accessSelector);
+    $('.' + liClass).remove();
+    for (var key in attachments) {
+      if (attachments[key] >= 1024) {
+        target.append('<li data-icon="gear" class="' + liClass + '"><a href="#" id="' + attachments[key] + '">Download ' + key + '</a></li>')
+      }
+    }
+    target.listview('refresh');
+  });
 
+}
 
 function RefreshPatient()
 {
@@ -737,6 +738,7 @@
 
         SetupAnonymizedOrModifiedFrom('#patient-anonymized-from', patient, 'patient', ANONYMIZED_FROM);
         SetupAnonymizedOrModifiedFrom('#patient-modified-from', patient, 'patient', MODIFIED_FROM);
+        SetupAttachments('#patient-access', 'patient-attachment', pageData.uuid, 'patients');
 
         target.listview('refresh');
 
@@ -784,6 +786,7 @@
 
           SetupAnonymizedOrModifiedFrom('#study-anonymized-from', study, 'study', ANONYMIZED_FROM);
           SetupAnonymizedOrModifiedFrom('#study-modified-from', study, 'study', MODIFIED_FROM);
+          SetupAttachments('#study-access', 'study-attachment', pageData.uuid, 'studies');
 
           target = $('#list-series');
           $('li', target).remove();
@@ -801,6 +804,7 @@
           }
           target.listview('refresh');
 
+
           currentPage = 'study';
           currentUuid = pageData.uuid;
         });
@@ -838,6 +842,7 @@
 
             SetupAnonymizedOrModifiedFrom('#series-anonymized-from', series, 'series', ANONYMIZED_FROM);
             SetupAnonymizedOrModifiedFrom('#series-modified-from', series, 'series', MODIFIED_FROM);
+            SetupAttachments('#series-access', 'series-attachment', pageData.uuid, 'series');
 
             target = $('#list-instances');
             $('li', target).remove();
@@ -977,6 +982,8 @@
             SetupAnonymizedOrModifiedFrom('#instance-anonymized-from', instance, 'instance', ANONYMIZED_FROM);
             SetupAnonymizedOrModifiedFrom('#instance-modified-from', instance, 'instance', MODIFIED_FROM);
 
+            SetupAttachments('#instance-access', 'instance-attachment', pageData.uuid, 'instances');
+
             currentPage = 'instance';
             currentUuid = pageData.uuid;
           });
@@ -1113,7 +1120,7 @@
           if (frames.length == 1)
           {
             // Viewing a single-frame image
-            jQuery.slimbox('../instances/' + pageData.uuid + '/preview', '', {
+            jQuery.slimbox('../instances/' + pageData.uuid + '/preview?returnUnsupportedImage', '', {
               overlayFadeDuration : 1,
               resizeDuration : 1,
               imageFadeDuration : 1
@@ -1125,7 +1132,7 @@
 
             images = [];
             for (var i = 0; i < frames.length; i++) {
-              images.push([ '../instances/' + pageData.uuid + '/frames/' + i + '/preview' ]);
+              images.push([ '../instances/' + pageData.uuid + '/frames/' + i + '/preview?returnUnsupportedImage' ]);
             }
 
             jQuery.slimbox(images, 0, {
@@ -1155,7 +1162,7 @@
 
         images = [];
         for (var i = 0; i < instances.length; i++) {
-          images.push([ '../instances/' + instances[i].ID + '/preview',
+          images.push([ '../instances/' + instances[i].ID + '/preview?returnUnsupportedImage',
                         (i + 1).toString() + '/' + instances.length.toString() ])
         }
 
@@ -1346,7 +1353,25 @@
   window.location.href = '../series/' + $.mobile.pageData.uuid + '/media';
 });
 
+$('.patient-attachment').live('click', function(e) {
+  e.preventDefault();  //stop the browser from following
+  window.location.href = '../patients/' + $.mobile.pageData.uuid + '/attachments/' + e.target.id + '/data';
+});
 
+$('.study-attachment').live('click', function(e) {
+  e.preventDefault();  //stop the browser from following
+  window.location.href = '../studies/' + $.mobile.pageData.uuid + '/attachments/' + e.target.id + '/data';
+});
+
+$('.series-attachment').live('click', function(e) {
+  e.preventDefault();  //stop the browser from following
+  window.location.href = '../series/' + $.mobile.pageData.uuid + '/attachments/' + e.target.id + '/data';
+});
+
+$('.instance-attachment').live('click', function(e) {
+  e.preventDefault();  //stop the browser from following
+  window.location.href = '../instances/' + $.mobile.pageData.uuid + '/attachments/' + e.target.id + '/data';
+});
 
 $('#protection').live('change', function(e) {
   var isProtected = e.target.value == "on";
--- a/OrthancServer/OrthancExplorer/file-upload.js	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/OrthancExplorer/file-upload.js	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/OrthancExplorer/query-retrieve.js	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/OrthancExplorer/query-retrieve.js	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Engine/IPluginServiceProvider.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/IPluginServiceProvider.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -79,8 +68,9 @@
 #include <boost/regex.hpp>
 #include <dcmtk/dcmdata/dcdict.h>
 #include <dcmtk/dcmdata/dcdicent.h>
-
-#define ERROR_MESSAGE_64BIT "A 64bit version of the Orthanc API is necessary"
+#include <dcmtk/dcmnet/dimse.h>
+
+#define ERROR_MESSAGE_64BIT "A 64bit version of the Orthanc SDK is necessary to use buffers > 4GB and it is currently not available !"
 
 
 namespace Orthanc
@@ -1165,6 +1155,8 @@
     typedef std::list<OrthancPluginIncomingHttpRequestFilter>  IncomingHttpRequestFilters;
     typedef std::list<OrthancPluginIncomingHttpRequestFilter2>  IncomingHttpRequestFilters2;
     typedef std::list<OrthancPluginIncomingDicomInstanceFilter>  IncomingDicomInstanceFilters;
+    typedef std::list<OrthancPluginIncomingCStoreInstanceFilter>  IncomingCStoreInstanceFilters;
+    typedef std::list<OrthancPluginReceivedInstanceCallback>  ReceivedInstanceCallbacks;
     typedef std::list<OrthancPluginDecodeImageCallback>  DecodeImageCallbacks;
     typedef std::list<OrthancPluginTranscoderCallback>  TranscoderCallbacks;
     typedef std::list<OrthancPluginJobsUnserializer>  JobsUnserializers;
@@ -1187,6 +1179,8 @@
     IncomingHttpRequestFilters  incomingHttpRequestFilters_;
     IncomingHttpRequestFilters2 incomingHttpRequestFilters2_;
     IncomingDicomInstanceFilters  incomingDicomInstanceFilters_;
+    IncomingCStoreInstanceFilters  incomingCStoreInstanceFilters_;  // New in Orthanc 1.9.8
+    ReceivedInstanceCallbacks  receivedInstanceCallbacks_;  // New in Orthanc 1.9.8
     RefreshMetricsCallbacks refreshMetricsCallbacks_;
     StorageCommitmentScpCallbacks storageCommitmentScpCallbacks_;
     std::unique_ptr<StorageAreaFactory>  storageArea_;
@@ -2261,7 +2255,104 @@
     return true;
   }
 
-  
+
+
+  uint16_t OrthancPlugins::FilterIncomingCStoreInstance(const DicomInstanceToStore& instance,
+                                                        const Json::Value& simplified)
+  {
+    DicomInstanceFromCallback wrapped(instance);
+    
+    boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_);
+    
+    for (PImpl::IncomingCStoreInstanceFilters::const_iterator
+           filter = pimpl_->incomingCStoreInstanceFilters_.begin();
+         filter != pimpl_->incomingCStoreInstanceFilters_.end(); ++filter)
+    {
+      int32_t filterResult = (*filter) (reinterpret_cast<const OrthancPluginDicomInstance*>(&wrapped));
+
+      if (filterResult >= 0 && filterResult <= 0xFFFF)
+      {
+        return static_cast<uint16_t>(filterResult);
+      }
+      else
+      {
+        // The callback is only allowed to answer uint16_t
+        throw OrthancException(ErrorCode_Plugin);
+      }
+    }
+
+    return STATUS_Success;
+  }
+
+
+  bool OrthancPlugins::ApplyReceivedInstanceCallbacks(const void* receivedDicom,
+                                                      size_t receivedDicomSize,
+                                                      void** modifiedDicomBufferData,
+                                                      size_t& modifiedDicomBufferSize)
+  {
+    uint64_t modifiedDicomSize64 = 0;
+    *modifiedDicomBufferData = NULL;
+
+    boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_);
+    
+    for (PImpl::ReceivedInstanceCallbacks::const_iterator
+           callback = pimpl_->receivedInstanceCallbacks_.begin();
+         callback != pimpl_->receivedInstanceCallbacks_.end(); ++callback)
+    {
+      OrthancPluginReceivedInstanceCallbackResult callbackResult = (*callback) (receivedDicom,
+                                                                                receivedDicomSize,
+                                                                                modifiedDicomBufferData,
+                                                                                &modifiedDicomSize64);
+
+      if (callbackResult == OrthancPluginReceivedInstanceCallbackResult_Discard)
+      {
+        if (modifiedDicomSize64 > 0 || *modifiedDicomBufferData != NULL)
+        {
+          free(modifiedDicomBufferData);
+          throw OrthancException(ErrorCode_Plugin, "The ReceivedInstanceCallback plugin is returning a modified buffer while it has discarded the instance");
+        }
+
+        CLOG(INFO, PLUGINS) << "A plugin has discarded the instance in its ReceivedInstanceCallback";        
+        return false;
+      }
+      else if (callbackResult == OrthancPluginReceivedInstanceCallbackResult_KeepAsIs)
+      {
+        if (modifiedDicomSize64 > 0 || *modifiedDicomBufferData != NULL)
+        {
+          free(modifiedDicomBufferData);
+          throw OrthancException(ErrorCode_Plugin, "The ReceivedInstanceCallback plugin is returning a modified buffer while it has not modified the instance");
+        }
+        return true; 
+      }
+      else if (callbackResult == OrthancPluginReceivedInstanceCallbackResult_Modified)
+      {
+        if (modifiedDicomSize64 > 0 && modifiedDicomBufferData != NULL)
+        {
+          if (static_cast<size_t>(modifiedDicomSize64) != modifiedDicomSize64)  // Orthanc is running in 32bits and has received a > 4GB buffer
+          {
+            free(modifiedDicomBufferData);
+            throw OrthancException(ErrorCode_Plugin, "The Plugin has returned a > 4GB which is too large for Orthanc running in 32bits");
+          }
+
+          modifiedDicomBufferSize = static_cast<size_t>(modifiedDicomSize64);
+
+          CLOG(INFO, PLUGINS) << "A plugin has modified the instance in its ReceivedInstanceCallback";        
+          return true;
+        }
+        else
+        {
+          throw OrthancException(ErrorCode_Plugin, "The ReceivedInstanceCallback plugin is not returning a modified buffer while it has modified the instance");
+        }
+      }
+      else
+      {
+        throw OrthancException(ErrorCode_Plugin, "The ReceivedInstanceCallback has returned an invalid value");
+      }
+    }
+
+    return true;
+  }
+
   void OrthancPlugins::SignalChangeInternal(OrthancPluginChangeType changeType,
                                             OrthancPluginResourceType resourceType,
                                             const char* resource)
@@ -2479,6 +2570,24 @@
   }
 
 
+  void OrthancPlugins::RegisterIncomingCStoreInstanceFilter(const void* parameters)
+  {
+    const _OrthancPluginIncomingCStoreInstanceFilter& p = 
+      *reinterpret_cast<const _OrthancPluginIncomingCStoreInstanceFilter*>(parameters);
+
+    CLOG(INFO, PLUGINS) << "Plugin has registered a callback to filter incoming C-Store DICOM instances";
+    pimpl_->incomingCStoreInstanceFilters_.push_back(p.callback);
+  }
+
+  void OrthancPlugins::RegisterReceivedInstanceCallback(const void* parameters)
+  {
+    const _OrthancPluginReceivedInstanceCallback& p = 
+      *reinterpret_cast<const _OrthancPluginReceivedInstanceCallback*>(parameters);
+
+    CLOG(INFO, PLUGINS) << "Plugin has registered a received instance callback";
+    pimpl_->receivedInstanceCallbacks_.push_back(p.callback);
+  }
+
   void OrthancPlugins::RegisterRefreshMetricsCallback(const void* parameters)
   {
     const _OrthancPluginRegisterRefreshMetricsCallback& p = 
@@ -4957,6 +5066,14 @@
         RegisterIncomingDicomInstanceFilter(parameters);
         return true;
 
+      case _OrthancPluginService_RegisterIncomingCStoreInstanceFilter:
+        RegisterIncomingCStoreInstanceFilter(parameters);
+        return true;
+
+      case _OrthancPluginService_RegisterReceivedInstanceCallback:
+        RegisterReceivedInstanceCallback(parameters);
+        return true;
+
       case _OrthancPluginService_RegisterRefreshMetricsCallback:
         RegisterRefreshMetricsCallback(parameters);
         return true;
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -133,6 +122,10 @@
 
     void RegisterIncomingDicomInstanceFilter(const void* parameters);
 
+    void RegisterIncomingCStoreInstanceFilter(const void* parameters);
+
+    void RegisterReceivedInstanceCallback(const void* parameters);
+
     void RegisterRefreshMetricsCallback(const void* parameters);
 
     void RegisterStorageCommitmentScpCallback(const void* parameters);
@@ -279,6 +272,14 @@
     virtual bool FilterIncomingInstance(const DicomInstanceToStore& instance,
                                         const Json::Value& simplified) ORTHANC_OVERRIDE;
 
+    virtual uint16_t FilterIncomingCStoreInstance(const DicomInstanceToStore& instance,
+                                                  const Json::Value& simplified) ORTHANC_OVERRIDE;
+
+    virtual bool ApplyReceivedInstanceCallbacks(const void* receivedDicomBuffer,
+                                                size_t receivedDicomBufferSize,
+                                                void** modifiedDicomBufferData,
+                                                size_t& modifiedDicomBufferSize);
+
     bool HasStorageArea() const;
 
     IStorageArea* CreateStorageArea();  // To be freed after use
--- a/OrthancServer/Plugins/Engine/PluginsEnumerations.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/PluginsEnumerations.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Engine/PluginsEnumerations.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/PluginsEnumerations.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Engine/PluginsErrorDictionary.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/PluginsErrorDictionary.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Engine/PluginsErrorDictionary.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/PluginsErrorDictionary.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Engine/PluginsJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/PluginsJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Engine/PluginsJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/PluginsJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -75,6 +64,7 @@
 
     virtual bool GetOutput(std::string& output,
                            MimeType& mime,
+                           std::string& filename,
                            const std::string& key) ORTHANC_OVERRIDE
     {
       // TODO
--- a/OrthancServer/Plugins/Engine/PluginsManager.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/PluginsManager.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Engine/PluginsManager.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Engine/PluginsManager.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Plugins/Include/orthanc/OrthancCDatabasePlugin.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Include/orthanc/OrthancCDatabasePlugin.h	Sun Feb 20 12:59:30 2022 +0100
@@ -6,7 +6,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h	Sun Feb 20 12:59:30 2022 +0100
@@ -83,7 +83,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -461,7 +462,9 @@
     _OrthancPluginService_RegisterIncomingDicomInstanceFilter = 1014,
     _OrthancPluginService_RegisterTranscoderCallback = 1015,   /* New in Orthanc 1.7.0 */
     _OrthancPluginService_RegisterStorageArea2 = 1016,         /* New in Orthanc 1.9.0 */
-    
+    _OrthancPluginService_RegisterIncomingCStoreInstanceFilter = 1017,  /* New in Orthanc 1.9.8 */
+    _OrthancPluginService_RegisterReceivedInstanceCallback = 1018,  /* New in Orthanc 1.9.8 */
+
     /* Sending answers to REST calls */
     _OrthancPluginService_AnswerBuffer = 2000,
     _OrthancPluginService_CompressAndAnswerPngImage = 2001,  /* Unused as of Orthanc 0.9.4 */
@@ -999,7 +1002,19 @@
       is already in use */
   } OrthancPluginStorageCommitmentFailureReason;
 
-  
+
+  /**
+   * The return value of ReceivedInstanceCallback
+   **/
+  typedef enum
+  {
+    OrthancPluginReceivedInstanceCallbackResult_KeepAsIs = 1,           /*!< Keep the instance as is */
+    OrthancPluginReceivedInstanceCallbackResult_Modified = 2,           /*!< Modified the instance */
+    OrthancPluginReceivedInstanceCallbackResult_Discard = 3,            /*!< Tell Orthanc to discard the instance */
+
+    _OrthancPluginReceivedInstanceCallbackResult_INTERNAL = 0x7fffffff
+  } OrthancPluginReceivedInstanceCallbackResult;
+
 
   /**
    * @brief A 32-bit memory buffer allocated by the core system of Orthanc.
@@ -7764,6 +7779,130 @@
 
 
   /**
+   * @brief Callback to filter incoming DICOM instances received by 
+   * Orthanc through C-Store.
+   *
+   * Signature of a callback function that is triggered whenever
+   * Orthanc receives a new DICOM instance (through DICOM protocol), 
+   * and that answers whether this DICOM instance should be accepted 
+   * or discarded by Orthanc.  If the instance is discarded, the callback
+   * can specify the C-Store error code.
+   *
+   * Note that the metadata information is not available
+   * (i.e. GetInstanceMetadata() should not be used on "instance").
+   *
+   * @param instance The received DICOM instance.
+   * @return 0 to accept the instance, any valid C-Store error code
+   * to reject the instance, -1 if error.
+   * @ingroup Callback
+   **/
+  typedef int32_t (*OrthancPluginIncomingCStoreInstanceFilter) (
+    const OrthancPluginDicomInstance* instance);
+
+
+  typedef struct
+  {
+    OrthancPluginIncomingCStoreInstanceFilter callback;
+  } _OrthancPluginIncomingCStoreInstanceFilter;
+
+  /**
+   * @brief Register a callback to filter incoming DICOM instances
+   * received by Orthanc through C-Store.
+   *
+   *
+   * @warning Your callback function will be called synchronously with
+   * the core of Orthanc. This implies that deadlocks might emerge if
+   * you call other core primitives of Orthanc in your callback (such
+   * deadlocks are particular visible in the presence of other plugins
+   * or Lua scripts). It is thus strongly advised to avoid any call to
+   * the REST API of Orthanc in the callback. If you have to call
+   * other primitives of Orthanc, you should make these calls in a
+   * separate thread, passing the pending events to be processed
+   * through a message queue.
+   * 
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @param callback The callback.
+   * @return 0 if success, other value if error.
+   * @ingroup Callbacks
+   **/
+  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterIncomingCStoreInstanceFilter(
+    OrthancPluginContext*                     context,
+    OrthancPluginIncomingCStoreInstanceFilter  callback)
+  {
+    _OrthancPluginIncomingCStoreInstanceFilter params;
+    params.callback = callback;
+
+    return context->InvokeService(context, _OrthancPluginService_RegisterIncomingCStoreInstanceFilter, &params);
+  }
+
+  /**
+   * @brief Callback to possibly modify a DICOM instance received
+   * by Orthanc through any source (C-Store or Rest API)
+   *
+   * Signature of a callback function that is triggered whenever
+   * Orthanc receives a new DICOM instance (through DICOM protocol or 
+   * Rest API), and that answers a possibly modified version of the 
+   * DICOM that should be stored in Orthanc.  
+   *
+   * This callback is called immediately after receiption: before 
+   * transcoding and before filtering (FilterIncomingInstance).
+   *
+   * @param receivedDicomBuffer A buffer containing the received DICOM (input).
+   * @param receivedDicomBufferSize The size of the received DICOM (input)
+   * @param modifiedDicomBuffer A buffer containing the modified DICOM (output).
+   *                            This buffer will be freed by the Orthanc Core and must have
+   *                            been allocated by malloc in your plugin or by Orthanc core through
+   *                            a plugin method.
+   * @param modifiedDicomBufferSize The size of the modified DICOM (output)
+   * @return OrthancPluginReceivedInstanceCallbackResult_KeepAsIs to accept the instance as is
+   *         OrthancPluginReceivedInstanceCallbackResult_Modified to store the modified DICOM
+   *         OrthancPluginReceivedInstanceCallbackResult_Discard to tell Orthanc to discard the instance
+   * @ingroup Callback
+   **/
+  typedef OrthancPluginReceivedInstanceCallbackResult (*OrthancPluginReceivedInstanceCallback) (
+    const void* receivedDicomBuffer,
+    uint64_t receivedDicomBufferSize,
+    void** modifiedDicomBuffer,
+    uint64_t* modifiedDicomBufferSize
+    );
+
+
+  typedef struct
+  {
+    OrthancPluginReceivedInstanceCallback callback;
+  } _OrthancPluginReceivedInstanceCallback;
+
+  /**
+   * @brief Register a callback to possibly modify a DICOM instance received
+   * by Orthanc through any source (C-Store or Rest API)
+   *
+   *
+   * @warning Your callback function will be called synchronously with
+   * the core of Orthanc. This implies that deadlocks might emerge if
+   * you call other core primitives of Orthanc in your callback (such
+   * deadlocks are particular visible in the presence of other plugins
+   * or Lua scripts). It is thus strongly advised to avoid any call to
+   * the REST API of Orthanc in the callback. If you have to call
+   * other primitives of Orthanc, you should make these calls in a
+   * separate thread, passing the pending events to be processed
+   * through a message queue.
+   * 
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @param callback The callback.
+   * @return 0 if success, other value if error.
+   * @ingroup Callbacks
+   **/
+  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterReceivedInstanceCallback(
+    OrthancPluginContext*                     context,
+    OrthancPluginReceivedInstanceCallback     callback)
+  {
+    _OrthancPluginReceivedInstanceCallback params;
+    params.callback = callback;
+
+    return context->InvokeService(context, _OrthancPluginService_RegisterReceivedInstanceCallback, &params);
+  }
+
+  /**
    * @brief Get the transfer syntax of a DICOM file.
    *
    * This function returns a pointer to a newly created string that
--- a/OrthancServer/Plugins/Samples/AutomatedJpeg2kCompression/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/AutomatedJpeg2kCompression/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/AutomatedJpeg2kCompression/Plugin.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/AutomatedJpeg2kCompression/Plugin.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/Basic/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/Basic/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/Basic/Plugin.c	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/Basic/Plugin.c	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -539,6 +540,13 @@
                               const std::string& password)
   {
     Clear();
+
+    if (body.size() > 0xffffffffu)
+    {
+      LogError("Cannot handle body size > 4GB");
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
+    }
+
     return CheckHttp(OrthancPluginHttpPost(GetGlobalContext(), &buffer_, url.c_str(),
                                            body.c_str(), body.size(),
                                            username.empty() ? NULL : username.c_str(),
@@ -552,6 +560,13 @@
                              const std::string& password)
   {
     Clear();
+
+    if (body.size() > 0xffffffffu)
+    {
+      LogError("Cannot handle body size > 4GB");
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
+    }
+
     return CheckHttp(OrthancPluginHttpPut(GetGlobalContext(), &buffer_, url.c_str(),
                                           body.empty() ? NULL : body.c_str(),
                                           body.size(),
@@ -1892,6 +1907,12 @@
       ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange);
     }
 
+    if (body.size() > 0xffffffffu)
+    {
+      LogError("Cannot handle body size > 4GB");
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
+    }
+
     OrthancPlugins::MemoryBuffer answer;
     uint16_t status;
     OrthancPluginErrorCode code = OrthancPluginCallPeerApi
@@ -1920,6 +1941,12 @@
       ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange);
     }
 
+    if (body.size() > 0xffffffffu)
+    {
+      LogError("Cannot handle body size > 4GB");
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
+    }
+
     OrthancPlugins::MemoryBuffer answer;
     uint16_t status;
     OrthancPluginErrorCode code = OrthancPluginCallPeerApi
@@ -2569,8 +2596,8 @@
   
   void HttpClient::ClearCredentials()
   {
-    username_.empty();
-    password_.empty();
+    username_.clear();
+    password_.clear();
   }
 
 
@@ -2883,6 +2910,12 @@
 
     MemoryBuffer answerBodyBuffer, answerHeadersBuffer;
 
+    if (body.size() > 0xffffffffu)
+    {
+      LogError("Cannot handle body size > 4GB");
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
+    }
+
     OrthancPluginErrorCode error = OrthancPluginHttpClient(
       GetGlobalContext(),
       *answerBodyBuffer,
--- a/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/Common/OrthancPluginException.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginException.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/Common/OrthancPlugins.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/Common/OrthancPlugins.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/Common/OrthancPluginsExports.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/Common/OrthancPluginsExports.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/ConnectivityChecks/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/ConnectivityChecks/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/ConnectivityChecks/JavaScriptLibraries.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/ConnectivityChecks/JavaScriptLibraries.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/ConnectivityChecks/Plugin.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/ConnectivityChecks/Plugin.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/ConnectivityChecks/WebResources/app.js	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/ConnectivityChecks/WebResources/app.js	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/CustomImageDecoder/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/CustomImageDecoder/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/CustomImageDecoder/Plugin.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/CustomImageDecoder/Plugin.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/ModalityWorklists/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/ModalityWorklists/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/ModalityWorklists/Plugin.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/ModalityWorklists/Plugin.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancServer/Plugins/Samples/Sanitizer/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -0,0 +1,59 @@
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+cmake_minimum_required(VERSION 2.8)
+
+project(Sanitizer)
+
+SET(STATIC_BUILD OFF CACHE BOOL "Static build of the third-party libraries (necessary for Windows)")
+SET(ALLOW_DOWNLOADS OFF CACHE BOOL "Allow CMake to download packages")
+
+SET(USE_SYSTEM_JSONCPP ON CACHE BOOL "Use the system version of JsonCpp")
+SET(USE_SYSTEM_BOOST ON CACHE BOOL "Use the system version of boost")
+SET(ORTHANC_FRAMEWORK_SOURCE path)
+SET(ORTHANC_FRAMEWORK_ROOT ${CMAKE_SOURCE_DIR}/../../../../OrthancFramework/Sources)
+
+include(${CMAKE_SOURCE_DIR}/../Common/OrthancPlugins.cmake)
+include(${CMAKE_SOURCE_DIR}/../../../../OrthancFramework/Resources/CMake/JsonCppConfiguration.cmake)
+include(${CMAKE_SOURCE_DIR}/../../../../OrthancFramework/Resources/CMake/BoostConfiguration.cmake)
+
+include(${CMAKE_SOURCE_DIR}/../../../../OrthancFramework/Resources/CMake/DownloadOrthancFramework.cmake)
+include(${ORTHANC_FRAMEWORK_ROOT}/../Resources/CMake/OrthancFrameworkParameters.cmake)
+set(ENABLE_LOCALE ON)
+set(ENABLE_DCMTK ON)
+include(${ORTHANC_FRAMEWORK_ROOT}/../Resources/CMake/OrthancFrameworkConfiguration.cmake)
+include_directories(${ORTHANC_FRAMEWORK_ROOT})
+
+
+add_library(Sanitizer SHARED 
+    ${CMAKE_SOURCE_DIR}/../Common/OrthancPluginCppWrapper.cpp
+    ${JSONCPP_SOURCES}
+    ${BOOST_SOURCES}
+    Plugin.cpp
+    ${ORTHANC_CORE_SOURCES}
+    ${ORTHANC_DICOM_SOURCES}
+    )
+
+
+install(
+  TARGETS Sanitizer
+  RUNTIME DESTINATION lib    # Destination for Windows
+  LIBRARY DESTINATION share/orthanc/plugins    # Destination for Linux
+  )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancServer/Plugins/Samples/Sanitizer/Plugin.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -0,0 +1,100 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "../../../../OrthancFramework/Sources/Compatibility.h"
+#include "../../../../OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h"
+#include "../../../../OrthancFramework/Sources/OrthancFramework.h"
+#include "../Common/OrthancPluginCppWrapper.h"
+
+#include <boost/filesystem.hpp>
+#include <json/value.h> 
+#include <string.h>
+#include <iostream>
+
+
+
+
+OrthancPluginReceivedInstanceCallbackResult ReceivedInstanceCallback(const void* receivedDicomBuffer,
+                                                                     uint64_t receivedDicomBufferSize,
+                                                                     void** modifiedDicomBuffer,
+                                                                     uint64_t* modifiedDicomBufferSize)
+{
+  Orthanc::ParsedDicomFile dicom(receivedDicomBuffer, receivedDicomBufferSize);
+  std::string institutionName = "My institution";
+
+  dicom.Replace(Orthanc::DICOM_TAG_INSTITUTION_NAME, institutionName, false, Orthanc::DicomReplaceMode_InsertIfAbsent, "");
+  
+  std::string modifiedDicom;
+  dicom.SaveToMemoryBuffer(modifiedDicom);
+
+  *modifiedDicomBuffer = malloc(modifiedDicom.size());
+  *modifiedDicomBufferSize = modifiedDicom.size();
+  memcpy(*modifiedDicomBuffer, modifiedDicom.c_str(), modifiedDicom.size());
+  
+  return OrthancPluginReceivedInstanceCallbackResult_Modified;
+}
+
+
+extern "C"
+{
+  ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c)
+  {
+    OrthancPlugins::SetGlobalContext(c);
+
+    Orthanc::InitializeFramework("", true);
+
+    /* Check the version of the Orthanc core */
+    // if (OrthancPluginCheckVersion(c) == 0)
+    // {
+    //   OrthancPlugins::ReportMinimalOrthancVersion(ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER,
+    //                                               ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER,
+    //                                               ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER);
+    //   return -1;
+    // }
+
+    OrthancPlugins::LogWarning("Sanitizer plugin is initializing");
+    OrthancPluginSetDescription(c, "Sample plugin to sanitize incoming DICOM instances.");
+
+    OrthancPluginRegisterReceivedInstanceCallback(c, ReceivedInstanceCallback);
+
+    return 0;
+  }
+
+
+  ORTHANC_PLUGINS_API void OrthancPluginFinalize()
+  {
+    OrthancPlugins::LogWarning("Sanitizer plugin is finalizing");
+    Orthanc::FinalizeFramework();
+  }
+
+
+  ORTHANC_PLUGINS_API const char* OrthancPluginGetName()
+  {
+    return "sanitizer";
+  }
+
+
+  ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion()
+  {
+    return "0.1";
+  }
+}
--- a/OrthancServer/Plugins/Samples/ServeFolders/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/ServeFolders/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/ServeFolders/Plugin.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/ServeFolders/Plugin.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/StorageArea/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/StorageArea/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/StorageArea/Plugin.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/StorageArea/Plugin.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/StorageCommitmentScp/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/StorageCommitmentScp/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/StorageCommitmentScp/Plugin.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/StorageCommitmentScp/Plugin.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/WebSkeleton/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/WebSkeleton/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/WebSkeleton/Configuration.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/WebSkeleton/Configuration.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/WebSkeleton/Framework/EmbedResources.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/WebSkeleton/Framework/EmbedResources.py	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/WebSkeleton/Framework/Framework.cmake	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/WebSkeleton/Framework/Framework.cmake	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Plugins/Samples/WebSkeleton/Framework/Plugin.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Plugins/Samples/WebSkeleton/Framework/Plugin.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Configuration.json	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Configuration.json	Sun Feb 20 12:59:30 2022 +0100
@@ -40,7 +40,13 @@
   // in the storage (a value of "0" indicates no limit on the number
   // of patients)
   "MaximumPatientCount" : 0,
-  
+
+  // Maximum size of the storage cache in MB.  The storage cache
+  // is stored in RAM and contains a copy of recently accessed
+  // files (written or read).  A value of "0" indicates the cache
+  // is disabled.  (new in Orthanc 1.9.8)
+  "MaximumStorageCacheSize" : 128,
+
   // List of paths to the custom Lua scripts that are to be loaded
   // into this instance of Orthanc
   "LuaScripts" : [
@@ -283,8 +289,17 @@
   // from SCU modalities it does not know about (i.e. that are not
   // listed in the "DicomModalities" option above). Setting this
   // option to "true" implies security risks. (new in Orthanc 1.9.0)
+  // Note: from version 1.10.0, this option applies to C-FIND requests
+  // for Patients/Studies/Series/Instances. Another option is available
+  // for Worklists (see below)
   "DicomAlwaysAllowFind" : false,
 
+  // Whether the Orthanc SCP allows incoming C-FIND requests for worklists, 
+  // even from SCU modalities it does not know about (i.e. that are not
+  // listed in the "DicomModalities" option above). Setting this
+  // option to "true" implies security risks. (new in Orthanc 1.10.0)
+  "DicomAlwaysAllowFindWorklist" : false,
+
   // Whether the Orthanc SCP allows incoming C-GET requests, even
   // from SCU modalities it does not know about (i.e. that are not
   // listed in the "DicomModalities" option above). Setting this
@@ -381,6 +396,7 @@
     //  "Manufacturer" : "Generic",
     //  "AllowEcho" : false,
     //  "AllowFind" : false,
+    //  "AllowFindWorklist" : false,       // new in 1.10.0
     //  "AllowGet"  : false,
     //  "AllowMove" : false,
     //  "AllowStore" : true,
@@ -418,7 +434,16 @@
   // (1.2.840.10008.1.2.1). This parameter can possibly correspond to
   // a compressed transfer syntax. (new in Orthanc 1.9.0)
   "DicomScuPreferredTransferSyntax" : "1.2.840.10008.1.2.1",
-  
+
+  // Number of threads that are used by the embedded DICOM server.
+  // This defines the number of concurrent DICOM operations that can
+  // be run.  Note: this is not limiting the number of concurrent 
+  // connections.  With a single thread, if a C-Find is received
+  // during e.g the transcoding of an incoming C-Store, it will
+  // have to wait until the end of the C-Store before being processed.
+  // (new in Orthanc 1.9.8, before this version, the value was fixed to 4)
+  "DicomThreadsCount" : 4,
+
   // The list of the known Orthanc peers. This option is ignored if
   // "OrthancPeersInDatabase" is set to "true", in which case you must
   // use the REST API to define Orthanc peers.
@@ -624,10 +649,13 @@
   // multiplicity (> 0 with defaults to 1), possibly the maximum
   // multiplicity (0 means arbitrary multiplicity, defaults to 1), and
   // possibly the Private Creator (for private tags).
+  // Note: for private tags, you should only declare the lower 8 bits
+  // of the element since the higher 8 bits may vary from one file to
+  // the other.
   "Dictionary" : {
     // "0014,1020" : [ "DA", "ValidationExpiryDate", 1, 1 ]
-    // "00e1,10c2" : [ "UI", "PET-CT Multi Modality Name", 1, 1, "ELSCINT1" ]
-    // "7053,1003" : [ "ST", "Original Image Filename", 1, 1, "Philips PET Private Group" ]
+    // "00e1,c2" : [ "UI", "PET-CT Multi Modality Name", 1, 1, "ELSCINT1" ]
+    // "7053,03" : [ "ST", "Original Image Filename", 1, 1, "Philips PET Private Group" ]
     // "2001,5f" : [ "SQ", "StackSequence", 1, 1, "Philips Imaging DD 001" ]
   },
 
@@ -828,5 +856,12 @@
   // disk space and might lead to HTTP timeouts on large archives). If
   // set to "true", the chunks of the ZIP file are progressively sent
   // as soon as one DICOM file gets compressed (new in Orthanc 1.9.4)
-  "SynchronousZipStream" : true
+  "SynchronousZipStream" : true,
+
+  // Default number of loader threads when generating Zip archive/media.
+  // A value of 0 means reading and writing are performed in sequence
+  // (default behaviour).  A value > 1 is meaningful only if the storage
+  // is a distributed network storage (e.g object storage plugin).
+  // (new in Orthanc 1.9.8)
+  "ZipLoaderThreads": 0
 }
--- a/OrthancServer/Resources/DicomConformanceStatement.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/DicomConformanceStatement.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,24 +3,13 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Resources/Fonts/GenerateFont.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Fonts/GenerateFont.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/GenerateAnonymizationProfile.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/GenerateAnonymizationProfile.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,24 +3,13 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Resources/Graveyard/DatabaseOptimizations/LookupIdentifierQuery.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Graveyard/DatabaseOptimizations/LookupIdentifierQuery.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Resources/Graveyard/DatabaseOptimizations/LookupIdentifierQuery.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Graveyard/DatabaseOptimizations/LookupIdentifierQuery.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Resources/Graveyard/DatabaseOptimizations/LookupResource.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Graveyard/DatabaseOptimizations/LookupResource.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Resources/Graveyard/DatabaseOptimizations/LookupResource.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Graveyard/DatabaseOptimizations/LookupResource.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Resources/Graveyard/DatabasePluginSample/Database.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Graveyard/DatabasePluginSample/Database.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Resources/Graveyard/DatabasePluginSample/Database.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Graveyard/DatabasePluginSample/Database.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Resources/Graveyard/DatabasePluginSample/DatabaseWrapperBase.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Graveyard/DatabasePluginSample/DatabaseWrapperBase.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Resources/Graveyard/DatabasePluginSample/DatabaseWrapperBase.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Graveyard/DatabasePluginSample/DatabaseWrapperBase.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Resources/Graveyard/DatabasePluginSample/Plugin.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Graveyard/DatabasePluginSample/Plugin.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Resources/RunCppCheck.sh	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/RunCppCheck.sh	Sun Feb 20 12:59:30 2022 +0100
@@ -12,25 +12,25 @@
 constParameter:../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.cpp
 knownArgument:../../OrthancFramework/UnitTestsSources/ImageTests.cpp
 knownConditionTrueFalse:../../OrthancServer/Plugins/Engine/OrthancPlugins.cpp
-nullPointer:../../OrthancFramework/UnitTestsSources/RestApiTests.cpp:320
+nullPointer:../../OrthancFramework/UnitTestsSources/RestApiTests.cpp:321
 nullPointerRedundantCheck:../../OrthancFramework/UnitTestsSources/DicomMapTests.cpp
-stlFindInsert:../../OrthancFramework/Sources/DicomFormat/DicomMap.cpp:1194
-stlFindInsert:../../OrthancFramework/Sources/RestApi/RestApiCallDocumentation.cpp:164
-stlFindInsert:../../OrthancFramework/Sources/RestApi/RestApiCallDocumentation.cpp:72
-stlFindInsert:../../OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp:384
-stlFindInsert:../../OrthancServer/Sources/OrthancWebDav.cpp:386
-stlFindInsert:../../OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp:51
-stlFindInsert:../../OrthancServer/Sources/ServerJobs/SplitStudyJob.cpp:201
-syntaxError:../../OrthancFramework/Sources/SQLite/FunctionContext.h:50
-syntaxError:../../OrthancFramework/UnitTestsSources/ZipTests.cpp:131
-syntaxError:../../OrthancServer/UnitTestsSources/UnitTestsMain.cpp:321
-uninitMemberVar:../../OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.cpp:427
+stlFindInsert:../../OrthancFramework/Sources/DicomFormat/DicomMap.cpp:1195
+stlFindInsert:../../OrthancFramework/Sources/RestApi/RestApiCallDocumentation.cpp:165
+stlFindInsert:../../OrthancFramework/Sources/RestApi/RestApiCallDocumentation.cpp:73
+stlFindInsert:../../OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp:373
+stlFindInsert:../../OrthancServer/Sources/OrthancWebDav.cpp:375
+stlFindInsert:../../OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp:40
+stlFindInsert:../../OrthancServer/Sources/ServerJobs/SplitStudyJob.cpp:190
+syntaxError:../../OrthancFramework/Sources/SQLite/FunctionContext.h:52
+syntaxError:../../OrthancFramework/UnitTestsSources/ZipTests.cpp:132
+syntaxError:../../OrthancServer/UnitTestsSources/UnitTestsMain.cpp:310
+uninitMemberVar:../../OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.cpp:416
 unreadVariable:../../OrthancFramework/Sources/FileStorage/StorageAccessor.cpp
-unreadVariable:../../OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp:1124
+unreadVariable:../../OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp:1115
 unusedFunction
-useInitializationList:../../OrthancFramework/Sources/Images/PngReader.cpp:89
-useInitializationList:../../OrthancFramework/Sources/Images/PngWriter.cpp:97
-useInitializationList:../../OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.cpp:285
+useInitializationList:../../OrthancFramework/Sources/Images/PngReader.cpp:90
+useInitializationList:../../OrthancFramework/Sources/Images/PngWriter.cpp:98
+useInitializationList:../../OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.cpp:274
 EOF
 
 ${CPPCHECK} --enable=all --quiet --std=c++11 \
--- a/OrthancServer/Resources/Samples/CppHelpers/Logging/ILogger.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/CppHelpers/Logging/ILogger.h	Sun Feb 20 12:59:30 2022 +0100
@@ -1,3 +1,25 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
 #pragma once
 
 #include <string>
--- a/OrthancServer/Resources/Samples/CppHelpers/Logging/NullLogger.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/CppHelpers/Logging/NullLogger.h	Sun Feb 20 12:59:30 2022 +0100
@@ -1,3 +1,25 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
 #pragma once
 
 #include "ILogger.h"
--- a/OrthancServer/Resources/Samples/CppHelpers/Logging/OrthancLogger.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/CppHelpers/Logging/OrthancLogger.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -1,3 +1,25 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
 #include "OrthancLogger.h"
 #include "Logging.h"
 
--- a/OrthancServer/Resources/Samples/CppHelpers/Logging/OrthancLogger.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/CppHelpers/Logging/OrthancLogger.h	Sun Feb 20 12:59:30 2022 +0100
@@ -1,3 +1,25 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
 #pragma once
 
 #include "ILogger.h"
--- a/OrthancServer/Resources/Samples/CppHelpers/Logging/OrthancPluginLogger.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/CppHelpers/Logging/OrthancPluginLogger.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -1,3 +1,25 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
 #include "OrthancPluginLogger.h"
 
 namespace OrthancHelpers
--- a/OrthancServer/Resources/Samples/CppHelpers/Logging/OrthancPluginLogger.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/CppHelpers/Logging/OrthancPluginLogger.h	Sun Feb 20 12:59:30 2022 +0100
@@ -1,3 +1,25 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
 #pragma once
 
 #include "ILogger.h"
--- a/OrthancServer/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/ImportDicomFiles/OrthancImport.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/ImportDicomFiles/OrthancImport.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/Lua/CallWebService.js	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Lua/CallWebService.js	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/Python/AnonymizeAllPatients.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Python/AnonymizeAllPatients.py	Sun Feb 20 12:59:30 2022 +0100
@@ -4,7 +4,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/Python/ArchiveAllPatients.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Python/ArchiveAllPatients.py	Sun Feb 20 12:59:30 2022 +0100
@@ -4,7 +4,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/Python/ArchiveStudiesInTimeRange.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Python/ArchiveStudiesInTimeRange.py	Sun Feb 20 12:59:30 2022 +0100
@@ -4,7 +4,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
@@ -35,7 +36,7 @@
 
 def CheckIsDate(date):
     if len(date) != 8 or not date.isdigit():
-        print '"%s" is not a valid date!\n' % date
+        print('"%s" is not a valid date!\n' % date)
         exit(-1)
 
 
@@ -82,7 +83,9 @@
                                             GetTag(study, 'StudyDescription'))
 
         # Remove any non-ASCII character in the filename
-        filename = filename.encode('ascii', errors = 'replace').translate(None, r"'\/:*?\"<>|!=").strip()
+        filename = filename.encode('ascii', errors = 'replace')
+        filename = filename.translate(None, b"'\/:*?\"<>|!=")
+        filename = filename.decode('ascii').strip()
 
         # Download the ZIP archive of the study
         print('Downloading %s' % filename)
--- a/OrthancServer/Resources/Samples/Python/AutoClassify.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Python/AutoClassify.py	Sun Feb 20 12:59:30 2022 +0100
@@ -4,7 +4,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/Python/ChangesLoop.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Python/ChangesLoop.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/Python/ContinuousPatientAnonymization.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Python/ContinuousPatientAnonymization.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
@@ -23,7 +24,7 @@
 import time
 import sys
 import RestToolbox
-import md5
+import hashlib
 
 
 ##
@@ -65,13 +66,15 @@
         
         # The PatientID after anonymization is taken as the 8 first
         # characters from the MD5 hash of the original PatientID
-        anonymizedID = md5.new(patientID).hexdigest()[:8]
+        h = hashlib.md5(patientID.encode('ascii'))
+        anonymizedID = h.hexdigest()[:8]
         anonymizedName = 'Anonymized patient %d' % COUNT
         COUNT += 1
 
         RestToolbox.DoPost(URL + path + '/anonymize',
                            { 'Replace' : { 'PatientID' : anonymizedID,
-                                           'PatientName' : anonymizedName } })
+                                           'PatientName' : anonymizedName },
+                             'Force' : True })
 
         # Delete the source patient after the anonymization
         RestToolbox.DoDelete(URL + change['Path'])
--- a/OrthancServer/Resources/Samples/Python/DeleteAllStudies.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Python/DeleteAllStudies.py	Sun Feb 20 12:59:30 2022 +0100
@@ -4,7 +4,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/Python/DownloadAnonymized.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Python/DownloadAnonymized.py	Sun Feb 20 12:59:30 2022 +0100
@@ -4,7 +4,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/Python/HighPerformanceAutoRouting.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Python/HighPerformanceAutoRouting.py	Sun Feb 20 12:59:30 2022 +0100
@@ -4,7 +4,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/Python/ManualModification.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Python/ManualModification.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/Python/Replicate.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Python/Replicate.py	Sun Feb 20 12:59:30 2022 +0100
@@ -3,7 +3,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/Python/RestToolbox.py	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Python/RestToolbox.py	Sun Feb 20 12:59:30 2022 +0100
@@ -1,7 +1,8 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/Tools/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Tools/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,24 +1,13 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Resources/Samples/Tools/RecoverCompressedFile.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/Tools/RecoverCompressedFile.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/WebApplications/DrawingDicomizer.js	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/WebApplications/DrawingDicomizer.js	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/WebApplications/DrawingDicomizer/orthanc.js	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/WebApplications/DrawingDicomizer/orthanc.js	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Samples/WebApplications/NodeToolbox.js	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Samples/WebApplications/NodeToolbox.js	Sun Feb 20 12:59:30 2022 +0100
@@ -2,7 +2,8 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
--- a/OrthancServer/Resources/Testing/Issue32/Cpp/CMakeLists.txt	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Resources/Testing/Issue32/Cpp/CMakeLists.txt	Sun Feb 20 12:59:30 2022 +0100
@@ -1,24 +1,13 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2021 Osimis S.A., Belgium
+# Copyright (C) 2017-2022 Osimis S.A., Belgium
+# Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/DatabaseLookup.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/DatabaseLookup.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/DatabaseLookup.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/DatabaseLookup.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/ICreateInstance.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/ICreateInstance.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/ICreateInstance.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/ICreateInstance.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/IGetChildrenMetadata.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/IGetChildrenMetadata.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/IGetChildrenMetadata.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/IGetChildrenMetadata.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/ILookupResourceAndParent.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/ILookupResourceAndParent.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/ILookupResourceAndParent.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/ILookupResourceAndParent.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/ILookupResources.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/ILookupResources.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/ILookupResources.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/ILookupResources.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/ISetResourcesContent.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/ISetResourcesContent.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/SetOfResources.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/SetOfResources.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Compatibility/SetOfResources.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/SetOfResources.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/IDatabaseListener.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/IDatabaseListener.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/IDatabaseWrapper.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/IDatabaseWrapper.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/InstallTrackAttachmentsSize.sql	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/InstallTrackAttachmentsSize.sql	Sun Feb 20 12:59:30 2022 +0100
@@ -1,24 +1,13 @@
 -- Orthanc - A Lightweight, RESTful DICOM Store
 -- Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 -- Department, University Hospital of Liege, Belgium
--- Copyright (C) 2017-2021 Osimis S.A., Belgium
+-- Copyright (C) 2017-2022 Osimis S.A., Belgium
+-- Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/PrepareDatabase.sql	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/PrepareDatabase.sql	Sun Feb 20 12:59:30 2022 +0100
@@ -1,24 +1,13 @@
 -- Orthanc - A Lightweight, RESTful DICOM Store
 -- Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 -- Department, University Hospital of Liege, Belgium
--- Copyright (C) 2017-2021 Osimis S.A., Belgium
+-- Copyright (C) 2017-2022 Osimis S.A., Belgium
+-- Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/ResourcesContent.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/ResourcesContent.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/ResourcesContent.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/ResourcesContent.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -74,6 +63,11 @@
       return "ESCAPE '\\'";
     }
 
+    virtual bool IsEscapeBrackets() const ORTHANC_OVERRIDE
+    {
+      return false;
+    }
+
     void Bind(SQLite::Statement& statement) const
     {
       size_t pos = 0;
--- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -2810,7 +2799,7 @@
         
         if (!ok)
         {
-          throw OrthancException(ErrorCode_FullStorage);
+          throw OrthancException(ErrorCode_FullStorage, "Cannot recycle more patients");
         }
       
         LOG(TRACE) << "Recycling one patient";
@@ -3264,11 +3253,18 @@
         {
           if (e.GetErrorCode() == ErrorCode_DatabaseCannotSerialize)
           {
-            throw;
+            throw;  // the transaction has failed -> do not commit the current transaction (and retry)
           }
           else
           {
-            LOG(ERROR) << "EXCEPTION [" << e.What() << "]";
+            LOG(ERROR) << "EXCEPTION [" << e.What() << " - " << e.GetDetails() << "]";
+
+            if (e.GetErrorCode() == ErrorCode_FullStorage)
+            {
+              throw; // do not commit the current transaction
+            }
+
+            // this is an expected failure, exit normaly and commit the current transaction
             storeStatus_ = StoreStatus_Failure;
           }
         }
--- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Upgrade3To4.sql	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Upgrade3To4.sql	Sun Feb 20 12:59:30 2022 +0100
@@ -1,24 +1,13 @@
 -- Orthanc - A Lightweight, RESTful DICOM Store
 -- Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 -- Department, University Hospital of Liege, Belgium
--- Copyright (C) 2017-2021 Osimis S.A., Belgium
+-- Copyright (C) 2017-2022 Osimis S.A., Belgium
+-- Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/Upgrade4To5.sql	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/Upgrade4To5.sql	Sun Feb 20 12:59:30 2022 +0100
@@ -1,25 +1,14 @@
 -- Orthanc - A Lightweight, RESTful DICOM Store
 -- Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 -- Department, University Hospital of Liege, Belgium
--- Copyright (C) 2017-2021 Osimis S.A., Belgium
+-- Copyright (C) 2017-2022 Osimis S.A., Belgium
+-- Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/VoidDatabaseListener.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/VoidDatabaseListener.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Database/VoidDatabaseListener.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Database/VoidDatabaseListener.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/DicomInstanceOrigin.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/DicomInstanceOrigin.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/DicomInstanceOrigin.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/DicomInstanceOrigin.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/DicomInstanceToStore.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/DicomInstanceToStore.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/DicomInstanceToStore.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/DicomInstanceToStore.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/EmbeddedResourceHttpHandler.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/EmbeddedResourceHttpHandler.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/EmbeddedResourceHttpHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/EmbeddedResourceHttpHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ExportedResource.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ExportedResource.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ExportedResource.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ExportedResource.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/IDicomImageDecoder.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/IDicomImageDecoder.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/IServerListener.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/IServerListener.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -55,5 +44,9 @@
 
     virtual bool FilterIncomingInstance(const DicomInstanceToStore& instance,
                                         const Json::Value& simplified) = 0;
+
+    virtual uint16_t FilterIncomingCStoreInstance(const DicomInstanceToStore& instance,
+                                                  const Json::Value& simplified) = 0;
+
   };
 }
--- a/OrthancServer/Sources/LuaScripting.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/LuaScripting.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -43,6 +32,8 @@
 #include "../../OrthancFramework/Sources/Logging.h"
 #include "../../OrthancFramework/Sources/Lua/LuaFunctionCall.h"
 
+#include <dcmtk/dcmnet/dimse.h>
+
 #include <OrthancServerResources.h>
 
 
@@ -945,6 +936,41 @@
     return true;
   }
 
+  uint16_t LuaScripting::FilterIncomingCStoreInstance(const DicomInstanceToStore& instance,
+                                                      const Json::Value& simplified)
+  {
+    static const char* NAME = "ReceivedCStoreInstanceFilter";
+
+    boost::recursive_mutex::scoped_lock lock(mutex_);
+
+    if (lua_.IsExistingFunction(NAME))
+    {
+      LuaFunctionCall call(lua_, NAME);
+      call.PushJson(simplified);
+
+      Json::Value origin;
+      instance.GetOrigin().Format(origin);
+      call.PushJson(origin);
+
+      Json::Value info = Json::objectValue;
+      info["HasPixelData"] = instance.HasPixelData();
+
+      DicomTransferSyntax s;
+      if (instance.LookupTransferSyntax(s))
+      {
+        info["TransferSyntaxUID"] = GetTransferSyntaxUid(s);
+      }
+
+      call.PushJson(info);
+
+      int result;
+      call.ExecuteToInt(result);
+      return static_cast<uint16_t>(result);
+    }
+
+    return STATUS_Success;
+  }
+
 
   void LuaScripting::Execute(const std::string& command)
   {
--- a/OrthancServer/Sources/LuaScripting.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/LuaScripting.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -129,6 +118,9 @@
     bool FilterIncomingInstance(const DicomInstanceToStore& instance,
                                 const Json::Value& simplifiedTags);
 
+    uint16_t FilterIncomingCStoreInstance(const DicomInstanceToStore& instance,
+                                          const Json::Value& simplified);
+
     void Execute(const std::string& command);
 
     void SignalJobSubmitted(const std::string& jobId);
--- a/OrthancServer/Sources/OrthancConfiguration.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancConfiguration.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/OrthancConfiguration.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancConfiguration.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/OrthancFindRequestHandler.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancFindRequestHandler.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/OrthancFindRequestHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancFindRequestHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/OrthancGetRequestHandler.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancGetRequestHandler.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -497,7 +486,7 @@
   {
     MetricsRegistry::Timer timer(context_.GetMetricsRegistry(), "orthanc_get_scp_duration_ms");
 
-    CLOG(WARNING, DICOM) << "C-GET-SCU request received from AET \"" << originatorAet << "\"";
+    CLOG(INFO, DICOM) << "C-GET-SCU request received from AET \"" << originatorAet << "\"";
 
     {
       DicomArray query(input);
--- a/OrthancServer/Sources/OrthancGetRequestHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancGetRequestHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/OrthancHttpHandler.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancHttpHandler.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/OrthancHttpHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancHttpHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/OrthancInitialization.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancInitialization.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/OrthancInitialization.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancInitialization.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/OrthancMoveRequestHandler.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancMoveRequestHandler.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -334,7 +323,7 @@
   {
     MetricsRegistry::Timer timer(context_.GetMetricsRegistry(), "orthanc_move_scp_duration_ms");
 
-    CLOG(WARNING, DICOM) << "Move-SCU request received for AET \"" << targetAet << "\"";
+    CLOG(INFO, DICOM) << "Move-SCU request received for AET \"" << targetAet << "\"";
 
     {
       DicomArray query(input);
--- a/OrthancServer/Sources/OrthancMoveRequestHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancMoveRequestHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -554,16 +543,16 @@
     toStore->SetOrigin(DicomInstanceOrigin::FromRest(call));
 
     ServerContext& context = OrthancRestApi::GetContext(call);
-    StoreStatus status = context.Store(id, *toStore, StoreInstanceMode_Default);
+    ServerContext::StoreResult result = context.Store(id, *toStore, StoreInstanceMode_Default);
 
-    if (status == StoreStatus_Failure)
+    if (result.GetStatus() == StoreStatus_Failure)
     {
       throw OrthancException(ErrorCode_CannotStoreInstance);
     }
 
     if (sendAnswer)
     {
-      OrthancRestApi::GetApi(call).AnswerStoredInstance(call, *toStore, status, id);
+      OrthancRestApi::GetApi(call).AnswerStoredInstance(call, *toStore, result.GetStatus(), id);
     }
   }
 
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestApi.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestApi.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -199,10 +188,10 @@
 
           try
           {
-            StoreStatus status = context.Store(publicId, *toStore, StoreInstanceMode_Default);
+            ServerContext::StoreResult result = context.Store(publicId, *toStore, StoreInstanceMode_Default);
 
             Json::Value info;
-            SetupResourceAnswer(info, *toStore, status, publicId);
+            SetupResourceAnswer(info, *toStore, result.GetStatus(), publicId);
             answer.append(info);
           }
           catch (OrthancException& e)
@@ -252,9 +241,9 @@
       toStore->SetOrigin(DicomInstanceOrigin::FromRest(call));
 
       std::string publicId;
-      StoreStatus status = context.Store(publicId, *toStore, StoreInstanceMode_Default);
+      ServerContext::StoreResult result = context.Store(publicId, *toStore, StoreInstanceMode_Default);
 
-      OrthancRestApi::GetApi(call).AnswerStoredInstance(call, *toStore, status, publicId);
+      OrthancRestApi::GetApi(call).AnswerStoredInstance(call, *toStore, result.GetStatus(), publicId);
     }
   }
 
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestApi.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestApi.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestArchive.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestArchive.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -51,7 +40,9 @@
   static const char* const KEY_RESOURCES = "Resources";
   static const char* const KEY_EXTENDED = "Extended";
   static const char* const KEY_TRANSCODE = "Transcode";
-  
+
+  static const char* const CONFIG_LOADER_THREADS = "ZipLoaderThreads";
+
   static void AddResourcesOfInterestFromArray(ArchiveJob& job,
                                               const Json::Value& resources)
   {
@@ -123,6 +114,7 @@
                                bool& transcode,              /* out */
                                DicomTransferSyntax& syntax,  /* out */
                                int& priority,                /* out */
+                               unsigned int& loaderThreads,  /* out */
                                const Json::Value& body,      /* in */
                                const bool defaultExtended    /* in */)
   {
@@ -151,6 +143,12 @@
     {
       transcode = false;
     }
+
+    {
+      OrthancConfiguration::ReaderLock lock;
+      loaderThreads = lock.GetConfiguration().GetUnsignedIntegerParameter(CONFIG_LOADER_THREADS, 0);  // New in Orthanc 1.9.8
+    }
+   
   }
 
 
@@ -554,8 +552,9 @@
       bool synchronous, extended, transcode;
       DicomTransferSyntax transferSyntax;
       int priority;
+      unsigned int loaderThreads;
       GetJobParameters(synchronous, extended, transcode, transferSyntax,
-                       priority, body, DEFAULT_IS_EXTENDED);
+                       priority, loaderThreads, body, DEFAULT_IS_EXTENDED);
       
       std::unique_ptr<ArchiveJob> job(new ArchiveJob(context, IS_MEDIA, extended));
       AddResourcesOfInterest(*job, body);
@@ -565,6 +564,8 @@
         job->SetTranscode(transferSyntax);
       }
       
+      job->SetLoaderThreads(loaderThreads);
+
       SubmitJob(call.GetOutput(), context, job, priority, synchronous, "Archive.zip");
     }
     else
@@ -578,6 +579,8 @@
   template <bool IS_MEDIA>
   static void CreateSingleGet(RestApiGetCall& call)
   {
+    static const char* const TRANSCODE = "transcode";
+
     if (call.IsDocumentation())
     {
       ResourceType t = StringToResourceType(call.GetFullUri()[0].c_str());
@@ -591,7 +594,7 @@
                         "which might *not* be desirable to archive large amount of data, as it might "
                         "lead to network timeouts. Prefer the asynchronous version using `POST` method.")
         .SetUriArgument("id", "Orthanc identifier of the " + r + " of interest")
-        .SetHttpGetArgument("transcode", RestApiCallDocumentation::Type_String,
+        .SetHttpGetArgument(TRANSCODE, RestApiCallDocumentation::Type_String,
                             "If present, the DICOM files in the archive will be transcoded to the provided "
                             "transfer syntax: https://book.orthanc-server.com/faq/transcoding.html", false)
         .AddAnswerType(MimeType_Zip, "ZIP file containing the archive");
@@ -621,12 +624,17 @@
     std::unique_ptr<ArchiveJob> job(new ArchiveJob(context, IS_MEDIA, extended));
     job->AddResource(id);
 
-    static const char* const TRANSCODE = "transcode";
     if (call.HasArgument(TRANSCODE))
     {
       job->SetTranscode(GetTransferSyntax(call.GetArgument(TRANSCODE, "")));
     }
 
+    {
+      OrthancConfiguration::ReaderLock lock;
+      unsigned int loaderThreads = lock.GetConfiguration().GetUnsignedIntegerParameter(CONFIG_LOADER_THREADS, 0);  // New in Orthanc 1.9.8
+      job->SetLoaderThreads(loaderThreads);
+    }
+
     SubmitJob(call.GetOutput(), context, job, 0 /* priority */,
               true /* synchronous */, id + ".zip");
   }
@@ -660,8 +668,9 @@
       bool synchronous, extended, transcode;
       DicomTransferSyntax transferSyntax;
       int priority;
+      unsigned int loaderThreads;
       GetJobParameters(synchronous, extended, transcode, transferSyntax,
-                       priority, body, false /* by default, not extented */);
+                       priority, loaderThreads, body, false /* by default, not extented */);
       
       std::unique_ptr<ArchiveJob> job(new ArchiveJob(context, IS_MEDIA, extended));
       job->AddResource(id);
@@ -671,6 +680,8 @@
         job->SetTranscode(transferSyntax);
       }
 
+      job->SetLoaderThreads(loaderThreads);
+
       SubmitJob(call.GetOutput(), context, job, priority, synchronous, id + ".zip");
     }
     else
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestChanges.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestChanges.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestModalities.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -134,6 +123,8 @@
                          "Whether to accept C-STORE SCU commands issued by the remote modality", false)
         .SetRequestField("AllowFind", RestApiCallDocumentation::Type_Boolean,
                          "Whether to accept C-FIND SCU commands issued by the remote modality", false)
+        .SetRequestField("AllowFindWorklist", RestApiCallDocumentation::Type_Boolean,
+                         "Whether to accept C-FIND SCU commands for worklists issued by the remote modality", false)
         .SetRequestField("AllowMove", RestApiCallDocumentation::Type_Boolean,
                          "Whether to accept C-MOVE SCU commands issued by the remote modality", false)
         .SetRequestField("AllowGet", RestApiCallDocumentation::Type_Boolean,
@@ -2034,6 +2025,7 @@
       sample["AllowEcho"] = true;
       sample["AllowEventReport"] = true;
       sample["AllowFind"] = true;
+      sample["AllowFindWorklist"] = true;
       sample["AllowGet"] = true;
       sample["AllowMove"] = true;
       sample["AllowNAction"] = true;
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -42,6 +31,7 @@
 #include "../../../OrthancFramework/Sources/HttpServer/HttpContentNegociation.h"
 #include "../../../OrthancFramework/Sources/Images/Image.h"
 #include "../../../OrthancFramework/Sources/Images/ImageProcessing.h"
+#include "../../../OrthancFramework/Sources/Images/NumpyWriter.h"
 #include "../../../OrthancFramework/Sources/Logging.h"
 #include "../../../OrthancFramework/Sources/MultiThreading/Semaphore.h"
 #include "../../../OrthancFramework/Sources/SerializationToolbox.h"
@@ -755,6 +745,7 @@
             .SetTag("Instances")
             .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest")
             .SetHttpGetArgument("quality", RestApiCallDocumentation::Type_Number, "Quality for JPEG images (between 1 and 100, defaults to 90)", false)
+            .SetHttpGetArgument("returnUnsupportedImage", RestApiCallDocumentation::Type_Boolean, "Returns an unsupported.png placeholder image if unable to provide the image instead of returning a 415 HTTP error (defaults to false)", false)
             .SetHttpHeader("Accept", "Format of the resulting image. Can be `image/png` (default), `image/jpeg` or `image/x-portable-arbitrarymap`")
             .AddAnswerType(MimeType_Png, "PNG image")
             .AddAnswerType(MimeType_Jpeg, "JPEG image")
@@ -817,13 +808,20 @@
           }
           else
           {
-            std::string root = "";
-            for (size_t i = 1; i < call.GetFullUri().size(); i++)
+            if (call.HasArgument("returnUnsupportedImage"))
             {
-              root += "../";
+              std::string root = "";
+              for (size_t i = 1; i < call.GetFullUri().size(); i++)
+              {
+                root += "../";
+              }
+
+              call.GetOutput().Redirect(root + "app/images/unsupported.png");
             }
-
-            call.GetOutput().Redirect(root + "app/images/unsupported.png");
+            else
+            {
+              call.GetOutput().SignalError(HttpStatus_415_UnsupportedMediaType);
+            }
           }
           return;
         }
@@ -1072,9 +1070,9 @@
             windowWidth = 1;
           }
 
-          if (std::abs(rescaleSlope) <= 0.1)
+          if (std::abs(rescaleSlope) <= 0.0001)
           {
-            rescaleSlope = 0.1;
+            rescaleSlope = 0.0001;
           }
 
           const double scaling = 255.0 * rescaleSlope / windowWidth;
@@ -1133,6 +1131,247 @@
   }
 
 
+  static void DocumentSharedNumpy(RestApiGetCall& call)
+  {
+    call.GetDocumentation()
+      .SetUriArgument("id", "Orthanc identifier of the DICOM resource of interest")
+      .SetHttpGetArgument("compress", RestApiCallDocumentation::Type_Boolean, "Compress the file as `.npz`", false)
+      .SetHttpGetArgument("rescale", RestApiCallDocumentation::Type_Boolean,
+                          "On grayscale images, apply the rescaling and return floating-point values", false)
+      .AddAnswerType(MimeType_PlainText, "Numpy file: https://numpy.org/devdocs/reference/generated/numpy.lib.format.html");
+  }
+
+
+  namespace
+  {
+    class NumpyVisitor : public boost::noncopyable
+    {
+    private:
+      bool           rescale_;
+      unsigned int   depth_;
+      unsigned int   currentDepth_;
+      unsigned int   width_;
+      unsigned int   height_;
+      PixelFormat    format_;
+      ChunkedBuffer  buffer_;
+
+    public:
+      NumpyVisitor(unsigned int depth /* can be zero if 2D frame */,
+                   bool rescale) :
+        rescale_(rescale),
+        depth_(depth),
+        currentDepth_(0),
+        width_(0),  // dummy initialization
+        height_(0),  // dummy initialization
+        format_(PixelFormat_Grayscale8)  // dummy initialization
+      {
+      }
+
+      void WriteFrame(const ParsedDicomFile& dicom,
+                      unsigned int frame)
+      {
+        std::unique_ptr<ImageAccessor> decoded(dicom.DecodeFrame(frame));
+
+        if (decoded.get() == NULL)
+        {
+          throw OrthancException(ErrorCode_NotImplemented, "Cannot decode DICOM instance");
+        }
+
+        if (currentDepth_ == 0)
+        {
+          width_ = decoded->GetWidth();
+          height_ = decoded->GetHeight();
+          format_ = decoded->GetFormat();
+        }
+        else if (width_ != decoded->GetWidth() ||
+                 height_ != decoded->GetHeight())
+        {
+          throw OrthancException(ErrorCode_IncompatibleImageSize, "The size of the frames varies across the instance(s)");
+        }
+        else if (format_ != decoded->GetFormat())
+        {
+          throw OrthancException(ErrorCode_IncompatibleImageFormat, "The pixel format of the frames varies across the instance(s)");
+        }
+
+        if (rescale_ &&
+            decoded->GetFormat() != PixelFormat_RGB24)
+        {
+          if (currentDepth_ == 0)
+          {
+            NumpyWriter::WriteHeader(buffer_, depth_, width_, height_, PixelFormat_Float32);
+          }
+          
+          double rescaleIntercept, rescaleSlope;
+          dicom.GetRescale(rescaleIntercept, rescaleSlope, frame);
+
+          Image converted(PixelFormat_Float32, decoded->GetWidth(), decoded->GetHeight(), false);
+          ImageProcessing::Convert(converted, *decoded);
+          ImageProcessing::ShiftScale2(converted, static_cast<float>(rescaleIntercept), static_cast<float>(rescaleSlope), false);
+
+          NumpyWriter::WritePixels(buffer_, converted);
+        }
+        else
+        {
+          if (currentDepth_ == 0)
+          {
+            NumpyWriter::WriteHeader(buffer_, depth_, width_, height_, format_);
+          }
+
+          NumpyWriter::WritePixels(buffer_, *decoded);
+        }
+
+        currentDepth_ ++;
+      }
+
+      void Answer(RestApiOutput& output,
+                  bool compress)
+      {
+        if ((depth_ == 0 && currentDepth_ != 1) ||
+            (depth_ != 0 && currentDepth_ != depth_))
+        {
+          throw OrthancException(ErrorCode_BadSequenceOfCalls);
+        }
+        else
+        {
+          std::string answer;
+          NumpyWriter::Finalize(answer, buffer_, compress);
+          output.AnswerBuffer(answer, MimeType_Binary);
+        }
+      }
+    };
+  }
+
+
+  static void GetNumpyFrame(RestApiGetCall& call)
+  {
+    if (call.IsDocumentation())
+    {
+      DocumentSharedNumpy(call);
+      call.GetDocumentation()
+        .SetTag("Instances")
+        .SetSummary("Decode frame for numpy")
+        .SetDescription("Decode one frame of interest from the given DICOM instance, for use with numpy in Python. "
+                        "The numpy array has 3 dimensions: (height, width, color channel).")
+        .SetUriArgument("frame", RestApiCallDocumentation::Type_Number, "Index of the frame (starts at `0`)");
+    }
+    else
+    {
+      const std::string instanceId = call.GetUriComponent("id", "");
+      const bool compress = call.GetBooleanArgument("compress", false);
+      const bool rescale = call.GetBooleanArgument("rescale", true);
+
+      uint32_t frame;
+      if (!SerializationToolbox::ParseUnsignedInteger32(frame, call.GetUriComponent("frame", "0")))
+      {
+        throw OrthancException(ErrorCode_ParameterOutOfRange, "Expected an unsigned integer for the \"frame\" argument");
+      }
+
+      NumpyVisitor visitor(0 /* no depth, 2D frame */, rescale);
+
+      {
+        Semaphore::Locker throttling(throttlingSemaphore_);
+        ServerContext::DicomCacheLocker locker(OrthancRestApi::GetContext(call), instanceId);
+        
+        visitor.WriteFrame(locker.GetDicom(), frame);
+      }
+
+      visitor.Answer(call.GetOutput(), compress);
+    }
+  }
+
+
+  static void GetNumpyInstance(RestApiGetCall& call)
+  {
+    if (call.IsDocumentation())
+    {
+      DocumentSharedNumpy(call);
+      call.GetDocumentation()
+        .SetTag("Instances")
+        .SetSummary("Decode instance for numpy")
+        .SetDescription("Decode the given DICOM instance, for use with numpy in Python. "
+                        "The numpy array has 4 dimensions: (frame, height, width, color channel).");
+    }
+    else
+    {
+      const std::string instanceId = call.GetUriComponent("id", "");
+      const bool compress = call.GetBooleanArgument("compress", false);
+      const bool rescale = call.GetBooleanArgument("rescale", true);
+
+      {
+        Semaphore::Locker throttling(throttlingSemaphore_);
+        ServerContext::DicomCacheLocker locker(OrthancRestApi::GetContext(call), instanceId);
+
+        const unsigned int depth = locker.GetDicom().GetFramesCount();
+        if (depth == 0)
+        {
+          throw OrthancException(ErrorCode_BadFileFormat, "Empty DICOM instance");
+        }
+
+        NumpyVisitor visitor(depth, rescale);
+
+        for (unsigned int frame = 0; frame < depth; frame++)
+        {
+          visitor.WriteFrame(locker.GetDicom(), frame);
+        }
+
+        visitor.Answer(call.GetOutput(), compress);
+      }
+    }
+  }
+
+
+  static void GetNumpySeries(RestApiGetCall& call)
+  {
+    if (call.IsDocumentation())
+    {
+      DocumentSharedNumpy(call);
+      call.GetDocumentation()
+        .SetTag("Series")
+        .SetSummary("Decode series for numpy")
+        .SetDescription("Decode the given DICOM series, for use with numpy in Python. "
+                        "The numpy array has 4 dimensions: (frame, height, width, color channel).");
+    }
+    else
+    {
+      const std::string seriesId = call.GetUriComponent("id", "");
+      const bool compress = call.GetBooleanArgument("compress", false);
+      const bool rescale = call.GetBooleanArgument("rescale", true);
+
+      Semaphore::Locker throttling(throttlingSemaphore_);
+
+      ServerIndex& index = OrthancRestApi::GetIndex(call);
+      SliceOrdering ordering(index, seriesId);
+
+      unsigned int depth = 0;
+      for (size_t i = 0; i < ordering.GetInstancesCount(); i++)
+      {
+        depth += ordering.GetFramesCount(i);
+      }
+
+      ServerContext& context = OrthancRestApi::GetContext(call);
+
+      NumpyVisitor visitor(depth, rescale);
+
+      for (size_t i = 0; i < ordering.GetInstancesCount(); i++)
+      {
+        const std::string& instanceId = ordering.GetInstanceId(i);
+        unsigned int framesCount = ordering.GetFramesCount(i);
+
+        {
+          ServerContext::DicomCacheLocker locker(context, instanceId);
+
+          for (unsigned int frame = 0; frame < framesCount; frame++)
+          {
+            visitor.WriteFrame(locker.GetDicom(), frame);
+          }
+        }
+      }
+
+      visitor.Answer(call.GetOutput(), compress);
+    }
+  }
+
+
   static void GetMatlabImage(RestApiGetCall& call)
   {
     if (call.IsDocumentation())
@@ -1680,6 +1919,8 @@
         .SetSummary("List attachments")
         .SetDescription("Get the list of attachments that are associated with the given " + r)
         .SetUriArgument("id", "Orthanc identifier of the " + r + " of interest")
+        .SetHttpGetArgument("full", RestApiCallDocumentation::Type_String,
+                            "If present, retrieve the attachments list and their numerical ids", false)
         .AddAnswerType(MimeType_Json, "JSON array containing the names of the attachments")
         .SetHttpGetSample(GetDocumentationSampleResource(t) + "/attachments", true);
       return;
@@ -1690,12 +1931,28 @@
     std::set<FileContentType> attachments;
     OrthancRestApi::GetIndex(call).ListAvailableAttachments(attachments, publicId, StringToResourceType(resourceType.c_str()));
 
-    Json::Value result = Json::arrayValue;
-
-    for (std::set<FileContentType>::const_iterator 
-           it = attachments.begin(); it != attachments.end(); ++it)
+    Json::Value result;
+
+    if (call.HasArgument("full"))
     {
-      result.append(EnumerationToString(*it));
+      result = Json::objectValue;
+      
+      for (std::set<FileContentType>::const_iterator 
+            it = attachments.begin(); it != attachments.end(); ++it)
+      {
+        std::string key = EnumerationToString(*it);
+        result[key] = static_cast<uint16_t>(*it);
+      }
+    }
+    else
+    {
+      result = Json::arrayValue;
+      
+      for (std::set<FileContentType>::const_iterator 
+            it = attachments.begin(); it != attachments.end(); ++it)
+      {
+        result.append(EnumerationToString(*it));
+      }
     }
 
     call.GetOutput().AnswerJson(result);
@@ -1779,6 +2036,7 @@
 
       operations.append("compressed-size");
       operations.append("data");
+      operations.append("info");
       operations.append("is-compressed");
 
       if (info.GetUncompressedMD5() != "")
@@ -1795,6 +2053,8 @@
         operations.append("verify-md5");
       }
 
+      operations.append("uuid");
+
       call.GetOutput().AnswerJson(operations);
     }
   }
@@ -1882,6 +2142,36 @@
     }
   }
 
+  static void GetAttachmentInfo(RestApiGetCall& call)
+  {
+    if (call.IsDocumentation())
+    {
+      ResourceType t = StringToResourceType(call.GetFullUri()[0].c_str());
+      std::string r = GetResourceTypeText(t, false /* plural */, false /* upper case */);
+      AddAttachmentDocumentation(call, r);
+      call.GetDocumentation()
+        .SetTag(GetResourceTypeText(t, true /* plural */, true /* upper case */))
+        .SetSummary("Get info about the attachment")
+        .SetDescription("Get all the information about the attachment associated with the given " + r)
+        .AddAnswerType(MimeType_Json, "JSON object containing the information about the attachment")
+        .SetHttpGetSample("https://demo.orthanc-server.com/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/dicom/info", true);
+      return;
+    }
+
+    FileInfo info;
+    if (GetAttachmentInfo(info, call))
+    {
+      Json::Value result = Json::objectValue;    
+      result["Uuid"] = info.GetUuid();
+      result["ContentType"] = info.GetContentType();
+      result["UncompressedSize"] = Json::Value::UInt64(info.GetUncompressedSize());
+      result["CompressedSize"] = Json::Value::UInt64(info.GetCompressedSize());
+      result["UncompressedMD5"] = info.GetUncompressedMD5();
+      result["CompressedMD5"] = info.GetCompressedMD5();
+
+      call.GetOutput().AnswerJson(result);
+    }
+  }
 
   static void GetAttachmentCompressedSize(RestApiGetCall& call)
   {
@@ -2969,7 +3259,7 @@
     std::string publicId = call.GetUriComponent("id", "");
 
     std::string dicomContent;
-    context.ReadDicom(dicomContent, publicId);
+    context.ReadDicomForHeader(dicomContent, publicId);
 
     // TODO Consider using "DicomMap::ParseDicomMetaInformation()" to
     // speed up things here
@@ -3125,7 +3415,7 @@
 
       call.GetDocumentation()
         .SetTag("System")
-        .SetSummary("Describe a set of instances")
+        .SetSummary("Describe a set of resources")
         .SetRequestField("Resources", RestApiCallDocumentation::Type_JsonListOfStrings,
                          "List of the Orthanc identifiers of the patients/studies/series/instances of interest.", true)
         .SetRequestField(LEVEL, RestApiCallDocumentation::Type_String,
@@ -3301,7 +3591,7 @@
     {
       call.GetDocumentation()
         .SetTag("System")
-        .SetSummary("Delete a set of instances")
+        .SetSummary("Delete a set of resources")
         .SetRequestField("Resources", RestApiCallDocumentation::Type_JsonListOfStrings,
                          "List of the Orthanc identifiers of the patients/studies/series/instances of interest.", true)
         .SetDescription("Delete all the DICOM patients, studies, series or instances "
@@ -3387,6 +3677,7 @@
     Register("/instances/{id}/frames/{frame}/matlab", GetMatlabImage);
     Register("/instances/{id}/frames/{frame}/raw", GetRawFrame<false>);
     Register("/instances/{id}/frames/{frame}/raw.gz", GetRawFrame<true>);
+    Register("/instances/{id}/frames/{frame}/numpy", GetNumpyFrame);  // New in Orthanc 1.9.8
     Register("/instances/{id}/pdf", ExtractPdf);
     Register("/instances/{id}/preview", GetImage<ImageExtractionMode_Preview>);
     Register("/instances/{id}/rendered", GetRenderedFrame);
@@ -3395,6 +3686,7 @@
     Register("/instances/{id}/image-int16", GetImage<ImageExtractionMode_Int16>);
     Register("/instances/{id}/matlab", GetMatlabImage);
     Register("/instances/{id}/header", GetInstanceHeader);
+    Register("/instances/{id}/numpy", GetNumpyInstance);  // New in Orthanc 1.9.8
 
     Register("/patients/{id}/protected", IsProtectedPatient);
     Register("/patients/{id}/protected", SetPatientProtection);
@@ -3425,6 +3717,7 @@
       Register("/" + resourceTypes[i] + "/{id}/attachments/{name}/md5", GetAttachmentMD5);
       Register("/" + resourceTypes[i] + "/{id}/attachments/{name}/size", GetAttachmentSize);
       Register("/" + resourceTypes[i] + "/{id}/attachments/{name}/uncompress", ChangeAttachmentCompression<CompressionType_None>);
+      Register("/" + resourceTypes[i] + "/{id}/attachments/{name}/info", GetAttachmentInfo);
       Register("/" + resourceTypes[i] + "/{id}/attachments/{name}/verify-md5", VerifyAttachment);
     }
 
@@ -3453,6 +3746,7 @@
     Register("/instances/{id}/content/*", GetRawContent);
 
     Register("/series/{id}/ordered-slices", OrderSlices);
+    Register("/series/{id}/numpy", GetNumpySeries);  // New in Orthanc 1.9.8
 
     Register("/patients/{id}/reconstruct", ReconstructResource<ResourceType_Patient>);
     Register("/studies/{id}/reconstruct", ReconstructResource<ResourceType_Study>);
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -696,10 +685,16 @@
 
     std::string value;
     MimeType mime;
+    std::string filename;
     
     if (OrthancRestApi::GetContext(call).GetJobsEngine().
-        GetRegistry().GetJobOutput(value, mime, job, key))
+        GetRegistry().GetJobOutput(value, mime, filename, job, key))
     {
+      if (!filename.empty())
+      {
+        call.GetOutput().SetContentFilename(filename.c_str());
+      }
+
       call.GetOutput().AnswerBuffer(value, mime);
     }
     else
--- a/OrthancServer/Sources/OrthancWebDav.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancWebDav.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -1313,9 +1302,9 @@
         try
         {
           std::string publicId;
-          StoreStatus status = context_.Store(publicId, *instance, StoreInstanceMode_Default);
-          if (status == StoreStatus_Success ||
-              status == StoreStatus_AlreadyStored)
+          ServerContext::StoreResult result = context_.Store(publicId, *instance, StoreInstanceMode_Default);
+          if (result.GetStatus() == StoreStatus_Success ||
+              result.GetStatus() == StoreStatus_AlreadyStored)
           {
             LOG(INFO) << "Successfully imported DICOM instance from WebDAV: "
                       << path << " (Orthanc ID: " << publicId << ")";
--- a/OrthancServer/Sources/OrthancWebDav.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/OrthancWebDav.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/PrecompiledHeadersServer.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/PrecompiledHeadersServer.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/PrecompiledHeadersServer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/PrecompiledHeadersServer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/QueryRetrieveHandler.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/QueryRetrieveHandler.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/QueryRetrieveHandler.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/QueryRetrieveHandler.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Search/DatabaseConstraint.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Search/DatabaseConstraint.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Search/DatabaseConstraint.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Search/DatabaseConstraint.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Search/DatabaseLookup.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Search/DatabaseLookup.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Search/DatabaseLookup.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Search/DatabaseLookup.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Search/DicomTagConstraint.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Search/DicomTagConstraint.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Search/DicomTagConstraint.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Search/DicomTagConstraint.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Search/HierarchicalMatcher.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Search/HierarchicalMatcher.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Search/HierarchicalMatcher.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Search/HierarchicalMatcher.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/Search/ISqlLookupFormatter.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Search/ISqlLookupFormatter.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -79,7 +68,8 @@
   static bool FormatComparison(std::string& target,
                                ISqlLookupFormatter& formatter,
                                const DatabaseConstraint& constraint,
-                               size_t index)
+                               size_t index,
+                               bool escapeBrackets)
   {
     std::string tag = "t" + boost::lexical_cast<std::string>(index);
 
@@ -196,6 +186,14 @@
             {
               escaped += "\\\\";
             }
+            else if (escapeBrackets && value[i] == '[')
+            {
+              escaped += "\\[";
+            }
+            else if (escapeBrackets && value[i] == ']')
+            {
+              escaped += "\\]";
+            }
             else
             {
               escaped += value[i];
@@ -303,6 +301,8 @@
     assert(upperLevel <= queryLevel &&
            queryLevel <= lowerLevel);
 
+    const bool escapeBrackets = formatter.IsEscapeBrackets();
+    
     std::string joins, comparisons;
 
     size_t count = 0;
@@ -311,7 +311,7 @@
     {
       std::string comparison;
       
-      if (FormatComparison(comparison, formatter, lookup[i], count))
+      if (FormatComparison(comparison, formatter, lookup[i], count, escapeBrackets))
       {
         std::string join;
         FormatJoin(join, lookup[i], count);
--- a/OrthancServer/Sources/Search/ISqlLookupFormatter.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/Search/ISqlLookupFormatter.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -60,6 +49,13 @@
 
     virtual std::string FormatWildcardEscape() = 0;
 
+    /**
+     * Whether to escape '[' and ']', which is only needed for
+     * MSSQL. New in Orthanc 1.9.8, from the following changeset:
+     * https://hg.orthanc-server.com/orthanc-databases/rev/389c037387ea
+     **/
+    virtual bool IsEscapeBrackets() const = 0;
+
     static void Apply(std::string& sql,
                       ISqlLookupFormatter& formatter,
                       const std::vector<DatabaseConstraint>& lookup,
--- a/OrthancServer/Sources/ServerContext.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerContext.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -46,6 +35,7 @@
 #include "../../OrthancFramework/Sources/HttpServer/HttpStreamTranscoder.h"
 #include "../../OrthancFramework/Sources/JobsEngine/SetOfInstancesJob.h"
 #include "../../OrthancFramework/Sources/Logging.h"
+#include "../../OrthancFramework/Sources/MallocMemoryBuffer.h"
 #include "../../OrthancFramework/Sources/MetricsRegistry.h"
 #include "../Plugins/Engine/OrthancPlugins.h"
 
@@ -57,6 +47,7 @@
 #include "StorageCommitmentReports.h"
 
 #include <dcmtk/dcmdata/dcfilefo.h>
+#include <dcmtk/dcmnet/dimse.h>
 
 
 static size_t DICOM_CACHE_SIZE = 128 * 1024 * 1024;  // 128 MB
@@ -100,6 +91,13 @@
       transferSyntax != DicomTransferSyntax_XML);
   }
 
+
+  ServerContext::StoreResult::StoreResult() :
+    status_(StoreStatus_Failure),
+    cstoreStatusCode_(0)
+  {
+  }
+
   
   void ServerContext::ChangeThread(ServerContext* that,
                                    unsigned int sleepDelay)
@@ -484,14 +482,14 @@
   void ServerContext::RemoveFile(const std::string& fileUuid,
                                  FileContentType type)
   {
-    StorageAccessor accessor(area_, GetMetricsRegistry());
+    StorageAccessor accessor(area_, storageCache_, GetMetricsRegistry());
     accessor.Remove(fileUuid, type);
   }
 
 
-  StoreStatus ServerContext::StoreAfterTranscoding(std::string& resultPublicId,
-                                                   DicomInstanceToStore& dicom,
-                                                   StoreInstanceMode mode)
+  ServerContext::StoreResult ServerContext::StoreAfterTranscoding(std::string& resultPublicId,
+                                                                  DicomInstanceToStore& dicom,
+                                                                  StoreInstanceMode mode)
   {
     bool overwrite;
     switch (mode)
@@ -526,7 +524,7 @@
     try
     {
       MetricsRegistry::Timer timer(GetMetricsRegistry(), "orthanc_store_dicom_duration_ms");
-      StorageAccessor accessor(area_, GetMetricsRegistry());
+      StorageAccessor accessor(area_, storageCache_, GetMetricsRegistry());
 
       DicomInstanceHasher hasher(summary);
       resultPublicId = hasher.HashInstance();
@@ -538,7 +536,7 @@
       Toolbox::SimplifyDicomAsJson(simplifiedTags, dicomAsJson, DicomToJsonFormat_Human);
 
       // Test if the instance must be filtered out
-      bool accepted = true;
+      StoreResult result;
 
       {
         boost::shared_lock<boost::shared_mutex> lock(listenersMutex_);
@@ -549,9 +547,22 @@
           {
             if (!it->GetListener().FilterIncomingInstance(dicom, simplifiedTags))
             {
-              accepted = false;
+              result.SetStatus(StoreStatus_FilteredOut);
+              result.SetCStoreStatusCode(STATUS_Success); // to keep backward compatibility, we still return 'success'
               break;
             }
+
+            if (dicom.GetOrigin().GetRequestOrigin() == Orthanc::RequestOrigin_DicomProtocol)
+            {
+              uint16_t filterResult = it->GetListener().FilterIncomingCStoreInstance(dicom, simplifiedTags);
+              if (filterResult != 0x0000)
+              {
+                result.SetStatus(StoreStatus_FilteredOut);
+                result.SetCStoreStatusCode(filterResult);
+                break;
+              }
+            }
+            
           }
           catch (OrthancException& e)
           {
@@ -563,10 +574,10 @@
         }
       }
 
-      if (!accepted)
+      if (result.GetStatus() == StoreStatus_FilteredOut)
       {
         LOG(INFO) << "An incoming instance has been discarded by the filter";
-        return StoreStatus_FilteredOut;
+        return result;
       }
 
       // Remove the file from the DicomCache (useful if
@@ -595,9 +606,9 @@
 
       typedef std::map<MetadataType, std::string>  InstanceMetadata;
       InstanceMetadata  instanceMetadata;
-      StoreStatus status = index_.Store(
+      result.SetStatus(index_.Store(
         instanceMetadata, summary, attachments, dicom.GetMetadata(), dicom.GetOrigin(), overwrite,
-        hasTransferSyntax, transferSyntax, hasPixelDataOffset, pixelDataOffset);
+        hasTransferSyntax, transferSyntax, hasPixelDataOffset, pixelDataOffset));
 
       // Only keep the metadata for the "instance" level
       dicom.ClearMetadata();
@@ -608,7 +619,7 @@
         dicom.AddMetadata(ResourceType_Instance, it->first, it->second);
       }
             
-      if (status != StoreStatus_Success)
+      if (result.GetStatus() != StoreStatus_Success)
       {
         accessor.Remove(dicomInfo);
 
@@ -618,7 +629,7 @@
         }
       }
 
-      switch (status)
+      switch (result.GetStatus())
       {
         case StoreStatus_Success:
           LOG(INFO) << "New instance stored";
@@ -637,8 +648,8 @@
           break;
       }
 
-      if (status == StoreStatus_Success ||
-          status == StoreStatus_AlreadyStored)
+      if (result.GetStatus() == StoreStatus_Success ||
+          result.GetStatus() == StoreStatus_AlreadyStored)
       {
         boost::shared_lock<boost::shared_mutex> lock(listenersMutex_);
 
@@ -657,7 +668,7 @@
         }
       }
 
-      return status;
+      return result;
     }
     catch (OrthancException& e)
     {
@@ -671,14 +682,47 @@
   }
 
 
-  StoreStatus ServerContext::Store(std::string& resultPublicId,
-                                   DicomInstanceToStore& dicom,
-                                   StoreInstanceMode mode)
-  {
+  ServerContext::StoreResult ServerContext::Store(std::string& resultPublicId,
+                                                  DicomInstanceToStore& receivedDicom,
+                                                  StoreInstanceMode mode)
+  { 
+    DicomInstanceToStore* dicom = &receivedDicom;
+    std::unique_ptr<DicomInstanceToStore> modifiedDicom;
+
+    std::unique_ptr<MallocMemoryBuffer> raii(new MallocMemoryBuffer);
+
+#if ORTHANC_ENABLE_PLUGINS == 1
+    if (HasPlugins())
+    {
+      void* modifiedDicomBuffer = NULL;
+      size_t modifiedDicomBufferSize = 0;
+
+      bool store = GetPlugins().ApplyReceivedInstanceCallbacks(receivedDicom.GetBufferData(), 
+                                                               receivedDicom.GetBufferSize(),
+                                                               &modifiedDicomBuffer,
+                                                               modifiedDicomBufferSize);
+      raii->Assign(modifiedDicomBuffer, modifiedDicomBufferSize, ::free);
+
+      if (!store)
+      {
+        StoreResult result;
+        result.SetStatus(StoreStatus_FilteredOut);
+        return result;
+      }
+
+      if (modifiedDicomBufferSize > 0 && modifiedDicomBuffer != NULL)
+      {
+        modifiedDicom.reset(DicomInstanceToStore::CreateFromBuffer(modifiedDicomBuffer, modifiedDicomBufferSize));
+        modifiedDicom->SetOrigin(dicom->GetOrigin());
+        dicom = modifiedDicom.get();
+      }
+    }
+#endif
+
     if (!isIngestTranscoding_)
     {
       // No automated transcoding. This was the only path in Orthanc <= 1.6.1.
-      return StoreAfterTranscoding(resultPublicId, dicom, mode);
+      return StoreAfterTranscoding(resultPublicId, *dicom, mode);
     }
     else
     {
@@ -687,7 +731,7 @@
       bool transcode = false;
 
       DicomTransferSyntax sourceSyntax;
-      if (!dicom.LookupTransferSyntax(sourceSyntax) ||
+      if (!dicom->LookupTransferSyntax(sourceSyntax) ||
           sourceSyntax == ingestTransferSyntax_)
       {
         // Don't transcode if the incoming DICOM is already in the proper transfer syntax
@@ -714,7 +758,7 @@
       if (!transcode)
       {
         // No transcoding
-        return StoreAfterTranscoding(resultPublicId, dicom, mode);
+        return StoreAfterTranscoding(resultPublicId, *dicom, mode);
       }
       else
       {
@@ -723,7 +767,7 @@
         syntaxes.insert(ingestTransferSyntax_);
         
         IDicomTranscoder::DicomImage source;
-        source.SetExternalBuffer(dicom.GetBufferData(), dicom.GetBufferSize());
+        source.SetExternalBuffer(dicom->GetBufferData(), dicom->GetBufferSize());
         
         IDicomTranscoder::DicomImage transcoded;
         if (Transcode(transcoded, source, syntaxes, true /* allow new SOP instance UID */))
@@ -731,17 +775,17 @@
           std::unique_ptr<ParsedDicomFile> tmp(transcoded.ReleaseAsParsedDicomFile());
 
           std::unique_ptr<DicomInstanceToStore> toStore(DicomInstanceToStore::CreateFromParsedDicomFile(*tmp));
-          toStore->SetOrigin(dicom.GetOrigin());
+          toStore->SetOrigin(dicom->GetOrigin());
 
-          StoreStatus ok = StoreAfterTranscoding(resultPublicId, *toStore, mode);
+          StoreResult result = StoreAfterTranscoding(resultPublicId, *toStore, mode);
           assert(resultPublicId == tmp->GetHasher().HashInstance());
 
-          return ok;
+          return result;
         }
         else
         {
           // Cannot transcode => store the original file
-          return StoreAfterTranscoding(resultPublicId, dicom, mode);
+          return StoreAfterTranscoding(resultPublicId, *dicom, mode);
         }
       }
     }
@@ -760,7 +804,7 @@
     }
     else
     {
-      StorageAccessor accessor(area_, GetMetricsRegistry());
+      StorageAccessor accessor(area_, storageCache_, GetMetricsRegistry());
       accessor.AnswerFile(output, attachment, GetFileContentMime(content));
     }
   }
@@ -790,7 +834,7 @@
 
     std::string content;
 
-    StorageAccessor accessor(area_, GetMetricsRegistry());
+    StorageAccessor accessor(area_, storageCache_, GetMetricsRegistry());
     accessor.Read(content, attachment);
 
     FileInfo modified = accessor.Write(content.empty() ? NULL : content.c_str(),
@@ -846,7 +890,7 @@
       std::string dicom;
 
       {
-        StorageAccessor accessor(area_, GetMetricsRegistry());
+        StorageAccessor accessor(area_, storageCache_, GetMetricsRegistry());
         accessor.Read(dicom, attachment);
       }
 
@@ -911,8 +955,8 @@
       
         std::unique_ptr<IMemoryBuffer> dicom;
         {
-          MetricsRegistry::Timer timer(GetMetricsRegistry(), "orthanc_storage_read_range_duration_ms");
-          dicom.reset(area_.ReadRange(attachment.GetUuid(), FileContentType_Dicom, 0, pixelDataOffset));
+          StorageAccessor accessor(area_, storageCache_, GetMetricsRegistry());
+          dicom.reset(accessor.ReadStartRange(attachment.GetUuid(), FileContentType_Dicom, pixelDataOffset, FileContentType_DicomUntilPixelData));
         }
 
         if (dicom.get() == NULL)
@@ -941,7 +985,7 @@
         std::string dicomAsJson;
 
         {
-          StorageAccessor accessor(area_, GetMetricsRegistry());
+          StorageAccessor accessor(area_, storageCache_, GetMetricsRegistry());
           accessor.Read(dicomAsJson, attachment);
         }
 
@@ -1010,7 +1054,15 @@
     int64_t revision;
     ReadAttachment(dicom, revision, instancePublicId, FileContentType_Dicom, true /* uncompress */);
   }
-    
+
+  void ServerContext::ReadDicomForHeader(std::string& dicom,
+                                         const std::string& instancePublicId)
+  {
+    if (!ReadDicomUntilPixelData(dicom, instancePublicId))
+    {
+      ReadDicom(dicom, instancePublicId);
+    }
+  }
 
   bool ServerContext::ReadDicomUntilPixelData(std::string& dicom,
                                               const std::string& instancePublicId)
@@ -1039,8 +1091,10 @@
       {
         uint64_t pixelDataOffset = boost::lexical_cast<uint64_t>(s);
 
+        StorageAccessor accessor(area_, storageCache_, GetMetricsRegistry());
+
         std::unique_ptr<IMemoryBuffer> buffer(
-          area_.ReadRange(attachment.GetUuid(), attachment.GetContentType(), 0, pixelDataOffset));
+          accessor.ReadStartRange(attachment.GetUuid(), attachment.GetContentType(), pixelDataOffset, FileContentType_DicomUntilPixelData));
         buffer->MoveToString(dicom);
         return true;   // Success
       }
@@ -1071,7 +1125,7 @@
     assert(attachment.GetContentType() == content);
 
     {
-      StorageAccessor accessor(area_, GetMetricsRegistry());
+      StorageAccessor accessor(area_, storageCache_, GetMetricsRegistry());
 
       if (uncompressIfNeeded)
       {
@@ -1171,7 +1225,7 @@
     // TODO Should we use "gzip" instead?
     CompressionType compression = (compressionEnabled_ ? CompressionType_ZlibWithSize : CompressionType_None);
 
-    StorageAccessor accessor(area_, GetMetricsRegistry());
+    StorageAccessor accessor(area_, storageCache_, GetMetricsRegistry());
     FileInfo attachment = accessor.Write(data, size, attachmentType, compression, storeMD5_);
 
     try
--- a/OrthancServer/Sources/ServerContext.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerContext.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -43,6 +32,7 @@
 #include "../../OrthancFramework/Sources/DicomParsing/DicomModification.h"
 #include "../../OrthancFramework/Sources/DicomParsing/IDicomTranscoder.h"
 #include "../../OrthancFramework/Sources/DicomParsing/ParsedDicomCache.h"
+#include "../../OrthancFramework/Sources/FileStorage/StorageCache.h"
 #include "../../OrthancFramework/Sources/MultiThreading/Semaphore.h"
 
 
@@ -93,6 +83,36 @@
                          const Json::Value* dicomAsJson) = 0;
     };
     
+    struct StoreResult
+    {
+    private:
+      StoreStatus  status_;
+      uint16_t     cstoreStatusCode_;
+      // uint16_t     httpStatusCode_; // for future use
+
+    public:
+      StoreResult();
+
+      void SetStatus(StoreStatus status)
+      {
+        status_ = status;
+      }
+
+      StoreStatus GetStatus()
+      {
+        return status_;
+      }
+
+      void SetCStoreStatusCode(uint16_t statusCode)
+      {
+        cstoreStatusCode_ = statusCode;
+      }
+
+      uint16_t GetCStoreStatusCode()
+      {
+        return cstoreStatusCode_;
+      }
+    };
     
   private:
     class LuaServerListener : public IServerListener
@@ -123,6 +143,12 @@
       {
         return context_.filterLua_.FilterIncomingInstance(instance, simplified);
       }
+
+      virtual uint16_t FilterIncomingCStoreInstance(const DicomInstanceToStore& instance,
+                                                    const Json::Value& simplified) ORTHANC_OVERRIDE
+      {
+        return context_.filterLua_.FilterIncomingCStoreInstance(instance, simplified);
+      }
     };
     
     class ServerListener
@@ -169,6 +195,7 @@
 
     ServerIndex index_;
     IStorageArea& area_;
+    StorageCache storageCache_;
 
     bool compressionEnabled_;
     bool storeMD5_;
@@ -231,7 +258,7 @@
     bool isUnknownSopClassAccepted_;
     std::set<DicomTransferSyntax>  acceptedTransferSyntaxes_;
 
-    StoreStatus StoreAfterTranscoding(std::string& resultPublicId,
+    StoreResult StoreAfterTranscoding(std::string& resultPublicId,
                                       DicomInstanceToStore& dicom,
                                       StoreInstanceMode mode);
 
@@ -288,6 +315,11 @@
       return index_;
     }
 
+    void SetMaximumStorageCacheSize(size_t size)
+    {
+      return storageCache_.SetMaximumSize(size);
+    }
+
     void SetCompressionEnabled(bool enabled);
 
     bool IsCompressionEnabled() const
@@ -304,7 +336,7 @@
                        int64_t oldRevision,
                        const std::string& oldMD5);
 
-    StoreStatus Store(std::string& resultPublicId,
+    StoreResult Store(std::string& resultPublicId,
                       DicomInstanceToStore& dicom,
                       StoreInstanceMode mode);
 
@@ -325,7 +357,10 @@
 
     void ReadDicom(std::string& dicom,
                    const std::string& instancePublicId);
-    
+
+    void ReadDicomForHeader(std::string& dicom,
+                            const std::string& instancePublicId);
+
     bool ReadDicomUntilPixelData(std::string& dicom,
                                  const std::string& instancePublicId);
 
--- a/OrthancServer/Sources/ServerEnumerations.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerEnumerations.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerEnumerations.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerEnumerations.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -60,7 +49,7 @@
     StoreStatus_Success,
     StoreStatus_AlreadyStored,
     StoreStatus_Failure,
-    StoreStatus_FilteredOut     // Removed by NewInstanceFilter
+    StoreStatus_FilteredOut     // Removed by NewInstanceFilter or ReceivedInstanceCallback
   };
 
   enum DicomTagType
--- a/OrthancServer/Sources/ServerIndex.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerIndex.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerIndex.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerIndex.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerIndexChange.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerIndexChange.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/ArchiveJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -40,6 +29,7 @@
 #include "../../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
 #include "../../../OrthancFramework/Sources/Logging.h"
 #include "../../../OrthancFramework/Sources/OrthancException.h"
+#include "../../../OrthancFramework/Sources/MultiThreading/Semaphore.h"
 #include "../OrthancConfiguration.h"
 #include "../ServerContext.h"
 
@@ -88,6 +78,181 @@
   }
 
 
+  class ArchiveJob::InstanceLoader : public boost::noncopyable
+  {
+  protected:
+    ServerContext&                        context_;
+  public:
+    explicit InstanceLoader(ServerContext& context)
+    : context_(context)
+    {
+    }
+
+    virtual ~InstanceLoader()
+    {
+    }
+
+    virtual void PrepareDicom(const std::string& instanceId)
+    {
+
+    }
+
+    virtual void GetDicom(std::string& dicom, const std::string& instanceId) = 0;
+
+    virtual void Clear()
+    {
+    }
+  };
+
+  class ArchiveJob::SynchronousInstanceLoader : public ArchiveJob::InstanceLoader
+  {
+  public:
+    explicit SynchronousInstanceLoader(ServerContext& context)
+    : InstanceLoader(context)
+    {
+    }
+
+    virtual void GetDicom(std::string& dicom, const std::string& instanceId) ORTHANC_OVERRIDE
+    {
+      context_.ReadDicom(dicom, instanceId);
+    }
+  };
+
+  class InstanceId : public Orthanc::IDynamicObject
+  {
+  private:
+    std::string id_;
+
+  public:
+    explicit InstanceId(const std::string& id) : id_(id)
+    {
+    }
+
+    virtual ~InstanceId() ORTHANC_OVERRIDE
+    {
+    }
+
+    std::string GetId() const {return id_;};
+  };
+
+  class ArchiveJob::ThreadedInstanceLoader : public ArchiveJob::InstanceLoader
+  {
+    Semaphore                           availableInstancesSemaphore_;
+    std::map<std::string, boost::shared_ptr<std::string> >  availableInstances_;
+    boost::mutex                        availableInstancesMutex_;
+    SharedMessageQueue                  instancesToPreload_;
+    std::vector<boost::thread*>         threads_;
+
+
+  public:
+    ThreadedInstanceLoader(ServerContext& context, size_t threadCount)
+    : InstanceLoader(context),
+      availableInstancesSemaphore_(0)
+    {
+      for (size_t i = 0; i < threadCount; i++)
+      {
+        threads_.push_back(new boost::thread(PreloaderWorkerThread, this));
+      }
+    }
+
+    virtual ~ThreadedInstanceLoader()
+    {
+      Clear();
+    }
+
+    virtual void Clear() ORTHANC_OVERRIDE
+    {
+      for (size_t i = 0; i < threads_.size(); i++)
+      {
+        instancesToPreload_.Enqueue(NULL);
+      }
+
+      for (size_t i = 0; i < threads_.size(); i++)
+      {
+        if (threads_[i]->joinable())
+        {
+          threads_[i]->join();
+        }
+        delete threads_[i];
+      }
+
+      threads_.clear();
+      availableInstances_.clear();
+    }
+
+    static void PreloaderWorkerThread(ThreadedInstanceLoader* that)
+    {
+      while (true)
+      {
+        std::unique_ptr<InstanceId> instanceId(dynamic_cast<InstanceId*>(that->instancesToPreload_.Dequeue(0)));
+        if (instanceId.get() == NULL)  // that's the signal to exit the thread
+        {
+          return;
+        }
+
+        try
+        {
+          boost::shared_ptr<std::string> dicomContent(new std::string());
+          that->context_.ReadDicom(*dicomContent, instanceId->GetId());
+          {
+            boost::mutex::scoped_lock lock(that->availableInstancesMutex_);
+            that->availableInstances_[instanceId->GetId()] = dicomContent;
+          }
+
+          that->availableInstancesSemaphore_.Release();
+        }
+        catch (OrthancException& e)
+        {
+          boost::mutex::scoped_lock lock(that->availableInstancesMutex_);
+          // store a NULL result to notify that we could not read the instance
+          that->availableInstances_[instanceId->GetId()] = boost::shared_ptr<std::string>(); 
+          that->availableInstancesSemaphore_.Release();
+        }
+      }
+    }
+
+    virtual void PrepareDicom(const std::string& instanceId) ORTHANC_OVERRIDE
+    {
+      instancesToPreload_.Enqueue(new InstanceId(instanceId));
+    }
+
+    virtual void GetDicom(std::string& dicom, const std::string& instanceId) ORTHANC_OVERRIDE
+    {
+      while (true)
+      {
+        // wait for an instance to be available but this might not be the one we are waiting for !
+        availableInstancesSemaphore_.Acquire();
+
+        boost::shared_ptr<std::string> dicomContent;
+        {
+          if (availableInstances_.find(instanceId) != availableInstances_.end())
+          {
+            // this is the instance we were waiting for
+            dicomContent = availableInstances_[instanceId];
+            availableInstances_.erase(instanceId);
+
+            if (dicomContent.get() == NULL)  // there has been an error while reading the file
+            {
+              throw OrthancException(ErrorCode_InexistentItem);
+            }
+            dicom.swap(*dicomContent);
+
+            if (availableInstances_.size() > 0)
+            {
+              // we have just read the instance we were waiting for but there are still other instances available ->
+              // make sure the next GetDicom call does not wait !
+              availableInstancesSemaphore_.Release();
+            }
+            return;
+          }
+          // we have not found the expected instance, simply wait for the next loader thread to signal the semaphore when
+          // a new instance is available
+        }
+      }
+    }
+  };
+
+
   class ArchiveJob::ResourceIdentifiers : public boost::noncopyable
   {
   private:
@@ -402,6 +567,7 @@
         
       void Apply(HierarchicalZipWriter& writer,
                  ServerContext& context,
+                 InstanceLoader& instanceLoader,
                  DicomDirWriter* dicomDir,
                  const std::string& dicomDirFolder,
                  bool transcode,
@@ -423,7 +589,7 @@
 
             try
             {
-              context.ReadDicom(content, instanceId_);
+              instanceLoader.GetDicom(content, instanceId_);
             }
             catch (OrthancException& e)
             {
@@ -494,10 +660,12 @@
     std::deque<Command*>  commands_;
     uint64_t              uncompressedSize_;
     unsigned int          instancesCount_;
+    InstanceLoader&       instanceLoader_;
 
       
     void ApplyInternal(HierarchicalZipWriter& writer,
                        ServerContext& context,
+                       InstanceLoader& instanceLoader,
                        size_t index,
                        DicomDirWriter* dicomDir,
                        const std::string& dicomDirFolder,
@@ -509,13 +677,14 @@
         throw OrthancException(ErrorCode_ParameterOutOfRange);
       }
 
-      commands_[index]->Apply(writer, context, dicomDir, dicomDirFolder, transcode, transferSyntax);
+      commands_[index]->Apply(writer, context, instanceLoader, dicomDir, dicomDirFolder, transcode, transferSyntax);
     }
       
   public:
-    ZipCommands() :
+    explicit ZipCommands(InstanceLoader& instanceLoader) :
       uncompressedSize_(0),
-      instancesCount_(0)
+      instancesCount_(0),
+      instanceLoader_(instanceLoader)
     {
     }
       
@@ -547,23 +716,25 @@
     // "media" flavor (with DICOMDIR)
     void Apply(HierarchicalZipWriter& writer,
                ServerContext& context,
+               InstanceLoader& instanceLoader,
                size_t index,
                DicomDirWriter& dicomDir,
                const std::string& dicomDirFolder,
                bool transcode,
                DicomTransferSyntax transferSyntax) const
     {
-      ApplyInternal(writer, context, index, &dicomDir, dicomDirFolder, transcode, transferSyntax);
+      ApplyInternal(writer, context, instanceLoader, index, &dicomDir, dicomDirFolder, transcode, transferSyntax);
     }
 
     // "archive" flavor (without DICOMDIR)
     void Apply(HierarchicalZipWriter& writer,
                ServerContext& context,
+               InstanceLoader& instanceLoader,
                size_t index,
                bool transcode,
                DicomTransferSyntax transferSyntax) const
     {
-      ApplyInternal(writer, context, index, NULL, "", transcode, transferSyntax);
+      ApplyInternal(writer, context, instanceLoader, index, NULL, "", transcode, transferSyntax);
     }
       
     void AddOpenDirectory(const std::string& filename)
@@ -580,6 +751,7 @@
                           const std::string& instanceId,
                           uint64_t uncompressedSize)
     {
+      instanceLoader_.PrepareDicom(instanceId);
       commands_.push_back(new Command(Type_WriteInstance, filename, instanceId));
       instancesCount_ ++;
       uncompressedSize_ += uncompressedSize;
@@ -747,6 +919,7 @@
   {
   private:
     ServerContext&                          context_;
+    InstanceLoader&                         instanceLoader_;
     ZipCommands                             commands_;
     std::unique_ptr<HierarchicalZipWriter>  zip_;
     std::unique_ptr<DicomDirWriter>         dicomDir_;
@@ -755,10 +928,13 @@
 
   public:
     ZipWriterIterator(ServerContext& context,
+                      InstanceLoader& instanceLoader,
                       ArchiveIndex& archive,
                       bool isMedia,
                       bool enableExtendedSopClass) :
       context_(context),
+      instanceLoader_(instanceLoader),
+      commands_(instanceLoader),
       isMedia_(isMedia),
       isStream_(false)
     {
@@ -882,13 +1058,13 @@
         if (isMedia_)
         {
           assert(dicomDir_.get() != NULL);
-          commands_.Apply(*zip_, context_, index, *dicomDir_,
+          commands_.Apply(*zip_, context_, instanceLoader_, index, *dicomDir_,
                           MEDIA_IMAGES_FOLDER, transcode, transferSyntax);
         }
         else
         {
           assert(dicomDir_.get() == NULL);
-          commands_.Apply(*zip_, context_, index, transcode, transferSyntax);
+          commands_.Apply(*zip_, context_, instanceLoader_, index, transcode, transferSyntax);
         }
       }
     }
@@ -917,7 +1093,8 @@
     uncompressedSize_(0),
     archiveSize_(0),
     transcode_(false),
-    transferSyntax_(DicomTransferSyntax_LittleEndianImplicit)
+    transferSyntax_(DicomTransferSyntax_LittleEndianImplicit),
+    loaderThreads_(0)
   {
   }
 
@@ -993,6 +1170,19 @@
   }
 
   
+  void ArchiveJob::SetLoaderThreads(unsigned int loaderThreads)
+  {
+    if (writer_.get() != NULL)   // Already started
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      loaderThreads_ = loaderThreads;
+    }
+  }
+
+
   void ArchiveJob::Reset()
   {
     throw OrthancException(ErrorCode_BadSequenceOfCalls,
@@ -1002,6 +1192,16 @@
   
   void ArchiveJob::Start()
   {
+    if (loaderThreads_ == 0)
+    {
+      // default behaviour before loaderThreads was introducted in 1.9.8
+      instanceLoader_.reset(new SynchronousInstanceLoader(context_));
+    }
+    else
+    {
+      instanceLoader_.reset(new ThreadedInstanceLoader(context_, loaderThreads_));
+    }
+
     if (writer_.get() != NULL)
     {
       throw OrthancException(ErrorCode_BadSequenceOfCalls);
@@ -1023,7 +1223,7 @@
           assert(asynchronousTarget_.get() != NULL);
           asynchronousTarget_->Touch();  // Make sure we can write to the temporary file
           
-          writer_.reset(new ZipWriterIterator(context_, *archive_, isMedia_, enableExtendedSopClass_));
+          writer_.reset(new ZipWriterIterator(context_, *instanceLoader_, *archive_, isMedia_, enableExtendedSopClass_));
           writer_->SetOutputFile(asynchronousTarget_->GetPath());
         }
       }
@@ -1031,7 +1231,7 @@
       {
         assert(synchronousTarget_.get() != NULL);
     
-        writer_.reset(new ZipWriterIterator(context_, *archive_, isMedia_, enableExtendedSopClass_));
+        writer_.reset(new ZipWriterIterator(context_, *instanceLoader_, *archive_, isMedia_, enableExtendedSopClass_));
         writer_->AcquireOutputStream(synchronousTarget_.release());
       }
 
@@ -1076,6 +1276,11 @@
       writer_.reset();
     }
 
+    if (instanceLoader_.get() != NULL)
+    {
+      instanceLoader_->Clear();
+    }
+
     if (asynchronousTarget_.get() != NULL)
     {
       // Asynchronous behavior: Move the resulting file into the media archive
@@ -1196,6 +1401,7 @@
 
   bool ArchiveJob::GetOutput(std::string& output,
                              MimeType& mime,
+                             std::string& filename,
                              const std::string& key)
   {   
     if (key == "archive" &&
@@ -1208,6 +1414,7 @@
         const DynamicTemporaryFile& f = dynamic_cast<DynamicTemporaryFile&>(accessor.GetItem());
         f.GetFile().Read(output);
         mime = MimeType_Zip;
+        filename = "archive.zip";
         return true;
       }
       else
--- a/OrthancServer/Sources/ServerJobs/ArchiveJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/ArchiveJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -55,10 +44,14 @@
     class ResourceIdentifiers;
     class ZipCommands;
     class ZipWriterIterator;
-    
+    class InstanceLoader;
+    class SynchronousInstanceLoader;
+    class ThreadedInstanceLoader;
+
     std::unique_ptr<ZipWriter::IOutputStream>  synchronousTarget_;  // Only valid before "Start()"
     std::unique_ptr<TemporaryFile>        asynchronousTarget_;
     ServerContext&                        context_;
+    std::unique_ptr<InstanceLoader>       instanceLoader_;
     boost::shared_ptr<ArchiveIndex>       archive_;
     bool                                  isMedia_;
     bool                                  enableExtendedSopClass_;
@@ -75,6 +68,9 @@
     bool                 transcode_;
     DicomTransferSyntax  transferSyntax_;
 
+    // New in Orthanc 1.9.8
+    unsigned int         loaderThreads_;
+
     void FinalizeTarget();
     
   public:
@@ -97,6 +93,8 @@
 
     void SetTranscode(DicomTransferSyntax transferSyntax);
 
+    void SetLoaderThreads(unsigned int loaderThreads);
+
     virtual void Reset() ORTHANC_OVERRIDE;
 
     virtual void Start() ORTHANC_OVERRIDE;
@@ -118,6 +116,7 @@
 
     virtual bool GetOutput(std::string& output,
                            MimeType& mime,
+                           std::string& filename,
                            const std::string& key) ORTHANC_OVERRIDE;
   };
 }
--- a/OrthancServer/Sources/ServerJobs/CleaningInstancesJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/CleaningInstancesJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/CleaningInstancesJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/CleaningInstancesJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/DicomModalityStoreJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/DicomMoveScuJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/DicomMoveScuJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/DicomMoveScuJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/DicomMoveScuJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/IStorageCommitmentFactory.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/IStorageCommitmentFactory.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/LuaJobManager.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/LuaJobManager.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/LuaJobManager.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/LuaJobManager.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -161,8 +150,8 @@
     toStore->SetOrigin(origin_);
 
     std::string modifiedInstance;
-    if (GetContext().Store(modifiedInstance, *toStore,
-                       StoreInstanceMode_Default) != StoreStatus_Success)
+    ServerContext::StoreResult result = GetContext().Store(modifiedInstance, *toStore, StoreInstanceMode_Default);
+    if (result.GetStatus() != StoreStatus_Success)
     {
       LOG(ERROR) << "Error while storing a modified instance " << instance;
       return false;
--- a/OrthancServer/Sources/ServerJobs/MergeStudyJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/MergeStudyJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/Operations/DeleteResourceOperation.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/Operations/DeleteResourceOperation.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/Operations/DeleteResourceOperation.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/Operations/DeleteResourceOperation.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/Operations/DicomInstanceOperationValue.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/Operations/DicomInstanceOperationValue.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/Operations/DicomInstanceOperationValue.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/Operations/DicomInstanceOperationValue.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/Operations/StorePeerOperation.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/Operations/StorePeerOperation.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/Operations/StorePeerOperation.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/Operations/StorePeerOperation.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/Operations/StoreScuOperation.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/Operations/SystemCallOperation.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/Operations/SystemCallOperation.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/Operations/SystemCallOperation.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/Operations/SystemCallOperation.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/OrthancJobUnserializer.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/OrthancJobUnserializer.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/OrthancJobUnserializer.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/OrthancJobUnserializer.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/OrthancPeerStoreJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/ResourceModificationJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/ResourceModificationJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -290,8 +279,8 @@
      **/
 
     std::string modifiedInstance;
-    if (GetContext().Store(modifiedInstance, *toStore,
-                           StoreInstanceMode_Default) != StoreStatus_Success)
+    ServerContext::StoreResult result = GetContext().Store(modifiedInstance, *toStore, StoreInstanceMode_Default);
+    if (result.GetStatus() != StoreStatus_Success)
     {
       throw OrthancException(ErrorCode_CannotStoreInstance,
                              "Error while storing a modified instance " + instance);
--- a/OrthancServer/Sources/ServerJobs/ResourceModificationJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/ResourceModificationJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/SplitStudyJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/SplitStudyJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -143,8 +132,8 @@
     toStore->SetOrigin(origin_);
 
     std::string modifiedInstance;
-    if (GetContext().Store(modifiedInstance, *toStore,
-                           StoreInstanceMode_Default) != StoreStatus_Success)
+    ServerContext::StoreResult result = GetContext().Store(modifiedInstance, *toStore, StoreInstanceMode_Default);
+    if (result.GetStatus() != StoreStatus_Success)
     {
       LOG(ERROR) << "Error while storing a modified instance " << instance;
       return false;
--- a/OrthancServer/Sources/ServerJobs/SplitStudyJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/SplitStudyJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerJobs/StorageCommitmentScpJob.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/ServerToolbox.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerToolbox.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -36,6 +25,7 @@
 
 #include "../../OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h"
 #include "../../OrthancFramework/Sources/FileStorage/StorageAccessor.h"
+#include "../../OrthancFramework/Sources/FileStorage/StorageCache.h"
 #include "../../OrthancFramework/Sources/Logging.h"
 #include "../../OrthancFramework/Sources/OrthancException.h"
 #include "Database/IDatabaseWrapper.h"
@@ -176,7 +166,8 @@
         try
         {
           // Read and parse the content of the DICOM file
-          StorageAccessor accessor(storageArea);
+          StorageCache cache; // we create a temporary cache for this operation (required by the StorageAccessor)
+          StorageAccessor accessor(storageArea, cache);
 
           std::string content;
           accessor.Read(content, attachment);
--- a/OrthancServer/Sources/ServerToolbox.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/ServerToolbox.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/SliceOrdering.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/SliceOrdering.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/SliceOrdering.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/SliceOrdering.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/StorageCommitmentReports.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/StorageCommitmentReports.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/StorageCommitmentReports.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/StorageCommitmentReports.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/Sources/main.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/Sources/main.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -84,10 +73,10 @@
   }
 
 
-  virtual int  Handle(DcmDataset& dicom,
-                      const std::string& remoteIp,
-                      const std::string& remoteAet,
-                      const std::string& calledAet) ORTHANC_OVERRIDE 
+  virtual uint16_t Handle(DcmDataset& dicom,
+                          const std::string& remoteIp,
+                          const std::string& remoteAet,
+                          const std::string& calledAet) ORTHANC_OVERRIDE 
   {
     std::unique_ptr<DicomInstanceToStore> toStore(DicomInstanceToStore::CreateFromDcmDataset(dicom));
     
@@ -97,15 +86,19 @@
                          (remoteIp.c_str(), remoteAet.c_str(), calledAet.c_str()));
 
       std::string id;
-      StoreStatus res = context_.Store(id, *toStore, StoreInstanceMode_Default);
-      if (res == StoreStatus_FilteredOut)
+      ServerContext::StoreResult result = context_.Store(id, *toStore, StoreInstanceMode_Default);
+
+      if (result.GetStatus() == StoreStatus_FilteredOut)
       {
-        return 0xA700; // C-Store "Out of Resources" error code
+        return STATUS_STORE_Refused_OutOfResources;  // C-Store "Out of Resources" error code (0xa700)
       }
-      return 0x0000;
+      else
+      {
+        return result.GetCStoreStatusCode();
+      }
     }
 
-    return 0xC000;  // C-Store "Cannot understand" error code
+    return STATUS_STORE_Error_CannotUnderstand;  // C-Store "Cannot understand" error code (0xc000)
   }
 };
 
@@ -285,6 +278,7 @@
   ServerContext&  context_;
   bool            alwaysAllowEcho_;
   bool            alwaysAllowFind_;  // New in Orthanc 1.9.0
+  bool            alwaysAllowFindWorklist_; // New in Orthanc 1.10.0
   bool            alwaysAllowGet_;   // New in Orthanc 1.9.0
   bool            alwaysAllowMove_;  // New in Orthanc 1.9.7
   bool            alwaysAllowStore_;
@@ -297,6 +291,7 @@
       OrthancConfiguration::ReaderLock lock;
       alwaysAllowEcho_ = lock.GetConfiguration().GetBooleanParameter("DicomAlwaysAllowEcho", true);
       alwaysAllowFind_ = lock.GetConfiguration().GetBooleanParameter("DicomAlwaysAllowFind", false);
+      alwaysAllowFindWorklist_ = lock.GetConfiguration().GetBooleanParameter("DicomAlwaysAllowFindWorklist", false);
       alwaysAllowGet_ = lock.GetConfiguration().GetBooleanParameter("DicomAlwaysAllowGet", false);
       alwaysAllowMove_ = lock.GetConfiguration().GetBooleanParameter("DicomAlwaysAllowMove", false);
       alwaysAllowStore_ = lock.GetConfiguration().GetBooleanParameter("DicomAlwaysAllowStore", true);
@@ -307,6 +302,11 @@
       LOG(WARNING) << "Security risk in DICOM SCP: C-FIND requests are always allowed, even from unknown modalities";
     }
 
+    if (alwaysAllowFindWorklist_)
+    {
+      LOG(WARNING) << "Security risk in DICOM SCP: C-FIND requests for worklists are always allowed, even from unknown modalities";
+    }
+
     if (alwaysAllowGet_)
     {
       LOG(WARNING) << "Security risk in DICOM SCP: C-GET requests are always allowed, even from unknown modalities";
@@ -327,6 +327,7 @@
 
     if (alwaysAllowEcho_ ||
         alwaysAllowFind_ ||
+        alwaysAllowFindWorklist_ ||
         alwaysAllowGet_ ||
         alwaysAllowMove_ ||
         alwaysAllowStore_)
@@ -344,7 +345,7 @@
                                       const std::string& remoteAet,
                                       DicomRequestType type)
   {
-    LOG(WARNING) << "Unable to check DICOM authorization for AET " << remoteAet
+    LOG(WARNING) << "DICOM authorization rejected for AET " << remoteAet
                  << " on IP " << remoteIp << ": The DICOM command "
                  << EnumerationToString(type) << " is not allowed for this modality "
                  << "according to configuration option \"DicomModalities\"";
@@ -371,6 +372,12 @@
       // Incoming C-Find requests are always accepted, even from unknown AET
       return true;
     }
+    else if (type == DicomRequestType_FindWorklist &&
+             alwaysAllowFindWorklist_)
+    {
+      // Incoming C-Find requests for worklists are always accepted, even from unknown AET
+      return true;
+    }
     else if (type == DicomRequestType_Store &&
              alwaysAllowStore_)
     {
@@ -402,7 +409,7 @@
       
       if (modalities.empty())
       {
-        LOG(WARNING) << "Unable to check DICOM authorization for AET " << remoteAet
+        LOG(WARNING) << "DICOM authorization rejected  for AET " << remoteAet
                      << " on IP " << remoteIp << ": This AET is not listed in "
                      << "configuration option \"DicomModalities\"";
         return false;
@@ -413,7 +420,7 @@
         if (checkIp &&
             remoteIp != modalities.front().GetHost())
         {
-          LOG(WARNING) << "Unable to check DICOM authorization for AET " << remoteAet
+          LOG(WARNING) << "DICOM authorization rejected for AET " << remoteAet
                        << " on IP " << remoteIp << ": Its IP address should be "
                        << modalities.front().GetHost()
                        << " according to configuration option \"DicomModalities\"";
@@ -449,7 +456,7 @@
           }
         }
 
-        LOG(WARNING) << "Unable to check DICOM authorization for AET " << remoteAet
+        LOG(WARNING) << "DICOM authorization rejected for AET " << remoteAet
                      << " on IP " << remoteIp << ": " << modalities.size()
                      << " modalites found with this AET in configuration option "
                      << "\"DicomModalities\", but none of them matches the IP";
@@ -718,8 +725,9 @@
   std::cout
     << path << " " << ORTHANC_VERSION << std::endl
     << "Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics Department, University Hospital of Liege (Belgium)" << std::endl
-    << "Copyright (C) 2017-2021 Osimis S.A. (Belgium)" << std::endl
-    << "Licensing GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>, with OpenSSL exception." << std::endl
+    << "Copyright (C) 2017-2022 Osimis S.A. (Belgium)" << std::endl
+    << "Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain (Belgium)" << std::endl
+    << "Licensing GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>." << std::endl
     << "This is free software: you are free to change and redistribute it." << std::endl
     << "There is NO WARRANTY, to the extent permitted by law." << std::endl
     << std::endl
@@ -1217,6 +1225,7 @@
       dicomServer.SetCalledApplicationEntityTitleCheck(lock.GetConfiguration().GetBooleanParameter("DicomCheckCalledAet", false));
       dicomServer.SetAssociationTimeout(lock.GetConfiguration().GetUnsignedIntegerParameter("DicomScpTimeout", 30));
       dicomServer.SetPortNumber(lock.GetConfiguration().GetUnsignedIntegerParameter("DicomPort", 4242));
+      dicomServer.SetThreadsCount(lock.GetConfiguration().GetUnsignedIntegerParameter("DicomThreadsCount", 4));
       dicomServer.SetApplicationEntityTitle(lock.GetConfiguration().GetOrthancAET());
 
       // Configuration of DICOM TLS for Orthanc SCP (since Orthanc 1.9.0)
@@ -1528,6 +1537,16 @@
     {
       context.GetIndex().SetMaximumStorageSize(0);
     }
+
+    try
+    {
+      uint64_t size = lock.GetConfiguration().GetUnsignedIntegerParameter("MaximumStorageCacheSize", 128);
+      context.SetMaximumStorageCacheSize(size * 1024 * 1024);
+    }
+    catch (...)
+    {
+      context.SetMaximumStorageCacheSize(128);
+    }
   }
 
   {
--- a/OrthancServer/UnitTestsSources/DatabaseLookupTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/UnitTestsSources/DatabaseLookupTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/UnitTestsSources/LuaServerTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/UnitTestsSources/LuaServerTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/UnitTestsSources/PluginsTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/UnitTestsSources/PluginsTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -34,6 +23,7 @@
 #include "PrecompiledHeadersUnitTests.h"
 #include <gtest/gtest.h>
 
+#include "../../OrthancFramework/Sources/Compatibility.h"
 #include "../../OrthancFramework/Sources/OrthancException.h"
 #include "../Plugins/Engine/PluginsManager.h"
 
@@ -86,11 +76,54 @@
   //ASSERT_TRUE(l.HasFunction("_init"));
   
 #elif defined(__linux__) || defined(__FreeBSD_kernel__)
-  SharedLibrary l("libdl.so");
-  ASSERT_THROW(l.GetFunction("world"), OrthancException);
-  ASSERT_TRUE(l.GetFunction("dlopen") != NULL);
-  ASSERT_TRUE(l.HasFunction("dlclose"));
-  ASSERT_FALSE(l.HasFunction("world"));
+  /**
+   * Since Orthanc 1.9.8, we test the "libdl.so.2" instead of the
+   * "libdl.so", as discussed here:
+   * https://groups.google.com/g/orthanc-users/c/I5g1fN6MCvg/m/JVdvRyjJAAAJ
+   * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1001305
+   * https://salsa.debian.org/med-team/orthanc/-/blob/master/debian/patches/glibc-2.34.patch
+   **/
+
+  try
+  {
+    SharedLibrary l("libdl.so.2");
+    ASSERT_THROW(l.GetFunction("world"), OrthancException);
+    ASSERT_TRUE(l.GetFunction("dlopen") != NULL);
+    ASSERT_TRUE(l.HasFunction("dlclose"));
+    ASSERT_FALSE(l.HasFunction("world"));
+    return;  // Success
+  }
+  catch (OrthancException&)
+  {
+  }
+  
+  try
+  {
+    SharedLibrary l("libdl.so"); // Fallback for backward compat
+    ASSERT_THROW(l.GetFunction("world"), OrthancException);
+    ASSERT_TRUE(l.GetFunction("dlopen") != NULL);
+    ASSERT_TRUE(l.HasFunction("dlclose"));
+    ASSERT_FALSE(l.HasFunction("world"));
+    return;  // Success
+  }
+  catch (OrthancException&)
+  {
+  }
+  
+  try
+  {
+    SharedLibrary l("libmemusage.so"); // Try another common library
+    ASSERT_THROW(l.GetFunction("world"), OrthancException);
+    ASSERT_TRUE(l.GetFunction("munmap") != NULL);
+    ASSERT_TRUE(l.HasFunction("free"));
+    ASSERT_FALSE(l.HasFunction("world"));
+    return;  // Success
+  }
+  catch (OrthancException&)
+  {
+  }
+  
+  ASSERT_TRUE(0);
 
 #elif defined(__FreeBSD__) || defined(__OpenBSD__)
   // dlopen() in FreeBSD/OpenBSD is supplied by libc, libc.so is
--- a/OrthancServer/UnitTestsSources/PrecompiledHeadersUnitTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/UnitTestsSources/PrecompiledHeadersUnitTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/UnitTestsSources/PrecompiledHeadersUnitTests.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/UnitTestsSources/PrecompiledHeadersUnitTests.h	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/UnitTestsSources/ServerIndexTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/UnitTestsSources/ServerIndexTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -859,7 +848,8 @@
       ASSERT_EQ(id, hasher.HashInstance());
 
       std::string id2;
-      ASSERT_EQ(StoreStatus_Success, context.Store(id2, *toStore, StoreInstanceMode_Default));
+      ServerContext::StoreResult result = context.Store(id2, *toStore, StoreInstanceMode_Default);
+      ASSERT_EQ(StoreStatus_Success, result.GetStatus());
       ASSERT_EQ(id, id2);
     }
 
@@ -908,8 +898,8 @@
       toStore->SetOrigin(DicomInstanceOrigin::FromPlugins());
 
       std::string id2;
-      ASSERT_EQ(overwrite ? StoreStatus_Success : StoreStatus_AlreadyStored,
-                context.Store(id2, *toStore, StoreInstanceMode_Default));
+      ServerContext::StoreResult result = context.Store(id2, *toStore, StoreInstanceMode_Default);
+      ASSERT_EQ(overwrite ? StoreStatus_Success : StoreStatus_AlreadyStored, result.GetStatus());
       ASSERT_EQ(id, id2);
     }
 
@@ -1008,7 +998,8 @@
         std::unique_ptr<DicomInstanceToStore> toStore(DicomInstanceToStore::CreateFromParsedDicomFile(dicom));
         dicomSize = toStore->GetBufferSize();
         toStore->SetOrigin(DicomInstanceOrigin::FromPlugins());
-        ASSERT_EQ(StoreStatus_Success, context.Store(id, *toStore, StoreInstanceMode_Default));
+        ServerContext::StoreResult result = context.Store(id, *toStore, StoreInstanceMode_Default);
+        ASSERT_EQ(StoreStatus_Success, result.GetStatus());
       }
 
       std::set<FileContentType> attachments;
--- a/OrthancServer/UnitTestsSources/ServerJobsTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/UnitTestsSources/ServerJobsTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -140,6 +129,7 @@
 
     virtual bool GetOutput(std::string& output,
                            MimeType& mime,
+                           std::string& filename,
                            const std::string& key) ORTHANC_OVERRIDE
     {
       return false;
@@ -537,7 +527,8 @@
 
       std::unique_ptr<DicomInstanceToStore> toStore(DicomInstanceToStore::CreateFromParsedDicomFile(dicom));
 
-      return (context_->Store(id, *toStore, StoreInstanceMode_Default) == StoreStatus_Success);
+      ServerContext::StoreResult result = context_->Store(id, *toStore, StoreInstanceMode_Default);
+      return (result.GetStatus() == StoreStatus_Success);
     }
   };
 }
--- a/OrthancServer/UnitTestsSources/SizeOfTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/UnitTestsSources/SizeOfTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -111,6 +100,7 @@
 #include "../../OrthancFramework/Sources/FileStorage/IStorageArea.h"
 #include "../../OrthancFramework/Sources/FileStorage/MemoryStorageArea.h"
 #include "../../OrthancFramework/Sources/FileStorage/StorageAccessor.h"
+#include "../../OrthancFramework/Sources/FileStorage/StorageCache.h"
 #include "../../OrthancFramework/Sources/HttpClient.h"
 #include "../../OrthancFramework/Sources/HttpServer/BufferHttpSender.h"
 #include "../../OrthancFramework/Sources/HttpServer/FilesystemHttpHandler.h"
@@ -142,6 +132,7 @@
 #include "../../OrthancFramework/Sources/Images/ImageTraits.h"
 #include "../../OrthancFramework/Sources/Images/JpegReader.h"
 #include "../../OrthancFramework/Sources/Images/JpegWriter.h"
+#include "../../OrthancFramework/Sources/Images/NumpyWriter.h"
 #include "../../OrthancFramework/Sources/Images/PamReader.h"
 #include "../../OrthancFramework/Sources/Images/PamWriter.h"
 #include "../../OrthancFramework/Sources/Images/PixelTraits.h"
--- a/OrthancServer/UnitTestsSources/SizeOfTests.impl.h	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/UnitTestsSources/SizeOfTests.impl.h	Sun Feb 20 12:59:30 2022 +0100
@@ -50,6 +50,7 @@
   printf("sizeof(::Orthanc::ImageAccessor) == %d\n", static_cast<int>(sizeof(::Orthanc::ImageAccessor)));
   printf("sizeof(::Orthanc::ImageBuffer) == %d\n", static_cast<int>(sizeof(::Orthanc::ImageBuffer)));
   printf("sizeof(::Orthanc::ImageProcessing) == %d\n", static_cast<int>(sizeof(::Orthanc::ImageProcessing)));
+  printf("sizeof(::Orthanc::ImageProcessing::IPolygonFiller) == %d\n", static_cast<int>(sizeof(::Orthanc::ImageProcessing::IPolygonFiller)));
   printf("sizeof(::Orthanc::ImageProcessing::ImagePoint) == %d\n", static_cast<int>(sizeof(::Orthanc::ImageProcessing::ImagePoint)));
   printf("sizeof(::Orthanc::JobInfo) == %d\n", static_cast<int>(sizeof(::Orthanc::JobInfo)));
   printf("sizeof(::Orthanc::JobOperationValues) == %d\n", static_cast<int>(sizeof(::Orthanc::JobOperationValues)));
@@ -72,6 +73,7 @@
   printf("sizeof(::Orthanc::MetricsRegistry::Timer) == %d\n", static_cast<int>(sizeof(::Orthanc::MetricsRegistry::Timer)));
   printf("sizeof(::Orthanc::MultipartStreamReader) == %d\n", static_cast<int>(sizeof(::Orthanc::MultipartStreamReader)));
   printf("sizeof(::Orthanc::NullOperationValue) == %d\n", static_cast<int>(sizeof(::Orthanc::NullOperationValue)));
+  printf("sizeof(::Orthanc::NumpyWriter) == %d\n", static_cast<int>(sizeof(::Orthanc::NumpyWriter)));
   printf("sizeof(::Orthanc::OrthancException) == %d\n", static_cast<int>(sizeof(::Orthanc::OrthancException)));
   printf("sizeof(::Orthanc::PamReader) == %d\n", static_cast<int>(sizeof(::Orthanc::PamReader)));
   printf("sizeof(::Orthanc::PamWriter) == %d\n", static_cast<int>(sizeof(::Orthanc::PamWriter)));
@@ -103,6 +105,7 @@
   printf("sizeof(::Orthanc::SharedLibrary) == %d\n", static_cast<int>(sizeof(::Orthanc::SharedLibrary)));
   printf("sizeof(::Orthanc::SharedMessageQueue) == %d\n", static_cast<int>(sizeof(::Orthanc::SharedMessageQueue)));
   printf("sizeof(::Orthanc::StorageAccessor) == %d\n", static_cast<int>(sizeof(::Orthanc::StorageAccessor)));
+  printf("sizeof(::Orthanc::StorageCache) == %d\n", static_cast<int>(sizeof(::Orthanc::StorageCache)));
   printf("sizeof(::Orthanc::StreamBlockReader) == %d\n", static_cast<int>(sizeof(::Orthanc::StreamBlockReader)));
   printf("sizeof(::Orthanc::StringMatcher) == %d\n", static_cast<int>(sizeof(::Orthanc::StringMatcher)));
   printf("sizeof(::Orthanc::StringOperationValue) == %d\n", static_cast<int>(sizeof(::Orthanc::StringOperationValue)));
--- a/OrthancServer/UnitTestsSources/UnitTestsMain.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/UnitTestsSources/UnitTestsMain.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
--- a/OrthancServer/UnitTestsSources/VersionsTests.cpp	Wed Sep 29 10:32:23 2021 +0200
+++ b/OrthancServer/UnitTestsSources/VersionsTests.cpp	Sun Feb 20 12:59:30 2022 +0100
@@ -2,24 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2021 Osimis S.A., Belgium
+ * Copyright (C) 2017-2022 Osimis S.A., Belgium
+ * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, 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
@@ -177,8 +166,11 @@
 #if ORTHANC_ENABLE_SSL == 1
 TEST(Version, OpenSslStatic)
 {
-  ASSERT_TRUE(OPENSSL_VERSION_NUMBER == 0x1000210fL /* openssl-1.0.2p */ ||
-              OPENSSL_VERSION_NUMBER == 0x101010bfL /* openssl-1.1.1k */);
+  // openssl-3.0.1
+  ASSERT_EQ(3 * 0x10000000L +
+            0 * 0x00100000L +
+            1 * 0x00000010L +
+            0 * 0x0000000fL, OPENSSL_VERSION_NUMBER);
 }
 #endif
 
--- a/TODO	Wed Sep 29 10:32:23 2021 +0200
+++ b/TODO	Sun Feb 20 12:59:30 2022 +0100
@@ -20,7 +20,11 @@
 * Option to enable DNS lookups in DICOM:
   https://hg.orthanc-server.com/orthanc/file/Orthanc-1.9.3/OrthancFramework/Sources/OrthancFramework.cpp#l88
 * Toolbox::ComputeMD5() fails on files larger than 4GB
-
+* Add an option to run Orthanc in read-only mode both for DICOM and for Rest API.
+* Logging: add some information like Thread-Id to contextualize the logs
+* Accept extra DICOM tags dictionaries in the DCMTK format '.dic' (easier to use than declare
+  them in the Orthanc configuration file).  Even the standard dictionaries could be 
+  overriden by these custom dictionaries.
 
 ============================
 Documentation (Orthanc Book)
@@ -36,7 +40,15 @@
 * Discuss HL7 in a dedicated page:
   https://groups.google.com/d/msg/orthanc-users/4dt4992O0lQ/opTjTFU2BgAJ
   https://groups.google.com/g/orthanc-users/c/Spjtcj9vSPo/m/ktUArWxUDQAJ
-  
+
+
+================
+Orthanc Explorer
+================
+
+* Option to tune the number of results for a local lookup:
+  https://groups.google.com/g/orthanc-users/c/LF39musq02Y/
+
 
 ========
 REST API
@@ -60,6 +72,8 @@
   image. The SOPClassUID might be used to identify such secondary
   captures.
 * Support "/preview" and "/matlab" for LUT color images
+* Try to transcode files if a simple decoding fails:
+  https://groups.google.com/g/orthanc-users/c/b8168-NkAhA/m/Df3j-CO9CgAJ
 * Add asynchronous mode in "/modalitities/.../move" for C-MOVE SCU:
   https://groups.google.com/g/orthanc-users/c/G3_jBy4X4NQ/m/8BanTsdMBQAJ
 * Ranges of DICOM tags for "Keep" and "Remove" in ".../modify" and ".../anonymize": 
@@ -99,7 +113,7 @@
 Long-term
 ---------
 
-* Support extended association:
+* Support extended association (e.g. for C-Find relational queries):
   https://groups.google.com/d/msg/orthanc-users/xD4d3mpc6ms/srF7E2goAAAJ
 * Support C-MOVE-CANCEL:
   https://groups.google.com/d/msg/orthanc-users/KnduYBFd06A/o86cl5SeCAAJ
@@ -119,13 +133,14 @@
 Performance
 ===========
 
-* StorageAccessor => add a memory cache using MemoryStringCache, for
-  instance to speed up WADO-RS Retrieve Frames in DICOMweb plugin
 * ServerContext::DicomCacheLocker => give access to the raw buffer,
   useful in ServerContext::DecodeDicomInstance()
 * DicomMap: create a cache to the main DICOM tags index
 * Check out rapidjson: https://github.com/miloyip/nativejson-benchmark
-
+* optimize tools/find with ModalitiesInStudies: 
+  https://groups.google.com/g/orthanc-users/c/aN8nqcRd3jw/m/pmc9ylVeAwAJ.
+  One solution could be: filter first without ModalitiesInStudies and then
+  cycle through the responses to filter out with ModalitiesInStudies
 
 ========
 Database
@@ -154,6 +169,7 @@
   https://groups.google.com/d/msg/orthanc-users/BtvLTE5Ni8A/vIMhmMgfBAAJ
 * In "OrthancPluginLog[Error|Warning|Info]()", prefix the log line with
   the name of the plugin, as retrieved by "OrthancPluginGetName()"
+* update the SDK to handle buffer sizes > 4GB (all sizes are currently coded in uint32_t)
 
 ----------------
 Ideas of plugins