[med-svn] [orthanc] 01/05: New upstream version 1.3.1+dfsg
Sebastien Jodogne
jodogne-guest at moszumanska.debian.org
Thu Nov 30 11:28:24 UTC 2017
This is an automated email from the git hooks/post-receive script.
jodogne-guest pushed a commit to branch master
in repository orthanc.
commit 4d644cab00866ab1058d8aec003de161452575e8
Author: jodogne-guest <s.jodogne at gmail.com>
Date: Thu Nov 30 12:04:28 2017 +0100
New upstream version 1.3.1+dfsg
---
.hg_archival.txt | 8 +-
.travis.yml | 2 +-
CMakeLists.txt | 399 ++++------------
Core/Cache/SharedArchive.h | 8 +
Core/Compression/HierarchicalZipWriter.h | 4 +
Core/Compression/ZipWriter.h | 4 -
Core/DicomFormat/DicomImageInformation.cpp | 32 +-
Core/DicomFormat/DicomMap.cpp | 191 ++++++++
Core/DicomFormat/DicomMap.h | 24 +
Core/DicomFormat/DicomTag.h | 11 +
Core/DicomFormat/DicomValue.cpp | 102 +++++
Core/DicomFormat/DicomValue.h | 16 +
.../DicomNetworking}/DicomFindAnswers.cpp | 9 +-
.../DicomNetworking}/DicomFindAnswers.h | 2 +-
.../DicomNetworking}/DicomServer.cpp | 44 +-
.../DicomNetworking}/DicomServer.h | 25 +
.../DicomNetworking}/DicomUserConnection.cpp | 17 +-
.../DicomNetworking}/DicomUserConnection.h | 6 +-
.../DicomNetworking}/IApplicationEntityFilter.h | 2 +-
.../DicomNetworking}/IFindRequestHandler.h | 2 +
.../DicomNetworking}/IFindRequestHandlerFactory.h | 0
.../DicomNetworking}/IMoveRequestHandler.h | 0
.../DicomNetworking}/IMoveRequestHandlerFactory.h | 0
.../DicomNetworking}/IStoreRequestHandler.h | 0
.../DicomNetworking}/IStoreRequestHandlerFactory.h | 0
.../DicomNetworking}/IWorklistRequestHandler.h | 0
.../IWorklistRequestHandlerFactory.h | 0
.../Internals/CommandDispatcher.cpp | 11 +-
.../DicomNetworking}/Internals/CommandDispatcher.h | 4 +-
.../DicomNetworking}/Internals/FindScp.cpp | 21 +-
.../DicomNetworking}/Internals/FindScp.h | 4 +-
.../DicomNetworking}/Internals/MoveScp.cpp | 13 +-
.../DicomNetworking}/Internals/MoveScp.h | 2 +-
.../DicomNetworking}/Internals/StoreScp.cpp | 20 +-
.../DicomNetworking}/Internals/StoreScp.h | 2 +-
.../DicomNetworking}/RemoteModalityParameters.cpp | 6 +-
.../DicomNetworking}/RemoteModalityParameters.h | 2 +-
.../ReusableDicomUserConnection.cpp | 6 +-
.../DicomNetworking}/ReusableDicomUserConnection.h | 0
.../DicomParsing}/DicomDirWriter.cpp | 72 ++-
.../DicomParsing}/DicomDirWriter.h | 4 +
.../DicomParsing}/DicomModification.cpp | 6 +-
.../DicomParsing}/DicomModification.h | 0
.../DicomParsing}/FromDcmtkBridge.cpp | 124 ++++-
.../DicomParsing}/FromDcmtkBridge.h | 48 +-
.../DicomParsing}/Internals/DicomFrameIndex.cpp | 11 +-
.../DicomParsing}/Internals/DicomFrameIndex.h | 2 +
.../DicomParsing}/Internals/DicomImageDecoder.cpp | 266 +++++++++--
.../DicomParsing}/Internals/DicomImageDecoder.h | 18 +-
.../DicomParsing}/ParsedDicomFile.cpp | 189 +++++---
.../DicomParsing}/ParsedDicomFile.h | 47 +-
.../DicomParsing}/ToDcmtkBridge.cpp | 4 +-
.../DicomParsing}/ToDcmtkBridge.h | 6 +-
Core/Endianness.h | 4 +-
Core/Enumerations.cpp | 233 +++++++++-
Core/Enumerations.h | 108 ++++-
Core/FileStorage/FilesystemStorage.h | 8 +
Core/FileStorage/StorageAccessor.cpp | 11 +-
Core/FileStorage/StorageAccessor.h | 27 +-
Core/HttpServer/MongooseServer.cpp | 62 ++-
Core/HttpServer/MongooseServer.h | 14 +
Core/Images/Font.cpp | 17 +-
Core/Images/Font.h | 2 +
Core/Images/FontRegistry.cpp | 4 +
Core/Images/FontRegistry.h | 12 +-
Core/Images/ImageAccessor.cpp | 4 +
Core/Images/ImageProcessing.cpp | 68 ++-
Core/Images/ImageProcessing.h | 10 +-
Core/Images/JpegErrorManager.h | 8 +
Core/Images/JpegReader.h | 16 +-
Core/Images/JpegWriter.cpp | 2 +
Core/Images/JpegWriter.h | 8 +
Core/Images/PngReader.h | 8 +
Core/Images/PngWriter.cpp | 2 +
Core/Images/PngWriter.h | 8 +
Core/Logging.cpp | 7 +-
Core/Lua/LuaContext.cpp | 2 +
Core/Lua/LuaContext.h | 11 +-
Core/MultiThreading/Mutex.cpp | 4 +-
Core/PrecompiledHeaders.h | 19 +-
Core/SQLite/OrthancSQLiteException.h | 5 +
Core/SQLite/Statement.h | 2 +-
Core/SystemToolbox.cpp | 51 ++-
Core/SystemToolbox.h | 2 -
Core/Toolbox.cpp | 28 +-
Core/Toolbox.h | 16 +-
LinuxCompilation.txt | 6 +-
NEWS | 35 ++
OrthancServer/DefaultDicomImageDecoder.h | 4 +-
OrthancServer/DicomInstanceToStore.cpp | 14 +-
OrthancServer/DicomInstanceToStore.h | 2 +-
OrthancServer/OrthancFindRequestHandler.cpp | 4 +-
OrthancServer/OrthancFindRequestHandler.h | 2 +-
OrthancServer/OrthancInitialization.cpp | 82 +---
OrthancServer/OrthancInitialization.h | 21 +-
OrthancServer/OrthancMoveRequestHandler.cpp | 2 +-
OrthancServer/OrthancMoveRequestHandler.h | 2 +-
.../OrthancRestApi/OrthancRestAnonymizeModify.cpp | 6 +-
OrthancServer/OrthancRestApi/OrthancRestApi.cpp | 1 -
OrthancServer/OrthancRestApi/OrthancRestApi.h | 3 +-
.../OrthancRestApi/OrthancRestArchive.cpp | 19 +-
.../OrthancRestApi/OrthancRestModalities.cpp | 2 +-
.../OrthancRestApi/OrthancRestResources.cpp | 117 +++--
OrthancServer/OrthancRestApi/OrthancRestSystem.cpp | 4 +-
OrthancServer/PrecompiledHeadersServer.h | 38 +-
OrthancServer/QueryRetrieveHandler.cpp | 2 +-
OrthancServer/Scheduler/ModifyInstanceCommand.h | 2 +-
OrthancServer/Search/HierarchicalMatcher.cpp | 10 +-
OrthancServer/Search/HierarchicalMatcher.h | 3 +-
OrthancServer/Search/IFindConstraint.cpp | 2 +-
OrthancServer/Search/LookupIdentifierQuery.cpp | 2 +-
OrthancServer/Search/LookupResource.cpp | 2 +-
OrthancServer/ServerContext.cpp | 82 +++-
OrthancServer/ServerContext.h | 26 +-
OrthancServer/ServerEnumerations.cpp | 191 --------
OrthancServer/ServerEnumerations.h | 87 ----
OrthancServer/ServerIndex.cpp | 4 +-
OrthancServer/ServerToolbox.cpp | 84 +---
OrthancServer/ServerToolbox.h | 2 -
OrthancServer/main.cpp | 48 +-
Plugins/Engine/OrthancPlugins.cpp | 6 +-
Plugins/Engine/OrthancPlugins.h | 8 +-
Plugins/Engine/PluginsEnumerations.cpp | 24 +
Plugins/Engine/PluginsManager.cpp | 2 +-
Plugins/Engine/SharedLibrary.cpp | 8 +-
Plugins/Include/orthanc/OrthancCPlugin.h | 44 +-
Plugins/Samples/Common/DicomTag.h | 2 +
Plugins/Samples/Common/OrthancPluginCppWrapper.h | 4 +-
Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp | 12 +
Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h | 12 +
Plugins/Samples/ServeFolders/Plugin.cpp | 1 +
Resources/CMake/BoostConfiguration.cmake | 292 ++++++------
Resources/CMake/BoostConfiguration.sh | 26 +-
Resources/CMake/CivetwebConfiguration.cmake | 57 +++
Resources/CMake/Compiler.cmake | 62 ++-
Resources/CMake/DcmtkConfiguration.cmake | 9 +-
Resources/CMake/GoogleTestConfiguration.cmake | 47 +-
Resources/CMake/JsonCppConfiguration.cmake | 5 +-
Resources/CMake/LibCurlConfiguration.cmake | 3 +-
Resources/CMake/LibIconvConfiguration.cmake | 148 +++---
Resources/CMake/LibP11Configuration.cmake | 1 +
.../CMake/OrthancFrameworkConfiguration.cmake | 509 +++++++++++++++++++++
Resources/CMake/OrthancFrameworkParameters.cmake | 96 ++++
Resources/CMake/PugixmlConfiguration.cmake | 43 +-
Resources/CMake/SQLiteConfiguration.cmake | 8 +-
.../CMake/VisualStudioPrecompiledHeaders.cmake | 4 +-
Resources/CMake/ZlibConfiguration.cmake | 9 +
Resources/Configuration.json | 6 +
Resources/OldBuildInstructions.txt | 8 +-
.../OrthancFramework/MicroService/CMakeLists.txt | 16 +
.../OrthancFramework/MicroService/README.txt | 2 +
.../OrthancFramework/MicroService/Sample.cpp | 61 +++
Resources/Samples/Tools/CMakeLists.txt | 22 +-
TODO | 11 +
UnitTestsSources/DicomMapTests.cpp | 150 +++++-
UnitTestsSources/FromDcmtkTests.cpp | 59 ++-
UnitTestsSources/ImageTests.cpp | 2 +-
UnitTestsSources/JpegLosslessTests.cpp | 4 +-
UnitTestsSources/LuaTests.cpp | 11 +-
UnitTestsSources/MultiThreadingTests.cpp | 2 +-
UnitTestsSources/PluginsTests.cpp | 4 +-
UnitTestsSources/RestApiTests.cpp | 8 +-
UnitTestsSources/UnitTestsMain.cpp | 8 +-
UnitTestsSources/VersionsTests.cpp | 10 +-
164 files changed, 3726 insertions(+), 1590 deletions(-)
diff --git a/.hg_archival.txt b/.hg_archival.txt
index 185a01a..8e2e699 100644
--- a/.hg_archival.txt
+++ b/.hg_archival.txt
@@ -1,6 +1,6 @@
repo: 3959d33612ccaadc0d4d707227fbed09ac35e5fe
-node: ed050cfd5898523069a3304daee76a1822769ba1
-branch: Orthanc-1.3.0
+node: 4d4dff4693b87cb4a29cd563776a739b0e8fdebf
+branch: Orthanc-1.3.1
latesttag: dcmtk-3.6.1
-latesttagdistance: 21
-changessincelatesttag: 22
+latesttagdistance: 97
+changessincelatesttag: 102
diff --git a/.travis.yml b/.travis.yml
index 1da1cfa..ae15d7a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -44,7 +44,7 @@ before_script:
- if [ $TRAVIS_OS_NAME == linux -a $TRAVIS_MINGW == OFF ]; then cmake
-DCMAKE_BUILD_TYPE=Debug "-DDCMTK_LIBRARIES=CharLS;dcmjpls;wrap;oflog"
-DALLOW_DOWNLOADS=ON -DUSE_SYSTEM_BOOST=OFF -DUSE_SYSTEM_MONGOOSE=OFF -DUSE_SYSTEM_JSONCPP=OFF
- -DUSE_SYSTEM_GOOGLE_LOG=OFF -DUSE_SYSTEM_PUGIXML=OFF -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON
+ -DUSE_SYSTEM_GOOGLE_LOG=OFF -DUSE_SYSTEM_PUGIXML=OFF -DUSE_GOOGLE_TEST_DEBIAN_PACKAGE=ON
..; fi
- if [ $TRAVIS_OS_NAME == linux -a $TRAVIS_MINGW == ON ]; then cmake
-DCMAKE_BUILD_TYPE=Debug -DSTATIC_BUILD=ON -DSTANDALONE_BUILD=ON -DALLOW_DOWNLOADS=ON
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d66b960..020a1dc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,180 +2,62 @@ cmake_minimum_required(VERSION 2.8)
project(Orthanc)
-# Version of the build, should always be "mainline" except in release branches
-set(ORTHANC_VERSION "1.3.0")
-# Version of the database schema. History:
-# * Orthanc 0.1.0 -> Orthanc 0.3.0 = no versioning
-# * Orthanc 0.3.1 = version 2
-# * Orthanc 0.4.0 -> Orthanc 0.7.2 = version 3
-# * Orthanc 0.7.3 -> Orthanc 0.8.4 = version 4
-# * Orthanc 0.8.5 -> Orthanc 0.9.4 = version 5
-# * Orthanc 0.9.5 -> mainline = version 6
-set(ORTHANC_DATABASE_VERSION 6)
+#####################################################################
+## Generic parameters of the Orthanc framework
+#####################################################################
+
+include(${CMAKE_SOURCE_DIR}/Resources/CMake/OrthancFrameworkParameters.cmake)
+
+# Enable all the optional components of the Orthanc framework
+set(ENABLE_CRYPTO_OPTIONS ON)
+set(ENABLE_DCMTK ON)
+set(ENABLE_DCMTK_NETWORKING ON)
+set(ENABLE_GOOGLE_TEST ON)
+set(ENABLE_JPEG ON)
+set(ENABLE_LOCALE ON)
+set(ENABLE_LUA ON)
+set(ENABLE_PNG ON)
+set(ENABLE_PUGIXML ON)
+set(ENABLE_SQLITE ON)
+set(ENABLE_WEB_CLIENT ON)
+set(ENABLE_WEB_SERVER ON)
+
+set(HAS_EMBEDDED_RESOURCES ON)
#####################################################################
-## CMake parameters tunable at the command line
+## CMake parameters tunable at the command line to configure the
+## plugins, the companion tools, and the unit tests
#####################################################################
# Parameters of the build
-SET(STATIC_BUILD OFF CACHE BOOL "Static build of the third-party libraries (necessary for Windows)")
-SET(STANDALONE_BUILD ON CACHE BOOL "Standalone build (all the resources are embedded, necessary for releases)")
-SET(ENABLE_SSL ON CACHE BOOL "Include support for SSL")
-SET(DCMTK_DICTIONARY_DIR "" CACHE PATH "Directory containing the DCMTK dictionaries \"dicom.dic\" and \"private.dic\" (only when using system version of DCMTK)")
-SET(ALLOW_DOWNLOADS OFF CACHE BOOL "Allow CMake to download packages")
-SET(UNIT_TESTS_WITH_HTTP_CONNEXIONS ON CACHE BOOL "Allow unit tests to make HTTP requests")
-SET(ENABLE_JPEG ON CACHE BOOL "Enable JPEG decompression")
-SET(ENABLE_JPEG_LOSSLESS ON CACHE BOOL "Enable JPEG-LS (Lossless) decompression")
-SET(ENABLE_PLUGINS ON CACHE BOOL "Enable plugins")
-SET(BUILD_SERVE_FOLDERS ON CACHE BOOL "Whether to build the ServeFolders plugin")
SET(BUILD_MODALITY_WORKLISTS ON CACHE BOOL "Whether to build the sample plugin to serve modality worklists")
SET(BUILD_RECOVER_COMPRESSED_FILE ON CACHE BOOL "Whether to build the companion tool to recover files compressed using Orthanc")
-SET(ENABLE_PKCS11 OFF CACHE BOOL "Enable PKCS#11 for HTTPS client authentication using hardware security modules and smart cards")
-SET(ENABLE_PROFILING OFF CACHE BOOL "Whether to enable the generation of profiling information with gprof")
-
-# Advanced parameters to fine-tune linking against system libraries
-SET(USE_SYSTEM_JSONCPP ON CACHE BOOL "Use the system version of JsonCpp")
-SET(USE_SYSTEM_GOOGLE_TEST ON CACHE BOOL "Use the system version of Google Test")
-SET(USE_SYSTEM_SQLITE ON CACHE BOOL "Use the system version of SQLite")
-SET(USE_SYSTEM_MONGOOSE ON CACHE BOOL "Use the system version of Mongoose")
-SET(USE_SYSTEM_LUA ON CACHE BOOL "Use the system version of Lua")
-SET(USE_SYSTEM_DCMTK ON CACHE BOOL "Use the system version of DCMTK")
-SET(USE_SYSTEM_BOOST ON CACHE BOOL "Use the system version of Boost")
-SET(USE_SYSTEM_LIBPNG ON CACHE BOOL "Use the system version of libpng")
-SET(USE_SYSTEM_LIBJPEG ON CACHE BOOL "Use the system version of libjpeg")
-SET(USE_SYSTEM_CURL ON CACHE BOOL "Use the system version of LibCurl")
-SET(USE_SYSTEM_OPENSSL ON CACHE BOOL "Use the system version of OpenSSL")
-SET(USE_SYSTEM_ZLIB ON CACHE BOOL "Use the system version of ZLib")
-SET(USE_SYSTEM_PUGIXML ON CACHE BOOL "Use the system version of Pugixml")
-SET(USE_SYSTEM_LIBP11 OFF CACHE BOOL "Use the system version of libp11 (PKCS#11 wrapper library)")
-
-# Advanced parameters
-SET(USE_PUGIXML ON CACHE BOOL "Use the Pugixml parser (turn off only for debug)")
-SET(USE_DCMTK_360 OFF CACHE BOOL "Use older DCMTK version 3.6.0 in static builds (instead of default 3.6.2)")
-SET(USE_DCMTK_362_PRIVATE_DIC ON CACHE BOOL "Use the dictionary of private tags from DCMTK 3.6.2 if using DCMTK 3.6.0")
-
-# Distribution-specific settings
-SET(USE_GTEST_DEBIAN_SOURCE_PACKAGE OFF CACHE BOOL "Use the sources of Google Test shipped with libgtest-dev (Debian only)")
-SET(SYSTEM_MONGOOSE_USE_CALLBACKS ON CACHE BOOL "The system version of Mongoose uses callbacks (version >= 3.7)")
-SET(USE_BOOST_ICONV ON CACHE BOOL "Use iconv instead of wconv (Windows only)")
-
-mark_as_advanced(USE_GTEST_DEBIAN_SOURCE_PACKAGE)
-mark_as_advanced(SYSTEM_MONGOOSE_USE_CALLBACKS)
-mark_as_advanced(USE_BOOST_ICONV)
-mark_as_advanced(USE_PUGIXML)
-
-# Path to the root folder of the Orthanc distribution
-set(ORTHANC_ROOT ${CMAKE_SOURCE_DIR})
-set(ENABLE_DCMTK_NETWORK ON)
-set(USE_BOOST_LOCALE_BACKEND OFF)
-
-# Some basic inclusions
-include(CheckIncludeFiles)
-include(CheckIncludeFileCXX)
-include(CheckLibraryExists)
-include(FindPythonInterp)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/AutoGeneratedCode.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/DownloadPackage.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/Compiler.cmake)
+SET(BUILD_SERVE_FOLDERS ON CACHE BOOL "Whether to build the ServeFolders plugin")
+SET(ENABLE_PLUGINS ON CACHE BOOL "Enable plugins")
+SET(UNIT_TESTS_WITH_HTTP_CONNEXIONS ON CACHE BOOL "Allow unit tests to make HTTP requests")
+
+
+#####################################################################
+## Configuration of the Orthanc framework
+#####################################################################
+
include(${CMAKE_SOURCE_DIR}/Resources/CMake/VisualStudioPrecompiledHeaders.cmake)
+include(${CMAKE_SOURCE_DIR}/Resources/CMake/OrthancFrameworkConfiguration.cmake)
+include_directories(${ORTHANC_ROOT})
#####################################################################
## List of source files
#####################################################################
-set(ORTHANC_CORE_SOURCES
- Core/Cache/MemoryCache.cpp
- Core/Cache/SharedArchive.cpp
- Core/ChunkedBuffer.cpp
- Core/Compression/DeflateBaseCompressor.cpp
- Core/Compression/GzipCompressor.cpp
- Core/Compression/HierarchicalZipWriter.cpp
- Core/Compression/ZipWriter.cpp
- Core/Compression/ZlibCompressor.cpp
- Core/DicomFormat/DicomArray.cpp
- Core/DicomFormat/DicomMap.cpp
- Core/DicomFormat/DicomTag.cpp
- Core/DicomFormat/DicomImageInformation.cpp
- Core/DicomFormat/DicomIntegerPixelAccessor.cpp
- Core/DicomFormat/DicomInstanceHasher.cpp
- Core/DicomFormat/DicomValue.cpp
- Core/Enumerations.cpp
- Core/FileStorage/FilesystemStorage.cpp
- Core/FileStorage/StorageAccessor.cpp
- Core/HttpClient.cpp
- Core/HttpServer/BufferHttpSender.cpp
- Core/HttpServer/EmbeddedResourceHttpHandler.cpp
- Core/HttpServer/FilesystemHttpHandler.cpp
- Core/HttpServer/HttpToolbox.cpp
- Core/HttpServer/HttpOutput.cpp
- Core/HttpServer/StringHttpOutput.cpp
- Core/HttpServer/MongooseServer.cpp
- Core/HttpServer/HttpFileSender.cpp
- Core/HttpServer/FilesystemHttpSender.cpp
- Core/HttpServer/HttpContentNegociation.cpp
- Core/HttpServer/HttpStreamTranscoder.cpp
- Core/Logging.cpp
- Core/RestApi/RestApiCall.cpp
- Core/RestApi/RestApiGetCall.cpp
- Core/RestApi/RestApiHierarchy.cpp
- Core/RestApi/RestApiPath.cpp
- Core/RestApi/RestApiOutput.cpp
- Core/RestApi/RestApi.cpp
- Core/MultiThreading/BagOfTasksProcessor.cpp
- Core/MultiThreading/Mutex.cpp
- Core/MultiThreading/ReaderWriterLock.cpp
- Core/MultiThreading/RunnableWorkersPool.cpp
- Core/MultiThreading/Semaphore.cpp
- Core/MultiThreading/SharedMessageQueue.cpp
- Core/Images/Font.cpp
- Core/Images/FontRegistry.cpp
- Core/Images/IImageWriter.cpp
- Core/Images/Image.cpp
- Core/Images/ImageAccessor.cpp
- Core/Images/ImageBuffer.cpp
- Core/Images/ImageProcessing.cpp
- Core/Images/JpegErrorManager.cpp
- Core/Images/JpegReader.cpp
- Core/Images/JpegWriter.cpp
- Core/Images/PngReader.cpp
- Core/Images/PngWriter.cpp
- Core/SQLite/Connection.cpp
- Core/SQLite/FunctionContext.cpp
- Core/SQLite/Statement.cpp
- Core/SQLite/StatementId.cpp
- Core/SQLite/StatementReference.cpp
- Core/SQLite/Transaction.cpp
- Core/SystemToolbox.cpp
- Core/TemporaryFile.cpp
- Core/Toolbox.cpp
- Core/WebServiceParameters.cpp
- Core/Lua/LuaContext.cpp
- Core/Lua/LuaFunctionCall.cpp
- )
-
-
set(ORTHANC_SERVER_SOURCES
OrthancServer/DatabaseWrapper.cpp
OrthancServer/DatabaseWrapperBase.cpp
- OrthancServer/DicomDirWriter.cpp
- OrthancServer/DicomModification.cpp
- OrthancServer/DicomProtocol/DicomFindAnswers.cpp
- OrthancServer/DicomProtocol/DicomServer.cpp
- OrthancServer/DicomProtocol/DicomUserConnection.cpp
- OrthancServer/DicomProtocol/RemoteModalityParameters.cpp
- OrthancServer/DicomProtocol/ReusableDicomUserConnection.cpp
+ OrthancServer/DicomInstanceToStore.cpp
OrthancServer/ExportedResource.cpp
- OrthancServer/FromDcmtkBridge.cpp
- OrthancServer/Internals/CommandDispatcher.cpp
- OrthancServer/Internals/DicomFrameIndex.cpp
- OrthancServer/Internals/DicomImageDecoder.cpp
- OrthancServer/Internals/FindScp.cpp
- OrthancServer/Internals/MoveScp.cpp
- OrthancServer/Internals/StoreScp.cpp
OrthancServer/LuaScripting.cpp
OrthancServer/OrthancFindRequestHandler.cpp
OrthancServer/OrthancHttpHandler.cpp
@@ -188,15 +70,22 @@ set(ORTHANC_SERVER_SOURCES
OrthancServer/OrthancRestApi/OrthancRestModalities.cpp
OrthancServer/OrthancRestApi/OrthancRestResources.cpp
OrthancServer/OrthancRestApi/OrthancRestSystem.cpp
- OrthancServer/ParsedDicomFile.cpp
OrthancServer/QueryRetrieveHandler.cpp
+ OrthancServer/Scheduler/CallSystemCommand.cpp
+ OrthancServer/Scheduler/DeleteInstanceCommand.cpp
+ OrthancServer/Scheduler/ModifyInstanceCommand.cpp
+ OrthancServer/Scheduler/ServerCommandInstance.cpp
+ OrthancServer/Scheduler/ServerJob.cpp
+ OrthancServer/Scheduler/ServerScheduler.cpp
+ OrthancServer/Scheduler/StorePeerCommand.cpp
+ OrthancServer/Scheduler/StoreScuCommand.cpp
OrthancServer/Search/HierarchicalMatcher.cpp
OrthancServer/Search/IFindConstraint.cpp
+ OrthancServer/Search/ListConstraint.cpp
OrthancServer/Search/LookupIdentifierQuery.cpp
OrthancServer/Search/LookupResource.cpp
- OrthancServer/Search/SetOfResources.cpp
- OrthancServer/Search/ListConstraint.cpp
OrthancServer/Search/RangeConstraint.cpp
+ OrthancServer/Search/SetOfResources.cpp
OrthancServer/Search/ValueConstraint.cpp
OrthancServer/Search/WildcardConstraint.cpp
OrthancServer/ServerContext.cpp
@@ -204,18 +93,6 @@ set(ORTHANC_SERVER_SOURCES
OrthancServer/ServerIndex.cpp
OrthancServer/ServerToolbox.cpp
OrthancServer/SliceOrdering.cpp
- OrthancServer/ToDcmtkBridge.cpp
-
- # From "lua-scripting" branch
- OrthancServer/DicomInstanceToStore.cpp
- OrthancServer/Scheduler/DeleteInstanceCommand.cpp
- OrthancServer/Scheduler/ModifyInstanceCommand.cpp
- OrthancServer/Scheduler/ServerCommandInstance.cpp
- OrthancServer/Scheduler/ServerJob.cpp
- OrthancServer/Scheduler/ServerScheduler.cpp
- OrthancServer/Scheduler/StorePeerCommand.cpp
- OrthancServer/Scheduler/StoreScuCommand.cpp
- OrthancServer/Scheduler/CallSystemCommand.cpp
)
@@ -256,27 +133,31 @@ if (ENABLE_PLUGINS)
endif()
-set(ORTHANC_ALL_SOURCES
- ${ORTHANC_CORE_SOURCES}
- ${ORTHANC_SERVER_SOURCES}
- ${ORTHANC_UNIT_TESTS_SOURCES}
- Plugins/Samples/ServeFolders/Plugin.cpp
- Plugins/Samples/ModalityWorklists/Plugin.cpp
- OrthancServer/main.cpp
- )
-
-
if (CMAKE_COMPILER_IS_GNUCXX
AND NOT CMAKE_CROSSCOMPILING
AND USE_DCMTK_360)
# Add the "-pedantic" flag only on the Orthanc sources, and only if
- # using DCMTK 3.6.0
+ # cross-compiling DCMTK 3.6.0
+ set(ORTHANC_ALL_SOURCES
+ ${ORTHANC_CORE_SOURCES_INTERNAL}
+ ${ORTHANC_DICOM_SOURCES_INTERNAL}
+ ${ORTHANC_SERVER_SOURCES}
+ ${ORTHANC_UNIT_TESTS_SOURCES}
+ Plugins/Samples/ServeFolders/Plugin.cpp
+ Plugins/Samples/ModalityWorklists/Plugin.cpp
+ OrthancServer/main.cpp
+ )
+
set_source_files_properties(${ORTHANC_ALL_SOURCES}
PROPERTIES COMPILE_FLAGS -pedantic
)
endif()
+#####################################################################
+## Autogeneration of files
+#####################################################################
+
set(ORTHANC_EMBEDDED_FILES
PREPARE_DATABASE ${CMAKE_CURRENT_SOURCE_DIR}/OrthancServer/PrepareDatabase.sql
UPGRADE_DATABASE_3_TO_4 ${CMAKE_CURRENT_SOURCE_DIR}/OrthancServer/Upgrade3To4.sql
@@ -287,78 +168,6 @@ set(ORTHANC_EMBEDDED_FILES
FONT_UBUNTU_MONO_BOLD_16 ${CMAKE_CURRENT_SOURCE_DIR}/Resources/Fonts/UbuntuMonoBold-16.json
)
-
-
-#####################################################################
-## Inclusion of third-party dependencies
-#####################################################################
-
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/JsonCppConfiguration.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/LibCurlConfiguration.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/LibPngConfiguration.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/LibJpegConfiguration.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/LuaConfiguration.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/MongooseConfiguration.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/PugixmlConfiguration.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/SQLiteConfiguration.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/ZlibConfiguration.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/GoogleTestConfiguration.cmake)
-
-# These are the two most heavyweight dependencies. We put them as the
-# last includes to quickly spot problems when configuring static
-# builds.
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/BoostConfiguration.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/DcmtkConfiguration.cmake)
-
-
-if (ENABLE_SSL)
- add_definitions(-DORTHANC_ENABLE_SSL=1)
- include(${CMAKE_SOURCE_DIR}/Resources/CMake/OpenSslConfiguration.cmake)
-else()
- add_definitions(-DORTHANC_ENABLE_SSL=0)
-endif()
-
-
-if (ENABLE_JPEG)
- add_definitions(-DORTHANC_ENABLE_JPEG=1)
-else()
- add_definitions(-DORTHANC_ENABLE_JPEG=0)
-endif()
-
-
-if (ENABLE_JPEG_LOSSLESS)
- add_definitions(-DORTHANC_ENABLE_JPEG_LOSSLESS=1)
-else()
- add_definitions(-DORTHANC_ENABLE_JPEG_LOSSLESS=0)
-endif()
-
-
-if (ENABLE_PLUGINS)
- add_definitions(-DORTHANC_ENABLE_PLUGINS=1)
-else()
- add_definitions(-DORTHANC_ENABLE_PLUGINS=0)
-endif()
-
-
-if (ENABLE_PKCS11)
- if (ENABLE_SSL)
- include(${CMAKE_SOURCE_DIR}/Resources/CMake/LibP11Configuration.cmake)
-
- add_definitions(-DORTHANC_ENABLE_PKCS11=1)
- list(APPEND ORTHANC_CORE_SOURCES Core/Pkcs11.cpp)
- else()
- message(FATAL_ERROR "OpenSSL is required to enable PKCS#11")
- endif()
-else()
- add_definitions(-DORTHANC_ENABLE_PKCS11=0)
-endif()
-
-
-
-#####################################################################
-## Autogeneration of files
-#####################################################################
-
if (STANDALONE_BUILD)
# We embed all the resources in the binaries for standalone builds
add_definitions(-DORTHANC_STANDALONE=1)
@@ -399,26 +208,25 @@ endif()
## Configuration of the C/C++ macros
#####################################################################
+if (ENABLE_PLUGINS)
+ add_definitions(-DORTHANC_ENABLE_PLUGINS=1)
+else()
+ add_definitions(-DORTHANC_ENABLE_PLUGINS=0)
+endif()
+
+
if (UNIT_TESTS_WITH_HTTP_CONNEXIONS)
add_definitions(-DUNIT_TESTS_WITH_HTTP_CONNEXIONS=1)
else()
add_definitions(-DUNIT_TESTS_WITH_HTTP_CONNEXIONS=0)
endif()
+
include_directories(${CMAKE_SOURCE_DIR}/Plugins/Include)
add_definitions(
- -DORTHANC_VERSION="${ORTHANC_VERSION}"
- -DORTHANC_DATABASE_VERSION=${ORTHANC_DATABASE_VERSION}
-DORTHANC_BUILD_UNIT_TESTS=1
- -DORTHANC_ENABLE_BASE64=1
- -DORTHANC_ENABLE_LOGGING=1
- -DORTHANC_ENABLE_LOGGING_PLUGIN=0
- -DORTHANC_ENABLE_LUA=1
- -DORTHANC_ENABLE_MD5=1
- -DORTHANC_MAXIMUM_TAG_LENGTH=256
- -DORTHANC_SANDBOXED=0
-
+
# Macros for the plugins
-DHAS_ORTHANC_EXCEPTION=0
-DMODALITY_WORKLISTS_VERSION="${ORTHANC_VERSION}"
@@ -435,14 +243,22 @@ add_definitions(
if (MSVC)
add_definitions(-DORTHANC_USE_PRECOMPILED_HEADERS=1)
+ set(TMP
+ ${ORTHANC_CORE_SOURCES_INTERNAL}
+ ${ORTHANC_DICOM_SOURCES_INTERNAL}
+ )
+
ADD_VISUAL_STUDIO_PRECOMPILED_HEADERS(
- "PrecompiledHeaders.h" "Core/PrecompiledHeaders.cpp" ORTHANC_CORE_SOURCES)
+ "PrecompiledHeaders.h" "Core/PrecompiledHeaders.cpp"
+ TMP ORTHANC_CORE_PCH)
ADD_VISUAL_STUDIO_PRECOMPILED_HEADERS(
- "PrecompiledHeadersServer.h" "OrthancServer/PrecompiledHeadersServer.cpp" ORTHANC_SERVER_SOURCES)
+ "PrecompiledHeadersServer.h" "OrthancServer/PrecompiledHeadersServer.cpp"
+ ORTHANC_SERVER_SOURCES ORTHANC_SERVER_PCH)
ADD_VISUAL_STUDIO_PRECOMPILED_HEADERS(
- "PrecompiledHeadersUnitTests.h" "UnitTestsSources/PrecompiledHeadersUnitTests.cpp" ORTHANC_UNIT_TESTS_SOURCES)
+ "PrecompiledHeadersUnitTests.h" "UnitTestsSources/PrecompiledHeadersUnitTests.cpp"
+ ORTHANC_UNIT_TESTS_SOURCES ORTHANC_UNIT_TESTS_PCH)
endif()
@@ -451,36 +267,14 @@ endif()
## Build the core of Orthanc
#####################################################################
-list(LENGTH OPENSSL_SOURCES OPENSSL_SOURCES_LENGTH)
-if (${OPENSSL_SOURCES_LENGTH} GREATER 0)
- add_library(OpenSSL STATIC ${OPENSSL_SOURCES})
-endif()
-
-# "CodeLibrary" contains all the third-party dependencies and the
-# content of the "Core" folder, but not OpenSSL, nor DCMTK.
+# "CoreLibrary" contains all the third-party dependencies and the
+# content of the "Core" folder
add_library(CoreLibrary
STATIC
+ ${ORTHANC_CORE_PCH}
${ORTHANC_CORE_SOURCES}
+ ${ORTHANC_DICOM_SOURCES}
${AUTOGENERATED_SOURCES}
-
- ${BOOST_SOURCES}
- ${CURL_SOURCES}
- ${JSONCPP_SOURCES}
- ${LIBPNG_SOURCES}
- ${LIBJPEG_SOURCES}
- ${LUA_SOURCES}
- ${MONGOOSE_SOURCES}
- ${PUGIXML_SOURCES}
- ${SQLITE_SOURCES}
- ${ZLIB_SOURCES}
- ${LIBP11_SOURCES}
-
- ${CMAKE_SOURCE_DIR}/Resources/ThirdParty/md5/md5.c
- ${CMAKE_SOURCE_DIR}/Resources/ThirdParty/base64/base64.cpp
-
- # This is the minizip distribution to create ZIP files using zlib
- ${ORTHANC_ROOT}/Resources/ThirdParty/minizip/ioapi.c
- ${ORTHANC_ROOT}/Resources/ThirdParty/minizip/zip.c
)
@@ -488,10 +282,9 @@ add_library(CoreLibrary
## Build the Orthanc server
#####################################################################
-# "ServerLibrary" contains DCMTK
add_library(ServerLibrary
STATIC
- ${DCMTK_SOURCES}
+ ${ORTHANC_SERVER_PCH}
${ORTHANC_SERVER_SOURCES}
)
@@ -505,32 +298,28 @@ add_executable(Orthanc
target_link_libraries(Orthanc ServerLibrary CoreLibrary ${DCMTK_LIBRARIES})
-if (${OPENSSL_SOURCES_LENGTH} GREATER 0)
- target_link_libraries(Orthanc OpenSSL)
-endif()
-
install(
TARGETS Orthanc
RUNTIME DESTINATION sbin
)
-
#####################################################################
## Build the unit tests
#####################################################################
add_executable(UnitTests
- ${GTEST_SOURCES}
+ ${GOOGLE_TEST_SOURCES}
+ ${ORTHANC_UNIT_TESTS_PCH}
${ORTHANC_UNIT_TESTS_SOURCES}
)
-target_link_libraries(UnitTests ServerLibrary CoreLibrary ${DCMTK_LIBRARIES})
-
-if (${OPENSSL_SOURCES_LENGTH} GREATER 0)
- target_link_libraries(UnitTests OpenSSL)
-endif()
-
+target_link_libraries(UnitTests
+ ServerLibrary
+ CoreLibrary
+ ${DCMTK_LIBRARIES}
+ ${GOOGLE_TEST_LIBRARIES}
+ )
#####################################################################
@@ -557,6 +346,7 @@ if (ENABLE_PLUGINS AND BUILD_SERVE_FOLDERS)
add_library(ServeFolders SHARED
${BOOST_SOURCES}
${JSONCPP_SOURCES}
+ ${LIBICONV_SOURCES}
Plugins/Samples/ServeFolders/Plugin.cpp
Plugins/Samples/Common/OrthancPluginCppWrapper.cpp
${SERVE_FOLDERS_RESOURCES}
@@ -601,6 +391,7 @@ if (ENABLE_PLUGINS AND BUILD_MODALITY_WORKLISTS)
add_library(ModalityWorklists SHARED
${BOOST_SOURCES}
${JSONCPP_SOURCES}
+ ${LIBICONV_SOURCES}
Plugins/Samples/Common/OrthancPluginCppWrapper.cpp
Plugins/Samples/ModalityWorklists/Plugin.cpp
${MODALITY_WORKLISTS_RESOURCES}
diff --git a/Core/Cache/SharedArchive.h b/Core/Cache/SharedArchive.h
index 19cab4a..ff0b163 100644
--- a/Core/Cache/SharedArchive.h
+++ b/Core/Cache/SharedArchive.h
@@ -33,6 +33,14 @@
#pragma once
+#if !defined(ORTHANC_SANDBOXED)
+# error The macro ORTHANC_SANDBOXED must be defined
+#endif
+
+#if ORTHANC_SANDBOXED == 1
+# error The class SharedArchive cannot be used in sandboxed environments
+#endif
+
#include "LeastRecentlyUsedIndex.h"
#include "../IDynamicObject.h"
diff --git a/Core/Compression/HierarchicalZipWriter.h b/Core/Compression/HierarchicalZipWriter.h
index f77d735..4237442 100644
--- a/Core/Compression/HierarchicalZipWriter.h
+++ b/Core/Compression/HierarchicalZipWriter.h
@@ -39,6 +39,10 @@
#include <list>
#include <boost/lexical_cast.hpp>
+#if ORTHANC_BUILD_UNIT_TESTS == 1
+# include <gtest/gtest_prod.h>
+#endif
+
namespace Orthanc
{
class HierarchicalZipWriter
diff --git a/Core/Compression/ZipWriter.h b/Core/Compression/ZipWriter.h
index f4db7d4..d5b8705 100644
--- a/Core/Compression/ZipWriter.h
+++ b/Core/Compression/ZipWriter.h
@@ -37,10 +37,6 @@
#include <string>
#include <boost/shared_ptr.hpp>
-#if ORTHANC_BUILD_UNIT_TESTS == 1
-#include <gtest/gtest_prod.h>
-#endif
-
namespace Orthanc
{
class ZipWriter
diff --git a/Core/DicomFormat/DicomImageInformation.cpp b/Core/DicomFormat/DicomImageInformation.cpp
index cc68131..1bfb153 100644
--- a/Core/DicomFormat/DicomImageInformation.cpp
+++ b/Core/DicomFormat/DicomImageInformation.cpp
@@ -178,19 +178,21 @@ namespace Orthanc
throw OrthancException(ErrorCode_NotImplemented);
}
- try
+ if (values.HasTag(DICOM_TAG_NUMBER_OF_FRAMES))
{
- numberOfFrames_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_NUMBER_OF_FRAMES).GetContent());
+ try
+ {
+ numberOfFrames_ = boost::lexical_cast<unsigned int>(values.GetValue(DICOM_TAG_NUMBER_OF_FRAMES).GetContent());
+ }
+ catch (boost::bad_lexical_cast&)
+ {
+ throw OrthancException(ErrorCode_NotImplemented);
+ }
}
- catch (OrthancException&)
+ else
{
- // If the tag "NumberOfFrames" is absent, assume there is a single frame
numberOfFrames_ = 1;
}
- catch (boost::bad_lexical_cast&)
- {
- throw OrthancException(ErrorCode_NotImplemented);
- }
if ((bitsAllocated_ != 8 && bitsAllocated_ != 16 &&
bitsAllocated_ != 24 && bitsAllocated_ != 32) ||
@@ -217,9 +219,19 @@ namespace Orthanc
{
if (photometric_ == PhotometricInterpretation_Palette)
{
- return false;
- }
+ if (GetBitsStored() == 8 && GetChannelCount() == 1 && !IsSigned())
+ {
+ format = PixelFormat_RGB24;
+ return true;
+ }
+ if (GetBitsStored() == 16 && GetChannelCount() == 1 && !IsSigned())
+ {
+ format = PixelFormat_RGB48;
+ return true;
+ }
+ }
+
if (ignorePhotometricInterpretation ||
photometric_ == PhotometricInterpretation_Monochrome1 ||
photometric_ == PhotometricInterpretation_Monochrome2)
diff --git a/Core/DicomFormat/DicomMap.cpp b/Core/DicomFormat/DicomMap.cpp
index c11ee82..621fd98 100644
--- a/Core/DicomFormat/DicomMap.cpp
+++ b/Core/DicomFormat/DicomMap.cpp
@@ -36,7 +36,9 @@
#include <stdio.h>
#include <memory>
+
#include "../Endianness.h"
+#include "../Logging.h"
#include "../OrthancException.h"
@@ -781,4 +783,193 @@ namespace Orthanc
return true;
}
+
+
+ static std::string ValueAsString(const DicomMap& summary,
+ const DicomTag& tag)
+ {
+ const DicomValue& value = summary.GetValue(tag);
+ if (value.IsNull())
+ {
+ return "(null)";
+ }
+ else
+ {
+ return value.GetContent();
+ }
+ }
+
+
+ void DicomMap::LogMissingTagsForStore() const
+ {
+ std::string s, t;
+
+ if (HasTag(DICOM_TAG_PATIENT_ID))
+ {
+ if (t.size() > 0)
+ t += ", ";
+ t += "PatientID=" + ValueAsString(*this, DICOM_TAG_PATIENT_ID);
+ }
+ else
+ {
+ if (s.size() > 0)
+ s += ", ";
+ s += "PatientID";
+ }
+
+ if (HasTag(DICOM_TAG_STUDY_INSTANCE_UID))
+ {
+ if (t.size() > 0)
+ t += ", ";
+ t += "StudyInstanceUID=" + ValueAsString(*this, DICOM_TAG_STUDY_INSTANCE_UID);
+ }
+ else
+ {
+ if (s.size() > 0)
+ s += ", ";
+ s += "StudyInstanceUID";
+ }
+
+ if (HasTag(DICOM_TAG_SERIES_INSTANCE_UID))
+ {
+ if (t.size() > 0)
+ t += ", ";
+ t += "SeriesInstanceUID=" + ValueAsString(*this, DICOM_TAG_SERIES_INSTANCE_UID);
+ }
+ else
+ {
+ if (s.size() > 0)
+ s += ", ";
+ s += "SeriesInstanceUID";
+ }
+
+ if (HasTag(DICOM_TAG_SOP_INSTANCE_UID))
+ {
+ if (t.size() > 0)
+ t += ", ";
+ t += "SOPInstanceUID=" + ValueAsString(*this, DICOM_TAG_SOP_INSTANCE_UID);
+ }
+ else
+ {
+ if (s.size() > 0)
+ s += ", ";
+ s += "SOPInstanceUID";
+ }
+
+ if (t.size() == 0)
+ {
+ LOG(ERROR) << "Store has failed because all the required tags (" << s << ") are missing (is it a DICOMDIR file?)";
+ }
+ else
+ {
+ LOG(ERROR) << "Store has failed because required tags (" << s << ") are missing for the following instance: " << t;
+ }
+ }
+
+
+ bool DicomMap::CopyToString(std::string& result,
+ const DicomTag& tag,
+ bool allowBinary) const
+ {
+ const DicomValue* value = TestAndGetValue(tag);
+
+ if (value == NULL)
+ {
+ return false;
+ }
+ else
+ {
+ return value->CopyToString(result, allowBinary);
+ }
+ }
+
+ bool DicomMap::ParseInteger32(int32_t& result,
+ const DicomTag& tag) const
+ {
+ const DicomValue* value = TestAndGetValue(tag);
+
+ if (value == NULL)
+ {
+ return false;
+ }
+ else
+ {
+ return value->ParseInteger32(result);
+ }
+ }
+
+ bool DicomMap::ParseInteger64(int64_t& result,
+ const DicomTag& tag) const
+ {
+ const DicomValue* value = TestAndGetValue(tag);
+
+ if (value == NULL)
+ {
+ return false;
+ }
+ else
+ {
+ return value->ParseInteger64(result);
+ }
+ }
+
+ bool DicomMap::ParseUnsignedInteger32(uint32_t& result,
+ const DicomTag& tag) const
+ {
+ const DicomValue* value = TestAndGetValue(tag);
+
+ if (value == NULL)
+ {
+ return false;
+ }
+ else
+ {
+ return value->ParseUnsignedInteger32(result);
+ }
+ }
+
+ bool DicomMap::ParseUnsignedInteger64(uint64_t& result,
+ const DicomTag& tag) const
+ {
+ const DicomValue* value = TestAndGetValue(tag);
+
+ if (value == NULL)
+ {
+ return false;
+ }
+ else
+ {
+ return value->ParseUnsignedInteger64(result);
+ }
+ }
+
+ bool DicomMap::ParseFloat(float& result,
+ const DicomTag& tag) const
+ {
+ const DicomValue* value = TestAndGetValue(tag);
+
+ if (value == NULL)
+ {
+ return false;
+ }
+ else
+ {
+ return value->ParseFloat(result);
+ }
+ }
+
+ bool DicomMap::ParseDouble(double& result,
+ const DicomTag& tag) const
+ {
+ const DicomValue* value = TestAndGetValue(tag);
+
+ if (value == NULL)
+ {
+ return false;
+ }
+ else
+ {
+ return value->ParseDouble(result);
+ }
+ }
}
diff --git a/Core/DicomFormat/DicomMap.h b/Core/DicomFormat/DicomMap.h
index 80732ef..fd5f2dc 100644
--- a/Core/DicomFormat/DicomMap.h
+++ b/Core/DicomFormat/DicomMap.h
@@ -181,5 +181,29 @@ namespace Orthanc
static bool ParseDicomMetaInformation(DicomMap& result,
const char* dicom,
size_t size);
+
+ void LogMissingTagsForStore() const;
+
+ bool CopyToString(std::string& result,
+ const DicomTag& tag,
+ bool allowBinary) const;
+
+ bool ParseInteger32(int32_t& result,
+ const DicomTag& tag) const;
+
+ bool ParseInteger64(int64_t& result,
+ const DicomTag& tag) const;
+
+ bool ParseUnsignedInteger32(uint32_t& result,
+ const DicomTag& tag) const;
+
+ bool ParseUnsignedInteger64(uint64_t& result,
+ const DicomTag& tag) const;
+
+ bool ParseFloat(float& result,
+ const DicomTag& tag) const;
+
+ bool ParseDouble(double& result,
+ const DicomTag& tag) const;
};
}
diff --git a/Core/DicomFormat/DicomTag.h b/Core/DicomFormat/DicomTag.h
index 6b9ba90..14edf5d 100644
--- a/Core/DicomFormat/DicomTag.h
+++ b/Core/DicomFormat/DicomTag.h
@@ -173,6 +173,17 @@ namespace Orthanc
static const DicomTag DICOM_TAG_ACQUISITION_DEVICE_PROCESSING_DESCRIPTION(0x0018, 0x1400);
static const DicomTag DICOM_TAG_CONTRAST_BOLUS_AGENT(0x0018, 0x0010);
+ // Tags used within the Stone of Orthanc
+ static const DicomTag DICOM_TAG_FRAME_INCREMENT_POINTER(0x0028, 0x0009);
+ static const DicomTag DICOM_TAG_GRID_FRAME_OFFSET_VECTOR(0x3004, 0x000c);
+ static const DicomTag DICOM_TAG_PIXEL_SPACING(0x0028, 0x0030);
+ static const DicomTag DICOM_TAG_RESCALE_INTERCEPT(0x0028, 0x1052);
+ static const DicomTag DICOM_TAG_RESCALE_SLOPE(0x0028, 0x1053);
+ static const DicomTag DICOM_TAG_SLICE_THICKNESS(0x0018, 0x0050);
+ static const DicomTag DICOM_TAG_WINDOW_CENTER(0x0028, 0x1050);
+ static const DicomTag DICOM_TAG_WINDOW_WIDTH(0x0028, 0x1051);
+ static const DicomTag DICOM_TAG_DOSE_GRID_SCALING(0x3004, 0x000e);
+
// Counting patients, studies and series
// https://www.medicalconnections.co.uk/kb/Counting_Studies_Series_and_Instances
static const DicomTag DICOM_TAG_NUMBER_OF_PATIENT_RELATED_STUDIES(0x0020, 0x1200);
diff --git a/Core/DicomFormat/DicomValue.cpp b/Core/DicomFormat/DicomValue.cpp
index 9c8958d..507352a 100644
--- a/Core/DicomFormat/DicomValue.cpp
+++ b/Core/DicomFormat/DicomValue.cpp
@@ -37,6 +37,8 @@
#include "../OrthancException.h"
#include "../Toolbox.h"
+#include <boost/lexical_cast.hpp>
+
namespace Orthanc
{
DicomValue::DicomValue(const DicomValue& other) :
@@ -91,4 +93,104 @@ namespace Orthanc
}
#endif
+
+ template <typename T,
+ bool allowSigned>
+ static bool ParseValue(T& result,
+ const DicomValue& source)
+ {
+ if (source.IsBinary() ||
+ source.IsNull())
+ {
+ return false;
+ }
+
+ try
+ {
+ std::string value = Toolbox::StripSpaces(source.GetContent());
+ if (value.empty())
+ {
+ return false;
+ }
+
+ if (!allowSigned &&
+ value[0] == '-')
+ {
+ return false;
+ }
+
+ result = boost::lexical_cast<T>(value);
+ return true;
+ }
+ catch (boost::bad_lexical_cast&)
+ {
+ return false;
+ }
+ }
+
+ bool DicomValue::ParseInteger32(int32_t& result) const
+ {
+ int64_t tmp;
+ if (ParseValue<int64_t, true>(tmp, *this))
+ {
+ result = static_cast<int32_t>(tmp);
+ return (tmp == static_cast<int64_t>(result)); // Check no overflow occurs
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ bool DicomValue::ParseInteger64(int64_t& result) const
+ {
+ return ParseValue<int64_t, true>(result, *this);
+ }
+
+ bool DicomValue::ParseUnsignedInteger32(uint32_t& result) const
+ {
+ uint64_t tmp;
+ if (ParseValue<uint64_t, false>(tmp, *this))
+ {
+ result = static_cast<uint32_t>(tmp);
+ return (tmp == static_cast<uint64_t>(result)); // Check no overflow occurs
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ bool DicomValue::ParseUnsignedInteger64(uint64_t& result) const
+ {
+ return ParseValue<uint64_t, false>(result, *this);
+ }
+
+ bool DicomValue::ParseFloat(float& result) const
+ {
+ return ParseValue<float, true>(result, *this);
+ }
+
+ bool DicomValue::ParseDouble(double& result) const
+ {
+ return ParseValue<double, true>(result, *this);
+ }
+
+ bool DicomValue::CopyToString(std::string& result,
+ bool allowBinary) const
+ {
+ if (IsNull())
+ {
+ return false;
+ }
+ else if (IsBinary() && !allowBinary)
+ {
+ return false;
+ }
+ else
+ {
+ result.assign(content_);
+ return true;
+ }
+ }
}
diff --git a/Core/DicomFormat/DicomValue.h b/Core/DicomFormat/DicomValue.h
index 405cdda..5b607ed 100644
--- a/Core/DicomFormat/DicomValue.h
+++ b/Core/DicomFormat/DicomValue.h
@@ -33,6 +33,7 @@
#pragma once
+#include <stdint.h>
#include <string>
#include <boost/noncopyable.hpp>
@@ -93,5 +94,20 @@ namespace Orthanc
FormatDataUriScheme(target, "application/octet-stream");
}
#endif
+
+ bool CopyToString(std::string& result,
+ bool allowBinary) const;
+
+ bool ParseInteger32(int32_t& result) const;
+
+ bool ParseInteger64(int64_t& result) const;
+
+ bool ParseUnsignedInteger32(uint32_t& result) const;
+
+ bool ParseUnsignedInteger64(uint64_t& result) const;
+
+ bool ParseFloat(float& result) const;
+
+ bool ParseDouble(double& result) const;
};
}
diff --git a/OrthancServer/DicomProtocol/DicomFindAnswers.cpp b/Core/DicomNetworking/DicomFindAnswers.cpp
similarity index 95%
rename from OrthancServer/DicomProtocol/DicomFindAnswers.cpp
rename to Core/DicomNetworking/DicomFindAnswers.cpp
index c32f26a..d418bc0 100644
--- a/OrthancServer/DicomProtocol/DicomFindAnswers.cpp
+++ b/Core/DicomNetworking/DicomFindAnswers.cpp
@@ -31,12 +31,11 @@
**/
-#include "../PrecompiledHeadersServer.h"
+#include "../PrecompiledHeaders.h"
#include "DicomFindAnswers.h"
-#include "../OrthancInitialization.h"
-#include "../FromDcmtkBridge.h"
-#include "../../Core/OrthancException.h"
+#include "../DicomParsing/FromDcmtkBridge.h"
+#include "../OrthancException.h"
#include <memory>
#include <dcmtk/dcmdata/dcfilefo.h>
@@ -64,7 +63,7 @@ namespace Orthanc
DicomFindAnswers::DicomFindAnswers(bool isWorklist) :
- encoding_(Configuration::GetDefaultEncoding()),
+ encoding_(GetDefaultDicomEncoding()),
isWorklist_(isWorklist),
complete_(true)
{
diff --git a/OrthancServer/DicomProtocol/DicomFindAnswers.h b/Core/DicomNetworking/DicomFindAnswers.h
similarity index 98%
rename from OrthancServer/DicomProtocol/DicomFindAnswers.h
rename to Core/DicomNetworking/DicomFindAnswers.h
index da07d76..ffaa841 100644
--- a/OrthancServer/DicomProtocol/DicomFindAnswers.h
+++ b/Core/DicomNetworking/DicomFindAnswers.h
@@ -33,7 +33,7 @@
#pragma once
-#include "../ParsedDicomFile.h"
+#include "../DicomParsing/ParsedDicomFile.h"
namespace Orthanc
{
diff --git a/OrthancServer/DicomProtocol/DicomServer.cpp b/Core/DicomNetworking/DicomServer.cpp
similarity index 91%
rename from OrthancServer/DicomProtocol/DicomServer.cpp
rename to Core/DicomNetworking/DicomServer.cpp
index c9337e4..e63f4f7 100644
--- a/OrthancServer/DicomProtocol/DicomServer.cpp
+++ b/Core/DicomNetworking/DicomServer.cpp
@@ -31,16 +31,14 @@
**/
-#include "../PrecompiledHeadersServer.h"
+#include "../PrecompiledHeaders.h"
#include "DicomServer.h"
#include "../../Core/Logging.h"
+#include "../../Core/MultiThreading/RunnableWorkersPool.h"
#include "../../Core/OrthancException.h"
#include "../../Core/Toolbox.h"
-#include "../Internals/CommandDispatcher.h"
-#include "../OrthancInitialization.h"
-#include "EmbeddedResources.h"
-#include "../../Core/MultiThreading/RunnableWorkersPool.h"
+#include "Internals/CommandDispatcher.h"
#include <boost/thread.hpp>
@@ -91,6 +89,7 @@ namespace Orthanc
aet_("ANY-SCP")
{
port_ = 104;
+ modalities_ = NULL;
findRequestHandlerFactory_ = NULL;
moveRequestHandlerFactory_ = NULL;
storeRequestHandlerFactory_ = NULL;
@@ -180,6 +179,24 @@ namespace Orthanc
return aet_;
}
+ void DicomServer::SetRemoteModalities(IRemoteModalities& modalities)
+ {
+ Stop();
+ modalities_ = &modalities;
+ }
+
+ DicomServer::IRemoteModalities& DicomServer::GetRemoteModalities() const
+ {
+ if (modalities_ == NULL)
+ {
+ throw OrthancException(ErrorCode_BadSequenceOfCalls);
+ }
+ else
+ {
+ return *modalities_;
+ }
+ }
+
void DicomServer::SetFindRequestHandlerFactory(IFindRequestHandlerFactory& factory)
{
Stop();
@@ -297,6 +314,12 @@ namespace Orthanc
void DicomServer::Start()
{
+ if (modalities_ == NULL)
+ {
+ LOG(ERROR) << "No list of modalities was provided to the DICOM server";
+ throw OrthancException(ErrorCode_BadSequenceOfCalls);
+ }
+
Stop();
/* initialize network, i.e. create an instance of T_ASC_Network*. */
@@ -340,13 +363,20 @@ namespace Orthanc
bool DicomServer::IsMyAETitle(const std::string& aet) const
{
+ if (modalities_ == NULL)
+ {
+ throw OrthancException(ErrorCode_BadSequenceOfCalls);
+ }
+
if (!HasCalledApplicationEntityTitleCheck())
{
// OK, no check on the AET.
return true;
}
-
- return Configuration::IsSameAETitle(aet, GetApplicationEntityTitle());
+ else
+ {
+ return modalities_->IsSameAETitle(aet, GetApplicationEntityTitle());
+ }
}
}
diff --git a/OrthancServer/DicomProtocol/DicomServer.h b/Core/DicomNetworking/DicomServer.h
similarity index 83%
rename from OrthancServer/DicomProtocol/DicomServer.h
rename to Core/DicomNetworking/DicomServer.h
index 5afadda..a00f919 100644
--- a/OrthancServer/DicomProtocol/DicomServer.h
+++ b/Core/DicomNetworking/DicomServer.h
@@ -33,11 +33,16 @@
#pragma once
+#if ORTHANC_ENABLE_DCMTK_NETWORKING != 1
+# error The macro ORTHANC_ENABLE_DCMTK_NETWORKING must be set to 1
+#endif
+
#include "IFindRequestHandlerFactory.h"
#include "IMoveRequestHandlerFactory.h"
#include "IStoreRequestHandlerFactory.h"
#include "IWorklistRequestHandlerFactory.h"
#include "IApplicationEntityFilter.h"
+#include "RemoteModalityParameters.h"
#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
@@ -47,6 +52,22 @@ namespace Orthanc
{
class DicomServer : public boost::noncopyable
{
+ public:
+ // WARNING: The methods of this class must be thread-safe
+ class IRemoteModalities : public boost::noncopyable
+ {
+ public:
+ virtual ~IRemoteModalities()
+ {
+ }
+
+ virtual bool IsSameAETitle(const std::string& aet1,
+ const std::string& aet2) = 0;
+
+ virtual bool LookupAETitle(RemoteModalityParameters& modality,
+ const std::string& aet) = 0;
+ };
+
private:
struct PImpl;
boost::shared_ptr<PImpl> pimpl_;
@@ -56,6 +77,7 @@ namespace Orthanc
uint16_t port_;
bool continue_;
uint32_t associationTimeout_;
+ IRemoteModalities* modalities_;
IFindRequestHandlerFactory* findRequestHandlerFactory_;
IMoveRequestHandlerFactory* moveRequestHandlerFactory_;
IStoreRequestHandlerFactory* storeRequestHandlerFactory_;
@@ -81,6 +103,9 @@ namespace Orthanc
void SetApplicationEntityTitle(const std::string& aet);
const std::string& GetApplicationEntityTitle() const;
+ void SetRemoteModalities(IRemoteModalities& modalities);
+ IRemoteModalities& GetRemoteModalities() const;
+
void SetFindRequestHandlerFactory(IFindRequestHandlerFactory& handler);
bool HasFindRequestHandlerFactory() const;
IFindRequestHandlerFactory& GetFindRequestHandlerFactory() const;
diff --git a/OrthancServer/DicomProtocol/DicomUserConnection.cpp b/Core/DicomNetworking/DicomUserConnection.cpp
similarity index 99%
rename from OrthancServer/DicomProtocol/DicomUserConnection.cpp
rename to Core/DicomNetworking/DicomUserConnection.cpp
index fccc033..927545d 100644
--- a/OrthancServer/DicomProtocol/DicomUserConnection.cpp
+++ b/Core/DicomNetworking/DicomUserConnection.cpp
@@ -79,15 +79,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=========================================================================*/
-#include "../PrecompiledHeadersServer.h"
+#include "../PrecompiledHeaders.h"
#include "DicomUserConnection.h"
-#include "../../Core/DicomFormat/DicomArray.h"
-#include "../../Core/Logging.h"
-#include "../../Core/OrthancException.h"
-#include "../FromDcmtkBridge.h"
-#include "../ToDcmtkBridge.h"
-#include "../OrthancInitialization.h"
+#include "../DicomFormat/DicomArray.h"
+#include "../Logging.h"
+#include "../OrthancException.h"
+#include "../DicomParsing/FromDcmtkBridge.h"
+#include "../DicomParsing/ToDcmtkBridge.h"
#include <dcmtk/dcmdata/dcistrmb.h>
#include <dcmtk/dcmdata/dcistrmf.h>
@@ -402,8 +401,8 @@ namespace Orthanc
else
{
DicomMap m;
- Configuration::ExtractDicomSummary(m, *responseIdentifiers);
-
+ FromDcmtkBridge::ExtractDicomSummary(m, *responseIdentifiers);
+
if (!m.HasTag(DICOM_TAG_QUERY_RETRIEVE_LEVEL))
{
m.SetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL, payload.level, false);
diff --git a/OrthancServer/DicomProtocol/DicomUserConnection.h b/Core/DicomNetworking/DicomUserConnection.h
similarity index 97%
rename from OrthancServer/DicomProtocol/DicomUserConnection.h
rename to Core/DicomNetworking/DicomUserConnection.h
index d3a7b4d..6a2b1f1 100644
--- a/OrthancServer/DicomProtocol/DicomUserConnection.h
+++ b/Core/DicomNetworking/DicomUserConnection.h
@@ -33,8 +33,12 @@
#pragma once
+#if ORTHANC_ENABLE_DCMTK_NETWORKING != 1
+# error The macro ORTHANC_ENABLE_DCMTK_NETWORKING must be set to 1
+#endif
+
#include "DicomFindAnswers.h"
-#include "../ServerEnumerations.h"
+#include "../Enumerations.h"
#include "RemoteModalityParameters.h"
#include <stdint.h>
diff --git a/OrthancServer/DicomProtocol/IApplicationEntityFilter.h b/Core/DicomNetworking/IApplicationEntityFilter.h
similarity index 98%
rename from OrthancServer/DicomProtocol/IApplicationEntityFilter.h
rename to Core/DicomNetworking/IApplicationEntityFilter.h
index 2e46d5d..7276968 100644
--- a/OrthancServer/DicomProtocol/IApplicationEntityFilter.h
+++ b/Core/DicomNetworking/IApplicationEntityFilter.h
@@ -33,7 +33,7 @@
#pragma once
-#include "../ServerEnumerations.h"
+#include "../Enumerations.h"
#include <string>
diff --git a/OrthancServer/DicomProtocol/IFindRequestHandler.h b/Core/DicomNetworking/IFindRequestHandler.h
similarity index 99%
rename from OrthancServer/DicomProtocol/IFindRequestHandler.h
rename to Core/DicomNetworking/IFindRequestHandler.h
index 91eef22..227385e 100644
--- a/OrthancServer/DicomProtocol/IFindRequestHandler.h
+++ b/Core/DicomNetworking/IFindRequestHandler.h
@@ -35,6 +35,8 @@
#include "DicomFindAnswers.h"
+#include <list>
+
namespace Orthanc
{
class IFindRequestHandler : public boost::noncopyable
diff --git a/OrthancServer/DicomProtocol/IFindRequestHandlerFactory.h b/Core/DicomNetworking/IFindRequestHandlerFactory.h
similarity index 100%
rename from OrthancServer/DicomProtocol/IFindRequestHandlerFactory.h
rename to Core/DicomNetworking/IFindRequestHandlerFactory.h
diff --git a/OrthancServer/DicomProtocol/IMoveRequestHandler.h b/Core/DicomNetworking/IMoveRequestHandler.h
similarity index 100%
rename from OrthancServer/DicomProtocol/IMoveRequestHandler.h
rename to Core/DicomNetworking/IMoveRequestHandler.h
diff --git a/OrthancServer/DicomProtocol/IMoveRequestHandlerFactory.h b/Core/DicomNetworking/IMoveRequestHandlerFactory.h
similarity index 100%
rename from OrthancServer/DicomProtocol/IMoveRequestHandlerFactory.h
rename to Core/DicomNetworking/IMoveRequestHandlerFactory.h
diff --git a/OrthancServer/DicomProtocol/IStoreRequestHandler.h b/Core/DicomNetworking/IStoreRequestHandler.h
similarity index 100%
rename from OrthancServer/DicomProtocol/IStoreRequestHandler.h
rename to Core/DicomNetworking/IStoreRequestHandler.h
diff --git a/OrthancServer/DicomProtocol/IStoreRequestHandlerFactory.h b/Core/DicomNetworking/IStoreRequestHandlerFactory.h
similarity index 100%
rename from OrthancServer/DicomProtocol/IStoreRequestHandlerFactory.h
rename to Core/DicomNetworking/IStoreRequestHandlerFactory.h
diff --git a/OrthancServer/DicomProtocol/IWorklistRequestHandler.h b/Core/DicomNetworking/IWorklistRequestHandler.h
similarity index 100%
rename from OrthancServer/DicomProtocol/IWorklistRequestHandler.h
rename to Core/DicomNetworking/IWorklistRequestHandler.h
diff --git a/OrthancServer/DicomProtocol/IWorklistRequestHandlerFactory.h b/Core/DicomNetworking/IWorklistRequestHandlerFactory.h
similarity index 100%
rename from OrthancServer/DicomProtocol/IWorklistRequestHandlerFactory.h
rename to Core/DicomNetworking/IWorklistRequestHandlerFactory.h
diff --git a/OrthancServer/Internals/CommandDispatcher.cpp b/Core/DicomNetworking/Internals/CommandDispatcher.cpp
similarity index 99%
rename from OrthancServer/Internals/CommandDispatcher.cpp
rename to Core/DicomNetworking/Internals/CommandDispatcher.cpp
index 71ed77e..aaf2d8f 100644
--- a/OrthancServer/Internals/CommandDispatcher.cpp
+++ b/Core/DicomNetworking/Internals/CommandDispatcher.cpp
@@ -80,14 +80,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=========================================================================*/
-#include "../PrecompiledHeadersServer.h"
+#include "../../PrecompiledHeaders.h"
#include "CommandDispatcher.h"
#include "FindScp.h"
#include "StoreScp.h"
#include "MoveScp.h"
-#include "../../Core/Toolbox.h"
-#include "../../Core/Logging.h"
+#include "../../Toolbox.h"
+#include "../../Logging.h"
#include <dcmtk/dcmnet/dcasccfg.h> /* for class DcmAssociationConfiguration */
#include <boost/lexical_cast.hpp>
@@ -871,8 +871,9 @@ namespace Orthanc
worklistHandler.reset(server_.GetWorklistRequestHandlerFactory().ConstructWorklistRequestHandler());
}
- cond = Internals::findScp(assoc_, &msg, presID, findHandler.get(),
- worklistHandler.get(), remoteIp_, remoteAet_, calledAet_);
+ cond = Internals::findScp(assoc_, &msg, presID, server_.GetRemoteModalities(),
+ findHandler.get(), worklistHandler.get(),
+ remoteIp_, remoteAet_, calledAet_);
}
break;
diff --git a/OrthancServer/Internals/CommandDispatcher.h b/Core/DicomNetworking/Internals/CommandDispatcher.h
similarity index 96%
rename from OrthancServer/Internals/CommandDispatcher.h
rename to Core/DicomNetworking/Internals/CommandDispatcher.h
index 84553eb..5e645a9 100644
--- a/OrthancServer/Internals/CommandDispatcher.h
+++ b/Core/DicomNetworking/Internals/CommandDispatcher.h
@@ -33,8 +33,8 @@
#pragma once
-#include "../DicomProtocol/DicomServer.h"
-#include "../../Core/MultiThreading/IRunnableBySteps.h"
+#include "../DicomServer.h"
+#include "../../MultiThreading/IRunnableBySteps.h"
#include <dcmtk/dcmnet/dimse.h>
diff --git a/OrthancServer/Internals/FindScp.cpp b/Core/DicomNetworking/Internals/FindScp.cpp
similarity index 95%
rename from OrthancServer/Internals/FindScp.cpp
rename to Core/DicomNetworking/Internals/FindScp.cpp
index a17e601..daa6d62 100644
--- a/OrthancServer/Internals/FindScp.cpp
+++ b/Core/DicomNetworking/Internals/FindScp.cpp
@@ -80,14 +80,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "../PrecompiledHeadersServer.h"
+#include "../../PrecompiledHeaders.h"
#include "FindScp.h"
-#include "../FromDcmtkBridge.h"
-#include "../ToDcmtkBridge.h"
-#include "../../Core/Logging.h"
-#include "../../Core/OrthancException.h"
-#include "../OrthancInitialization.h"
+#include "../../DicomParsing/FromDcmtkBridge.h"
+#include "../../DicomParsing/ToDcmtkBridge.h"
+#include "../../Logging.h"
+#include "../../OrthancException.h"
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcdeftag.h>
@@ -139,6 +138,7 @@ namespace Orthanc
{
struct FindScpData
{
+ DicomServer::IRemoteModalities* modalities_;
IFindRequestHandler* findHandler_;
IWorklistRequestHandler* worklistHandler_;
DicomFindAnswers answers_;
@@ -197,7 +197,8 @@ namespace Orthanc
* Ensure that the remote modality is known to Orthanc for C-FIND requests.
**/
- if (!Configuration::LookupDicomModalityUsingAETitle(modality, *data.remoteAet_))
+ assert(data.modalities_ != NULL);
+ if (!data.modalities_->LookupAETitle(modality, *data.remoteAet_))
{
LOG(ERROR) << "Modality with AET \"" << *data.remoteAet_
<< "\" is not defined in the \"DicomModalities\" configuration option";
@@ -252,7 +253,7 @@ namespace Orthanc
}
DicomMap input;
- Configuration::ExtractDicomSummary(input, *requestIdentifiers);
+ FromDcmtkBridge::ExtractDicomSummary(input, *requestIdentifiers);
data.findHandler_->Handle(data.answers_, input, sequencesToReturn,
*data.remoteIp_, *data.remoteAet_,
@@ -314,6 +315,7 @@ namespace Orthanc
OFCondition Internals::findScp(T_ASC_Association * assoc,
T_DIMSE_Message * msg,
T_ASC_PresentationContextID presID,
+ DicomServer::IRemoteModalities& modalities,
IFindRequestHandler* findHandler,
IWorklistRequestHandler* worklistHandler,
const std::string& remoteIp,
@@ -321,9 +323,10 @@ namespace Orthanc
const std::string& calledAet)
{
FindScpData data;
- data.lastRequest_ = NULL;
+ data.modalities_ = &modalities;
data.findHandler_ = findHandler;
data.worklistHandler_ = worklistHandler;
+ data.lastRequest_ = NULL;
data.remoteIp_ = &remoteIp;
data.remoteAet_ = &remoteAet;
data.calledAet_ = &calledAet;
diff --git a/OrthancServer/Internals/FindScp.h b/Core/DicomNetworking/Internals/FindScp.h
similarity index 95%
rename from OrthancServer/Internals/FindScp.h
rename to Core/DicomNetworking/Internals/FindScp.h
index 5d63f94..accdd13 100644
--- a/OrthancServer/Internals/FindScp.h
+++ b/Core/DicomNetworking/Internals/FindScp.h
@@ -33,8 +33,7 @@
#pragma once
-#include "../DicomProtocol/IFindRequestHandler.h"
-#include "../DicomProtocol/IWorklistRequestHandler.h"
+#include "../DicomServer.h"
#include <dcmtk/dcmnet/dimse.h>
@@ -45,6 +44,7 @@ namespace Orthanc
OFCondition findScp(T_ASC_Association * assoc,
T_DIMSE_Message * msg,
T_ASC_PresentationContextID presID,
+ DicomServer::IRemoteModalities& modalities,
IFindRequestHandler* findHandler, // can be NULL
IWorklistRequestHandler* worklistHandler, // can be NULL
const std::string& remoteIp,
diff --git a/OrthancServer/Internals/MoveScp.cpp b/Core/DicomNetworking/Internals/MoveScp.cpp
similarity index 96%
rename from OrthancServer/Internals/MoveScp.cpp
rename to Core/DicomNetworking/Internals/MoveScp.cpp
index 5578f88..2d0c80c 100644
--- a/OrthancServer/Internals/MoveScp.cpp
+++ b/Core/DicomNetworking/Internals/MoveScp.cpp
@@ -80,16 +80,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=========================================================================*/
-#include "../PrecompiledHeadersServer.h"
+#include "../../PrecompiledHeaders.h"
#include "MoveScp.h"
#include <memory>
-#include "../FromDcmtkBridge.h"
-#include "../ToDcmtkBridge.h"
-#include "../OrthancInitialization.h"
-#include "../../Core/Logging.h"
-#include "../../Core/OrthancException.h"
+#include "../../DicomParsing/FromDcmtkBridge.h"
+#include "../../DicomParsing/ToDcmtkBridge.h"
+#include "../../Logging.h"
+#include "../../OrthancException.h"
#include <boost/lexical_cast.hpp>
@@ -169,7 +168,7 @@ namespace Orthanc
if (data.lastRequest_ == NULL)
{
DicomMap input;
- Configuration::ExtractDicomSummary(input, *requestIdentifiers);
+ FromDcmtkBridge::ExtractDicomSummary(input, *requestIdentifiers);
try
{
diff --git a/OrthancServer/Internals/MoveScp.h b/Core/DicomNetworking/Internals/MoveScp.h
similarity index 97%
rename from OrthancServer/Internals/MoveScp.h
rename to Core/DicomNetworking/Internals/MoveScp.h
index 0e4e103..8f9a016 100644
--- a/OrthancServer/Internals/MoveScp.h
+++ b/Core/DicomNetworking/Internals/MoveScp.h
@@ -33,7 +33,7 @@
#pragma once
-#include "../DicomProtocol/IMoveRequestHandler.h"
+#include "../IMoveRequestHandler.h"
#include <dcmtk/dcmnet/dimse.h>
diff --git a/OrthancServer/Internals/StoreScp.cpp b/Core/DicomNetworking/Internals/StoreScp.cpp
similarity index 95%
rename from OrthancServer/Internals/StoreScp.cpp
rename to Core/DicomNetworking/Internals/StoreScp.cpp
index 692765a..31880a4 100644
--- a/OrthancServer/Internals/StoreScp.cpp
+++ b/Core/DicomNetworking/Internals/StoreScp.cpp
@@ -80,15 +80,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=========================================================================*/
-#include "../PrecompiledHeadersServer.h"
+#include "../../PrecompiledHeaders.h"
#include "StoreScp.h"
-#include "../FromDcmtkBridge.h"
-#include "../ServerToolbox.h"
-#include "../ToDcmtkBridge.h"
-#include "../OrthancInitialization.h"
-#include "../../Core/OrthancException.h"
-#include "../../Core/Logging.h"
+#include "../../DicomParsing/FromDcmtkBridge.h"
+#include "../../DicomParsing/ToDcmtkBridge.h"
+#include "../../OrthancException.h"
+#include "../../Logging.h"
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcmetinf.h>
@@ -169,8 +167,10 @@ namespace Orthanc
try
{
- Configuration::ExtractDicomSummary(summary, **imageDataSet);
- Configuration::ExtractDicomAsJson(dicomJson, **imageDataSet);
+ std::set<DicomTag> ignoreTagLength;
+
+ FromDcmtkBridge::ExtractDicomSummary(summary, **imageDataSet);
+ FromDcmtkBridge::ExtractDicomAsJson(dicomJson, **imageDataSet, ignoreTagLength);
if (!FromDcmtkBridge::SaveToMemoryBuffer(buffer, **imageDataSet))
{
@@ -213,7 +213,7 @@ namespace Orthanc
if (e.GetErrorCode() == ErrorCode_InexistentTag)
{
- ServerToolbox::LogMissingRequiredTag(summary);
+ summary.LogMissingTagsForStore();
}
else
{
diff --git a/OrthancServer/Internals/StoreScp.h b/Core/DicomNetworking/Internals/StoreScp.h
similarity index 97%
rename from OrthancServer/Internals/StoreScp.h
rename to Core/DicomNetworking/Internals/StoreScp.h
index 6c28fb4..bf202ce 100644
--- a/OrthancServer/Internals/StoreScp.h
+++ b/Core/DicomNetworking/Internals/StoreScp.h
@@ -33,7 +33,7 @@
#pragma once
-#include "../DicomProtocol/IStoreRequestHandler.h"
+#include "../IStoreRequestHandler.h"
#include <dcmtk/dcmnet/dimse.h>
diff --git a/OrthancServer/DicomProtocol/RemoteModalityParameters.cpp b/Core/DicomNetworking/RemoteModalityParameters.cpp
similarity index 97%
rename from OrthancServer/DicomProtocol/RemoteModalityParameters.cpp
rename to Core/DicomNetworking/RemoteModalityParameters.cpp
index a99c643..72eb4bd 100644
--- a/OrthancServer/DicomProtocol/RemoteModalityParameters.cpp
+++ b/Core/DicomNetworking/RemoteModalityParameters.cpp
@@ -31,11 +31,11 @@
**/
-#include "../PrecompiledHeadersServer.h"
+#include "../PrecompiledHeaders.h"
#include "RemoteModalityParameters.h"
-#include "../../Core/Logging.h"
-#include "../../Core/OrthancException.h"
+#include "../Logging.h"
+#include "../OrthancException.h"
#include <boost/lexical_cast.hpp>
#include <stdexcept>
diff --git a/OrthancServer/DicomProtocol/RemoteModalityParameters.h b/Core/DicomNetworking/RemoteModalityParameters.h
similarity index 98%
rename from OrthancServer/DicomProtocol/RemoteModalityParameters.h
rename to Core/DicomNetworking/RemoteModalityParameters.h
index 7b382ee..7141f44 100644
--- a/OrthancServer/DicomProtocol/RemoteModalityParameters.h
+++ b/Core/DicomNetworking/RemoteModalityParameters.h
@@ -33,7 +33,7 @@
#pragma once
-#include "../ServerEnumerations.h"
+#include "../Enumerations.h"
#include <stdint.h>
#include <string>
diff --git a/OrthancServer/DicomProtocol/ReusableDicomUserConnection.cpp b/Core/DicomNetworking/ReusableDicomUserConnection.cpp
similarity index 97%
rename from OrthancServer/DicomProtocol/ReusableDicomUserConnection.cpp
rename to Core/DicomNetworking/ReusableDicomUserConnection.cpp
index 65f84a6..e200a75 100644
--- a/OrthancServer/DicomProtocol/ReusableDicomUserConnection.cpp
+++ b/Core/DicomNetworking/ReusableDicomUserConnection.cpp
@@ -31,11 +31,11 @@
**/
-#include "../PrecompiledHeadersServer.h"
+#include "../PrecompiledHeaders.h"
#include "ReusableDicomUserConnection.h"
-#include "../../Core/Logging.h"
-#include "../../Core/OrthancException.h"
+#include "../Logging.h"
+#include "../OrthancException.h"
namespace Orthanc
{
diff --git a/OrthancServer/DicomProtocol/ReusableDicomUserConnection.h b/Core/DicomNetworking/ReusableDicomUserConnection.h
similarity index 100%
rename from OrthancServer/DicomProtocol/ReusableDicomUserConnection.h
rename to Core/DicomNetworking/ReusableDicomUserConnection.h
diff --git a/OrthancServer/DicomDirWriter.cpp b/Core/DicomParsing/DicomDirWriter.cpp
similarity index 89%
rename from OrthancServer/DicomDirWriter.cpp
rename to Core/DicomParsing/DicomDirWriter.cpp
index f7975ee..174cac3 100644
--- a/OrthancServer/DicomDirWriter.cpp
+++ b/Core/DicomParsing/DicomDirWriter.cpp
@@ -98,17 +98,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***/
-#include "PrecompiledHeadersServer.h"
+#include "../PrecompiledHeaders.h"
#include "DicomDirWriter.h"
#include "FromDcmtkBridge.h"
#include "ToDcmtkBridge.h"
-#include "../Core/Logging.h"
-#include "../Core/OrthancException.h"
-#include "../Core/TemporaryFile.h"
-#include "../Core/Toolbox.h"
-#include "../Core/SystemToolbox.h"
+#include "../Logging.h"
+#include "../OrthancException.h"
+#include "../TemporaryFile.h"
+#include "../Toolbox.h"
+#include "../SystemToolbox.h"
#include <dcmtk/dcmdata/dcdicdir.h>
#include <dcmtk/dcmdata/dcmetinf.h>
@@ -128,8 +128,9 @@ namespace Orthanc
class DicomDirWriter::PImpl
{
private:
- std::string fileSetId_;
- TemporaryFile file_;
+ std::string fileSetId_;
+ bool extendedSopClass_;
+ TemporaryFile file_;
std::auto_ptr<DcmDicomDir> dir_;
typedef std::pair<ResourceType, std::string> IndexKey;
@@ -211,6 +212,13 @@ namespace Orthanc
std::string value;
bool found = GetUtf8TagValue(value, source, encoding, key);
+ if (!found)
+ {
+ // We don't raise an exception if "!optional", even if this
+ // results in an invalid DICOM file
+ value.clear();
+ }
+
SetTagValue(target, key, value);
return found;
}
@@ -240,12 +248,38 @@ namespace Orthanc
CopyString(target, source, encoding, key, false, true);
}
+ static void CopyStringType3(DcmDirectoryRecord& target,
+ DcmDataset& source,
+ Encoding encoding,
+ const DcmTagKey& key)
+ {
+ CopyString(target, source, encoding, key, true, true);
+ }
+
public:
- PImpl() : fileSetId_("ORTHANC_MEDIA")
+ PImpl() :
+ fileSetId_("ORTHANC_MEDIA"),
+ extendedSopClass_(false)
{
}
+ void EnableExtendedSopClass(bool enable)
+ {
+ if (enable)
+ {
+ LOG(WARNING) << "Generating a DICOMDIR with type 3 attributes, "
+ << "which leads to an Extended SOP Class";
+ }
+
+ extendedSopClass_ = enable;
+ }
+
+ bool IsExtendedSopClass() const
+ {
+ return extendedSopClass_;
+ }
+
void FillPatient(DcmDirectoryRecord& record,
DcmDataset& dicom,
Encoding encoding)
@@ -304,6 +338,14 @@ namespace Orthanc
CopyStringType1(record, dicom, encoding, DCM_SeriesInstanceUID);
/* use type 1C instead of 1 in order to avoid unwanted overwriting */
CopyStringType1C(record, dicom, encoding, DCM_SeriesNumber);
+
+ // Add extended (non-standard) type 3 tags, those are not generated by DCMTK
+ // http://dicom.nema.org/medical/Dicom/2016a/output/chtml/part02/sect_7.3.html
+ // https://groups.google.com/d/msg/orthanc-users/Y7LOvZMDeoc/9cp3kDgxAwAJ
+ if (extendedSopClass_)
+ {
+ CopyStringType3(record, dicom, encoding, DCM_SeriesDescription);
+ }
}
void FillInstance(DcmDirectoryRecord& record,
@@ -507,4 +549,16 @@ namespace Orthanc
{
pimpl_->Read(target);
}
+
+
+ void DicomDirWriter::EnableExtendedSopClass(bool enable)
+ {
+ pimpl_->EnableExtendedSopClass(enable);
+ }
+
+
+ bool DicomDirWriter::IsExtendedSopClass() const
+ {
+ return pimpl_->IsExtendedSopClass();
+ }
}
diff --git a/OrthancServer/DicomDirWriter.h b/Core/DicomParsing/DicomDirWriter.h
similarity index 96%
rename from OrthancServer/DicomDirWriter.h
rename to Core/DicomParsing/DicomDirWriter.h
index 0e09353..b2bcbc6 100644
--- a/OrthancServer/DicomDirWriter.h
+++ b/Core/DicomParsing/DicomDirWriter.h
@@ -57,6 +57,10 @@ namespace Orthanc
ParsedDicomFile& dicom);
void Encode(std::string& target);
+
+ void EnableExtendedSopClass(bool enable);
+
+ bool IsExtendedSopClass() const;
};
}
diff --git a/OrthancServer/DicomModification.cpp b/Core/DicomParsing/DicomModification.cpp
similarity index 99%
rename from OrthancServer/DicomModification.cpp
rename to Core/DicomParsing/DicomModification.cpp
index dc15d97..d7ad0cc 100644
--- a/OrthancServer/DicomModification.cpp
+++ b/Core/DicomParsing/DicomModification.cpp
@@ -31,11 +31,11 @@
**/
-#include "PrecompiledHeadersServer.h"
+#include "../PrecompiledHeaders.h"
#include "DicomModification.h"
-#include "../Core/Logging.h"
-#include "../Core/OrthancException.h"
+#include "../Logging.h"
+#include "../OrthancException.h"
#include "FromDcmtkBridge.h"
#include <memory> // For std::auto_ptr
diff --git a/OrthancServer/DicomModification.h b/Core/DicomParsing/DicomModification.h
similarity index 100%
rename from OrthancServer/DicomModification.h
rename to Core/DicomParsing/DicomModification.h
diff --git a/OrthancServer/FromDcmtkBridge.cpp b/Core/DicomParsing/FromDcmtkBridge.cpp
similarity index 94%
rename from OrthancServer/FromDcmtkBridge.cpp
rename to Core/DicomParsing/FromDcmtkBridge.cpp
index b81362b..923d071 100644
--- a/OrthancServer/FromDcmtkBridge.cpp
+++ b/Core/DicomParsing/FromDcmtkBridge.cpp
@@ -31,7 +31,7 @@
**/
-#include "PrecompiledHeadersServer.h"
+#include "../PrecompiledHeaders.h"
#ifndef NOMINMAX
#define NOMINMAX
@@ -39,11 +39,11 @@
#include "FromDcmtkBridge.h"
#include "ToDcmtkBridge.h"
-#include "../Core/Logging.h"
-#include "../Core/SystemToolbox.h"
-#include "../Core/Toolbox.h"
-#include "../Core/TemporaryFile.h"
-#include "../Core/OrthancException.h"
+#include "../Logging.h"
+#include "../SystemToolbox.h"
+#include "../Toolbox.h"
+#include "../TemporaryFile.h"
+#include "../OrthancException.h"
#include <list>
#include <limits>
@@ -84,9 +84,16 @@
#include <dcmtk/dcmdata/dcvrus.h>
#include <dcmtk/dcmdata/dcvrut.h>
-
#if DCMTK_USE_EMBEDDED_DICTIONARIES == 1
-#include <EmbeddedResources.h>
+# include <EmbeddedResources.h>
+#endif
+
+#if ORTHANC_ENABLE_DCMTK_JPEG == 1
+# include <dcmtk/dcmjpeg/djdecode.h>
+#endif
+
+#if ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS == 1
+# include <dcmtk/dcmjpls/djdecode.h>
#endif
@@ -209,7 +216,7 @@ namespace Orthanc
LOG(INFO) << "The dictionary of private tags has not been loaded";
}
-#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
+#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__)
std::string path = DCMTK_DICTIONARY_DIR;
const char* env = std::getenv(DCM_DICT_ENVIRONMENT_VARIABLE);
@@ -388,6 +395,8 @@ namespace Orthanc
unsigned int maxStringLength,
Encoding defaultEncoding)
{
+ std::set<DicomTag> ignoreTagLength;
+
Encoding encoding = DetectEncoding(dataset, defaultEncoding);
target.Clear();
@@ -398,7 +407,8 @@ namespace Orthanc
{
target.SetValue(element->getTag().getGTag(),
element->getTag().getETag(),
- ConvertLeafElement(*element, DicomToJsonFlags_Default, maxStringLength, encoding));
+ ConvertLeafElement(*element, DicomToJsonFlags_Default,
+ maxStringLength, encoding, ignoreTagLength));
}
}
}
@@ -419,7 +429,8 @@ namespace Orthanc
DicomValue* FromDcmtkBridge::ConvertLeafElement(DcmElement& element,
DicomToJsonFlags flags,
unsigned int maxStringLength,
- Encoding encoding)
+ Encoding encoding,
+ const std::set<DicomTag>& ignoreTagLength)
{
if (!element.isLeaf())
{
@@ -441,7 +452,8 @@ namespace Orthanc
std::string utf8 = Toolbox::ConvertToUtf8(s, encoding);
if (maxStringLength != 0 &&
- utf8.size() > maxStringLength)
+ utf8.size() > maxStringLength &&
+ ignoreTagLength.find(GetTag(element)) == ignoreTagLength.end())
{
return new DicomValue; // Too long, create a NULL value
}
@@ -479,7 +491,8 @@ namespace Orthanc
return new DicomValue("", false); // Empty string
}
else if (maxStringLength != 0 &&
- element.getLength() > maxStringLength)
+ element.getLength() > maxStringLength &&
+ ignoreTagLength.find(GetTag(element)) == ignoreTagLength.end())
{
return new DicomValue; // Too long, create a NULL value
}
@@ -492,7 +505,7 @@ namespace Orthanc
}
}
-
+
try
{
// http://support.dcmtk.org/docs/dcvr_8h-source.html
@@ -807,7 +820,8 @@ namespace Orthanc
DicomToJsonFormat format,
DicomToJsonFlags flags,
unsigned int maxStringLength,
- Encoding encoding)
+ Encoding encoding,
+ const std::set<DicomTag>& ignoreTagLength)
{
if (parent.type() == Json::nullValue)
{
@@ -820,8 +834,17 @@ namespace Orthanc
if (element.isLeaf())
{
// The "0" below lets "LeafValueToJson()" take care of "TooLong" values
- std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(element, flags, 0, encoding));
- LeafValueToJson(target, *v, format, flags, maxStringLength);
+ std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement
+ (element, flags, 0, encoding, ignoreTagLength));
+
+ if (ignoreTagLength.find(GetTag(element)) == ignoreTagLength.end())
+ {
+ LeafValueToJson(target, *v, format, flags, maxStringLength);
+ }
+ else
+ {
+ LeafValueToJson(target, *v, format, flags, 0);
+ }
}
else
{
@@ -837,7 +860,7 @@ namespace Orthanc
{
DcmItem* child = sequence.getItem(i);
Json::Value& v = target.append(Json::objectValue);
- DatasetToJson(v, *child, format, flags, maxStringLength, encoding);
+ DatasetToJson(v, *child, format, flags, maxStringLength, encoding, ignoreTagLength);
}
}
}
@@ -848,7 +871,8 @@ namespace Orthanc
DicomToJsonFormat format,
DicomToJsonFlags flags,
unsigned int maxStringLength,
- Encoding encoding)
+ Encoding encoding,
+ const std::set<DicomTag>& ignoreTagLength)
{
assert(parent.type() == Json::objectValue);
@@ -893,7 +917,8 @@ namespace Orthanc
}
}
- FromDcmtkBridge::ElementToJson(parent, *element, format, flags, maxStringLength, encoding);
+ FromDcmtkBridge::ElementToJson(parent, *element, format, flags,
+ maxStringLength, encoding, ignoreTagLength);
}
}
@@ -903,12 +928,13 @@ namespace Orthanc
DicomToJsonFormat format,
DicomToJsonFlags flags,
unsigned int maxStringLength,
- Encoding defaultEncoding)
+ Encoding defaultEncoding,
+ const std::set<DicomTag>& ignoreTagLength)
{
Encoding encoding = DetectEncoding(dataset, defaultEncoding);
target = Json::objectValue;
- DatasetToJson(target, dataset, format, flags, maxStringLength, encoding);
+ DatasetToJson(target, dataset, format, flags, maxStringLength, encoding, ignoreTagLength);
}
@@ -918,8 +944,9 @@ namespace Orthanc
DicomToJsonFlags flags,
unsigned int maxStringLength)
{
+ std::set<DicomTag> ignoreTagLength;
target = Json::objectValue;
- DatasetToJson(target, dataset, format, flags, maxStringLength, Encoding_Ascii);
+ DatasetToJson(target, dataset, format, flags, maxStringLength, Encoding_Ascii, ignoreTagLength);
}
@@ -1879,6 +1906,7 @@ namespace Orthanc
result->transferInit();
if (!result->read(is).good())
{
+ LOG(ERROR) << "Cannot parse an invalid DICOM file (size: " << size << " bytes)";
throw OrthancException(ErrorCode_BadFileFormat);
}
@@ -2017,4 +2045,54 @@ namespace Orthanc
}
}
#endif
+
+
+ void FromDcmtkBridge::ExtractDicomSummary(DicomMap& target,
+ DcmItem& dataset)
+ {
+ ExtractDicomSummary(target, dataset,
+ ORTHANC_MAXIMUM_TAG_LENGTH,
+ GetDefaultDicomEncoding());
+ }
+
+
+ void FromDcmtkBridge::ExtractDicomAsJson(Json::Value& target,
+ DcmDataset& dataset,
+ const std::set<DicomTag>& ignoreTagLength)
+ {
+ ExtractDicomAsJson(target, dataset,
+ DicomToJsonFormat_Full,
+ DicomToJsonFlags_Default,
+ ORTHANC_MAXIMUM_TAG_LENGTH,
+ GetDefaultDicomEncoding(),
+ ignoreTagLength);
+ }
+
+
+ void FromDcmtkBridge::InitializeCodecs()
+ {
+#if ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS == 1
+ LOG(WARNING) << "Registering JPEG Lossless codecs in DCMTK";
+ DJLSDecoderRegistration::registerCodecs();
+#endif
+
+#if ORTHANC_ENABLE_DCMTK_JPEG == 1
+ LOG(WARNING) << "Registering JPEG codecs in DCMTK";
+ DJDecoderRegistration::registerCodecs();
+#endif
+ }
+
+
+ void FromDcmtkBridge::FinalizeCodecs()
+ {
+#if ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS == 1
+ // Unregister JPEG-LS codecs
+ DJLSDecoderRegistration::cleanup();
+#endif
+
+#if ORTHANC_ENABLE_DCMTK_JPEG == 1
+ // Unregister JPEG codecs
+ DJDecoderRegistration::cleanup();
+#endif
+ }
}
diff --git a/OrthancServer/FromDcmtkBridge.h b/Core/DicomParsing/FromDcmtkBridge.h
similarity index 85%
rename from OrthancServer/FromDcmtkBridge.h
rename to Core/DicomParsing/FromDcmtkBridge.h
index 9a05d5f..72624eb 100644
--- a/OrthancServer/FromDcmtkBridge.h
+++ b/Core/DicomParsing/FromDcmtkBridge.h
@@ -33,10 +33,8 @@
#pragma once
-#include "ServerEnumerations.h"
-
-#include "../Core/DicomFormat/DicomElement.h"
-#include "../Core/DicomFormat/DicomMap.h"
+#include "../DicomFormat/DicomElement.h"
+#include "../DicomFormat/DicomMap.h"
#include <dcmtk/dcmdata/dcdatset.h>
#include <dcmtk/dcmdata/dcmetinf.h>
@@ -44,20 +42,28 @@
#include <dcmtk/dcmdata/dcfilefo.h>
#include <json/json.h>
-#if !defined(ORTHANC_BUILD_UNIT_TESTS)
-# error The macro ORTHANC_BUILD_UNIT_TESTS must be defined
-#endif
-
#if !defined(ORTHANC_ENABLE_LUA)
# error The macro ORTHANC_ENABLE_LUA must be defined
#endif
+#if ORTHANC_ENABLE_DCMTK != 1
+# error The macro ORTHANC_ENABLE_DCMTK must be set to 1
+#endif
+
#if ORTHANC_BUILD_UNIT_TESTS == 1
# include <gtest/gtest_prod.h>
#endif
#if ORTHANC_ENABLE_LUA == 1
-# include "../Core/Lua/LuaFunctionCall.h"
+# include "../Lua/LuaFunctionCall.h"
+#endif
+
+#if !defined(ORTHANC_ENABLE_DCMTK_JPEG)
+# error The macro ORTHANC_ENABLE_DCMTK_JPEG must be defined
+#endif
+
+#if !defined(ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS)
+# error The macro ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS must be defined
#endif
@@ -70,7 +76,6 @@ namespace Orthanc
#endif
friend class ParsedDicomFile;
- friend class Configuration;
private:
FromDcmtkBridge(); // Pure static class
@@ -85,21 +90,24 @@ namespace Orthanc
DicomToJsonFormat format,
DicomToJsonFlags flags,
unsigned int maxStringLength,
- Encoding encoding);
+ Encoding encoding,
+ const std::set<DicomTag>& ignoreTagLength);
static void ElementToJson(Json::Value& parent,
DcmElement& element,
DicomToJsonFormat format,
DicomToJsonFlags flags,
unsigned int maxStringLength,
- Encoding dicomEncoding);
+ Encoding dicomEncoding,
+ const std::set<DicomTag>& ignoreTagLength);
static void ExtractDicomAsJson(Json::Value& target,
DcmDataset& dataset,
DicomToJsonFormat format,
DicomToJsonFlags flags,
unsigned int maxStringLength,
- Encoding defaultEncoding);
+ Encoding defaultEncoding,
+ const std::set<DicomTag>& ignoreTagLength);
static void ChangeStringEncoding(DcmItem& dataset,
Encoding source,
@@ -127,7 +135,8 @@ namespace Orthanc
static DicomValue* ConvertLeafElement(DcmElement& element,
DicomToJsonFlags flags,
unsigned int maxStringLength,
- Encoding encoding);
+ Encoding encoding,
+ const std::set<DicomTag>& ignoreTagLength);
static void ExtractHeaderAsJson(Json::Value& target,
DcmMetaInfo& header,
@@ -220,5 +229,16 @@ namespace Orthanc
static void ExecuteToDicom(DicomMap& target,
LuaFunctionCall& call);
#endif
+
+ static void ExtractDicomSummary(DicomMap& target,
+ DcmItem& dataset);
+
+ static void ExtractDicomAsJson(Json::Value& target,
+ DcmDataset& dataset,
+ const std::set<DicomTag>& ignoreTagLength);
+
+ static void InitializeCodecs();
+
+ static void FinalizeCodecs();
};
}
diff --git a/OrthancServer/Internals/DicomFrameIndex.cpp b/Core/DicomParsing/Internals/DicomFrameIndex.cpp
similarity index 97%
rename from OrthancServer/Internals/DicomFrameIndex.cpp
rename to Core/DicomParsing/Internals/DicomFrameIndex.cpp
index 67c9406..94079c2 100644
--- a/OrthancServer/Internals/DicomFrameIndex.cpp
+++ b/Core/DicomParsing/Internals/DicomFrameIndex.cpp
@@ -31,14 +31,13 @@
**/
-#include "../PrecompiledHeadersServer.h"
+#include "../../PrecompiledHeaders.h"
#include "DicomFrameIndex.h"
-#include "../../Core/OrthancException.h"
-#include "../../Core/DicomFormat/DicomImageInformation.h"
+#include "../../OrthancException.h"
+#include "../../DicomFormat/DicomImageInformation.h"
#include "../FromDcmtkBridge.h"
-#include "../OrthancInitialization.h"
-#include "../../Core/Endianness.h"
+#include "../../Endianness.h"
#include "DicomImageDecoder.h"
#include <boost/lexical_cast.hpp>
@@ -405,7 +404,7 @@ namespace Orthanc
// Extract information about the image structure
DicomMap tags;
- Configuration::ExtractDicomSummary(tags, dataset);
+ FromDcmtkBridge::ExtractDicomSummary(tags, dataset);
DicomImageInformation information(tags);
diff --git a/OrthancServer/Internals/DicomFrameIndex.h b/Core/DicomParsing/Internals/DicomFrameIndex.h
similarity index 98%
rename from OrthancServer/Internals/DicomFrameIndex.h
rename to Core/DicomParsing/Internals/DicomFrameIndex.h
index 52a1819..603b154 100644
--- a/OrthancServer/Internals/DicomFrameIndex.h
+++ b/Core/DicomParsing/Internals/DicomFrameIndex.h
@@ -33,6 +33,8 @@
#pragma once
+#include "../../Enumerations.h"
+
#include <dcmtk/dcmdata/dcdatset.h>
#include <dcmtk/dcmdata/dcfilefo.h>
#include <vector>
diff --git a/OrthancServer/Internals/DicomImageDecoder.cpp b/Core/DicomParsing/Internals/DicomImageDecoder.cpp
similarity index 75%
rename from OrthancServer/Internals/DicomImageDecoder.cpp
rename to Core/DicomParsing/Internals/DicomImageDecoder.cpp
index a20f0ef..fa73ffd 100644
--- a/OrthancServer/Internals/DicomImageDecoder.cpp
+++ b/Core/DicomParsing/Internals/DicomImageDecoder.cpp
@@ -31,7 +31,7 @@
**/
-#include "../PrecompiledHeadersServer.h"
+#include "../../PrecompiledHeaders.h"
#include "DicomImageDecoder.h"
@@ -77,31 +77,39 @@
=========================================================================*/
-#include "../../Core/Logging.h"
-#include "../../Core/OrthancException.h"
-#include "../../Core/Images/Image.h"
-#include "../../Core/Images/ImageProcessing.h"
-#include "../../Core/Images/PngWriter.h"
-#include "../../Core/Images/JpegWriter.h"
-#include "../../Core/DicomFormat/DicomIntegerPixelAccessor.h"
+#include "../../Logging.h"
+#include "../../OrthancException.h"
+#include "../../Images/Image.h"
+#include "../../Images/ImageProcessing.h"
+#include "../../DicomFormat/DicomIntegerPixelAccessor.h"
#include "../ToDcmtkBridge.h"
#include "../FromDcmtkBridge.h"
#include "../ParsedDicomFile.h"
-#include "../OrthancInitialization.h"
+
+#if ORTHANC_ENABLE_PNG == 1
+# include "../../Images/PngWriter.h"
+#endif
+
+#if ORTHANC_ENABLE_JPEG == 1
+# include "../../Images/JpegWriter.h"
+#endif
#include <boost/lexical_cast.hpp>
+#include <dcmtk/dcmdata/dcdeftag.h>
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcrleccd.h>
#include <dcmtk/dcmdata/dcrlecp.h>
+#include <dcmtk/dcmdata/dcrlerp.h>
-#if ORTHANC_ENABLE_JPEG_LOSSLESS == 1
+#if ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS == 1
+# include <dcmtk/dcmjpeg/djrplol.h>
# include <dcmtk/dcmjpls/djcodecd.h>
# include <dcmtk/dcmjpls/djcparam.h>
-# include <dcmtk/dcmjpeg/djrplol.h>
+# include <dcmtk/dcmjpls/djrparam.h>
#endif
-#if ORTHANC_ENABLE_JPEG == 1
+#if ORTHANC_ENABLE_DCMTK_JPEG == 1
# include <dcmtk/dcmjpeg/djcodecd.h>
# include <dcmtk/dcmjpeg/djcparam.h>
# include <dcmtk/dcmjpeg/djdecbas.h>
@@ -110,6 +118,7 @@
# include <dcmtk/dcmjpeg/djdecpro.h>
# include <dcmtk/dcmjpeg/djdecsps.h>
# include <dcmtk/dcmjpeg/djdecsv1.h>
+# include <dcmtk/dcmjpeg/djrploss.h>
#endif
#if DCMTK_VERSION_NUMBER <= 360
@@ -251,7 +260,7 @@ namespace Orthanc
// See also: http://support.dcmtk.org/wiki/dcmtk/howto/accessing-compressed-data
DicomMap m;
- Configuration::ExtractDicomSummary(m, dataset);
+ FromDcmtkBridge::ExtractDicomSummary(m, dataset);
/**
* Create an accessor to the raw values of the DICOM image.
@@ -323,7 +332,7 @@ namespace Orthanc
bool ignorePhotometricInterpretation)
{
DicomMap m;
- Configuration::ExtractDicomSummary(m, dataset);
+ FromDcmtkBridge::ExtractDicomSummary(m, dataset);
DicomImageInformation info(m);
PixelFormat format;
@@ -376,33 +385,155 @@ namespace Orthanc
}
- ImageAccessor* DicomImageDecoder::DecodeUncompressedImage(DcmDataset& dataset,
- unsigned int frame)
+ static ImageAccessor* DecodeLookupTable(std::auto_ptr<ImageAccessor>& target,
+ const DicomImageInformation& info,
+ DcmDataset& dataset,
+ const uint8_t* pixelData,
+ unsigned long pixelLength)
{
- ImageSource source;
- source.Setup(dataset, frame);
+ LOG(INFO) << "Decoding a lookup table";
+
+ OFString r, g, b;
+ PixelFormat format;
+ const uint16_t* lutRed = NULL;
+ const uint16_t* lutGreen = NULL;
+ const uint16_t* lutBlue = NULL;
+ unsigned long rc = 0;
+ unsigned long gc = 0;
+ unsigned long bc = 0;
+
+ if (pixelData == NULL &&
+ !dataset.findAndGetUint8Array(DCM_PixelData, pixelData, &pixelLength).good())
+ {
+ throw OrthancException(ErrorCode_NotImplemented);
+ }
+
+ if (info.IsPlanar() ||
+ info.GetNumberOfFrames() != 1 ||
+ !info.ExtractPixelFormat(format, false) ||
+ !dataset.findAndGetOFStringArray(DCM_BluePaletteColorLookupTableDescriptor, b).good() ||
+ !dataset.findAndGetOFStringArray(DCM_GreenPaletteColorLookupTableDescriptor, g).good() ||
+ !dataset.findAndGetOFStringArray(DCM_RedPaletteColorLookupTableDescriptor, r).good() ||
+ !dataset.findAndGetUint16Array(DCM_BluePaletteColorLookupTableData, lutBlue, &bc).good() ||
+ !dataset.findAndGetUint16Array(DCM_GreenPaletteColorLookupTableData, lutGreen, &gc).good() ||
+ !dataset.findAndGetUint16Array(DCM_RedPaletteColorLookupTableData, lutRed, &rc).good() ||
+ r != g ||
+ r != b ||
+ g != b ||
+ lutRed == NULL ||
+ lutGreen == NULL ||
+ lutBlue == NULL ||
+ pixelData == NULL)
+ {
+ throw OrthancException(ErrorCode_NotImplemented);
+ }
+
+ switch (format)
+ {
+ case PixelFormat_RGB24:
+ {
+ if (r != "256\\0\\16" ||
+ rc != 256 ||
+ gc != 256 ||
+ bc != 256 ||
+ pixelLength != target->GetWidth() * target->GetHeight())
+ {
+ throw OrthancException(ErrorCode_NotImplemented);
+ }
+
+ const uint8_t* source = reinterpret_cast<const uint8_t*>(pixelData);
+
+ for (unsigned int y = 0; y < target->GetHeight(); y++)
+ {
+ uint8_t* p = reinterpret_cast<uint8_t*>(target->GetRow(y));
+
+ for (unsigned int x = 0; x < target->GetWidth(); x++)
+ {
+ p[0] = lutRed[*source] >> 8;
+ p[1] = lutGreen[*source] >> 8;
+ p[2] = lutBlue[*source] >> 8;
+ source++;
+ p += 3;
+ }
+ }
+
+ return target.release();
+ }
+
+ case PixelFormat_RGB48:
+ {
+ if (r != "0\\0\\16" ||
+ rc != 65536 ||
+ gc != 65536 ||
+ bc != 65536 ||
+ pixelLength != 2 * target->GetWidth() * target->GetHeight())
+ {
+ throw OrthancException(ErrorCode_NotImplemented);
+ }
+
+ const uint16_t* source = reinterpret_cast<const uint16_t*>(pixelData);
+
+ for (unsigned int y = 0; y < target->GetHeight(); y++)
+ {
+ uint16_t* p = reinterpret_cast<uint16_t*>(target->GetRow(y));
+
+ for (unsigned int x = 0; x < target->GetWidth(); x++)
+ {
+ p[0] = lutRed[*source];
+ p[1] = lutGreen[*source];
+ p[2] = lutBlue[*source];
+ source++;
+ p += 3;
+ }
+ }
+
+ return target.release();
+ }
+
+ default:
+ break;
+ }
+
+ throw OrthancException(ErrorCode_InternalError);
+ }
+ ImageAccessor* DicomImageDecoder::DecodeUncompressedImage(DcmDataset& dataset,
+ unsigned int frame)
+ {
/**
- * Resize the target image.
+ * Create the target image.
**/
std::auto_ptr<ImageAccessor> target(CreateImage(dataset, false));
+ ImageSource source;
+ source.Setup(dataset, frame);
+
if (source.GetWidth() != target->GetWidth() ||
source.GetHeight() != target->GetHeight())
{
throw OrthancException(ErrorCode_InternalError);
}
+
+ /**
+ * Deal with lookup tables
+ **/
+
+ const DicomImageInformation& info = source.GetAccessor().GetInformation();
+
+ if (info.GetPhotometricInterpretation() == PhotometricInterpretation_Palette)
+ {
+ return DecodeLookupTable(target, info, dataset, NULL, 0);
+ }
+
/**
* If the format of the DICOM buffer is natively supported, use a
* direct access to copy its values.
**/
- const DicomImageInformation& info = source.GetAccessor().GetInformation();
-
bool fastVersionSuccess = false;
PixelFormat sourceFormat;
if (!info.IsPlanar() &&
@@ -465,10 +596,12 @@ namespace Orthanc
}
- ImageAccessor* DicomImageDecoder::ApplyCodec(const DcmCodec& codec,
- const DcmCodecParameter& parameters,
- DcmDataset& dataset,
- unsigned int frame)
+ ImageAccessor* DicomImageDecoder::ApplyCodec
+ (const DcmCodec& codec,
+ const DcmCodecParameter& parameters,
+ const DcmRepresentationParameter& representationParameter,
+ DcmDataset& dataset,
+ unsigned int frame)
{
DcmPixelSequence* pixelSequence = FromDcmtkBridge::GetPixelSequence(dataset);
if (pixelSequence == NULL)
@@ -476,24 +609,49 @@ namespace Orthanc
throw OrthancException(ErrorCode_BadFileFormat);
}
+ DicomMap m;
+ FromDcmtkBridge::ExtractDicomSummary(m, dataset);
+ DicomImageInformation info(m);
+
std::auto_ptr<ImageAccessor> target(CreateImage(dataset, true));
Uint32 startFragment = 0; // Default
OFString decompressedColorModel; // Out
- DJ_RPLossless representationParameter;
- OFCondition c = codec.decodeFrame(&representationParameter,
- pixelSequence, ¶meters,
- &dataset, frame, startFragment, target->GetBuffer(),
- target->GetSize(), decompressedColorModel);
- if (c.good())
+ OFCondition c;
+
+ if (info.GetPhotometricInterpretation() == PhotometricInterpretation_Palette &&
+ info.GetChannelCount() == 1)
{
- return target.release();
+ std::string uncompressed;
+ uncompressed.resize(info.GetWidth() * info.GetHeight() * info.GetBytesPerValue());
+
+ if (uncompressed.size() == 0 ||
+ !codec.decodeFrame(&representationParameter,
+ pixelSequence, ¶meters,
+ &dataset, frame, startFragment, &uncompressed[0],
+ uncompressed.size(), decompressedColorModel).good())
+ {
+ LOG(ERROR) << "Cannot decode a palette image";
+ throw OrthancException(ErrorCode_BadFileFormat);
+ }
+
+ return DecodeLookupTable(target, info, dataset,
+ reinterpret_cast<const uint8_t*>(uncompressed.c_str()),
+ uncompressed.size());
}
else
{
- LOG(ERROR) << "Cannot decode an image";
- throw OrthancException(ErrorCode_BadFileFormat);
+ if (!codec.decodeFrame(&representationParameter,
+ pixelSequence, ¶meters,
+ &dataset, frame, startFragment, target->GetBuffer(),
+ target->GetSize(), decompressedColorModel).good())
+ {
+ LOG(ERROR) << "Cannot decode a non-palette image";
+ throw OrthancException(ErrorCode_BadFileFormat);
+ }
+
+ return target.release();
}
}
@@ -518,7 +676,7 @@ namespace Orthanc
}
-#if ORTHANC_ENABLE_JPEG_LOSSLESS == 1
+#if ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS == 1
/**
* Deal with JPEG-LS images.
**/
@@ -526,6 +684,10 @@ namespace Orthanc
if (syntax == EXS_JPEGLSLossless ||
syntax == EXS_JPEGLSLossy)
{
+ // The (2, OFTrue) are the default parameters as found in DCMTK 3.6.2
+ // http://support.dcmtk.org/docs/classDJLSRepresentationParameter.html
+ DJLSRepresentationParameter representationParameter(2, OFTrue);
+
DJLSCodecParameter parameters;
std::auto_ptr<DJLSDecoderBase> decoder;
@@ -545,12 +707,12 @@ namespace Orthanc
throw OrthancException(ErrorCode_InternalError);
}
- return ApplyCodec(*decoder, parameters, dataset, frame);
+ return ApplyCodec(*decoder, parameters, representationParameter, dataset, frame);
}
#endif
-#if ORTHANC_ENABLE_JPEG == 1
+#if ORTHANC_ENABLE_DCMTK_JPEG == 1
/**
* Deal with JPEG images.
**/
@@ -568,6 +730,7 @@ namespace Orthanc
EDC_photometricInterpretation, // Perform color space conversion from YCbCr to RGB if DICOM photometric interpretation indicates YCbCr
EUC_default, // Mode for UID creation, unused for decompression
EPC_default); // Automatically determine whether color-by-plane is required from the SOP Class UID and decompressed photometric interpretation
+ DJ_RPLossy representationParameter;
std::auto_ptr<DJCodecDecoder> decoder;
switch (syntax)
@@ -606,7 +769,7 @@ namespace Orthanc
throw OrthancException(ErrorCode_InternalError);
}
- return ApplyCodec(*decoder, parameters, dataset, frame);
+ return ApplyCodec(*decoder, parameters, representationParameter, dataset, frame);
}
#endif
@@ -616,7 +779,8 @@ namespace Orthanc
LOG(INFO) << "Decoding a RLE lossless DICOM image";
DcmRLECodecParameter parameters;
DcmRLECodecDecoder decoder;
- return ApplyCodec(decoder, parameters, dataset, frame);
+ DcmRLERepresentationParameter representationParameter;
+ return ApplyCodec(decoder, parameters, representationParameter, dataset, frame);
}
@@ -673,7 +837,8 @@ namespace Orthanc
if (image->GetFormat() != format)
{
// A conversion is required
- std::auto_ptr<ImageAccessor> target(new Image(format, image->GetWidth(), image->GetHeight(), false));
+ std::auto_ptr<ImageAccessor> target
+ (new Image(format, image->GetWidth(), image->GetHeight(), false));
ImageProcessing::Convert(*target, *image);
image = target;
}
@@ -692,13 +857,22 @@ namespace Orthanc
return true;
}
+ case PixelFormat_RGB48:
+ {
+ std::auto_ptr<ImageAccessor> target
+ (new Image(PixelFormat_RGB24, image->GetWidth(), image->GetHeight(), false));
+ ImageProcessing::Convert(*target, *image);
+ image = target;
+ return true;
+ }
+
case PixelFormat_Grayscale8:
case PixelFormat_Grayscale16:
case PixelFormat_SignedGrayscale16:
{
// Grayscale image: Stretch its dynamics to the [0,255] range
int64_t a, b;
- ImageProcessing::GetMinMaxValue(a, b, *image);
+ ImageProcessing::GetMinMaxIntegerValue(a, b, *image);
if (a == b)
{
@@ -706,13 +880,15 @@ namespace Orthanc
}
else
{
- ImageProcessing::ShiftScale(*image, static_cast<float>(-a), 255.0f / static_cast<float>(b - a));
+ ImageProcessing::ShiftScale(*image, static_cast<float>(-a),
+ 255.0f / static_cast<float>(b - a));
}
// If the source image is not grayscale 8bpp, convert it
if (image->GetFormat() != PixelFormat_Grayscale8)
{
- std::auto_ptr<ImageAccessor> target(new Image(PixelFormat_Grayscale8, image->GetWidth(), image->GetHeight(), false));
+ std::auto_ptr<ImageAccessor> target
+ (new Image(PixelFormat_Grayscale8, image->GetWidth(), image->GetHeight(), false));
ImageProcessing::Convert(*target, *image);
image = target;
}
@@ -775,6 +951,7 @@ namespace Orthanc
}
+#if ORTHANC_ENABLE_PNG == 1
void DicomImageDecoder::ExtractPngImage(std::string& result,
std::auto_ptr<ImageAccessor>& image,
ImageExtractionMode mode,
@@ -785,8 +962,10 @@ namespace Orthanc
PngWriter writer;
writer.WriteToMemory(result, *image);
}
+#endif
+#if ORTHANC_ENABLE_JPEG == 1
void DicomImageDecoder::ExtractJpegImage(std::string& result,
std::auto_ptr<ImageAccessor>& image,
ImageExtractionMode mode,
@@ -805,4 +984,5 @@ namespace Orthanc
writer.SetQuality(quality);
writer.WriteToMemory(result, *image);
}
+#endif
}
diff --git a/OrthancServer/Internals/DicomImageDecoder.h b/Core/DicomParsing/Internals/DicomImageDecoder.h
similarity index 87%
rename from OrthancServer/Internals/DicomImageDecoder.h
rename to Core/DicomParsing/Internals/DicomImageDecoder.h
index 5a791d0..f1beb28 100644
--- a/OrthancServer/Internals/DicomImageDecoder.h
+++ b/Core/DicomParsing/Internals/DicomImageDecoder.h
@@ -41,14 +41,23 @@
# error The macro ORTHANC_ENABLE_JPEG must be defined
#endif
-#if !defined(ORTHANC_ENABLE_JPEG_LOSSLESS)
-# error The macro ORTHANC_ENABLE_JPEG_LOSSLESS must be defined
+#if !defined(ORTHANC_ENABLE_PNG)
+# error The macro ORTHANC_ENABLE_PNG must be defined
+#endif
+
+#if !defined(ORTHANC_ENABLE_DCMTK_JPEG)
+# error The macro ORTHANC_ENABLE_DCMTK_JPEG must be defined
+#endif
+
+#if !defined(ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS)
+# error The macro ORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS must be defined
#endif
class DcmDataset;
class DcmCodec;
class DcmCodecParameter;
+class DcmRepresentationParameter;
namespace Orthanc
{
@@ -69,6 +78,7 @@ namespace Orthanc
static ImageAccessor* ApplyCodec(const DcmCodec& codec,
const DcmCodecParameter& parameters,
+ const DcmRepresentationParameter& representationParameter,
DcmDataset& dataset,
unsigned int frame);
@@ -91,15 +101,19 @@ namespace Orthanc
static ImageAccessor *Decode(ParsedDicomFile& dicom,
unsigned int frame);
+#if ORTHANC_ENABLE_PNG == 1
static void ExtractPngImage(std::string& result,
std::auto_ptr<ImageAccessor>& image,
ImageExtractionMode mode,
bool invert);
+#endif
+#if ORTHANC_ENABLE_JPEG == 1
static void ExtractJpegImage(std::string& result,
std::auto_ptr<ImageAccessor>& image,
ImageExtractionMode mode,
bool invert,
uint8_t quality);
+#endif
};
}
diff --git a/OrthancServer/ParsedDicomFile.cpp b/Core/DicomParsing/ParsedDicomFile.cpp
similarity index 93%
rename from OrthancServer/ParsedDicomFile.cpp
rename to Core/DicomParsing/ParsedDicomFile.cpp
index 158d12d..311d158 100644
--- a/OrthancServer/ParsedDicomFile.cpp
+++ b/Core/DicomParsing/ParsedDicomFile.cpp
@@ -73,7 +73,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=========================================================================*/
-#include "PrecompiledHeadersServer.h"
+#include "../PrecompiledHeaders.h"
#ifndef NOMINMAX
#define NOMINMAX
@@ -81,16 +81,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ParsedDicomFile.h"
-#include "OrthancInitialization.h"
-#include "ServerToolbox.h"
#include "FromDcmtkBridge.h"
#include "ToDcmtkBridge.h"
#include "Internals/DicomFrameIndex.h"
-#include "../Core/Images/JpegReader.h"
-#include "../Core/Images/PngReader.h"
-#include "../Core/Logging.h"
-#include "../Core/OrthancException.h"
-#include "../Core/Toolbox.h"
+#include "../Logging.h"
+#include "../OrthancException.h"
+#include "../Toolbox.h"
+#include "../SystemToolbox.h"
+
+#if ORTHANC_ENABLE_JPEG == 1
+# include "../Images/JpegReader.h"
+#endif
+
+#if ORTHANC_ENABLE_PNG == 1
+# include "../Images/PngReader.h"
+#endif
#include <list>
#include <limits>
@@ -141,9 +146,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
-static const char* CONTENT_TYPE_OCTET_STREAM = "application/octet-stream";
-
-
namespace Orthanc
{
@@ -154,6 +156,33 @@ namespace Orthanc
};
+#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
+ static const char* CONTENT_TYPE_OCTET_STREAM = "application/octet-stream";
+
+ static void ParseTagAndGroup(DcmTagKey& key,
+ const std::string& tag)
+ {
+ DicomTag t = FromDcmtkBridge::ParseTag(tag);
+ key = DcmTagKey(t.GetGroup(), t.GetElement());
+ }
+
+
+ static unsigned int GetPixelDataBlockCount(DcmPixelData& pixelData,
+ E_TransferSyntax transferSyntax)
+ {
+ DcmPixelSequence* pixelSequence = NULL;
+ if (pixelData.getEncapsulatedRepresentation
+ (transferSyntax, NULL, pixelSequence).good() && pixelSequence)
+ {
+ return pixelSequence->card();
+ }
+ else
+ {
+ return 1;
+ }
+ }
+
+
static void SendPathValueForDictionary(RestApiOutput& output,
DcmItem& dicom)
{
@@ -173,33 +202,6 @@ namespace Orthanc
output.AnswerJson(v);
}
- static inline uint16_t GetCharValue(char c)
- {
- if (c >= '0' && c <= '9')
- return c - '0';
- else if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- else if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- else
- return 0;
- }
-
- static inline uint16_t GetTagValue(const char* c)
- {
- return ((GetCharValue(c[0]) << 12) +
- (GetCharValue(c[1]) << 8) +
- (GetCharValue(c[2]) << 4) +
- GetCharValue(c[3]));
- }
-
- static void ParseTagAndGroup(DcmTagKey& key,
- const std::string& tag)
- {
- DicomTag t = FromDcmtkBridge::ParseTag(tag);
- key = DcmTagKey(t.GetGroup(), t.GetElement());
- }
-
static void SendSequence(RestApiOutput& output,
DcmSequenceOfItems& sequence)
@@ -216,22 +218,6 @@ namespace Orthanc
}
- static unsigned int GetPixelDataBlockCount(DcmPixelData& pixelData,
- E_TransferSyntax transferSyntax)
- {
- DcmPixelSequence* pixelSequence = NULL;
- if (pixelData.getEncapsulatedRepresentation
- (transferSyntax, NULL, pixelSequence).good() && pixelSequence)
- {
- return pixelSequence->card();
- }
- else
- {
- return 1;
- }
- }
-
-
namespace
{
class DicomFieldStream : public IHttpStreamAnswer
@@ -408,7 +394,6 @@ namespace Orthanc
}
-
static void SendPathValueForLeaf(RestApiOutput& output,
const std::string& tag,
DcmItem& dicom,
@@ -436,7 +421,32 @@ namespace Orthanc
output.AnswerStream(stream);
}
}
+#endif
+
+
+ static inline uint16_t GetCharValue(char c)
+ {
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ else if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ else
+ return 0;
+ }
+
+
+ static inline uint16_t GetTagValue(const char* c)
+ {
+ return ((GetCharValue(c[0]) << 12) +
+ (GetCharValue(c[1]) << 8) +
+ (GetCharValue(c[2]) << 4) +
+ GetCharValue(c[3]));
+ }
+
+#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
void ParsedDicomFile::SendPathValue(RestApiOutput& output,
const UriComponents& uri)
{
@@ -493,7 +503,8 @@ namespace Orthanc
SendPathValueForLeaf(output, uri.back(), *dicom, transferSyntax);
}
}
-
+#endif
+
void ParsedDicomFile::Remove(const DicomTag& tag)
{
@@ -777,6 +788,7 @@ namespace Orthanc
}
+#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
void ParsedDicomFile::Answer(RestApiOutput& output)
{
std::string serialized;
@@ -785,7 +797,7 @@ namespace Orthanc
output.AnswerBuffer(serialized, CONTENT_TYPE_OCTET_STREAM);
}
}
-
+#endif
bool ParsedDicomFile::GetTagValue(std::string& value,
@@ -830,9 +842,10 @@ namespace Orthanc
return false;
}
+ std::set<DicomTag> tmp;
std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement
(*element, DicomToJsonFlags_Default,
- ORTHANC_MAXIMUM_TAG_LENGTH, GetEncoding()));
+ 0, GetEncoding(), tmp));
if (v.get() == NULL ||
v->IsNull())
@@ -943,7 +956,7 @@ namespace Orthanc
ParsedDicomFile::ParsedDicomFile(const DicomMap& map) :
pimpl_(new PImpl)
{
- CreateFromDicomMap(map, Configuration::GetDefaultEncoding());
+ CreateFromDicomMap(map, GetDefaultDicomEncoding());
}
@@ -1016,10 +1029,23 @@ namespace Orthanc
Toolbox::ToLowerCase(mime);
- if (mime == "image/png" ||
- mime == "image/jpeg")
+ if (mime == "image/png")
+ {
+#if ORTHANC_ENABLE_PNG == 1
+ EmbedImage(mime, content);
+#else
+ LOG(ERROR) << "Orthanc was compiled without support of PNG";
+ throw OrthancException(ErrorCode_NotImplemented);
+#endif
+ }
+ else if (mime == "image/jpeg")
{
+#if ORTHANC_ENABLE_JPEG == 1
EmbedImage(mime, content);
+#else
+ LOG(ERROR) << "Orthanc was compiled without support of JPEG";
+ throw OrthancException(ErrorCode_NotImplemented);
+#endif
}
else if (mime == "application/pdf")
{
@@ -1044,6 +1070,8 @@ namespace Orthanc
}
+#if (ORTHANC_ENABLE_JPEG == 1 && \
+ ORTHANC_ENABLE_PNG == 1)
void ParsedDicomFile::EmbedImage(const std::string& mime,
const std::string& content)
{
@@ -1064,6 +1092,7 @@ namespace Orthanc
throw OrthancException(ErrorCode_NotImplemented);
}
}
+#endif
void ParsedDicomFile::EmbedImage(const ImageAccessor& accessor)
@@ -1191,7 +1220,7 @@ namespace Orthanc
Encoding ParsedDicomFile::GetEncoding() const
{
return FromDcmtkBridge::DetectEncoding(*pimpl_->file_->getDataset(),
- Configuration::GetDefaultEncoding());
+ GetDefaultDicomEncoding());
}
@@ -1213,14 +1242,36 @@ namespace Orthanc
DicomToJsonFlags flags,
unsigned int maxStringLength)
{
+ std::set<DicomTag> ignoreTagLength;
FromDcmtkBridge::ExtractDicomAsJson(target, *pimpl_->file_->getDataset(),
- format, flags, maxStringLength, Configuration::GetDefaultEncoding());
+ format, flags, maxStringLength,
+ GetDefaultDicomEncoding(), ignoreTagLength);
+ }
+
+
+ void ParsedDicomFile::DatasetToJson(Json::Value& target,
+ DicomToJsonFormat format,
+ DicomToJsonFlags flags,
+ unsigned int maxStringLength,
+ const std::set<DicomTag>& ignoreTagLength)
+ {
+ FromDcmtkBridge::ExtractDicomAsJson(target, *pimpl_->file_->getDataset(),
+ format, flags, maxStringLength,
+ GetDefaultDicomEncoding(), ignoreTagLength);
+ }
+
+
+ void ParsedDicomFile::DatasetToJson(Json::Value& target,
+ const std::set<DicomTag>& ignoreTagLength)
+ {
+ FromDcmtkBridge::ExtractDicomAsJson(target, *pimpl_->file_->getDataset(), ignoreTagLength);
}
void ParsedDicomFile::DatasetToJson(Json::Value& target)
{
- Configuration::ExtractDicomAsJson(target, *pimpl_->file_->getDataset());
+ const std::set<DicomTag> ignoreTagLength;
+ FromDcmtkBridge::ExtractDicomAsJson(target, *pimpl_->file_->getDataset(), ignoreTagLength);
}
@@ -1330,7 +1381,7 @@ namespace Orthanc
const bool decodeDataUriScheme = (flags & DicomFromJsonFlags_DecodeDataUriScheme) ? true : false;
std::auto_ptr<ParsedDicomFile> result(new ParsedDicomFile(generateIdentifiers));
- result->SetEncoding(FromDcmtkBridge::ExtractEncoding(json, Configuration::GetDefaultEncoding()));
+ result->SetEncoding(FromDcmtkBridge::ExtractEncoding(json, GetDefaultDicomEncoding()));
const Json::Value::Members tags = json.getMemberNames();
@@ -1417,13 +1468,7 @@ namespace Orthanc
void ParsedDicomFile::ExtractDicomSummary(DicomMap& target) const
{
- Configuration::ExtractDicomSummary(target, *pimpl_->file_->getDataset());
- }
-
-
- void ParsedDicomFile::ExtractDicomAsJson(Json::Value& target) const
- {
- Configuration::ExtractDicomAsJson(target, *pimpl_->file_->getDataset());
+ FromDcmtkBridge::ExtractDicomSummary(target, *pimpl_->file_->getDataset());
}
diff --git a/OrthancServer/ParsedDicomFile.h b/Core/DicomParsing/ParsedDicomFile.h
similarity index 82%
rename from OrthancServer/ParsedDicomFile.h
rename to Core/DicomParsing/ParsedDicomFile.h
index 2c8bdf8..902fde6 100644
--- a/OrthancServer/ParsedDicomFile.h
+++ b/Core/DicomParsing/ParsedDicomFile.h
@@ -33,12 +33,31 @@
#pragma once
-#include "../Core/DicomFormat/DicomInstanceHasher.h"
-#include "../Core/Images/ImageAccessor.h"
-#include "../Core/IDynamicObject.h"
-#include "../Core/RestApi/RestApiOutput.h"
-#include "../Core/Toolbox.h"
-#include "ServerEnumerations.h"
+#if !defined(ORTHANC_ENABLE_JPEG)
+# error Macro ORTHANC_ENABLE_JPEG must be defined to use this file
+#endif
+
+#if !defined(ORTHANC_ENABLE_PNG)
+# error Macro ORTHANC_ENABLE_PNG must be defined to use this file
+#endif
+
+#if !defined(ORTHANC_ENABLE_CIVETWEB)
+# error Macro ORTHANC_ENABLE_CIVETWEB must be defined to use this file
+#endif
+
+#if !defined(ORTHANC_ENABLE_MONGOOSE)
+# error Macro ORTHANC_ENABLE_MONGOOSE must be defined to use this file
+#endif
+
+#include "../DicomFormat/DicomInstanceHasher.h"
+#include "../Images/ImageAccessor.h"
+#include "../IDynamicObject.h"
+#include "../Toolbox.h"
+
+#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
+# include "../RestApi/RestApiOutput.h"
+#endif
+
class DcmDataset;
class DcmFileFormat;
@@ -89,10 +108,12 @@ namespace Orthanc
ParsedDicomFile* Clone();
+#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
void SendPathValue(RestApiOutput& output,
const UriComponents& uri);
void Answer(RestApiOutput& output);
+#endif
void Remove(const DicomTag& tag);
@@ -144,8 +165,11 @@ namespace Orthanc
void EmbedImage(const ImageAccessor& accessor);
+#if (ORTHANC_ENABLE_JPEG == 1 && \
+ ORTHANC_ENABLE_PNG == 1)
void EmbedImage(const std::string& mime,
const std::string& content);
+#endif
Encoding GetEncoding() const;
@@ -158,8 +182,17 @@ namespace Orthanc
DicomToJsonFlags flags,
unsigned int maxStringLength);
+ void DatasetToJson(Json::Value& target,
+ DicomToJsonFormat format,
+ DicomToJsonFlags flags,
+ unsigned int maxStringLength,
+ const std::set<DicomTag>& ignoreTagLength);
+
// This version uses the default parameters for
// FileContentType_DicomAsJson
+ void DatasetToJson(Json::Value& target,
+ const std::set<DicomTag>& ignoreTagLength);
+
void DatasetToJson(Json::Value& target);
void HeaderToJson(Json::Value& target,
@@ -184,8 +217,6 @@ namespace Orthanc
void ExtractDicomSummary(DicomMap& target) const;
- void ExtractDicomAsJson(Json::Value& target) const;
-
bool LookupTransferSyntax(std::string& result);
bool LookupPhotometricInterpretation(PhotometricInterpretation& result) const;
diff --git a/OrthancServer/ToDcmtkBridge.cpp b/Core/DicomParsing/ToDcmtkBridge.cpp
similarity index 98%
rename from OrthancServer/ToDcmtkBridge.cpp
rename to Core/DicomParsing/ToDcmtkBridge.cpp
index e848262..3d8a929 100644
--- a/OrthancServer/ToDcmtkBridge.cpp
+++ b/Core/DicomParsing/ToDcmtkBridge.cpp
@@ -31,13 +31,13 @@
**/
-#include "PrecompiledHeadersServer.h"
+#include "../PrecompiledHeaders.h"
#include "ToDcmtkBridge.h"
#include <memory>
#include <dcmtk/dcmnet/diutil.h>
-#include "../Core/OrthancException.h"
+#include "../OrthancException.h"
namespace Orthanc
diff --git a/OrthancServer/ToDcmtkBridge.h b/Core/DicomParsing/ToDcmtkBridge.h
similarity index 93%
rename from OrthancServer/ToDcmtkBridge.h
rename to Core/DicomParsing/ToDcmtkBridge.h
index 551640f..7a6b88f 100644
--- a/OrthancServer/ToDcmtkBridge.h
+++ b/Core/DicomParsing/ToDcmtkBridge.h
@@ -33,7 +33,11 @@
#pragma once
-#include "../Core/DicomFormat/DicomMap.h"
+#if ORTHANC_ENABLE_DCMTK != 1
+# error The macro ORTHANC_ENABLE_DCMTK must be set to 1
+#endif
+
+#include "../DicomFormat/DicomMap.h"
#include <dcmtk/dcmdata/dcdatset.h>
namespace Orthanc
diff --git a/Core/Endianness.h b/Core/Endianness.h
index 14cbca1..102bbd5 100644
--- a/Core/Endianness.h
+++ b/Core/Endianness.h
@@ -35,10 +35,10 @@
/********************************************************************
- ** LINUX ARCHITECTURES
+ ** LINUX-LIKE ARCHITECTURES
********************************************************************/
-#if defined(__linux__)
+#if defined(__linux__) || defined(__EMSCRIPTEN__)
# define ORTHANC_HAS_BUILTIN_BYTE_SWAP 1
# include <endian.h>
#endif
diff --git a/Core/Enumerations.cpp b/Core/Enumerations.cpp
index 8309e1a..57a52e6 100644
--- a/Core/Enumerations.cpp
+++ b/Core/Enumerations.cpp
@@ -38,6 +38,7 @@
#include "Toolbox.h"
#include "Logging.h"
+#include <boost/thread/mutex.hpp>
#include <string.h>
#include <cassert>
@@ -752,12 +753,128 @@ namespace Orthanc
case PixelFormat_Float32:
return "Grayscale (float 32bpp)";
+ case PixelFormat_Grayscale32:
+ return "Grayscale (unsigned 32bpp)";
+
+ case PixelFormat_RGB48:
+ return "RGB48";
+
+ default:
+ throw OrthancException(ErrorCode_ParameterOutOfRange);
+ }
+ }
+
+
+ const char* EnumerationToString(ModalityManufacturer manufacturer)
+ {
+ switch (manufacturer)
+ {
+ case ModalityManufacturer_Generic:
+ return "Generic";
+
+ case ModalityManufacturer_GenericNoWildcardInDates:
+ return "GenericNoWildcardInDates";
+
+ case ModalityManufacturer_GenericNoUniversalWildcard:
+ return "GenericNoUniversalWildcard";
+
+ case ModalityManufacturer_StoreScp:
+ return "StoreScp";
+
+ case ModalityManufacturer_ClearCanvas:
+ return "ClearCanvas";
+
+ case ModalityManufacturer_Dcm4Chee:
+ return "Dcm4Chee";
+
+ case ModalityManufacturer_Vitrea:
+ return "Vitrea";
+
default:
throw OrthancException(ErrorCode_ParameterOutOfRange);
}
}
+ const char* EnumerationToString(DicomRequestType type)
+ {
+ switch (type)
+ {
+ case DicomRequestType_Echo:
+ return "Echo";
+ break;
+
+ case DicomRequestType_Find:
+ return "Find";
+ break;
+
+ case DicomRequestType_Get:
+ return "Get";
+ break;
+
+ case DicomRequestType_Move:
+ return "Move";
+ break;
+
+ case DicomRequestType_Store:
+ return "Store";
+ break;
+
+ default:
+ throw OrthancException(ErrorCode_ParameterOutOfRange);
+ }
+ }
+
+
+ const char* EnumerationToString(TransferSyntax syntax)
+ {
+ switch (syntax)
+ {
+ case TransferSyntax_Deflated:
+ return "Deflated";
+
+ case TransferSyntax_Jpeg:
+ return "JPEG";
+
+ case TransferSyntax_Jpeg2000:
+ return "JPEG2000";
+
+ case TransferSyntax_JpegLossless:
+ return "JPEG Lossless";
+
+ case TransferSyntax_Jpip:
+ return "JPIP";
+
+ case TransferSyntax_Mpeg2:
+ return "MPEG2";
+
+ case TransferSyntax_Rle:
+ return "RLE";
+
+ default:
+ throw OrthancException(ErrorCode_ParameterOutOfRange);
+ }
+ }
+
+
+ const char* EnumerationToString(DicomVersion version)
+ {
+ switch (version)
+ {
+ case DicomVersion_2008:
+ return "2008";
+ break;
+
+ case DicomVersion_2017c:
+ return "2017c";
+ break;
+
+ default:
+ throw OrthancException(ErrorCode_ParameterOutOfRange);
+ }
+ }
+
+
Encoding StringToEncoding(const char* encoding)
{
std::string s(encoding);
@@ -1127,6 +1244,86 @@ namespace Orthanc
}
+ ModalityManufacturer StringToModalityManufacturer(const std::string& manufacturer)
+ {
+ ModalityManufacturer result;
+ bool obsolete = false;
+
+ if (manufacturer == "Generic")
+ {
+ return ModalityManufacturer_Generic;
+ }
+ else if (manufacturer == "GenericNoWildcardInDates")
+ {
+ return ModalityManufacturer_GenericNoWildcardInDates;
+ }
+ else if (manufacturer == "GenericNoUniversalWildcard")
+ {
+ return ModalityManufacturer_GenericNoUniversalWildcard;
+ }
+ else if (manufacturer == "ClearCanvas")
+ {
+ return ModalityManufacturer_ClearCanvas;
+ }
+ else if (manufacturer == "StoreScp")
+ {
+ return ModalityManufacturer_StoreScp;
+ }
+ else if (manufacturer == "Dcm4Chee")
+ {
+ return ModalityManufacturer_Dcm4Chee;
+ }
+ else if (manufacturer == "Vitrea")
+ {
+ return ModalityManufacturer_Vitrea;
+ }
+ else if (manufacturer == "AgfaImpax" ||
+ manufacturer == "SyngoVia")
+ {
+ result = ModalityManufacturer_GenericNoWildcardInDates;
+ obsolete = true;
+ }
+ else if (manufacturer == "EFilm2" ||
+ manufacturer == "MedInria")
+ {
+ result = ModalityManufacturer_Generic;
+ obsolete = true;
+ }
+ else
+ {
+ throw OrthancException(ErrorCode_ParameterOutOfRange);
+ }
+
+ if (obsolete)
+ {
+ LOG(WARNING) << "The \"" << manufacturer << "\" manufacturer is obsolete since "
+ << "Orthanc 1.3.0. To guarantee compatibility with future Orthanc "
+ << "releases, you should replace it by \""
+ << EnumerationToString(result)
+ << "\" in your configuration file.";
+ }
+
+ return result;
+ }
+
+
+ DicomVersion StringToDicomVersion(const std::string& version)
+ {
+ if (version == "2008")
+ {
+ return DicomVersion_2008;
+ }
+ else if (version == "2017c")
+ {
+ return DicomVersion_2017c;
+ }
+ else
+ {
+ throw OrthancException(ErrorCode_ParameterOutOfRange);
+ }
+ }
+
+
unsigned int GetBytesPerPixel(PixelFormat format)
{
switch (format)
@@ -1143,12 +1340,16 @@ namespace Orthanc
case PixelFormat_RGBA32:
case PixelFormat_BGRA32:
+ case PixelFormat_Grayscale32:
return 4;
case PixelFormat_Float32:
assert(sizeof(float) == 4);
return 4;
+ case PixelFormat_RGB48:
+ return 6;
+
default:
throw OrthancException(ErrorCode_ParameterOutOfRange);
}
@@ -1225,8 +1426,15 @@ namespace Orthanc
{
encoding = Encoding_Japanese;
}
- else if (s == "GB18030")
+ else if (s == "GB18030" || s == "GBK")
{
+ /**
+ * According to tumashu at 163.com, "In China, many dicom file's
+ * 0008,0005 tag is set as "GBK", instead of "GB18030", GBK is a
+ * subset of GB18030, and which is used frequently in China,
+ * suggest support it."
+ * https://groups.google.com/d/msg/orthanc-users/WMM8LMbjpUc/02-1f_yFCgAJ
+ **/
encoding = Encoding_Chinese;
}
/*
@@ -1475,5 +1683,28 @@ namespace Orthanc
default:
throw OrthancException(ErrorCode_ParameterOutOfRange);
}
+ }
+
+
+ static boost::mutex defaultEncodingMutex_; // Should not be necessary
+ static Encoding defaultEncoding_ = ORTHANC_DEFAULT_DICOM_ENCODING;
+
+ Encoding GetDefaultDicomEncoding()
+ {
+ boost::mutex::scoped_lock lock(defaultEncodingMutex_);
+ return defaultEncoding_;
}
+
+ void SetDefaultDicomEncoding(Encoding encoding)
+ {
+ std::string name = EnumerationToString(encoding);
+
+ {
+ boost::mutex::scoped_lock lock(defaultEncodingMutex_);
+ defaultEncoding_ = encoding;
+ }
+
+ LOG(INFO) << "Default encoding for DICOM was changed to: " << name;
+ }
+
}
diff --git a/Core/Enumerations.h b/Core/Enumerations.h
index aae6627..89e68d0 100644
--- a/Core/Enumerations.h
+++ b/Core/Enumerations.h
@@ -199,8 +199,21 @@ namespace Orthanc
**/
PixelFormat_Float32 = 6,
- // This is the memory layout for Cairo
- PixelFormat_BGRA32 = 7
+ // This is the memory layout for Cairo (for internal use in Stone of Orthanc)
+ PixelFormat_BGRA32 = 7,
+
+ /**
+ * {summary}{Graylevel, unsigned 32bpp image.}
+ * {description}{The image is graylevel. Each pixel is unsigned and stored in 4 bytes.}
+ **/
+ PixelFormat_Grayscale32 = 8,
+
+ /**
+ * {summary}{Color image in RGB48 format.}
+ * {description}{This format describes a color image. The pixels are stored in 6
+ * consecutive bytes. The memory layout is RGB.}
+ **/
+ PixelFormat_RGB48 = 9
};
@@ -443,6 +456,81 @@ namespace Orthanc
ValueRepresentation_NotSupported // Not supported by Orthanc, or tag not in dictionary
};
+ enum DicomReplaceMode
+ {
+ DicomReplaceMode_InsertIfAbsent,
+ DicomReplaceMode_ThrowIfAbsent,
+ DicomReplaceMode_IgnoreIfAbsent
+ };
+
+ enum DicomToJsonFormat
+ {
+ DicomToJsonFormat_Full,
+ DicomToJsonFormat_Short,
+ DicomToJsonFormat_Human
+ };
+
+ enum DicomToJsonFlags
+ {
+ DicomToJsonFlags_IncludeBinary = (1 << 0),
+ DicomToJsonFlags_IncludePrivateTags = (1 << 1),
+ DicomToJsonFlags_IncludeUnknownTags = (1 << 2),
+ DicomToJsonFlags_IncludePixelData = (1 << 3),
+ DicomToJsonFlags_ConvertBinaryToAscii = (1 << 4),
+ DicomToJsonFlags_ConvertBinaryToNull = (1 << 5),
+
+ // Some predefined combinations
+ DicomToJsonFlags_None = 0,
+ DicomToJsonFlags_Default = (DicomToJsonFlags_IncludeBinary |
+ DicomToJsonFlags_IncludePixelData |
+ DicomToJsonFlags_IncludePrivateTags |
+ DicomToJsonFlags_IncludeUnknownTags |
+ DicomToJsonFlags_ConvertBinaryToNull)
+ };
+
+ enum DicomFromJsonFlags
+ {
+ DicomFromJsonFlags_DecodeDataUriScheme = (1 << 0),
+ DicomFromJsonFlags_GenerateIdentifiers = (1 << 1)
+ };
+
+ enum DicomVersion
+ {
+ DicomVersion_2008,
+ DicomVersion_2017c
+ };
+
+ enum ModalityManufacturer
+ {
+ ModalityManufacturer_Generic,
+ ModalityManufacturer_GenericNoWildcardInDates,
+ ModalityManufacturer_GenericNoUniversalWildcard,
+ ModalityManufacturer_StoreScp,
+ ModalityManufacturer_ClearCanvas,
+ ModalityManufacturer_Dcm4Chee,
+ ModalityManufacturer_Vitrea
+ };
+
+ enum DicomRequestType
+ {
+ DicomRequestType_Echo,
+ DicomRequestType_Find,
+ DicomRequestType_Get,
+ DicomRequestType_Move,
+ DicomRequestType_Store
+ };
+
+ enum TransferSyntax
+ {
+ TransferSyntax_Deflated,
+ TransferSyntax_Jpeg,
+ TransferSyntax_Jpeg2000,
+ TransferSyntax_JpegLossless,
+ TransferSyntax_Jpip,
+ TransferSyntax_Mpeg2,
+ TransferSyntax_Rle
+ };
+
/**
* WARNING: Do not change the explicit values in the enumerations
@@ -513,6 +601,14 @@ namespace Orthanc
const char* EnumerationToString(PixelFormat format);
+ const char* EnumerationToString(ModalityManufacturer manufacturer);
+
+ const char* EnumerationToString(DicomRequestType type);
+
+ const char* EnumerationToString(TransferSyntax syntax);
+
+ const char* EnumerationToString(DicomVersion version);
+
Encoding StringToEncoding(const char* encoding);
ResourceType StringToResourceType(const char* type);
@@ -525,6 +621,10 @@ namespace Orthanc
bool throwIfUnsupported);
PhotometricInterpretation StringToPhotometricInterpretation(const char* value);
+
+ ModalityManufacturer StringToModalityManufacturer(const std::string& manufacturer);
+
+ DicomVersion StringToDicomVersion(const std::string& version);
unsigned int GetBytesPerPixel(PixelFormat format);
@@ -544,4 +644,8 @@ namespace Orthanc
bool IsUserContentType(FileContentType type);
bool IsBinaryValueRepresentation(ValueRepresentation vr);
+
+ Encoding GetDefaultDicomEncoding();
+
+ void SetDefaultDicomEncoding(Encoding encoding);
}
diff --git a/Core/FileStorage/FilesystemStorage.h b/Core/FileStorage/FilesystemStorage.h
index 793b6b5..630e82f 100644
--- a/Core/FileStorage/FilesystemStorage.h
+++ b/Core/FileStorage/FilesystemStorage.h
@@ -33,6 +33,14 @@
#pragma once
+#if !defined(ORTHANC_SANDBOXED)
+# error The macro ORTHANC_SANDBOXED must be defined
+#endif
+
+#if ORTHANC_SANDBOXED == 1
+# error The class FilesystemStorage cannot be used in sandboxed environments
+#endif
+
#include "IStorageArea.h"
#include <stdint.h>
diff --git a/Core/FileStorage/StorageAccessor.cpp b/Core/FileStorage/StorageAccessor.cpp
index 89830fc..6c523fc 100644
--- a/Core/FileStorage/StorageAccessor.cpp
+++ b/Core/FileStorage/StorageAccessor.cpp
@@ -36,10 +36,13 @@
#include "../Compression/ZlibCompressor.h"
#include "../OrthancException.h"
-#include "../HttpServer/HttpStreamTranscoder.h"
#include "../Toolbox.h"
#include "../SystemToolbox.h"
+#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
+# include "../HttpServer/HttpStreamTranscoder.h"
+#endif
+
namespace Orthanc
{
FileInfo StorageAccessor::Write(const void* data,
@@ -143,6 +146,7 @@ namespace Orthanc
}
+#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
void StorageAccessor::SetupSender(BufferHttpSender& sender,
const FileInfo& info,
const std::string& mime)
@@ -168,8 +172,10 @@ namespace Orthanc
sender.SetContentFilename(info.GetUuid() + std::string(extension));
}
+#endif
+#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
void StorageAccessor::AnswerFile(HttpOutput& output,
const FileInfo& info,
const std::string& mime)
@@ -180,8 +186,10 @@ namespace Orthanc
HttpStreamTranscoder transcoder(sender, info.GetCompressionType());
output.Answer(transcoder);
}
+#endif
+#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
void StorageAccessor::AnswerFile(RestApiOutput& output,
const FileInfo& info,
const std::string& mime)
@@ -192,4 +200,5 @@ namespace Orthanc
HttpStreamTranscoder transcoder(sender, info.GetCompressionType());
output.AnswerStream(transcoder);
}
+#endif
}
diff --git a/Core/FileStorage/StorageAccessor.h b/Core/FileStorage/StorageAccessor.h
index 6268d32..022e44c 100644
--- a/Core/FileStorage/StorageAccessor.h
+++ b/Core/FileStorage/StorageAccessor.h
@@ -33,10 +33,29 @@
#pragma once
+#if !defined(ORTHANC_SANDBOXED)
+# error The macro ORTHANC_SANDBOXED must be defined
+#endif
+
+#if ORTHANC_SANDBOXED == 1
+# error The class StorageAccessor cannot be used in sandboxed environments
+#endif
+
+#if !defined(ORTHANC_ENABLE_CIVETWEB)
+# error Macro ORTHANC_ENABLE_CIVETWEB must be defined to use this file
+#endif
+
+#if !defined(ORTHANC_ENABLE_MONGOOSE)
+# error Macro ORTHANC_ENABLE_MONGOOSE must be defined to use this file
+#endif
+
#include "IStorageArea.h"
#include "FileInfo.h"
-#include "../HttpServer/BufferHttpSender.h"
-#include "../RestApi/RestApiOutput.h"
+
+#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
+# include "../HttpServer/BufferHttpSender.h"
+# include "../RestApi/RestApiOutput.h"
+#endif
#include <vector>
#include <string>
@@ -51,9 +70,11 @@ namespace Orthanc
private:
IStorageArea& area_;
+#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
void SetupSender(BufferHttpSender& sender,
const FileInfo& info,
const std::string& mime);
+#endif
public:
StorageAccessor(IStorageArea& area) : area_(area)
@@ -86,6 +107,7 @@ namespace Orthanc
area_.Remove(info.GetUuid(), info.GetContentType());
}
+#if ORTHANC_ENABLE_CIVETWEB == 1 || ORTHANC_ENABLE_MONGOOSE == 1
void AnswerFile(HttpOutput& output,
const FileInfo& info,
const std::string& mime);
@@ -93,5 +115,6 @@ namespace Orthanc
void AnswerFile(RestApiOutput& output,
const FileInfo& info,
const std::string& mime);
+#endif
};
}
diff --git a/Core/HttpServer/MongooseServer.cpp b/Core/HttpServer/MongooseServer.cpp
index d89af62..8c3be1f 100644
--- a/Core/HttpServer/MongooseServer.cpp
+++ b/Core/HttpServer/MongooseServer.cpp
@@ -39,7 +39,17 @@
#include "../Logging.h"
#include "../ChunkedBuffer.h"
#include "HttpToolbox.h"
-#include "mongoose.h"
+
+#if ORTHANC_ENABLE_MONGOOSE == 1
+# include "mongoose.h"
+
+#elif ORTHANC_ENABLE_CIVETWEB == 1
+# include "civetweb.h"
+# define MONGOOSE_USE_CALLBACKS 1
+
+#else
+# error "Either Mongoose or Civetweb must be enabled to compile this file"
+#endif
#include <algorithm>
#include <string.h>
@@ -60,8 +70,6 @@
#define ORTHANC_REALM "Orthanc Secure Area"
-static const long LOCALHOST = (127ll << 24) + 1ll;
-
namespace Orthanc
{
@@ -586,9 +594,22 @@ namespace Orthanc
struct mg_connection *connection,
const struct mg_request_info *request)
{
+ bool localhost;
+
+#if ORTHANC_ENABLE_MONGOOSE == 1
+ static const long LOCALHOST = (127ll << 24) + 1ll;
+ localhost = (request->remote_ip == LOCALHOST);
+#elif ORTHANC_ENABLE_CIVETWEB == 1
+ // The "remote_ip" field of "struct mg_request_info" is tagged as
+ // deprecated in Civetweb, using "remote_addr" instead.
+ localhost = (std::string(request->remote_addr) == "127.0.0.1");
+#else
+#error
+#endif
+
// Check remote calls
if (!server.IsRemoteAccessAllowed() &&
- request->remote_ip != LOCALHOST)
+ !localhost)
{
output.SendUnauthorized(ORTHANC_REALM);
return;
@@ -638,7 +659,8 @@ namespace Orthanc
return;
}
-
+
+#if ORTHANC_ENABLE_MONGOOSE == 1
// Apply the filter, if it is installed
char remoteIp[24];
sprintf(remoteIp, "%d.%d.%d.%d",
@@ -646,6 +668,11 @@ namespace Orthanc
reinterpret_cast<const uint8_t*>(&request->remote_ip) [2],
reinterpret_cast<const uint8_t*>(&request->remote_ip) [1],
reinterpret_cast<const uint8_t*>(&request->remote_ip) [0]);
+#elif ORTHANC_ENABLE_CIVETWEB == 1
+ const char* remoteIp = request->remote_addr;
+#else
+#error
+#endif
std::string username = GetAuthenticatedUsername(headers);
@@ -747,8 +774,19 @@ namespace Orthanc
{
try
{
- MongooseServer* server = reinterpret_cast<MongooseServer*>(request->user_data);
+ void* that = NULL;
+
+#if ORTHANC_ENABLE_MONGOOSE == 1
+ that = request->user_data;
+#elif ORTHANC_ENABLE_CIVETWEB == 1
+ // https://github.com/civetweb/civetweb/issues/409
+ that = mg_get_user_data(mg_get_context(connection));
+#else
+#error
+#endif
+ MongooseServer* server = reinterpret_cast<MongooseServer*>(that);
+
if (server == NULL)
{
MongooseOutputStream stream(connection);
@@ -756,7 +794,7 @@ namespace Orthanc
output.SendStatus(HttpStatus_500_InternalServerError);
return;
}
-
+
MongooseOutputStream stream(connection);
HttpOutput output(stream, server->IsKeepAliveEnabled());
HttpMethod method = HttpMethod_Get;
@@ -846,7 +884,7 @@ namespace Orthanc
#elif MONGOOSE_USE_CALLBACKS == 1
static int Callback(struct mg_connection *connection)
{
- struct mg_request_info *request = mg_get_request_info(connection);
+ const struct mg_request_info *request = mg_get_request_info(connection);
ProtectedCallback(connection, request);
@@ -906,6 +944,14 @@ namespace Orthanc
void MongooseServer::Start()
{
+#if ORTHANC_ENABLE_MONGOOSE == 1
+ LOG(INFO) << "Starting embedded Web server using Mongoose";
+#elif ORTHANC_ENABLE_CIVETWEB == 1
+ LOG(INFO) << "Starting embedded Web server using Civetweb";
+#else
+#error
+#endif
+
if (!IsRunning())
{
std::string port = boost::lexical_cast<std::string>(port_);
diff --git a/Core/HttpServer/MongooseServer.h b/Core/HttpServer/MongooseServer.h
index a482ca1..e6af512 100644
--- a/Core/HttpServer/MongooseServer.h
+++ b/Core/HttpServer/MongooseServer.h
@@ -33,6 +33,20 @@
#pragma once
+#if !defined(ORTHANC_ENABLE_MONGOOSE)
+# error Macro ORTHANC_ENABLE_MONGOOSE must be defined to include this file
+#endif
+
+#if !defined(ORTHANC_ENABLE_CIVETWEB)
+# error Macro ORTHANC_ENABLE_CIVETWEB must be defined to include this file
+#endif
+
+#if (ORTHANC_ENABLE_MONGOOSE == 0 && \
+ ORTHANC_ENABLE_CIVETWEB == 0)
+# error Either ORTHANC_ENABLE_MONGOOSE or ORTHANC_ENABLE_CIVETWEB must be set to 1
+#endif
+
+
#include "IIncomingHttpRequestFilter.h"
#include "../OrthancException.h"
diff --git a/Core/Images/Font.cpp b/Core/Images/Font.cpp
index e063a5a..ffc5660 100644
--- a/Core/Images/Font.cpp
+++ b/Core/Images/Font.cpp
@@ -34,7 +34,14 @@
#include "../PrecompiledHeaders.h"
#include "Font.h"
-#include "../SystemToolbox.h"
+#if !defined(ORTHANC_ENABLE_LOCALE)
+# error ORTHANC_ENABLE_LOCALE must be defined to use this file
+#endif
+
+#if ORTHANC_SANDBOXED == 0
+# include "../SystemToolbox.h"
+#endif
+
#include "../Toolbox.h"
#include "../OrthancException.h"
@@ -134,12 +141,14 @@ namespace Orthanc
}
+#if ORTHANC_SANDBOXED == 0
void Font::LoadFromFile(const std::string& path)
{
std::string font;
SystemToolbox::ReadFile(font, path);
LoadFromMemory(font);
}
+#endif
static unsigned int MyMin(unsigned int a,
@@ -254,7 +263,13 @@ namespace Orthanc
int a = x;
+#if ORTHANC_ENABLE_LOCALE == 1
std::string s = Toolbox::ConvertFromUtf8(utf8, Encoding_Latin1);
+#else
+ // If the locale support is disabled, simply drop non-ASCII
+ // characters from the source UTF-8 string
+ std::string s = Toolbox::ConvertToAscii(utf8);
+#endif
for (size_t i = 0; i < s.size(); i++)
{
diff --git a/Core/Images/Font.h b/Core/Images/Font.h
index 3a91271..5a39181 100644
--- a/Core/Images/Font.h
+++ b/Core/Images/Font.h
@@ -84,7 +84,9 @@ namespace Orthanc
void LoadFromMemory(const std::string& font);
+#if ORTHANC_SANDBOXED == 0
void LoadFromFile(const std::string& path);
+#endif
const std::string& GetName() const
{
diff --git a/Core/Images/FontRegistry.cpp b/Core/Images/FontRegistry.cpp
index 20b8013..86f0df6 100644
--- a/Core/Images/FontRegistry.cpp
+++ b/Core/Images/FontRegistry.cpp
@@ -57,20 +57,24 @@ namespace Orthanc
}
+#if ORTHANC_SANDBOXED == 0
void FontRegistry::AddFromFile(const std::string& path)
{
std::auto_ptr<Font> f(new Font);
f->LoadFromFile(path);
fonts_.push_back(f.release());
}
+#endif
+#if ORTHANC_HAS_EMBEDDED_RESOURCES == 1
void FontRegistry::AddFromResource(EmbeddedResources::FileResourceId resource)
{
std::string content;
EmbeddedResources::GetFileResource(content, resource);
AddFromMemory(content);
}
+#endif
const Font& FontRegistry::GetFont(size_t i) const
diff --git a/Core/Images/FontRegistry.h b/Core/Images/FontRegistry.h
index e3519b0..c4c3af7 100644
--- a/Core/Images/FontRegistry.h
+++ b/Core/Images/FontRegistry.h
@@ -35,7 +35,13 @@
#include "Font.h"
-#include <EmbeddedResources.h> // Autogenerated file
+#if !defined(ORTHANC_HAS_EMBEDDED_RESOURCES)
+# error Macro ORTHANC_HAS_EMBEDDED_RESOURCES must be defined
+#endif
+
+#if ORTHANC_HAS_EMBEDDED_RESOURCES == 1
+# include <EmbeddedResources.h> // Autogenerated file
+#endif
namespace Orthanc
{
@@ -51,9 +57,13 @@ namespace Orthanc
void AddFromMemory(const std::string& font);
+#if ORTHANC_SANDBOXED == 0
void AddFromFile(const std::string& path);
+#endif
+#if ORTHANC_HAS_EMBEDDED_RESOURCES == 1
void AddFromResource(EmbeddedResources::FileResourceId resource);
+#endif
size_t GetSize() const
{
diff --git a/Core/Images/ImageAccessor.cpp b/Core/Images/ImageAccessor.cpp
index 2c61674..942be97 100644
--- a/Core/Images/ImageAccessor.cpp
+++ b/Core/Images/ImageAccessor.cpp
@@ -218,6 +218,10 @@ namespace Orthanc
ToMatlabStringInternal<uint16_t>(buffer, *this);
break;
+ case PixelFormat_Grayscale32:
+ ToMatlabStringInternal<uint32_t>(buffer, *this);
+ break;
+
case PixelFormat_SignedGrayscale16:
ToMatlabStringInternal<int16_t>(buffer, *this);
break;
diff --git a/Core/Images/ImageProcessing.cpp b/Core/Images/ImageProcessing.cpp
index eea0a85..12667a9 100644
--- a/Core/Images/ImageProcessing.cpp
+++ b/Core/Images/ImageProcessing.cpp
@@ -413,6 +413,13 @@ namespace Orthanc
}
if (target.GetFormat() == PixelFormat_Float32 &&
+ source.GetFormat() == PixelFormat_Grayscale32)
+ {
+ ConvertGrayscaleToFloat<uint32_t>(target, source);
+ return;
+ }
+
+ if (target.GetFormat() == PixelFormat_Float32 &&
source.GetFormat() == PixelFormat_SignedGrayscale16)
{
ConvertGrayscaleToFloat<int16_t>(target, source);
@@ -561,6 +568,26 @@ namespace Orthanc
return;
}
+ if (target.GetFormat() == PixelFormat_RGB24 &&
+ source.GetFormat() == PixelFormat_RGB48)
+ {
+ for (unsigned int y = 0; y < source.GetHeight(); y++)
+ {
+ const uint16_t* p = reinterpret_cast<const uint16_t*>(source.GetConstRow(y));
+ uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
+ for (unsigned int x = 0; x < source.GetWidth(); x++)
+ {
+ q[0] = p[0] >> 8;
+ q[1] = p[1] >> 8;
+ q[2] = p[2] >> 8;
+ p += 3;
+ q += 3;
+ }
+ }
+
+ return;
+ }
+
throw OrthancException(ErrorCode_NotImplemented);
}
@@ -579,6 +606,10 @@ namespace Orthanc
SetInternal<uint16_t>(image, value);
return;
+ case PixelFormat_Grayscale32:
+ SetInternal<uint32_t>(image, value);
+ return;
+
case PixelFormat_SignedGrayscale16:
SetInternal<int16_t>(image, value);
return;
@@ -664,9 +695,9 @@ namespace Orthanc
}
- void ImageProcessing::GetMinMaxValue(int64_t& minValue,
- int64_t& maxValue,
- const ImageAccessor& image)
+ void ImageProcessing::GetMinMaxIntegerValue(int64_t& minValue,
+ int64_t& maxValue,
+ const ImageAccessor& image)
{
switch (image.GetFormat())
{
@@ -688,6 +719,15 @@ namespace Orthanc
break;
}
+ case PixelFormat_Grayscale32:
+ {
+ uint32_t a, b;
+ GetMinMaxValueInternal<uint32_t>(a, b, image);
+ minValue = a;
+ maxValue = b;
+ break;
+ }
+
case PixelFormat_SignedGrayscale16:
{
int16_t a, b;
@@ -703,6 +743,28 @@ namespace Orthanc
}
+ void ImageProcessing::GetMinMaxFloatValue(float& minValue,
+ float& maxValue,
+ const ImageAccessor& image)
+ {
+ switch (image.GetFormat())
+ {
+ case PixelFormat_Float32:
+ {
+ assert(sizeof(float) == 32);
+ float a, b;
+ GetMinMaxValueInternal<float>(a, b, image);
+ minValue = a;
+ maxValue = b;
+ break;
+ }
+
+ default:
+ throw OrthancException(ErrorCode_NotImplemented);
+ }
+ }
+
+
void ImageProcessing::AddConstant(ImageAccessor& image,
int64_t value)
diff --git a/Core/Images/ImageProcessing.h b/Core/Images/ImageProcessing.h
index 8ee4297..1b6c616 100644
--- a/Core/Images/ImageProcessing.h
+++ b/Core/Images/ImageProcessing.h
@@ -60,9 +60,13 @@ namespace Orthanc
static void ShiftRight(ImageAccessor& target,
unsigned int shift);
- static void GetMinMaxValue(int64_t& minValue,
- int64_t& maxValue,
- const ImageAccessor& image);
+ static void GetMinMaxIntegerValue(int64_t& minValue,
+ int64_t& maxValue,
+ const ImageAccessor& image);
+
+ static void GetMinMaxFloatValue(float& minValue,
+ float& maxValue,
+ const ImageAccessor& image);
static void AddConstant(ImageAccessor& image,
int64_t value);
diff --git a/Core/Images/JpegErrorManager.h b/Core/Images/JpegErrorManager.h
index f149510..118e57e 100644
--- a/Core/Images/JpegErrorManager.h
+++ b/Core/Images/JpegErrorManager.h
@@ -32,6 +32,14 @@
#pragma once
+#if !defined(ORTHANC_ENABLE_JPEG)
+# error The macro ORTHANC_ENABLE_JPEG must be defined
+#endif
+
+#if ORTHANC_ENABLE_JPEG != 1
+# error JPEG support must be enabled to include this file
+#endif
+
#include <string.h>
#include <stdio.h>
#include <jpeglib.h>
diff --git a/Core/Images/JpegReader.h b/Core/Images/JpegReader.h
index 105a9b8..5c9781c 100644
--- a/Core/Images/JpegReader.h
+++ b/Core/Images/JpegReader.h
@@ -33,15 +33,23 @@
#pragma once
+#if !defined(ORTHANC_SANDBOXED)
+# error The macro ORTHANC_SANDBOXED must be defined
+#endif
+
+#if !defined(ORTHANC_ENABLE_JPEG)
+# error The macro ORTHANC_ENABLE_JPEG must be defined
+#endif
+
+#if ORTHANC_ENABLE_JPEG != 1
+# error JPEG support must be enabled to include this file
+#endif
+
#include "ImageAccessor.h"
#include <string>
#include <boost/noncopyable.hpp>
-#if !defined(ORTHANC_SANDBOXED)
-# error The macro ORTHANC_SANDBOXED must be defined
-#endif
-
namespace Orthanc
{
class JpegReader :
diff --git a/Core/Images/JpegWriter.cpp b/Core/Images/JpegWriter.cpp
index 1c62ac2..81b42a7 100644
--- a/Core/Images/JpegWriter.cpp
+++ b/Core/Images/JpegWriter.cpp
@@ -162,6 +162,7 @@ namespace Orthanc
#endif
+#if ORTHANC_SANDBOXED == 0
void JpegWriter::WriteToMemoryInternal(std::string& jpeg,
unsigned int width,
unsigned int height,
@@ -206,4 +207,5 @@ namespace Orthanc
jpeg.assign(reinterpret_cast<const char*>(data), size);
free(data);
}
+#endif
}
diff --git a/Core/Images/JpegWriter.h b/Core/Images/JpegWriter.h
index 94341c4..8570a61 100644
--- a/Core/Images/JpegWriter.h
+++ b/Core/Images/JpegWriter.h
@@ -33,6 +33,14 @@
#pragma once
+#if !defined(ORTHANC_ENABLE_JPEG)
+# error The macro ORTHANC_ENABLE_JPEG must be defined
+#endif
+
+#if ORTHANC_ENABLE_JPEG != 1
+# error JPEG support must be enabled to include this file
+#endif
+
#include "IImageWriter.h"
namespace Orthanc
diff --git a/Core/Images/PngReader.h b/Core/Images/PngReader.h
index f07013d..659037f 100644
--- a/Core/Images/PngReader.h
+++ b/Core/Images/PngReader.h
@@ -33,6 +33,14 @@
#pragma once
+#if !defined(ORTHANC_ENABLE_PNG)
+# error The macro ORTHANC_ENABLE_PNG must be defined
+#endif
+
+#if ORTHANC_ENABLE_PNG != 1
+# error PNG support must be enabled to include this file
+#endif
+
#include "ImageAccessor.h"
#include "../Enumerations.h"
diff --git a/Core/Images/PngWriter.cpp b/Core/Images/PngWriter.cpp
index bf04e9a..72aa6cd 100644
--- a/Core/Images/PngWriter.cpp
+++ b/Core/Images/PngWriter.cpp
@@ -248,6 +248,7 @@ namespace Orthanc
+#if ORTHANC_SANDBOXED == 0
void PngWriter::WriteToMemoryInternal(std::string& png,
unsigned int width,
unsigned int height,
@@ -271,4 +272,5 @@ namespace Orthanc
chunks.Flatten(png);
}
+#endif
}
diff --git a/Core/Images/PngWriter.h b/Core/Images/PngWriter.h
index 691a579..e7dd42b 100644
--- a/Core/Images/PngWriter.h
+++ b/Core/Images/PngWriter.h
@@ -33,6 +33,14 @@
#pragma once
+#if !defined(ORTHANC_ENABLE_PNG)
+# error The macro ORTHANC_ENABLE_PNG must be defined
+#endif
+
+#if ORTHANC_ENABLE_PNG != 1
+# error PNG support must be enabled to include this file
+#endif
+
#include "IImageWriter.h"
#include <boost/shared_ptr.hpp>
diff --git a/Core/Logging.cpp b/Core/Logging.cpp
index c1635a4..13e438c 100644
--- a/Core/Logging.cpp
+++ b/Core/Logging.cpp
@@ -161,12 +161,7 @@ namespace Orthanc
#include <fstream>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
-
-#if BOOST_HAS_DATE_TIME == 1
-# include <boost/date_time/posix_time/posix_time.hpp>
-#else
-# error Boost::date_time is required
-#endif
+#include <boost/date_time/posix_time/posix_time.hpp>
namespace
diff --git a/Core/Lua/LuaContext.cpp b/Core/Lua/LuaContext.cpp
index d8e80b7..9eb81a1 100644
--- a/Core/Lua/LuaContext.cpp
+++ b/Core/Lua/LuaContext.cpp
@@ -588,12 +588,14 @@ namespace Orthanc
}
+#if ORTHANC_HAS_EMBEDDED_RESOURCES == 1
void LuaContext::Execute(EmbeddedResources::FileResourceId resource)
{
std::string command;
EmbeddedResources::GetFileResource(command, resource);
ExecuteInternal(NULL, command);
}
+#endif
bool LuaContext::IsExistingFunction(const char* name)
diff --git a/Core/Lua/LuaContext.h b/Core/Lua/LuaContext.h
index ac51591..62e98d7 100644
--- a/Core/Lua/LuaContext.h
+++ b/Core/Lua/LuaContext.h
@@ -37,10 +37,18 @@
# error The macro ORTHANC_ENABLE_LUA must be defined
#endif
+#if !defined(ORTHANC_HAS_EMBEDDED_RESOURCES)
+# error Macro ORTHANC_HAS_EMBEDDED_RESOURCES must be defined
+#endif
+
#if ORTHANC_ENABLE_LUA == 0
# error The Lua support is disabled, cannot include this file
#endif
+#if ORTHANC_HAS_EMBEDDED_RESOURCES == 1
+# include <EmbeddedResources.h> // Autogenerated file
+#endif
+
#include "../HttpClient.h"
extern "C"
@@ -48,7 +56,6 @@ extern "C"
#include <lua.h>
}
-#include <EmbeddedResources.h>
#include <boost/noncopyable.hpp>
namespace Orthanc
@@ -105,7 +112,9 @@ namespace Orthanc
void Execute(Json::Value& output,
const std::string& command);
+#if ORTHANC_HAS_EMBEDDED_RESOURCES == 1
void Execute(EmbeddedResources::FileResourceId resource);
+#endif
bool IsExistingFunction(const char* name);
diff --git a/Core/MultiThreading/Mutex.cpp b/Core/MultiThreading/Mutex.cpp
index f15cc31..b0bd7c5 100644
--- a/Core/MultiThreading/Mutex.cpp
+++ b/Core/MultiThreading/Mutex.cpp
@@ -38,7 +38,7 @@
#if defined(_WIN32)
#include <windows.h>
-#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__FreeBSD__)
+#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#include <pthread.h>
#else
#error Support your platform here
@@ -76,7 +76,7 @@ namespace Orthanc
}
-#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__FreeBSD__)
+#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
struct Mutex::PImpl
{
diff --git a/Core/PrecompiledHeaders.h b/Core/PrecompiledHeaders.h
index 4fc6435..98d03ea 100644
--- a/Core/PrecompiledHeaders.h
+++ b/Core/PrecompiledHeaders.h
@@ -50,7 +50,7 @@
#include <json/value.h>
#if ORTHANC_ENABLE_PUGIXML == 1
-#include <pugixml.hpp>
+# include <pugixml.hpp>
#endif
#include "Enumerations.h"
@@ -58,4 +58,21 @@
#include "OrthancException.h"
#include "Toolbox.h"
+#if ORTHANC_ENABLE_DCMTK == 1
+# include "DicomParsing/ParsedDicomFile.h"
+
+// Headers from DCMTK used in Orthanc headers
+# include <dcmtk/dcmdata/dcdatset.h>
+# include <dcmtk/dcmdata/dcfilefo.h>
+# include <dcmtk/dcmdata/dcmetinf.h>
+# include <dcmtk/dcmdata/dcpixseq.h>
+#endif
+
+#if ORTHANC_ENABLE_DCMTK_NETWORKING == 1
+# include "DicomNetworking/DicomServer.h"
+
+// Headers from DCMTK used in Orthanc headers
+# include <dcmtk/dcmnet/dimse.h>
+#endif
+
#endif
diff --git a/Core/SQLite/OrthancSQLiteException.h b/Core/SQLite/OrthancSQLiteException.h
index 9ffd382..09d9feb 100644
--- a/Core/SQLite/OrthancSQLiteException.h
+++ b/Core/SQLite/OrthancSQLiteException.h
@@ -38,6 +38,11 @@
#pragma once
+#if ORTHANC_ENABLE_SQLITE != 1
+# error Macro ORTHANC_ENABLE_SQLITE must be set to 1 to use SQLite
+#endif
+
+
#if ORTHANC_SQLITE_STANDALONE == 1
#include <stdexcept>
diff --git a/Core/SQLite/Statement.h b/Core/SQLite/Statement.h
index 24b14c3..d3ba599 100644
--- a/Core/SQLite/Statement.h
+++ b/Core/SQLite/Statement.h
@@ -46,7 +46,7 @@
#include <stdint.h>
#if ORTHANC_BUILD_UNIT_TESTS == 1
-#include <gtest/gtest_prod.h>
+# include <gtest/gtest_prod.h>
#endif
diff --git a/Core/SystemToolbox.cpp b/Core/SystemToolbox.cpp
index 5fc53ae..7f722ef 100644
--- a/Core/SystemToolbox.cpp
+++ b/Core/SystemToolbox.cpp
@@ -35,11 +35,6 @@
#include "SystemToolbox.h"
-#if BOOST_HAS_DATE_TIME == 1
-# include <boost/date_time/posix_time/posix_time.hpp>
-#endif
-
-
#if defined(_WIN32)
# include <windows.h>
# include <process.h> // For "_spawnvp()" and "_getpid()"
@@ -62,12 +57,17 @@
#endif
+#if defined(__OpenBSD__)
+# include <sys/sysctl.h> // For "sysctl", "CTL_KERN" and "KERN_PROC_ARGS"
+#endif
+
+
// Inclusions for UUID
// http://stackoverflow.com/a/1626302
extern "C"
{
-#ifdef WIN32
+#if defined(_WIN32)
# include <rpc.h>
#else
# include <uuid/uuid.h>
@@ -81,6 +81,7 @@ extern "C"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
namespace Orthanc
@@ -157,7 +158,7 @@ namespace Orthanc
{
#if defined(_WIN32)
::Sleep(static_cast<DWORD>(microSeconds / static_cast<uint64_t>(1000)));
-#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__native_client__)
+#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__native_client__)
usleep(microSeconds);
#else
#error Support your platform here
@@ -349,6 +350,8 @@ namespace Orthanc
#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
static std::string GetPathToExecutableInternal()
{
+ // NOTE: For FreeBSD, using KERN_PROC_PATHNAME might be a better alternative
+
std::vector<char> buffer(PATH_MAX + 1);
ssize_t bytes = readlink("/proc/self/exe", &buffer[0], buffer.size() - 1);
if (bytes == 0)
@@ -370,6 +373,37 @@ namespace Orthanc
return std::string(pathbuf);
}
+#elif defined(__OpenBSD__)
+ static std::string GetPathToExecutableInternal()
+ {
+ // This is an adapted version of the patch proposed in issue #64
+ // without an explicit call to "malloc()" to prevent memory leak
+ // https://bitbucket.org/sjodogne/orthanc/issues/64/add-openbsd-support
+ // https://stackoverflow.com/q/31494901/881731
+
+ const int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV };
+
+ size_t len;
+ if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
+ {
+ throw OrthancException(ErrorCode_PathToExecutable);
+ }
+
+ std::string tmp;
+ tmp.resize(len);
+
+ char** buffer = reinterpret_cast<char**>(&tmp[0]);
+
+ if (sysctl(mib, 4, buffer, &len, NULL, 0) == -1)
+ {
+ throw OrthancException(ErrorCode_PathToExecutable);
+ }
+ else
+ {
+ return std::string(buffer[0]);
+ }
+ }
+
#else
#error Support your platform here
#endif
@@ -527,13 +561,13 @@ namespace Orthanc
}
-#if BOOST_HAS_DATE_TIME == 1
std::string SystemToolbox::GetNowIsoString()
{
boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
return boost::posix_time::to_iso_string(now);
}
+
void SystemToolbox::GetNowDicom(std::string& date,
std::string& time)
{
@@ -548,5 +582,4 @@ namespace Orthanc
sprintf(s, "%02d%02d%02d.%06d", tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
time.assign(s);
}
-#endif
}
diff --git a/Core/SystemToolbox.h b/Core/SystemToolbox.h
index 0b3fe3f..752af59 100644
--- a/Core/SystemToolbox.h
+++ b/Core/SystemToolbox.h
@@ -95,11 +95,9 @@ namespace Orthanc
std::string GenerateUuid();
-#if BOOST_HAS_DATE_TIME == 1
std::string GetNowIsoString();
void GetNowDicom(std::string& date,
std::string& time);
-#endif
}
}
diff --git a/Core/Toolbox.cpp b/Core/Toolbox.cpp
index 74b3c57..c9c02a2 100644
--- a/Core/Toolbox.cpp
+++ b/Core/Toolbox.cpp
@@ -40,7 +40,7 @@
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/lexical_cast.hpp>
-#include <boost/locale.hpp>
+#include <boost/regex.hpp>
#include <boost/uuid/sha1.hpp>
#include <string>
@@ -49,13 +49,6 @@
#include <algorithm>
#include <ctype.h>
-#if BOOST_HAS_REGEX == 1
-# include <boost/regex.hpp>
-#endif
-
-#if BOOST_HAS_LOCALE != 1
-# error Since version 0.7.6, Orthanc entirely relies on boost::locale
-#endif
#if ORTHANC_ENABLE_MD5 == 1
# include "../Resources/ThirdParty/md5/md5.h"
@@ -65,6 +58,10 @@
# include "../Resources/ThirdParty/base64/base64.h"
#endif
+#if ORTHANC_ENABLE_LOCALE == 1
+# include <boost/locale.hpp>
+#endif
+
#if defined(_MSC_VER) && (_MSC_VER < 1800)
// Patch for the missing "_strtoll" symbol when compiling with Visual Studio < 2013
@@ -369,7 +366,6 @@ namespace Orthanc
}
-# if BOOST_HAS_REGEX == 1
bool Toolbox::DecodeDataUriScheme(std::string& mime,
std::string& content,
const std::string& source)
@@ -389,7 +385,6 @@ namespace Orthanc
return false;
}
}
-# endif
void Toolbox::EncodeDataUriScheme(std::string& result,
@@ -402,6 +397,7 @@ namespace Orthanc
#endif
+#if ORTHANC_ENABLE_LOCALE == 1
static const char* GetBoostLocaleEncoding(const Encoding sourceEncoding)
{
switch (sourceEncoding)
@@ -468,8 +464,10 @@ namespace Orthanc
throw OrthancException(ErrorCode_NotImplemented);
}
}
+#endif
+#if ORTHANC_ENABLE_LOCALE == 1
std::string Toolbox::ConvertToUtf8(const std::string& source,
Encoding sourceEncoding)
{
@@ -496,8 +494,10 @@ namespace Orthanc
return ConvertToAscii(source);
}
}
+#endif
+
-
+#if ORTHANC_ENABLE_LOCALE == 1
std::string Toolbox::ConvertFromUtf8(const std::string& source,
Encoding targetEncoding)
{
@@ -524,6 +524,7 @@ namespace Orthanc
return ConvertToAscii(source);
}
}
+#endif
bool Toolbox::IsAsciiString(const void* data,
@@ -779,7 +780,6 @@ namespace Orthanc
}
-#if BOOST_HAS_REGEX == 1
std::string Toolbox::WildcardToRegularExpression(const std::string& source)
{
// TODO - Speed up this with a regular expression
@@ -807,8 +807,6 @@ namespace Orthanc
return result;
}
-#endif
-
void Toolbox::TokenizeString(std::vector<std::string>& result,
@@ -1254,6 +1252,7 @@ namespace Orthanc
}
+#if ORTHANC_ENABLE_LOCALE == 1
static std::auto_ptr<std::locale> globalLocale_;
static bool SetGlobalLocale(const char* locale)
@@ -1370,4 +1369,5 @@ namespace Orthanc
w = boost::algorithm::to_upper_copy<std::wstring>(w, *globalLocale_);
return boost::locale::conv::utf_to_utf<char>(w);
}
+#endif
}
diff --git a/Core/Toolbox.h b/Core/Toolbox.h
index f0a9623..d532adb 100644
--- a/Core/Toolbox.h
+++ b/Core/Toolbox.h
@@ -45,6 +45,10 @@
# error The macro ORTHANC_ENABLE_BASE64 must be defined
#endif
+#if !defined(ORTHANC_ENABLE_LOCALE)
+# error The macro ORTHANC_ENABLE_LOCALE must be defined
+#endif
+
#if !defined(ORTHANC_ENABLE_MD5)
# error The macro ORTHANC_ENABLE_MD5 must be defined
#endif
@@ -53,10 +57,6 @@
# error The macro ORTHANC_ENABLE_PUGIXML must be defined
#endif
-#if !defined(BOOST_HAS_REGEX)
-# error The macro BOOST_HAS_REGEX must be defined
-#endif
-
/**
* NOTE: GUID vs. UUID
@@ -132,22 +132,22 @@ namespace Orthanc
void EncodeBase64(std::string& result,
const std::string& data);
-# if BOOST_HAS_REGEX == 1
bool DecodeDataUriScheme(std::string& mime,
std::string& content,
const std::string& source);
-# endif
void EncodeDataUriScheme(std::string& result,
const std::string& mime,
const std::string& content);
#endif
+#if ORTHANC_ENABLE_LOCALE == 1
std::string ConvertToUtf8(const std::string& source,
Encoding sourceEncoding);
std::string ConvertFromUtf8(const std::string& source,
Encoding targetEncoding);
+#endif
bool IsAsciiString(const void* data,
size_t size);
@@ -161,9 +161,7 @@ namespace Orthanc
Endianness DetectEndianness();
-#if BOOST_HAS_REGEX == 1
std::string WildcardToRegularExpression(const std::string& s);
-#endif
void TokenizeString(std::vector<std::string>& result,
const std::string& source,
@@ -207,10 +205,12 @@ namespace Orthanc
bool StartsWithUuid(const std::string& str);
+#if ORTHANC_ENABLE_LOCALE == 1
void InitializeGlobalLocale(const char* locale);
void FinalizeGlobalLocale();
std::string ToUpperCaseWithAccents(const std::string& source);
+#endif
}
}
diff --git a/LinuxCompilation.txt b/LinuxCompilation.txt
index 8c075cb..e83a4e2 100644
--- a/LinuxCompilation.txt
+++ b/LinuxCompilation.txt
@@ -86,7 +86,7 @@ SUPPORTED - Debian Jessie/Sid
# cmake -DALLOW_DOWNLOADS=ON \
-DUSE_SYSTEM_MONGOOSE=OFF \
- -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
+ -DUSE_GOOGLE_TEST_DEBIAN_PACKAGE=ON \
-DDCMTK_LIBRARIES=dcmjpls \
~/Orthanc
@@ -108,7 +108,7 @@ SUPPORTED - Ubuntu 12.04.5 LTS
-DUSE_SYSTEM_MONGOOSE=OFF \
-DUSE_SYSTEM_JSONCPP=OFF \
-DUSE_SYSTEM_PUGIXML=OFF \
- -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
+ -DUSE_GOOGLE_TEST_DEBIAN_PACKAGE=ON \
~/Orthanc
@@ -123,7 +123,7 @@ SUPPORTED - Ubuntu 14.04 LTS
libcharls-dev libjsoncpp-dev libpugixml-dev
# cmake -DALLOW_DOWNLOADS=ON \
- -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
+ -DUSE_GOOGLE_TEST_DEBIAN_PACKAGE=ON \
-DUSE_SYSTEM_MONGOOSE=OFF \
-DDCMTK_LIBRARIES=dcmjpls \
~/Orthanc
diff --git a/NEWS b/NEWS
index 92dc78c..7eb8dbc 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,41 @@ Pending changes in the mainline
===============================
+Version 1.3.1 (2017-11-29)
+==========================
+
+General
+-------
+
+* Built-in decoding of palette images
+
+REST API
+--------
+
+* New URI: "/instances/.../frames/.../raw.gz" to compress raw frames using gzip
+* New argument "ignore-length" to force the inclusion of too long tags in JSON
+* New argument "/.../media?extended" to include additional type-3 tags in DICOMDIR
+
+Plugins
+-------
+
+* New pixel formats exposed in SDK: BGRA32, Float32, Grayscale32, RGB48
+
+Maintenance
+-----------
+
+* Creation of ./Resources/CMake/OrthancFramework*.cmake to reuse the Orthanc
+ C++ framework in other projects
+* New security-related options: "DicomAlwaysAllowEcho"
+* Use "GBK" (frequently used in China) as an alias for "GB18030"
+* Experimental support of actively maintained Civetweb to replace Mongoose 3.8
+* Fix issue 31 for good (create new modality types for Philips ADW, GE Xeleris, GE AWServer)
+* Fix issue 64 (OpenBSD support)
+* Fix static compilation of DCMTK 3.6.2 on Fedora
+* Upgrade to Boost 1.65.1 in static builds
+* Upgrade to SQLite amalgamation 3.21.0 in static builds
+
+
Version 1.3.0 (2017-07-19)
==========================
diff --git a/OrthancServer/DefaultDicomImageDecoder.h b/OrthancServer/DefaultDicomImageDecoder.h
index 2e9effd..bca5833 100644
--- a/OrthancServer/DefaultDicomImageDecoder.h
+++ b/OrthancServer/DefaultDicomImageDecoder.h
@@ -34,8 +34,8 @@
#pragma once
#include "IDicomImageDecoder.h"
-#include "ParsedDicomFile.h"
-#include "Internals/DicomImageDecoder.h"
+#include "../Core/DicomParsing/ParsedDicomFile.h"
+#include "../Core/DicomParsing/Internals/DicomImageDecoder.h"
namespace Orthanc
{
diff --git a/OrthancServer/DicomInstanceToStore.cpp b/OrthancServer/DicomInstanceToStore.cpp
index 68133e3..e916671 100644
--- a/OrthancServer/DicomInstanceToStore.cpp
+++ b/OrthancServer/DicomInstanceToStore.cpp
@@ -34,8 +34,7 @@
#include "PrecompiledHeadersServer.h"
#include "DicomInstanceToStore.h"
-#include "FromDcmtkBridge.h"
-#include "OrthancInitialization.h"
+#include "../Core/DicomParsing/FromDcmtkBridge.h"
#include "../Core/Logging.h"
#include <dcmtk/dcmdata/dcfilefo.h>
@@ -106,15 +105,18 @@ namespace Orthanc
if (!summary_.HasContent())
{
summary_.Allocate();
- Configuration::ExtractDicomSummary(summary_.GetContent(),
- *parsed_.GetContent().GetDcmtkObject().getDataset());
+ FromDcmtkBridge::ExtractDicomSummary(summary_.GetContent(),
+ *parsed_.GetContent().GetDcmtkObject().getDataset());
}
if (!json_.HasContent())
{
json_.Allocate();
- Configuration::ExtractDicomAsJson(json_.GetContent(),
- *parsed_.GetContent().GetDcmtkObject().getDataset());
+
+ std::set<DicomTag> ignoreTagLength;
+ FromDcmtkBridge::ExtractDicomAsJson(json_.GetContent(),
+ *parsed_.GetContent().GetDcmtkObject().getDataset(),
+ ignoreTagLength);
}
}
diff --git a/OrthancServer/DicomInstanceToStore.h b/OrthancServer/DicomInstanceToStore.h
index 1118fa0..e71813b 100644
--- a/OrthancServer/DicomInstanceToStore.h
+++ b/OrthancServer/DicomInstanceToStore.h
@@ -33,7 +33,7 @@
#pragma once
-#include "ParsedDicomFile.h"
+#include "../Core/DicomParsing/ParsedDicomFile.h"
#include "ServerIndex.h"
#include "../Core/OrthancException.h"
#include "../Core/RestApi/RestApiCall.h"
diff --git a/OrthancServer/OrthancFindRequestHandler.cpp b/OrthancServer/OrthancFindRequestHandler.cpp
index f64f5c6..4a93786 100644
--- a/OrthancServer/OrthancFindRequestHandler.cpp
+++ b/OrthancServer/OrthancFindRequestHandler.cpp
@@ -37,7 +37,7 @@
#include "../Core/DicomFormat/DicomArray.h"
#include "../Core/Lua/LuaFunctionCall.h"
#include "../Core/Logging.h"
-#include "FromDcmtkBridge.h"
+#include "../Core/DicomParsing/FromDcmtkBridge.h"
#include "OrthancInitialization.h"
#include "Search/LookupResource.h"
#include "ServerToolbox.h"
@@ -454,7 +454,7 @@ namespace Orthanc
// Whatever the manufacturer, remove the GenericGroupLength tags
// http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_7.2.html
// https://bitbucket.org/sjodogne/orthanc/issues/31/
- if (tag.GetGroup() == 0x0000)
+ if (tag.GetElement() == 0x0000)
{
return false;
}
diff --git a/OrthancServer/OrthancFindRequestHandler.h b/OrthancServer/OrthancFindRequestHandler.h
index 5577489..da9ba61 100644
--- a/OrthancServer/OrthancFindRequestHandler.h
+++ b/OrthancServer/OrthancFindRequestHandler.h
@@ -32,7 +32,7 @@
#pragma once
-#include "DicomProtocol/IFindRequestHandler.h"
+#include "../Core/DicomNetworking/IFindRequestHandler.h"
#include "ServerContext.h"
diff --git a/OrthancServer/OrthancInitialization.cpp b/OrthancServer/OrthancInitialization.cpp
index 0bc6ca1..1e732be 100644
--- a/OrthancServer/OrthancInitialization.cpp
+++ b/OrthancServer/OrthancInitialization.cpp
@@ -42,26 +42,14 @@
#include "ServerEnumerations.h"
#include "DatabaseWrapper.h"
-#include "FromDcmtkBridge.h"
-#include "ToDcmtkBridge.h"
+#include "../Core/DicomParsing/FromDcmtkBridge.h"
#include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp>
#include <curl/curl.h>
#include <boost/thread/recursive_mutex.hpp>
-
-#if ORTHANC_ENABLE_JPEG == 1
-# include <dcmtk/dcmjpeg/djdecode.h>
-#endif
-
-
-#if ORTHANC_ENABLE_JPEG_LOSSLESS == 1
-# include <dcmtk/dcmjpls/djdecode.h>
-#endif
-
-
-#include <dcmtk/dcmnet/dul.h>
+#include <dcmtk/dcmnet/dul.h> // For dcmDisableGethostbyaddr()
@@ -482,6 +470,16 @@ namespace Orthanc
Toolbox::InitializeGlobalLocale(NULL);
}
+ if (configuration_.isMember("DefaultEncoding"))
+ {
+ std::string encoding = GetGlobalStringParameterInternal("DefaultEncoding", "");
+ SetDefaultDicomEncoding(StringToEncoding(encoding.c_str()));
+ }
+ else
+ {
+ SetDefaultDicomEncoding(ORTHANC_DEFAULT_DICOM_ENCODING);
+ }
+
if (configuration_.isMember("Pkcs11"))
{
ConfigurePkcs11(configuration_["Pkcs11"]);
@@ -495,15 +493,7 @@ namespace Orthanc
FromDcmtkBridge::InitializeDictionary(GetGlobalBoolParameterInternal("LoadPrivateDictionary", true));
LoadCustomDictionary(configuration_);
-#if ORTHANC_ENABLE_JPEG_LOSSLESS == 1
- LOG(WARNING) << "Registering JPEG Lossless codecs";
- DJLSDecoderRegistration::registerCodecs();
-#endif
-
-#if ORTHANC_ENABLE_JPEG == 1
- LOG(WARNING) << "Registering JPEG codecs";
- DJDecoderRegistration::registerCodecs();
-#endif
+ FromDcmtkBridge::InitializeCodecs();
fontRegistry_.AddFromResource(EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16);
@@ -517,17 +507,7 @@ namespace Orthanc
{
boost::recursive_mutex::scoped_lock lock(globalMutex_);
HttpClient::GlobalFinalize();
-
-#if ORTHANC_ENABLE_JPEG_LOSSLESS == 1
- // Unregister JPEG-LS codecs
- DJLSDecoderRegistration::cleanup();
-#endif
-
-#if ORTHANC_ENABLE_JPEG == 1
- // Unregister JPEG codecs
- DJDecoderRegistration::cleanup();
-#endif
-
+ FromDcmtkBridge::FinalizeCodecs();
HttpClient::FinalizeOpenSsl();
Toolbox::FinalizeGlobalLocale();
}
@@ -1134,25 +1114,16 @@ namespace Orthanc
}
- Encoding Configuration::GetDefaultEncoding()
- {
- std::string s = GetGlobalStringParameter("DefaultEncoding", "Latin1");
-
- // By default, Latin1 encoding is assumed
- return s.empty() ? Encoding_Latin1 : StringToEncoding(s.c_str());
- }
-
-
void Configuration::SetDefaultEncoding(Encoding encoding)
{
- std::string name = EnumerationToString(encoding);
+ SetDefaultDicomEncoding(encoding);
{
+ // Propagate the encoding to the configuration file that is
+ // stored in memory
boost::recursive_mutex::scoped_lock lock(globalMutex_);
- configuration_["DefaultEncoding"] = name;
+ configuration_["DefaultEncoding"] = EnumerationToString(encoding);
}
-
- LOG(INFO) << "Default encoding was changed to: " << name;
}
@@ -1170,21 +1141,4 @@ namespace Orthanc
return a != b;
}
-
-
- void Configuration::ExtractDicomSummary(DicomMap& target,
- DcmItem& dataset)
- {
- FromDcmtkBridge::ExtractDicomSummary(target, dataset,
- ORTHANC_MAXIMUM_TAG_LENGTH, GetDefaultEncoding());
- }
-
-
- void Configuration::ExtractDicomAsJson(Json::Value& target,
- DcmDataset& dataset)
- {
- FromDcmtkBridge::ExtractDicomAsJson(target, dataset,
- DicomToJsonFormat_Full, DicomToJsonFlags_Default,
- ORTHANC_MAXIMUM_TAG_LENGTH, GetDefaultEncoding());
- }
}
diff --git a/OrthancServer/OrthancInitialization.h b/OrthancServer/OrthancInitialization.h
index 0fb20ae..eeeecc0 100644
--- a/OrthancServer/OrthancInitialization.h
+++ b/OrthancServer/OrthancInitialization.h
@@ -42,22 +42,11 @@
#include "../Core/HttpServer/MongooseServer.h"
#include "../Core/Images/FontRegistry.h"
#include "../Core/WebServiceParameters.h"
+#include "../Core/DicomNetworking/RemoteModalityParameters.h"
-#include "DicomProtocol/RemoteModalityParameters.h"
#include "IDatabaseWrapper.h"
#include "ServerEnumerations.h"
-#if !defined(ORTHANC_ENABLE_JPEG)
-# error The macro ORTHANC_ENABLE_JPEG must be defined
-#endif
-
-#if !defined(ORTHANC_ENABLE_JPEG_LOSSLESS)
-# error The macro ORTHANC_ENABLE_JPEG_LOSSLESS must be defined
-#endif
-
-
-class DcmDataset;
-class DcmItem;
namespace Orthanc
{
@@ -138,16 +127,8 @@ namespace Orthanc
static const FontRegistry& GetFontRegistry();
- static Encoding GetDefaultEncoding();
-
static void SetDefaultEncoding(Encoding encoding);
static bool HasConfigurationChanged();
-
- static void ExtractDicomSummary(DicomMap& target,
- DcmItem& dataset);
-
- static void ExtractDicomAsJson(Json::Value& target,
- DcmDataset& dataset);
};
}
diff --git a/OrthancServer/OrthancMoveRequestHandler.cpp b/OrthancServer/OrthancMoveRequestHandler.cpp
index 5e28bdf..081c426 100644
--- a/OrthancServer/OrthancMoveRequestHandler.cpp
+++ b/OrthancServer/OrthancMoveRequestHandler.cpp
@@ -35,7 +35,7 @@
#include "OrthancMoveRequestHandler.h"
#include "OrthancInitialization.h"
-#include "FromDcmtkBridge.h"
+#include "../../Core/DicomParsing/FromDcmtkBridge.h"
#include "../Core/DicomFormat/DicomArray.h"
#include "../Core/Logging.h"
diff --git a/OrthancServer/OrthancMoveRequestHandler.h b/OrthancServer/OrthancMoveRequestHandler.h
index 23c866b..23434a1 100644
--- a/OrthancServer/OrthancMoveRequestHandler.h
+++ b/OrthancServer/OrthancMoveRequestHandler.h
@@ -32,7 +32,7 @@
#pragma once
-#include "DicomProtocol/IMoveRequestHandler.h"
+#include "../Core/DicomNetworking/IMoveRequestHandler.h"
#include "ServerContext.h"
namespace Orthanc
diff --git a/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp b/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp
index 6b8c023..64f7663 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp
@@ -35,7 +35,7 @@
#include "OrthancRestApi.h"
#include "../../Core/Logging.h"
-#include "../FromDcmtkBridge.h"
+#include "../../Core/DicomParsing/FromDcmtkBridge.h"
#include "../ServerContext.h"
#include "../OrthancInitialization.h"
@@ -223,7 +223,7 @@ namespace Orthanc
static bool ParseAnonymizationRequest(DicomModification& target,
RestApiPostCall& call)
{
- // curl http://localhost:8042/instances/6e67da51-d119d6ae-c5667437-87b9a8a5-0f07c49f/anonymize -X POST -d '{"Replace":{"PatientName":"hello","0010-0020":"world"},"Keep":["StudyDescription", "SeriesDescription"],"KeepPrivateTags": null,"Remove":["Modality"]}' > Anonymized.dcm
+ // curl http://localhost:8042/instances/6e67da51-d119d6ae-c5667437-87b9a8a5-0f07c49f/anonymize -X POST -d '{"Replace":{"PatientName":"hello","0010-0020":"world"},"Keep":["StudyDescription", "SeriesDescription"],"KeepPrivateTags": true,"Remove":["Modality"]}' > Anonymized.dcm
Json::Value request;
if (!call.ParseJsonRequest(request) ||
@@ -710,7 +710,7 @@ namespace Orthanc
}
else
{
- encoding = Configuration::GetDefaultEncoding();
+ encoding = GetDefaultDicomEncoding();
}
dicom.SetEncoding(encoding);
diff --git a/OrthancServer/OrthancRestApi/OrthancRestApi.cpp b/OrthancServer/OrthancRestApi/OrthancRestApi.cpp
index c050a18..22b0d39 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestApi.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestApi.cpp
@@ -35,7 +35,6 @@
#include "OrthancRestApi.h"
#include "../../Core/Logging.h"
-#include "../DicomModification.h"
#include "../ServerContext.h"
namespace Orthanc
diff --git a/OrthancServer/OrthancRestApi/OrthancRestApi.h b/OrthancServer/OrthancRestApi/OrthancRestApi.h
index 8089e76..75552a6 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestApi.h
+++ b/OrthancServer/OrthancRestApi/OrthancRestApi.h
@@ -34,7 +34,8 @@
#pragma once
#include "../../Core/RestApi/RestApi.h"
-#include "../DicomModification.h"
+#include "../../Core/DicomParsing/DicomModification.h"
+#include "../ServerEnumerations.h"
#include <set>
diff --git a/OrthancServer/OrthancRestApi/OrthancRestArchive.cpp b/OrthancServer/OrthancRestApi/OrthancRestArchive.cpp
index 2b01f94..4441a8f 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestArchive.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestArchive.cpp
@@ -34,7 +34,7 @@
#include "../PrecompiledHeadersServer.h"
#include "OrthancRestApi.h"
-#include "../DicomDirWriter.h"
+#include "../../Core/DicomParsing/DicomDirWriter.h"
#include "../../Core/FileStorage/StorageAccessor.h"
#include "../../Core/Compression/HierarchicalZipWriter.h"
#include "../../Core/HttpServer/FilesystemHttpSender.h"
@@ -625,7 +625,8 @@ namespace Orthanc
static void Apply(RestApiOutput& output,
ServerContext& context,
ArchiveIndex& archive,
- const std::string& filename)
+ const std::string& filename,
+ bool enableExtendedSopClass)
{
archive.Expand(context.GetIndex());
@@ -643,10 +644,12 @@ namespace Orthanc
writer.SetZip64(isZip64);
writer.OpenDirectory("IMAGES");
- // Create the DICOMDIR writer
- DicomDirWriter dicomDir;
-
+ // Create a DICOMDIR writer
MediaWriterVisitor v(writer, context);
+
+ // Request type-3 arguments to be added to the DICOMDIR
+ v.dicomDir_.EnableExtendedSopClass(enableExtendedSopClass);
+
archive.Apply(v);
// Add the DICOMDIR
@@ -723,7 +726,8 @@ namespace Orthanc
MediaWriterVisitor::Apply(call.GetOutput(),
OrthancRestApi::GetContext(call),
archive,
- "Archive.zip");
+ "Archive.zip",
+ false);
}
}
@@ -758,7 +762,8 @@ namespace Orthanc
MediaWriterVisitor::Apply(call.GetOutput(),
OrthancRestApi::GetContext(call),
archive,
- id + ".zip");
+ id + ".zip",
+ call.HasArgument("extended"));
}
diff --git a/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp b/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp
index ad14b9b..5ec0257 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp
@@ -37,7 +37,7 @@
#include "../OrthancInitialization.h"
#include "../../Core/HttpClient.h"
#include "../../Core/Logging.h"
-#include "../FromDcmtkBridge.h"
+#include "../../Core/DicomParsing/FromDcmtkBridge.h"
#include "../Scheduler/ServerJob.h"
#include "../Scheduler/StoreScuCommand.h"
#include "../Scheduler/StorePeerCommand.h"
diff --git a/OrthancServer/OrthancRestApi/OrthancRestResources.cpp b/OrthancServer/OrthancRestApi/OrthancRestResources.cpp
index 2a49bf7..cbd4f2d 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestResources.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestResources.cpp
@@ -34,10 +34,11 @@
#include "../PrecompiledHeadersServer.h"
#include "OrthancRestApi.h"
+#include "../../Core/Compression/GzipCompressor.h"
+#include "../../Core/DicomParsing/FromDcmtkBridge.h"
+#include "../../Core/DicomParsing/Internals/DicomImageDecoder.h"
#include "../../Core/HttpServer/HttpContentNegociation.h"
#include "../../Core/Logging.h"
-#include "../FromDcmtkBridge.h"
-#include "../Internals/DicomImageDecoder.h"
#include "../OrthancInitialization.h"
#include "../Search/LookupResource.h"
#include "../ServerContext.h"
@@ -47,6 +48,42 @@
namespace Orthanc
{
+ static void AnswerDicomAsJson(RestApiCall& call,
+ const Json::Value& dicom,
+ bool simplify)
+ {
+ if (simplify)
+ {
+ Json::Value simplified;
+ ServerToolbox::SimplifyTags(simplified, dicom, DicomToJsonFormat_Human);
+ call.GetOutput().AnswerJson(simplified);
+ }
+ else
+ {
+ call.GetOutput().AnswerJson(dicom);
+ }
+ }
+
+
+ static void ParseSetOfTags(std::set<DicomTag>& target,
+ const RestApiGetCall& call,
+ const std::string& argument)
+ {
+ target.clear();
+
+ if (call.HasArgument(argument))
+ {
+ std::vector<std::string> tags;
+ Toolbox::TokenizeString(tags, call.GetArgument(argument, ""), ',');
+
+ for (size_t i = 0; i < tags.size(); i++)
+ {
+ target.insert(FromDcmtkBridge::ParseTag(tags[i]));
+ }
+ }
+ }
+
+
// List all the patients, studies, series or instances ----------------------
static void AnswerListOfResources(RestApiOutput& output,
@@ -205,18 +242,22 @@ namespace Orthanc
ServerContext& context = OrthancRestApi::GetContext(call);
std::string publicId = call.GetUriComponent("id", "");
+
+ std::set<DicomTag> ignoreTagLength;
+ ParseSetOfTags(ignoreTagLength, call, "ignore-length");
- if (simplify)
+ if (simplify ||
+ !ignoreTagLength.empty())
{
Json::Value full;
- context.ReadDicomAsJson(full, publicId);
-
- Json::Value simplified;
- ServerToolbox::SimplifyTags(simplified, full, DicomToJsonFormat_Human);
- call.GetOutput().AnswerJson(simplified);
+ context.ReadDicomAsJson(full, publicId, ignoreTagLength);
+ AnswerDicomAsJson(call, full, simplify);
}
else
{
+ // This path allows to avoid the JSON decoding if no
+ // simplification is asked, or if no "ignore-length" argument is
+ // present
std::string full;
context.ReadDicomAsJson(full, publicId);
call.GetOutput().AnswerBuffer(full, "application/json");
@@ -497,7 +538,7 @@ namespace Orthanc
}
-
+ template <bool GzipCompression>
static void GetRawFrame(RestApiGetCall& call)
{
std::string frameId = call.GetUriComponent("frame", "0");
@@ -520,7 +561,17 @@ namespace Orthanc
locker.GetDicom().GetRawFrame(raw, mime, frame);
}
- call.GetOutput().AnswerBuffer(raw, mime);
+ if (GzipCompression)
+ {
+ GzipCompressor gzip;
+ std::string compressed;
+ gzip.Compress(compressed, raw.empty() ? NULL : raw.c_str(), raw.size());
+ call.GetOutput().AnswerBuffer(compressed, "application/gzip");
+ }
+ else
+ {
+ call.GetOutput().AnswerBuffer(raw, mime);
+ }
}
@@ -999,16 +1050,7 @@ namespace Orthanc
if (ExtractSharedTags(sharedTags, context, publicId))
{
// Success: Send the value of the shared tags
- if (simplify)
- {
- Json::Value simplified;
- ServerToolbox::SimplifyTags(simplified, sharedTags, DicomToJsonFormat_Human);
- call.GetOutput().AnswerJson(simplified);
- }
- else
- {
- call.GetOutput().AnswerJson(sharedTags);
- }
+ AnswerDicomAsJson(call, sharedTags, simplify);
}
}
@@ -1031,6 +1073,9 @@ namespace Orthanc
std::string publicId = call.GetUriComponent("id", "");
bool simplify = call.HasArgument("simplify");
+ std::set<DicomTag> ignoreTagLength;
+ ParseSetOfTags(ignoreTagLength, call, "ignore-length");
+
typedef std::set<DicomTag> ModuleTags;
ModuleTags moduleTags;
DicomTag::AddTagsForModule(moduleTags, module);
@@ -1053,7 +1098,7 @@ namespace Orthanc
publicId = instances.front();
}
- context.ReadDicomAsJson(tags, publicId);
+ context.ReadDicomAsJson(tags, publicId, ignoreTagLength);
// Filter the tags of the instance according to the module
Json::Value result = Json::objectValue;
@@ -1066,16 +1111,7 @@ namespace Orthanc
}
}
- if (simplify)
- {
- Json::Value simplified;
- ServerToolbox::SimplifyTags(simplified, result, DicomToJsonFormat_Human);
- call.GetOutput().AnswerJson(simplified);
- }
- else
- {
- call.GetOutput().AnswerJson(result);
- }
+ AnswerDicomAsJson(call, result, simplify);
}
@@ -1272,6 +1308,9 @@ namespace Orthanc
std::string publicId = call.GetUriComponent("id", "");
bool simplify = call.HasArgument("simplify");
+ std::set<DicomTag> ignoreTagLength;
+ ParseSetOfTags(ignoreTagLength, call, "ignore-length");
+
// Retrieve all the instances of this patient/study/series
typedef std::list<std::string> Instances;
Instances instances;
@@ -1284,7 +1323,7 @@ namespace Orthanc
it != instances.end(); ++it)
{
Json::Value full;
- context.ReadDicomAsJson(full, *it);
+ context.ReadDicomAsJson(full, *it, ignoreTagLength);
if (simplify)
{
@@ -1383,16 +1422,7 @@ namespace Orthanc
Json::Value header;
dicom.HeaderToJson(header, DicomToJsonFormat_Full);
- if (simplify)
- {
- Json::Value simplified;
- ServerToolbox::SimplifyTags(simplified, header, DicomToJsonFormat_Human);
- call.GetOutput().AnswerJson(simplified);
- }
- else
- {
- call.GetOutput().AnswerJson(header);
- }
+ AnswerDicomAsJson(call, header, simplify);
}
@@ -1473,7 +1503,8 @@ namespace Orthanc
Register("/instances/{id}/frames/{frame}/image-uint16", GetImage<ImageExtractionMode_UInt16>);
Register("/instances/{id}/frames/{frame}/image-int16", GetImage<ImageExtractionMode_Int16>);
Register("/instances/{id}/frames/{frame}/matlab", GetMatlabImage);
- Register("/instances/{id}/frames/{frame}/raw", GetRawFrame);
+ Register("/instances/{id}/frames/{frame}/raw", GetRawFrame<false>);
+ Register("/instances/{id}/frames/{frame}/raw.gz", GetRawFrame<true>);
Register("/instances/{id}/pdf", ExtractPdf);
Register("/instances/{id}/preview", GetImage<ImageExtractionMode_Preview>);
Register("/instances/{id}/image-uint8", GetImage<ImageExtractionMode_UInt8>);
diff --git a/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp b/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp
index 69de4d1..bf725eb 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp
@@ -35,7 +35,7 @@
#include "OrthancRestApi.h"
#include "../OrthancInitialization.h"
-#include "../FromDcmtkBridge.h"
+#include "../../Core/DicomParsing/FromDcmtkBridge.h"
#include "../../Plugins/Engine/PluginsManager.h"
#include "../../Plugins/Engine/OrthancPlugins.h"
#include "../ServerContext.h"
@@ -251,7 +251,7 @@ namespace Orthanc
static void GetDefaultEncoding(RestApiGetCall& call)
{
- Encoding encoding = Configuration::GetDefaultEncoding();
+ Encoding encoding = GetDefaultDicomEncoding();
call.GetOutput().AnswerBuffer(EnumerationToString(encoding), "text/plain");
}
diff --git a/OrthancServer/PrecompiledHeadersServer.h b/OrthancServer/PrecompiledHeadersServer.h
index 84f7329..a85bcbb 100644
--- a/OrthancServer/PrecompiledHeadersServer.h
+++ b/OrthancServer/PrecompiledHeadersServer.h
@@ -37,42 +37,6 @@
#if ORTHANC_USE_PRECOMPILED_HEADERS == 1
-// DCMTK
-#include <dcmtk/dcmdata/dcchrstr.h>
-#include <dcmtk/dcmdata/dcdeftag.h>
-#include <dcmtk/dcmdata/dcdicent.h>
-#include <dcmtk/dcmdata/dcdict.h>
-#include <dcmtk/dcmdata/dcfilefo.h>
-#include <dcmtk/dcmdata/dcistrmb.h>
-#include <dcmtk/dcmdata/dcistrmf.h>
-#include <dcmtk/dcmdata/dcmetinf.h>
-#include <dcmtk/dcmdata/dcostrmb.h>
-#include <dcmtk/dcmdata/dcpixel.h>
-#include <dcmtk/dcmdata/dcpixseq.h>
-#include <dcmtk/dcmdata/dcpxitem.h>
-#include <dcmtk/dcmdata/dcuid.h>
-#include <dcmtk/dcmdata/dcvrae.h>
-#include <dcmtk/dcmdata/dcvras.h>
-#include <dcmtk/dcmdata/dcvrcs.h>
-#include <dcmtk/dcmdata/dcvrda.h>
-#include <dcmtk/dcmdata/dcvrds.h>
-#include <dcmtk/dcmdata/dcvrdt.h>
-#include <dcmtk/dcmdata/dcvrfd.h>
-#include <dcmtk/dcmdata/dcvrfl.h>
-#include <dcmtk/dcmdata/dcvris.h>
-#include <dcmtk/dcmdata/dcvrlo.h>
-#include <dcmtk/dcmdata/dcvrlt.h>
-#include <dcmtk/dcmdata/dcvrpn.h>
-#include <dcmtk/dcmdata/dcvrsh.h>
-#include <dcmtk/dcmdata/dcvrsl.h>
-#include <dcmtk/dcmdata/dcvrss.h>
-#include <dcmtk/dcmdata/dcvrst.h>
-#include <dcmtk/dcmdata/dcvrtm.h>
-#include <dcmtk/dcmdata/dcvrui.h>
-#include <dcmtk/dcmdata/dcvrul.h>
-#include <dcmtk/dcmdata/dcvrus.h>
-#include <dcmtk/dcmdata/dcvrut.h>
-#include <dcmtk/dcmnet/dcasccfg.h>
-#include <dcmtk/dcmnet/diutil.h>
+#include "ServerContext.h"
#endif
diff --git a/OrthancServer/QueryRetrieveHandler.cpp b/OrthancServer/QueryRetrieveHandler.cpp
index ef036b9..da92fb2 100644
--- a/OrthancServer/QueryRetrieveHandler.cpp
+++ b/OrthancServer/QueryRetrieveHandler.cpp
@@ -35,7 +35,7 @@
#include "QueryRetrieveHandler.h"
#include "OrthancInitialization.h"
-#include "FromDcmtkBridge.h"
+#include "../Core/DicomParsing/FromDcmtkBridge.h"
namespace Orthanc
diff --git a/OrthancServer/Scheduler/ModifyInstanceCommand.h b/OrthancServer/Scheduler/ModifyInstanceCommand.h
index 1553667..062457b 100644
--- a/OrthancServer/Scheduler/ModifyInstanceCommand.h
+++ b/OrthancServer/Scheduler/ModifyInstanceCommand.h
@@ -35,7 +35,7 @@
#include "IServerCommand.h"
#include "../ServerContext.h"
-#include "../DicomModification.h"
+#include "../../Core/DicomParsing/DicomModification.h"
namespace Orthanc
{
diff --git a/OrthancServer/Search/HierarchicalMatcher.cpp b/OrthancServer/Search/HierarchicalMatcher.cpp
index caf5131..ddb8e52 100644
--- a/OrthancServer/Search/HierarchicalMatcher.cpp
+++ b/OrthancServer/Search/HierarchicalMatcher.cpp
@@ -36,8 +36,8 @@
#include "../../Core/Logging.h"
#include "../../Core/OrthancException.h"
-#include "../FromDcmtkBridge.h"
-#include "../ToDcmtkBridge.h"
+#include "../../Core/DicomParsing/FromDcmtkBridge.h"
+#include "../../Core/DicomParsing/ToDcmtkBridge.h"
#include "../OrthancInitialization.h"
#include <dcmtk/dcmdata/dcfilefo.h>
@@ -122,9 +122,10 @@ namespace Orthanc
}
else
{
+ std::set<DicomTag> ignoreTagLength;
std::auto_ptr<DicomValue> value(FromDcmtkBridge::ConvertLeafElement
(*element, DicomToJsonFlags_None,
- ORTHANC_MAXIMUM_TAG_LENGTH, encoding));
+ ORTHANC_MAXIMUM_TAG_LENGTH, encoding, ignoreTagLength));
if (value->IsBinary())
{
@@ -222,9 +223,10 @@ namespace Orthanc
return false;
}
+ std::set<DicomTag> ignoreTagLength;
std::auto_ptr<DicomValue> value(FromDcmtkBridge::ConvertLeafElement
(*element, DicomToJsonFlags_None,
- ORTHANC_MAXIMUM_TAG_LENGTH, encoding));
+ ORTHANC_MAXIMUM_TAG_LENGTH, encoding, ignoreTagLength));
if (value->IsNull() ||
value->IsBinary() ||
diff --git a/OrthancServer/Search/HierarchicalMatcher.h b/OrthancServer/Search/HierarchicalMatcher.h
index d01859c..b8cee7c 100644
--- a/OrthancServer/Search/HierarchicalMatcher.h
+++ b/OrthancServer/Search/HierarchicalMatcher.h
@@ -33,9 +33,8 @@
#pragma once
-#include "../../Core/DicomFormat/DicomMap.h"
#include "IFindConstraint.h"
-#include "../ParsedDicomFile.h"
+#include "../../Core/DicomParsing/ParsedDicomFile.h"
class DcmItem;
diff --git a/OrthancServer/Search/IFindConstraint.cpp b/OrthancServer/Search/IFindConstraint.cpp
index 6f522ed..5e6149f 100644
--- a/OrthancServer/Search/IFindConstraint.cpp
+++ b/OrthancServer/Search/IFindConstraint.cpp
@@ -39,7 +39,7 @@
#include "ValueConstraint.h"
#include "WildcardConstraint.h"
-#include "../FromDcmtkBridge.h"
+#include "../../Core/DicomParsing/FromDcmtkBridge.h"
#include "../../Core/OrthancException.h"
namespace Orthanc
diff --git a/OrthancServer/Search/LookupIdentifierQuery.cpp b/OrthancServer/Search/LookupIdentifierQuery.cpp
index abe40c3..b0da867 100644
--- a/OrthancServer/Search/LookupIdentifierQuery.cpp
+++ b/OrthancServer/Search/LookupIdentifierQuery.cpp
@@ -36,7 +36,7 @@
#include "../../Core/OrthancException.h"
#include "SetOfResources.h"
-#include "../FromDcmtkBridge.h"
+#include "../../Core/DicomParsing/FromDcmtkBridge.h"
#include <cassert>
diff --git a/OrthancServer/Search/LookupResource.cpp b/OrthancServer/Search/LookupResource.cpp
index 35d7b67..38ba557 100644
--- a/OrthancServer/Search/LookupResource.cpp
+++ b/OrthancServer/Search/LookupResource.cpp
@@ -37,7 +37,7 @@
#include "../../Core/OrthancException.h"
#include "../../Core/FileStorage/StorageAccessor.h"
#include "../ServerToolbox.h"
-#include "../FromDcmtkBridge.h"
+#include "../../Core/DicomParsing/FromDcmtkBridge.h"
namespace Orthanc
diff --git a/OrthancServer/ServerContext.cpp b/OrthancServer/ServerContext.cpp
index b63c1ed..1acfd2d 100644
--- a/OrthancServer/ServerContext.cpp
+++ b/OrthancServer/ServerContext.cpp
@@ -38,7 +38,7 @@
#include "../Core/HttpServer/FilesystemHttpSender.h"
#include "../Core/HttpServer/HttpStreamTranscoder.h"
#include "../Core/Logging.h"
-#include "FromDcmtkBridge.h"
+#include "../Core/DicomParsing/FromDcmtkBridge.h"
#include "ServerToolbox.h"
#include "OrthancInitialization.h"
@@ -314,7 +314,7 @@ namespace Orthanc
{
if (e.GetErrorCode() == ErrorCode_InexistentTag)
{
- ServerToolbox::LogMissingRequiredTag(dicom.GetSummary());
+ dicom.GetSummary().LogMissingTagsForStore();
}
throw;
@@ -383,48 +383,82 @@ namespace Orthanc
}
- void ServerContext::ReadDicomAsJson(std::string& result,
- const std::string& instancePublicId)
+ void ServerContext::ReadDicomAsJsonInternal(std::string& result,
+ const std::string& instancePublicId)
{
FileInfo attachment;
if (index_.LookupAttachment(attachment, instancePublicId, FileContentType_DicomAsJson))
{
ReadAttachment(result, attachment);
- return;
}
+ else
+ {
+ // The "DICOM as JSON" summary is not available from the Orthanc
+ // store (most probably deleted), reconstruct it from the DICOM file
+ std::string dicom;
+ ReadDicom(dicom, instancePublicId);
- // The "DICOM as JSON" summary is not available from the Orthanc
- // store (most probably deleted), reconstruct it from the DICOM file
- std::string dicom;
- ReadDicom(dicom, instancePublicId);
-
- LOG(INFO) << "Reconstructing the missing DICOM-as-JSON summary for instance: " << instancePublicId;
+ LOG(INFO) << "Reconstructing the missing DICOM-as-JSON summary for instance: "
+ << instancePublicId;
- ParsedDicomFile parsed(dicom);
+ ParsedDicomFile parsed(dicom);
+
+ Json::Value summary;
+ parsed.DatasetToJson(summary);
- Json::Value summary;
- parsed.DatasetToJson(summary);
+ result = summary.toStyledString();
+
+ if (!AddAttachment(instancePublicId, FileContentType_DicomAsJson,
+ result.c_str(), result.size()))
+ {
+ LOG(WARNING) << "Cannot associate the DICOM-as-JSON summary to instance: " << instancePublicId;
+ throw OrthancException(ErrorCode_InternalError);
+ }
+ }
+ }
- result = summary.toStyledString();
- if (!AddAttachment(instancePublicId, FileContentType_DicomAsJson, result.c_str(), result.size()))
+ void ServerContext::ReadDicomAsJson(std::string& result,
+ const std::string& instancePublicId,
+ const std::set<DicomTag>& ignoreTagLength)
+ {
+ if (ignoreTagLength.empty())
{
- LOG(WARNING) << "Cannot associate the DICOM-as-JSON summary to instance: " << instancePublicId;
- throw OrthancException(ErrorCode_InternalError);
+ ReadDicomAsJsonInternal(result, instancePublicId);
+ }
+ else
+ {
+ Json::Value tmp;
+ ReadDicomAsJson(tmp, instancePublicId, ignoreTagLength);
+ result = tmp.toStyledString();
}
}
void ServerContext::ReadDicomAsJson(Json::Value& result,
- const std::string& instancePublicId)
+ const std::string& instancePublicId,
+ const std::set<DicomTag>& ignoreTagLength)
{
- std::string tmp;
- ReadDicomAsJson(tmp, instancePublicId);
+ if (ignoreTagLength.empty())
+ {
+ std::string tmp;
+ ReadDicomAsJsonInternal(tmp, instancePublicId);
- Json::Reader reader;
- if (!reader.parse(tmp, result))
+ Json::Reader reader;
+ if (!reader.parse(tmp, result))
+ {
+ throw OrthancException(ErrorCode_CorruptedFile);
+ }
+ }
+ else
{
- throw OrthancException(ErrorCode_CorruptedFile);
+ // The "DicomAsJson" attachment might have stored some tags as
+ // "too long". We are forced to re-parse the DICOM file.
+ std::string dicom;
+ ReadDicom(dicom, instancePublicId);
+
+ ParsedDicomFile parsed(dicom);
+ parsed.DatasetToJson(result, ignoreTagLength);
}
}
diff --git a/OrthancServer/ServerContext.h b/OrthancServer/ServerContext.h
index 72348db..c3f6c39 100644
--- a/OrthancServer/ServerContext.h
+++ b/OrthancServer/ServerContext.h
@@ -41,10 +41,10 @@
#include "../Core/RestApi/RestApiOutput.h"
#include "../Plugins/Engine/OrthancPlugins.h"
#include "DicomInstanceToStore.h"
-#include "DicomProtocol/ReusableDicomUserConnection.h"
+#include "../Core/DicomNetworking/ReusableDicomUserConnection.h"
#include "IServerListener.h"
#include "LuaScripting.h"
-#include "ParsedDicomFile.h"
+#include "../Core/DicomParsing/ParsedDicomFile.h"
#include "Scheduler/ServerScheduler.h"
#include "ServerIndex.h"
#include "OrthancHttpHandler.h"
@@ -106,6 +106,8 @@ namespace Orthanc
static void ChangeThread(ServerContext* that);
+ void ReadDicomAsJsonInternal(std::string& result,
+ const std::string& instancePublicId);
ServerIndex index_;
IStorageArea& area_;
@@ -193,10 +195,26 @@ namespace Orthanc
CompressionType compression);
void ReadDicomAsJson(std::string& result,
- const std::string& instancePublicId);
+ const std::string& instancePublicId,
+ const std::set<DicomTag>& ignoreTagLength);
void ReadDicomAsJson(Json::Value& result,
- const std::string& instancePublicId);
+ const std::string& instancePublicId,
+ const std::set<DicomTag>& ignoreTagLength);
+
+ void ReadDicomAsJson(std::string& result,
+ const std::string& instancePublicId)
+ {
+ std::set<DicomTag> ignoreTagLength;
+ ReadDicomAsJson(result, instancePublicId, ignoreTagLength);
+ }
+
+ void ReadDicomAsJson(Json::Value& result,
+ const std::string& instancePublicId)
+ {
+ std::set<DicomTag> ignoreTagLength;
+ ReadDicomAsJson(result, instancePublicId, ignoreTagLength);
+ }
void ReadDicom(std::string& dicom,
const std::string& instancePublicId)
diff --git a/OrthancServer/ServerEnumerations.cpp b/OrthancServer/ServerEnumerations.cpp
index b8e9746..c709288 100644
--- a/OrthancServer/ServerEnumerations.cpp
+++ b/OrthancServer/ServerEnumerations.cpp
@@ -317,197 +317,6 @@ namespace Orthanc
}
}
-
- const char* EnumerationToString(ModalityManufacturer manufacturer)
- {
- switch (manufacturer)
- {
- case ModalityManufacturer_Generic:
- return "Generic";
-
- case ModalityManufacturer_GenericNoWildcardInDates:
- return "GenericNoWildcardInDates";
-
- case ModalityManufacturer_GenericNoUniversalWildcard:
- return "GenericNoUniversalWildcard";
-
- case ModalityManufacturer_StoreScp:
- return "StoreScp";
-
- case ModalityManufacturer_ClearCanvas:
- return "ClearCanvas";
-
- case ModalityManufacturer_Dcm4Chee:
- return "Dcm4Chee";
-
- case ModalityManufacturer_Vitrea:
- return "Vitrea";
-
- default:
- throw OrthancException(ErrorCode_ParameterOutOfRange);
- }
- }
-
-
- const char* EnumerationToString(DicomRequestType type)
- {
- switch (type)
- {
- case DicomRequestType_Echo:
- return "Echo";
- break;
-
- case DicomRequestType_Find:
- return "Find";
- break;
-
- case DicomRequestType_Get:
- return "Get";
- break;
-
- case DicomRequestType_Move:
- return "Move";
- break;
-
- case DicomRequestType_Store:
- return "Store";
- break;
-
- default:
- throw OrthancException(ErrorCode_ParameterOutOfRange);
- }
- }
-
-
-
- ModalityManufacturer StringToModalityManufacturer(const std::string& manufacturer)
- {
- ModalityManufacturer result;
- bool obsolete = false;
-
- if (manufacturer == "Generic")
- {
- return ModalityManufacturer_Generic;
- }
- else if (manufacturer == "GenericNoWildcardInDates")
- {
- return ModalityManufacturer_GenericNoWildcardInDates;
- }
- else if (manufacturer == "GenericNoUniversalWildcard")
- {
- return ModalityManufacturer_GenericNoUniversalWildcard;
- }
- else if (manufacturer == "ClearCanvas")
- {
- return ModalityManufacturer_ClearCanvas;
- }
- else if (manufacturer == "StoreScp")
- {
- return ModalityManufacturer_StoreScp;
- }
- else if (manufacturer == "Dcm4Chee")
- {
- return ModalityManufacturer_Dcm4Chee;
- }
- else if (manufacturer == "Vitrea")
- {
- return ModalityManufacturer_Vitrea;
- }
- else if (manufacturer == "AgfaImpax" ||
- manufacturer == "SyngoVia")
- {
- result = ModalityManufacturer_GenericNoWildcardInDates;
- obsolete = true;
- }
- else if (manufacturer == "EFilm2" ||
- manufacturer == "MedInria")
- {
- result = ModalityManufacturer_Generic;
- obsolete = true;
- }
- else
- {
- throw OrthancException(ErrorCode_ParameterOutOfRange);
- }
-
- if (obsolete)
- {
- LOG(WARNING) << "The \"" << manufacturer << "\" manufacturer is obsolete since "
- << "Orthanc 1.3.0. To guarantee compatibility with future Orthanc "
- << "releases, you should replace it by \""
- << EnumerationToString(result)
- << "\" in your configuration file.";
- }
-
- return result;
- }
-
-
- const char* EnumerationToString(TransferSyntax syntax)
- {
- switch (syntax)
- {
- case TransferSyntax_Deflated:
- return "Deflated";
-
- case TransferSyntax_Jpeg:
- return "JPEG";
-
- case TransferSyntax_Jpeg2000:
- return "JPEG2000";
-
- case TransferSyntax_JpegLossless:
- return "JPEG Lossless";
-
- case TransferSyntax_Jpip:
- return "JPIP";
-
- case TransferSyntax_Mpeg2:
- return "MPEG2";
-
- case TransferSyntax_Rle:
- return "RLE";
-
- default:
- throw OrthancException(ErrorCode_ParameterOutOfRange);
- }
- }
-
-
- const char* EnumerationToString(DicomVersion version)
- {
- switch (version)
- {
- case DicomVersion_2008:
- return "2008";
- break;
-
- case DicomVersion_2017c:
- return "2017c";
- break;
-
- default:
- throw OrthancException(ErrorCode_ParameterOutOfRange);
- }
- }
-
-
- DicomVersion StringToDicomVersion(const std::string& version)
- {
- if (version == "2008")
- {
- return DicomVersion_2008;
- }
- else if (version == "2017c")
- {
- return DicomVersion_2017c;
- }
- else
- {
- throw OrthancException(ErrorCode_ParameterOutOfRange);
- }
- }
-
bool IsUserMetadata(MetadataType metadata)
{
diff --git a/OrthancServer/ServerEnumerations.h b/OrthancServer/ServerEnumerations.h
index 1c6f074..977b2f5 100644
--- a/OrthancServer/ServerEnumerations.h
+++ b/OrthancServer/ServerEnumerations.h
@@ -56,75 +56,6 @@ namespace Orthanc
StoreStatus_FilteredOut // Removed by NewInstanceFilter
};
- enum ModalityManufacturer
- {
- ModalityManufacturer_Generic,
- ModalityManufacturer_GenericNoWildcardInDates,
- ModalityManufacturer_GenericNoUniversalWildcard,
- ModalityManufacturer_StoreScp,
- ModalityManufacturer_ClearCanvas,
- ModalityManufacturer_Dcm4Chee,
- ModalityManufacturer_Vitrea
- };
-
- enum DicomRequestType
- {
- DicomRequestType_Echo,
- DicomRequestType_Find,
- DicomRequestType_Get,
- DicomRequestType_Move,
- DicomRequestType_Store
- };
-
- enum DicomReplaceMode
- {
- DicomReplaceMode_InsertIfAbsent,
- DicomReplaceMode_ThrowIfAbsent,
- DicomReplaceMode_IgnoreIfAbsent
- };
-
- enum TransferSyntax
- {
- TransferSyntax_Deflated,
- TransferSyntax_Jpeg,
- TransferSyntax_Jpeg2000,
- TransferSyntax_JpegLossless,
- TransferSyntax_Jpip,
- TransferSyntax_Mpeg2,
- TransferSyntax_Rle
- };
-
- enum DicomToJsonFormat
- {
- DicomToJsonFormat_Full,
- DicomToJsonFormat_Short,
- DicomToJsonFormat_Human
- };
-
- enum DicomToJsonFlags
- {
- DicomToJsonFlags_IncludeBinary = (1 << 0),
- DicomToJsonFlags_IncludePrivateTags = (1 << 1),
- DicomToJsonFlags_IncludeUnknownTags = (1 << 2),
- DicomToJsonFlags_IncludePixelData = (1 << 3),
- DicomToJsonFlags_ConvertBinaryToAscii = (1 << 4),
- DicomToJsonFlags_ConvertBinaryToNull = (1 << 5),
-
- // Some predefined combinations
- DicomToJsonFlags_None = 0,
- DicomToJsonFlags_Default = (DicomToJsonFlags_IncludeBinary |
- DicomToJsonFlags_IncludePixelData |
- DicomToJsonFlags_IncludePrivateTags |
- DicomToJsonFlags_IncludeUnknownTags |
- DicomToJsonFlags_ConvertBinaryToNull)
- };
-
- enum DicomFromJsonFlags
- {
- DicomFromJsonFlags_DecodeDataUriScheme = (1 << 0),
- DicomFromJsonFlags_GenerateIdentifiers = (1 << 1)
- };
-
enum IdentifierConstraintType
{
IdentifierConstraintType_Equal,
@@ -133,12 +64,6 @@ namespace Orthanc
IdentifierConstraintType_Wildcard /* Case sensitive, "*" or "?" are the only allowed wildcards */
};
- enum DicomVersion
- {
- DicomVersion_2008,
- DicomVersion_2017c
- };
-
/**
* WARNING: Do not change the explicit values in the enumerations
@@ -228,17 +153,5 @@ namespace Orthanc
const char* EnumerationToString(ChangeType type);
- const char* EnumerationToString(ModalityManufacturer manufacturer);
-
- const char* EnumerationToString(DicomRequestType type);
-
- const char* EnumerationToString(TransferSyntax syntax);
-
- const char* EnumerationToString(DicomVersion version);
-
- ModalityManufacturer StringToModalityManufacturer(const std::string& manufacturer);
-
- DicomVersion StringToDicomVersion(const std::string& version);
-
bool IsUserMetadata(MetadataType type);
}
diff --git a/OrthancServer/ServerIndex.cpp b/OrthancServer/ServerIndex.cpp
index a5ad4e5..aa5d2a5 100644
--- a/OrthancServer/ServerIndex.cpp
+++ b/OrthancServer/ServerIndex.cpp
@@ -41,13 +41,13 @@
#include "ServerIndexChange.h"
#include "EmbeddedResources.h"
#include "OrthancInitialization.h"
-#include "ParsedDicomFile.h"
+#include "../Core/DicomParsing/ParsedDicomFile.h"
#include "ServerToolbox.h"
#include "../Core/Toolbox.h"
#include "../Core/Logging.h"
#include "../Core/DicomFormat/DicomArray.h"
-#include "FromDcmtkBridge.h"
+#include "../Core/DicomParsing/FromDcmtkBridge.h"
#include "ServerContext.h"
#include "DicomInstanceToStore.h"
#include "Search/LookupResource.h"
diff --git a/OrthancServer/ServerToolbox.cpp b/OrthancServer/ServerToolbox.cpp
index 812cbcf..50f52cb 100644
--- a/OrthancServer/ServerToolbox.cpp
+++ b/OrthancServer/ServerToolbox.cpp
@@ -135,88 +135,6 @@ namespace Orthanc
}
- static std::string ValueAsString(const DicomMap& summary,
- const DicomTag& tag)
- {
- const DicomValue& value = summary.GetValue(tag);
- if (value.IsNull())
- {
- return "(null)";
- }
- else
- {
- return value.GetContent();
- }
- }
-
-
- void LogMissingRequiredTag(const DicomMap& summary)
- {
- std::string s, t;
-
- if (summary.HasTag(DICOM_TAG_PATIENT_ID))
- {
- if (t.size() > 0)
- t += ", ";
- t += "PatientID=" + ValueAsString(summary, DICOM_TAG_PATIENT_ID);
- }
- else
- {
- if (s.size() > 0)
- s += ", ";
- s += "PatientID";
- }
-
- if (summary.HasTag(DICOM_TAG_STUDY_INSTANCE_UID))
- {
- if (t.size() > 0)
- t += ", ";
- t += "StudyInstanceUID=" + ValueAsString(summary, DICOM_TAG_STUDY_INSTANCE_UID);
- }
- else
- {
- if (s.size() > 0)
- s += ", ";
- s += "StudyInstanceUID";
- }
-
- if (summary.HasTag(DICOM_TAG_SERIES_INSTANCE_UID))
- {
- if (t.size() > 0)
- t += ", ";
- t += "SeriesInstanceUID=" + ValueAsString(summary, DICOM_TAG_SERIES_INSTANCE_UID);
- }
- else
- {
- if (s.size() > 0)
- s += ", ";
- s += "SeriesInstanceUID";
- }
-
- if (summary.HasTag(DICOM_TAG_SOP_INSTANCE_UID))
- {
- if (t.size() > 0)
- t += ", ";
- t += "SOPInstanceUID=" + ValueAsString(summary, DICOM_TAG_SOP_INSTANCE_UID);
- }
- else
- {
- if (s.size() > 0)
- s += ", ";
- s += "SOPInstanceUID";
- }
-
- if (t.size() == 0)
- {
- LOG(ERROR) << "Store has failed because all the required tags (" << s << ") are missing (is it a DICOMDIR file?)";
- }
- else
- {
- LOG(ERROR) << "Store has failed because required tags (" << s << ") are missing for the following instance: " << t;
- }
- }
-
-
static void StoreMainDicomTagsInternal(IDatabaseWrapper& database,
int64_t resource,
const DicomMap& tags)
@@ -513,7 +431,7 @@ namespace Orthanc
ServerContext::DicomCacheLocker locker(context, *it);
Json::Value dicomAsJson;
- locker.GetDicom().ExtractDicomAsJson(dicomAsJson);
+ locker.GetDicom().DatasetToJson(dicomAsJson);
std::string s = dicomAsJson.toStyledString();
context.AddAttachment(*it, FileContentType_DicomAsJson, s.c_str(), s.size());
diff --git a/OrthancServer/ServerToolbox.h b/OrthancServer/ServerToolbox.h
index dfdf20e..adca9d9 100644
--- a/OrthancServer/ServerToolbox.h
+++ b/OrthancServer/ServerToolbox.h
@@ -45,8 +45,6 @@ namespace Orthanc
const Json::Value& source,
DicomToJsonFormat format);
- void LogMissingRequiredTag(const DicomMap& summary);
-
void StoreMainDicomTags(IDatabaseWrapper& database,
int64_t resource,
ResourceType level,
diff --git a/OrthancServer/main.cpp b/OrthancServer/main.cpp
index 67ecdc0..99ebbba 100644
--- a/OrthancServer/main.cpp
+++ b/OrthancServer/main.cpp
@@ -41,15 +41,15 @@
#include "../Core/HttpServer/FilesystemHttpHandler.h"
#include "../Core/Lua/LuaFunctionCall.h"
#include "../Core/DicomFormat/DicomArray.h"
-#include "DicomProtocol/DicomServer.h"
-#include "DicomProtocol/ReusableDicomUserConnection.h"
+#include "../Core/DicomNetworking/DicomServer.h"
+#include "../Core/DicomNetworking/ReusableDicomUserConnection.h"
#include "OrthancInitialization.h"
#include "ServerContext.h"
#include "OrthancFindRequestHandler.h"
#include "OrthancMoveRequestHandler.h"
#include "ServerToolbox.h"
#include "../Plugins/Engine/OrthancPlugins.h"
-#include "FromDcmtkBridge.h"
+#include "../Core/DicomParsing/FromDcmtkBridge.h"
using namespace Orthanc;
@@ -89,6 +89,23 @@ public:
+class ModalitiesFromConfiguration : public Orthanc::DicomServer::IRemoteModalities
+{
+public:
+ virtual bool IsSameAETitle(const std::string& aet1,
+ const std::string& aet2)
+ {
+ return Orthanc::Configuration::IsSameAETitle(aet1, aet2);
+ }
+
+ virtual bool LookupAETitle(RemoteModalityParameters& modality,
+ const std::string& aet)
+ {
+ return Orthanc::Configuration::LookupDicomModalityUsingAETitle(modality, aet);
+ }
+};
+
+
class MyDicomServerFactory :
public IStoreRequestHandlerFactory,
public IFindRequestHandlerFactory,
@@ -152,12 +169,14 @@ class OrthancApplicationEntityFilter : public IApplicationEntityFilter
{
private:
ServerContext& context_;
+ bool alwaysAllowEcho_;
bool alwaysAllowStore_;
public:
OrthancApplicationEntityFilter(ServerContext& context) :
context_(context)
{
+ alwaysAllowEcho_ = Configuration::GetGlobalBoolParameter("DicomAlwaysAllowEcho", true);
alwaysAllowStore_ = Configuration::GetGlobalBoolParameter("DicomAlwaysAllowStore", true);
}
@@ -168,7 +187,8 @@ public:
LOG(INFO) << "Incoming connection from AET " << remoteAet
<< " on IP " << remoteIp << ", calling AET " << calledAet;
- return (alwaysAllowStore_ ||
+ return (alwaysAllowEcho_ ||
+ alwaysAllowStore_ ||
Configuration::IsKnownAETitle(remoteAet, remoteIp));
}
@@ -180,10 +200,16 @@ public:
LOG(INFO) << "Incoming " << Orthanc::EnumerationToString(type) << " request from AET "
<< remoteAet << " on IP " << remoteIp << ", calling AET " << calledAet;
- if (type == DicomRequestType_Store &&
- alwaysAllowStore_)
+ if (type == DicomRequestType_Echo &&
+ alwaysAllowEcho_)
+ {
+ // Incoming C-Echo requests are always accepted, even from unknown AET
+ return true;
+ }
+ else if (type == DicomRequestType_Store &&
+ alwaysAllowStore_)
{
- // Incoming store requests are always accepted, even from unknown AET
+ // Incoming C-Store requests are always accepted, even from unknown AET
return true;
}
else if (!Configuration::IsKnownAETitle(remoteAet, remoteIp))
@@ -788,10 +814,12 @@ static bool StartDicomServer(ServerContext& context,
}
MyDicomServerFactory serverFactory(context);
-
- // DICOM server
- DicomServer dicomServer;
OrthancApplicationEntityFilter dicomFilter(context);
+ ModalitiesFromConfiguration modalities;
+
+ // Setup the DICOM server
+ DicomServer dicomServer;
+ dicomServer.SetRemoteModalities(modalities);
dicomServer.SetCalledApplicationEntityTitleCheck(Configuration::GetGlobalBoolParameter("DicomCheckCalledAet", false));
dicomServer.SetStoreRequestHandlerFactory(serverFactory);
dicomServer.SetMoveRequestHandlerFactory(serverFactory);
diff --git a/Plugins/Engine/OrthancPlugins.cpp b/Plugins/Engine/OrthancPlugins.cpp
index da07351..99ac7bf 100644
--- a/Plugins/Engine/OrthancPlugins.cpp
+++ b/Plugins/Engine/OrthancPlugins.cpp
@@ -45,13 +45,13 @@
#include "../../Core/Logging.h"
#include "../../Core/OrthancException.h"
#include "../../Core/Toolbox.h"
-#include "../../OrthancServer/FromDcmtkBridge.h"
-#include "../../OrthancServer/ToDcmtkBridge.h"
+#include "../../Core/DicomParsing/FromDcmtkBridge.h"
+#include "../../Core/DicomParsing/ToDcmtkBridge.h"
#include "../../OrthancServer/OrthancInitialization.h"
#include "../../OrthancServer/ServerContext.h"
#include "../../OrthancServer/ServerToolbox.h"
#include "../../OrthancServer/Search/HierarchicalMatcher.h"
-#include "../../OrthancServer/Internals/DicomImageDecoder.h"
+#include "../../Core/DicomParsing/Internals/DicomImageDecoder.h"
#include "../../Core/Compression/ZlibCompressor.h"
#include "../../Core/Compression/GzipCompressor.h"
#include "../../Core/Images/Image.h"
diff --git a/Plugins/Engine/OrthancPlugins.h b/Plugins/Engine/OrthancPlugins.h
index a8e8dff..7bf2820 100644
--- a/Plugins/Engine/OrthancPlugins.h
+++ b/Plugins/Engine/OrthancPlugins.h
@@ -53,14 +53,14 @@ namespace Orthanc
#else
+#include "../../Core/DicomNetworking/IFindRequestHandlerFactory.h"
+#include "../../Core/DicomNetworking/IMoveRequestHandlerFactory.h"
+#include "../../Core/DicomNetworking/IWorklistRequestHandlerFactory.h"
#include "../../Core/FileStorage/IStorageArea.h"
#include "../../Core/HttpServer/IHttpHandler.h"
#include "../../Core/HttpServer/IIncomingHttpRequestFilter.h"
-#include "../../OrthancServer/IServerListener.h"
#include "../../OrthancServer/IDicomImageDecoder.h"
-#include "../../OrthancServer/DicomProtocol/IWorklistRequestHandlerFactory.h"
-#include "../../OrthancServer/DicomProtocol/IFindRequestHandlerFactory.h"
-#include "../../OrthancServer/DicomProtocol/IMoveRequestHandlerFactory.h"
+#include "../../OrthancServer/IServerListener.h"
#include "OrthancPluginDatabase.h"
#include "PluginsManager.h"
diff --git a/Plugins/Engine/PluginsEnumerations.cpp b/Plugins/Engine/PluginsEnumerations.cpp
index 53f587e..86c2caf 100644
--- a/Plugins/Engine/PluginsEnumerations.cpp
+++ b/Plugins/Engine/PluginsEnumerations.cpp
@@ -139,15 +139,27 @@ namespace Orthanc
{
switch (format)
{
+ case PixelFormat_BGRA32:
+ return OrthancPluginPixelFormat_BGRA32;
+
+ case PixelFormat_Float32:
+ return OrthancPluginPixelFormat_Float32;
+
case PixelFormat_Grayscale16:
return OrthancPluginPixelFormat_Grayscale16;
+ case PixelFormat_Grayscale32:
+ return OrthancPluginPixelFormat_Grayscale32;
+
case PixelFormat_Grayscale8:
return OrthancPluginPixelFormat_Grayscale8;
case PixelFormat_RGB24:
return OrthancPluginPixelFormat_RGB24;
+ case PixelFormat_RGB48:
+ return OrthancPluginPixelFormat_RGB48;
+
case PixelFormat_RGBA32:
return OrthancPluginPixelFormat_RGBA32;
@@ -164,15 +176,27 @@ namespace Orthanc
{
switch (format)
{
+ case OrthancPluginPixelFormat_BGRA32:
+ return PixelFormat_BGRA32;
+
+ case OrthancPluginPixelFormat_Float32:
+ return PixelFormat_Float32;
+
case OrthancPluginPixelFormat_Grayscale16:
return PixelFormat_Grayscale16;
+ case OrthancPluginPixelFormat_Grayscale32:
+ return PixelFormat_Grayscale32;
+
case OrthancPluginPixelFormat_Grayscale8:
return PixelFormat_Grayscale8;
case OrthancPluginPixelFormat_RGB24:
return PixelFormat_RGB24;
+ case OrthancPluginPixelFormat_RGB48:
+ return PixelFormat_RGB48;
+
case OrthancPluginPixelFormat_RGBA32:
return PixelFormat_RGBA32;
diff --git a/Plugins/Engine/PluginsManager.cpp b/Plugins/Engine/PluginsManager.cpp
index 776c58a..0f0219d 100644
--- a/Plugins/Engine/PluginsManager.cpp
+++ b/Plugins/Engine/PluginsManager.cpp
@@ -49,7 +49,7 @@
#ifdef WIN32
#define PLUGIN_EXTENSION ".dll"
-#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
+#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#define PLUGIN_EXTENSION ".so"
#elif defined(__APPLE__) && defined(__MACH__)
#define PLUGIN_EXTENSION ".dylib"
diff --git a/Plugins/Engine/SharedLibrary.cpp b/Plugins/Engine/SharedLibrary.cpp
index 97e231d..74c0508 100644
--- a/Plugins/Engine/SharedLibrary.cpp
+++ b/Plugins/Engine/SharedLibrary.cpp
@@ -46,7 +46,7 @@
#if defined(_WIN32)
#include <windows.h>
-#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
+#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#include <dlfcn.h>
#else
#error Support your platform here
@@ -66,7 +66,7 @@ namespace Orthanc
throw OrthancException(ErrorCode_SharedLibrary);
}
-#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
+#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__)
handle_ = ::dlopen(path_.c_str(), RTLD_NOW);
if (handle_ == NULL)
{
@@ -92,7 +92,7 @@ namespace Orthanc
{
#if defined(_WIN32)
::FreeLibrary((HMODULE)handle_);
-#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
+#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__)
::dlclose(handle_);
#else
#error Support your platform here
@@ -110,7 +110,7 @@ namespace Orthanc
#if defined(_WIN32)
return ::GetProcAddress((HMODULE)handle_, name.c_str());
-#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
+#elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__)
return ::dlsym(handle_, name.c_str());
#else
#error Support your platform here
diff --git a/Plugins/Include/orthanc/OrthancCPlugin.h b/Plugins/Include/orthanc/OrthancCPlugin.h
index f278a36..542f223 100644
--- a/Plugins/Include/orthanc/OrthancCPlugin.h
+++ b/Plugins/Include/orthanc/OrthancCPlugin.h
@@ -118,7 +118,17 @@
#define ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER 1
#define ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER 3
-#define ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER 0
+#define ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER 1
+
+
+#if !defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE)
+#define ORTHANC_PLUGINS_VERSION_IS_ABOVE(major, minor, revision) \
+ (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER > major || \
+ (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER == major && \
+ (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER > minor || \
+ (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER == minor && \
+ ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER >= revision))))
+#endif
@@ -570,6 +580,38 @@ extern "C"
OrthancPluginPixelFormat_Unknown = 6, /*!< Unknown pixel format */
+ /**
+ * @brief Color image in RGB48 format.
+ *
+ * This format describes a color image. The pixels are stored in 6
+ * consecutive bytes. The memory layout is RRGGBB.
+ **/
+ OrthancPluginPixelFormat_RGB48 = 7,
+
+ /**
+ * @brief Graylevel, unsigned 32bpp image.
+ *
+ * The image is graylevel. Each pixel is unsigned and stored in
+ * four bytes.
+ **/
+ OrthancPluginPixelFormat_Grayscale32 = 8,
+
+ /**
+ * @brief Graylevel, floating-point 32bpp image.
+ *
+ * The image is graylevel. Each pixel is floating-point and stored
+ * in four bytes.
+ **/
+ OrthancPluginPixelFormat_Float32 = 9,
+
+ /**
+ * @brief Color image in BGRA32 format.
+ *
+ * This format describes a color image. The pixels are stored in 4
+ * consecutive bytes. The memory layout is BGRA.
+ **/
+ OrthancPluginPixelFormat_BGRA32 = 10,
+
_OrthancPluginPixelFormat_INTERNAL = 0x7fffffff
} OrthancPluginPixelFormat;
diff --git a/Plugins/Samples/Common/DicomTag.h b/Plugins/Samples/Common/DicomTag.h
index 51e5901..61f63f6 100644
--- a/Plugins/Samples/Common/DicomTag.h
+++ b/Plugins/Samples/Common/DicomTag.h
@@ -94,8 +94,10 @@ namespace OrthancPlugins
static const DicomTag DICOM_TAG_ROWS(0x0028, 0x0010);
static const DicomTag DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021f);
static const DicomTag DICOM_TAG_SAMPLES_PER_PIXEL(0x0028, 0x0002);
+ static const DicomTag DICOM_TAG_SERIES_INSTANCE_UID(0x0020, 0x000e);
static const DicomTag DICOM_TAG_SLICE_THICKNESS(0x0018, 0x0050);
static const DicomTag DICOM_TAG_SOP_CLASS_UID(0x0008, 0x0016);
+ static const DicomTag DICOM_TAG_SOP_INSTANCE_UID(0x0008, 0x0018);
static const DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_COLUMNS(0x0048, 0x0006);
static const DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_ROWS(0x0048, 0x0007);
static const DicomTag DICOM_TAG_TRANSFER_SYNTAX_UID(0x0002, 0x0010);
diff --git a/Plugins/Samples/Common/OrthancPluginCppWrapper.h b/Plugins/Samples/Common/OrthancPluginCppWrapper.h
index 4f8c1df..05838ad 100644
--- a/Plugins/Samples/Common/OrthancPluginCppWrapper.h
+++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.h
@@ -44,13 +44,15 @@
+#if !defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE)
#define ORTHANC_PLUGINS_VERSION_IS_ABOVE(major, minor, revision) \
(ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER > major || \
(ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER == major && \
(ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER > minor || \
(ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER == minor && \
ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER >= revision))))
-
+#endif
+
#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 2, 0)
// The "OrthancPluginFindMatcher()" primitive was introduced in Orthanc 1.2.0
diff --git a/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp b/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp
index 9ebb67b..976ebd7 100644
--- a/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp
+++ b/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp
@@ -199,6 +199,13 @@ namespace OrthancPlugins
case gdcm::PixelFormat::UINT8:
return OrthancPluginPixelFormat_RGB24;
+ case gdcm::PixelFormat::UINT16:
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 3, 1)
+ return OrthancPluginPixelFormat_RGB48;
+#else
+ throw std::runtime_error("RGB48 pixel format is only supported if compiled against Orthanc SDK >= 1.3.1");
+#endif
+
default:
break;
}
@@ -240,6 +247,11 @@ namespace OrthancPlugins
case OrthancPluginPixelFormat_RGB24:
return 3;
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 3, 1)
+ case OrthancPluginPixelFormat_RGB48:
+ return 6;
+#endif
+
default:
throw std::runtime_error("Unsupport pixel format");
}
diff --git a/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h b/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h
index ee80750..c7378ca 100644
--- a/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h
+++ b/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h
@@ -26,6 +26,18 @@
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
+
+// This is for compatibility with Orthanc SDK <= 1.3.0
+#if !defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE)
+#define ORTHANC_PLUGINS_VERSION_IS_ABOVE(major, minor, revision) \
+ (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER > major || \
+ (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER == major && \
+ (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER > minor || \
+ (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER == minor && \
+ ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER >= revision))))
+#endif
+
+
namespace OrthancPlugins
{
class GdcmImageDecoder : public boost::noncopyable
diff --git a/Plugins/Samples/ServeFolders/Plugin.cpp b/Plugins/Samples/ServeFolders/Plugin.cpp
index 8a444f2..ab323fa 100644
--- a/Plugins/Samples/ServeFolders/Plugin.cpp
+++ b/Plugins/Samples/ServeFolders/Plugin.cpp
@@ -67,6 +67,7 @@ static void RegisterDefaultExtensions()
extensions_["pexe"] = "application/x-pnacl";
extensions_["png"] = "image/png";
extensions_["svg"] = "image/svg+xml";
+ extensions_["wasm"] = "application/wasm";
extensions_["woff"] = "application/x-font-woff";
extensions_["xml"] = "application/xml";
}
diff --git a/Resources/CMake/BoostConfiguration.cmake b/Resources/CMake/BoostConfiguration.cmake
index 59728b5..66ccfa8 100644
--- a/Resources/CMake/BoostConfiguration.cmake
+++ b/Resources/CMake/BoostConfiguration.cmake
@@ -7,8 +7,12 @@ else()
#set(Boost_DEBUG 1)
#set(Boost_USE_STATIC_LIBS ON)
+ if (ENABLE_LOCALE)
+ list(APPEND ORTHANC_BOOST_COMPONENTS locale)
+ endif()
+
find_package(Boost
- COMPONENTS filesystem thread system date_time regex locale ${ORTHANC_BOOST_COMPONENTS})
+ COMPONENTS filesystem thread system date_time regex ${ORTHANC_BOOST_COMPONENTS})
if (NOT Boost_FOUND)
message(FATAL_ERROR "Unable to locate Boost on this system")
@@ -27,112 +31,120 @@ else()
)
endif()
- #if (${Boost_VERSION} LESS 104800)
- # boost::locale is only available from 1.48.00
- #message("Too old version of Boost (${Boost_LIB_VERSION}): Building the static version")
- # set(BOOST_STATIC 1)
- #endif()
-
include_directories(${Boost_INCLUDE_DIRS})
link_libraries(${Boost_LIBRARIES})
endif()
if (BOOST_STATIC)
- # Parameters for Boost 1.64.0
- set(BOOST_NAME boost_1_64_0)
- set(BOOST_BCP_SUFFIX bcpdigest-1.3.0)
- set(BOOST_MD5 "ecb266cf46adcc7f695ad12685871174")
+ ##
+ ## Parameters for static compilation of Boost
+ ##
+
+ set(BOOST_NAME boost_1_65_1)
+ set(BOOST_BCP_SUFFIX bcpdigest-1.3.1)
+ set(BOOST_MD5 "92c9c603e56bbd7a450a305f08747d90")
set(BOOST_URL "http://www.orthanc-server.com/downloads/third-party/${BOOST_NAME}_${BOOST_BCP_SUFFIX}.tar.gz")
- set(BOOST_FILESYSTEM_SOURCES_DIR "${BOOST_NAME}/libs/filesystem/src")
set(BOOST_SOURCES_DIR ${CMAKE_BINARY_DIR}/${BOOST_NAME})
DownloadPackage(${BOOST_MD5} ${BOOST_URL} "${BOOST_SOURCES_DIR}")
- set(BOOST_SOURCES)
- if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64")
+ ##
+ ## Generic configuration of Boost
+ ##
+
+ if (CMAKE_COMPILER_IS_GNUCXX)
+ add_definitions(-isystem ${BOOST_SOURCES_DIR})
+ endif()
+
+ include_directories(
+ ${BOOST_SOURCES_DIR}
+ )
+
+ add_definitions(
+ # Static build of Boost
+ -DBOOST_ALL_NO_LIB
+ -DBOOST_ALL_NOLIB
+ -DBOOST_DATE_TIME_NO_LIB
+ -DBOOST_THREAD_BUILD_LIB
+ -DBOOST_PROGRAM_OPTIONS_NO_LIB
+ -DBOOST_REGEX_NO_LIB
+ -DBOOST_SYSTEM_NO_LIB
+ -DBOOST_LOCALE_NO_LIB
+ )
+
+ set(BOOST_SOURCES
+ ${BOOST_SOURCES_DIR}/libs/system/src/error_code.cpp
+ )
+
+
+ ##
+ ## Configuration of boost::thread
+ ##
+
+ if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
+ CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
+ CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "kFreeBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR
+ CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR
+ CMAKE_SYSTEM_NAME STREQUAL "NaCl64")
list(APPEND BOOST_SOURCES
${BOOST_SOURCES_DIR}/libs/atomic/src/lockpool.cpp
${BOOST_SOURCES_DIR}/libs/thread/src/pthread/once.cpp
${BOOST_SOURCES_DIR}/libs/thread/src/pthread/thread.cpp
)
- add_definitions(
- -DBOOST_LOCALE_WITH_ICONV=1
- -DBOOST_LOCALE_NO_WINAPI_BACKEND=1
- -DBOOST_LOCALE_NO_STD_BACKEND=1
- )
if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64")
+ CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR
+ CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR
+ CMAKE_SYSTEM_NAME STREQUAL "NaCl64")
add_definitions(-DBOOST_HAS_SCHED_YIELD=1)
endif()
- elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
list(APPEND BOOST_SOURCES
${BOOST_SOURCES_DIR}/libs/thread/src/win32/tss_dll.cpp
${BOOST_SOURCES_DIR}/libs/thread/src/win32/thread.cpp
${BOOST_SOURCES_DIR}/libs/thread/src/win32/tss_pe.cpp
- ${BOOST_FILESYSTEM_SOURCES_DIR}/windows_file_codecvt.cpp
)
- # Starting with release 0.8.2, Orthanc statically links against
- # libiconv, even on Windows. Indeed, the "WCONV" library of
- # Windows XP seems not to support properly several codepages
- # (notably "Latin3", "Hebrew", and "Arabic").
-
- if (USE_BOOST_ICONV)
- include(${ORTHANC_ROOT}/Resources/CMake/LibIconvConfiguration.cmake)
- else()
- add_definitions(-DBOOST_LOCALE_WITH_WCONV=1)
- endif()
-
- add_definitions(
- -DBOOST_LOCALE_NO_POSIX_BACKEND=1
- -DBOOST_LOCALE_NO_STD_BACKEND=1
- )
-
- elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
- add_definitions(
- -DBOOST_LOCALE_NO_POSIX_BACKEND=1
- -DBOOST_LOCALE_NO_STD_BACKEND=1
- )
+ elseif (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
else()
message(FATAL_ERROR "Support your platform here")
endif()
- if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
- list(APPEND BOOST_SOURCES
- ${BOOST_SOURCES_DIR}/libs/filesystem/src/utf8_codecvt_facet.cpp
- )
- endif()
+ ##
+ ## Configuration of boost::regex
+ ##
+
aux_source_directory(${BOOST_SOURCES_DIR}/libs/regex/src BOOST_REGEX_SOURCES)
list(APPEND BOOST_SOURCES
${BOOST_REGEX_SOURCES}
+ )
+
+
+ ##
+ ## Configuration of boost::datetime
+ ##
+
+ list(APPEND BOOST_SOURCES
${BOOST_SOURCES_DIR}/libs/date_time/src/gregorian/greg_month.cpp
- ${BOOST_SOURCES_DIR}/libs/system/src/error_code.cpp
)
- if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
- list(APPEND BOOST_SOURCES
- ${BOOST_SOURCES_DIR}/libs/locale/src/encoding/codepage.cpp
- )
- endif()
- if (${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64")
+ ##
+ ## Configuration of boost::filesystem
+ ##
+
+ if (CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR
+ CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR
+ CMAKE_SYSTEM_NAME STREQUAL "NaCl64")
# boost::filesystem is not available on PNaCl
add_definitions(
-DBOOST_HAS_FILESYSTEM_V3=0
@@ -143,50 +155,36 @@ if (BOOST_STATIC)
-DBOOST_HAS_FILESYSTEM_V3=1
)
list(APPEND BOOST_SOURCES
- ${BOOST_FILESYSTEM_SOURCES_DIR}/codecvt_error_category.cpp
- ${BOOST_FILESYSTEM_SOURCES_DIR}/operations.cpp
- ${BOOST_FILESYSTEM_SOURCES_DIR}/path.cpp
- ${BOOST_FILESYSTEM_SOURCES_DIR}/path_traits.cpp
+ ${BOOST_NAME}/libs/filesystem/src/codecvt_error_category.cpp
+ ${BOOST_NAME}/libs/filesystem/src/operations.cpp
+ ${BOOST_NAME}/libs/filesystem/src/path.cpp
+ ${BOOST_NAME}/libs/filesystem/src/path_traits.cpp
)
- endif()
- if (USE_BOOST_LOCALE_BACKEND)
- if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64")
- list(APPEND BOOST_SOURCES
- ${BOOST_SOURCES_DIR}/libs/locale/src/posix/codecvt.cpp
- ${BOOST_SOURCES_DIR}/libs/locale/src/posix/collate.cpp
- ${BOOST_SOURCES_DIR}/libs/locale/src/posix/converter.cpp
- ${BOOST_SOURCES_DIR}/libs/locale/src/posix/numeric.cpp
- ${BOOST_SOURCES_DIR}/libs/locale/src/posix/posix_backend.cpp
+ if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
+ CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
+ list(APPEND BOOST_SOURCES
+ ${BOOST_SOURCES_DIR}/libs/filesystem/src/utf8_codecvt_facet.cpp
)
- elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
+
+ elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
list(APPEND BOOST_SOURCES
- ${BOOST_SOURCES_DIR}/libs/locale/src/win32/collate.cpp
- ${BOOST_SOURCES_DIR}/libs/locale/src/win32/converter.cpp
- ${BOOST_SOURCES_DIR}/libs/locale/src/win32/lcid.cpp
- ${BOOST_SOURCES_DIR}/libs/locale/src/win32/numeric.cpp
- ${BOOST_SOURCES_DIR}/libs/locale/src/win32/win_backend.cpp
+ ${BOOST_NAME}/libs/filesystem/src/windows_file_codecvt.cpp
)
- else()
- message(FATAL_ERROR "Support your platform here")
endif()
+ endif()
- list(APPEND BOOST_SOURCES
- ${BOOST_REGEX_SOURCES}
- ${BOOST_SOURCES_DIR}/libs/date_time/src/gregorian/greg_month.cpp
- ${BOOST_SOURCES_DIR}/libs/system/src/error_code.cpp
- ${BOOST_FILESYSTEM_SOURCES_DIR}/codecvt_error_category.cpp
- ${BOOST_FILESYSTEM_SOURCES_DIR}/operations.cpp
- ${BOOST_FILESYSTEM_SOURCES_DIR}/path.cpp
- ${BOOST_FILESYSTEM_SOURCES_DIR}/path_traits.cpp
+ ##
+ ## Configuration of boost::locale
+ ##
+ if (NOT ENABLE_LOCALE)
+ message("boost::locale is disabled")
+ else()
+ list(APPEND BOOST_SOURCES
+ ${BOOST_SOURCES_DIR}/libs/locale/src/encoding/codepage.cpp
${BOOST_SOURCES_DIR}/libs/locale/src/shared/generator.cpp
${BOOST_SOURCES_DIR}/libs/locale/src/shared/date_time.cpp
${BOOST_SOURCES_DIR}/libs/locale/src/shared/formatting.cpp
@@ -200,39 +198,75 @@ if (BOOST_STATIC)
${BOOST_SOURCES_DIR}/libs/locale/src/util/info.cpp
${BOOST_SOURCES_DIR}/libs/locale/src/util/locale_data.cpp
)
- endif()
- add_definitions(
- # Static build of Boost
- -DBOOST_ALL_NO_LIB
- -DBOOST_ALL_NOLIB
- -DBOOST_DATE_TIME_NO_LIB
- -DBOOST_THREAD_BUILD_LIB
- -DBOOST_PROGRAM_OPTIONS_NO_LIB
- -DBOOST_REGEX_NO_LIB
- -DBOOST_SYSTEM_NO_LIB
- -DBOOST_LOCALE_NO_LIB
- -DBOOST_HAS_LOCALE=1
- )
+ if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
+ CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
+ CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "kFreeBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR
+ CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR
+ CMAKE_SYSTEM_NAME STREQUAL "NaCl64")
+ list(APPEND BOOST_SOURCES
+ ${BOOST_SOURCES_DIR}/libs/locale/src/posix/codecvt.cpp
+ ${BOOST_SOURCES_DIR}/libs/locale/src/posix/collate.cpp
+ ${BOOST_SOURCES_DIR}/libs/locale/src/posix/converter.cpp
+ ${BOOST_SOURCES_DIR}/libs/locale/src/posix/numeric.cpp
+ ${BOOST_SOURCES_DIR}/libs/locale/src/posix/posix_backend.cpp
+ )
- if (CMAKE_COMPILER_IS_GNUCXX)
- add_definitions(-isystem ${BOOST_SOURCES_DIR})
- endif()
+ add_definitions(
+ -DBOOST_LOCALE_WITH_ICONV=1
+ -DBOOST_LOCALE_NO_WINAPI_BACKEND=1
+ -DBOOST_LOCALE_NO_STD_BACKEND=1
+ )
+
+ elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
+ list(APPEND BOOST_SOURCES
+ ${BOOST_SOURCES_DIR}/libs/locale/src/std/codecvt.cpp
+ ${BOOST_SOURCES_DIR}/libs/locale/src/std/collate.cpp
+ ${BOOST_SOURCES_DIR}/libs/locale/src/std/converter.cpp
+ ${BOOST_SOURCES_DIR}/libs/locale/src/std/numeric.cpp
+ ${BOOST_SOURCES_DIR}/libs/locale/src/std/std_backend.cpp
+ )
- include_directories(
- ${BOOST_SOURCES_DIR}
- )
+ add_definitions(
+ -DBOOST_LOCALE_WITH_ICONV=1
+ -DBOOST_LOCALE_NO_WINAPI_BACKEND=1
+ -DBOOST_LOCALE_NO_POSIX_BACKEND=1
+ )
+
+ elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ list(APPEND BOOST_SOURCES
+ ${BOOST_SOURCES_DIR}/libs/locale/src/win32/collate.cpp
+ ${BOOST_SOURCES_DIR}/libs/locale/src/win32/converter.cpp
+ ${BOOST_SOURCES_DIR}/libs/locale/src/win32/lcid.cpp
+ ${BOOST_SOURCES_DIR}/libs/locale/src/win32/numeric.cpp
+ ${BOOST_SOURCES_DIR}/libs/locale/src/win32/win_backend.cpp
+ )
- source_group(ThirdParty\\boost REGULAR_EXPRESSION ${BOOST_SOURCES_DIR}/.*)
+ add_definitions(
+ -DBOOST_LOCALE_NO_POSIX_BACKEND=1
+ -DBOOST_LOCALE_NO_STD_BACKEND=1
+ )
-else()
- add_definitions(
- -DBOOST_HAS_LOCALE=1
- )
-endif()
+ # Starting with release 0.8.2, Orthanc statically links against
+ # libiconv, even on Windows. Indeed, the "WCONV" library of
+ # Windows XP seems not to support properly several codepages
+ # (notably "Latin3", "Hebrew", and "Arabic"). Set
+ # "USE_BOOST_ICONV" to "OFF" to use WCONV anyway.
+ if (USE_BOOST_ICONV)
+ add_definitions(-DBOOST_LOCALE_WITH_ICONV=1)
+ else()
+ add_definitions(-DBOOST_LOCALE_WITH_WCONV=1)
+ endif()
-add_definitions(
- -DBOOST_HAS_DATE_TIME=1
- -DBOOST_HAS_REGEX=1
- )
+ else()
+ message(FATAL_ERROR "Support your platform here")
+ endif()
+ endif()
+
+
+ source_group(ThirdParty\\boost REGULAR_EXPRESSION ${BOOST_SOURCES_DIR}/.*)
+
+endif()
diff --git a/Resources/CMake/BoostConfiguration.sh b/Resources/CMake/BoostConfiguration.sh
index 2e0ca40..d77a8c6 100755
--- a/Resources/CMake/BoostConfiguration.sh
+++ b/Resources/CMake/BoostConfiguration.sh
@@ -16,22 +16,26 @@ set -u
## - Orthanc between 0.9.2 and 0.9.4: Boost 1.58.0
## - Orthanc between 0.9.5 and 1.0.0: Boost 1.59.0
## - Orthanc between 1.1.0 and 1.2.0: Boost 1.60.0
-## - Orthanc >= 1.3.0: Boost 1.64.0
+## - Orthanc 1.3.0: Boost 1.64.0
+## - Orthanc >= 1.3.1: Boost 1.65.1
-rm -rf /tmp/boost_1_64_0
-rm -rf /tmp/bcp/boost_1_64_0
+BOOST_VERSION=1_65_1
+ORTHANC_VERSION=1.3.1
+
+rm -rf /tmp/boost_${BOOST_VERSION}
+rm -rf /tmp/bcp/boost_${BOOST_VERSION}
cd /tmp
-echo "Uncompressing the sources of Boost 1.64.0..."
-tar xfz ./boost_1_64_0.tar.gz
+echo "Uncompressing the sources of Boost ${BOOST_VERSION}..."
+tar xfz ./boost_${BOOST_VERSION}.tar.gz
echo "Generating the subset..."
-mkdir -p /tmp/bcp/boost_1_64_0
-bcp --boost=/tmp/boost_1_64_0 thread system locale date_time filesystem math/special_functions algorithm uuid atomic iostreams program_options numeric/ublas /tmp/bcp/boost_1_64_0
+mkdir -p /tmp/bcp/boost_${BOOST_VERSION}
+bcp --boost=/tmp/boost_${BOOST_VERSION} thread system locale date_time filesystem math/special_functions algorithm uuid atomic iostreams program_options numeric/ublas geometry polygon /tmp/bcp/boost_${BOOST_VERSION}
cd /tmp/bcp
echo "Compressing the subset..."
-tar cfz boost_1_64_0_bcpdigest-1.3.0.tar.gz boost_1_64_0
-ls -l boost_1_64_0_bcpdigest-1.3.0.tar.gz
-md5sum boost_1_64_0_bcpdigest-1.3.0.tar.gz
-readlink -f boost_1_64_0_bcpdigest-1.3.0.tar.gz
+tar cfz boost_${BOOST_VERSION}_bcpdigest-${ORTHANC_VERSION}.tar.gz boost_${BOOST_VERSION}
+ls -l boost_${BOOST_VERSION}_bcpdigest-${ORTHANC_VERSION}.tar.gz
+md5sum boost_${BOOST_VERSION}_bcpdigest-${ORTHANC_VERSION}.tar.gz
+readlink -f boost_${BOOST_VERSION}_bcpdigest-${ORTHANC_VERSION}.tar.gz
diff --git a/Resources/CMake/CivetwebConfiguration.cmake b/Resources/CMake/CivetwebConfiguration.cmake
new file mode 100644
index 0000000..3e58509
--- /dev/null
+++ b/Resources/CMake/CivetwebConfiguration.cmake
@@ -0,0 +1,57 @@
+if (STATIC_BUILD OR NOT USE_SYSTEM_CIVETWEB)
+ set(CIVETWEB_SOURCES_DIR ${CMAKE_BINARY_DIR}/civetweb-1.9.1)
+ set(CIVETWEB_URL "http://www.orthanc-server.com/downloads/third-party/civetweb-1.9.1.tar.gz")
+ set(CIVETWEB_MD5 "c713f7336582d1a78897971260c67c2a")
+
+ DownloadPackage(${CIVETWEB_MD5} ${CIVETWEB_URL} "${CIVETWEB_SOURCES_DIR}")
+
+ include_directories(
+ ${CIVETWEB_SOURCES_DIR}/include
+ )
+
+ set(CIVETWEB_SOURCES
+ ${CIVETWEB_SOURCES_DIR}/src/civetweb.c
+ )
+
+
+ if (ENABLE_SSL)
+ add_definitions(
+ -DNO_SSL_DL=1
+ )
+ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
+ ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD")
+ link_libraries(dl)
+ endif()
+
+ else()
+ add_definitions(
+ -DNO_SSL=1 # Remove SSL support from civetweb
+ )
+ endif()
+
+
+ if (CMAKE_SYSTEM_NAME STREQUAL "Windows" AND
+ CMAKE_COMPILER_IS_GNUCXX)
+ # This is a patch for MinGW64
+ add_definitions(-D_TIMESPEC_DEFINED=1)
+ endif()
+
+ source_group(ThirdParty\\Civetweb REGULAR_EXPRESSION ${CIVETWEB_SOURCES_DIR}/.*)
+
+else()
+ include(CMakePushCheckState)
+
+ CHECK_INCLUDE_FILE_CXX(civetweb.h HAVE_CIVETWEB_H)
+ if (NOT HAVE_CIVETWEB_H)
+ message(FATAL_ERROR "Please install the libcivetweb-devel package")
+ endif()
+
+ cmake_reset_check_state()
+ set(CMAKE_REQUIRED_LIBRARIES dl pthread)
+ CHECK_LIBRARY_EXISTS(civetweb mg_start "" HAVE_CIVETWEB_LIB)
+ if (NOT HAVE_CIVETWEB_LIB)
+ message(FATAL_ERROR "Please install the libcivetweb-devel package")
+ endif()
+
+ link_libraries(civetweb)
+endif()
diff --git a/Resources/CMake/Compiler.cmake b/Resources/CMake/Compiler.cmake
index fa7577d..fcfe34a 100644
--- a/Resources/CMake/Compiler.cmake
+++ b/Resources/CMake/Compiler.cmake
@@ -7,7 +7,8 @@ if (CMAKE_CROSSCOMPILING)
endif()
if (CMAKE_COMPILER_IS_GNUCXX)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-long-long -Wno-implicit-function-declaration")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-long-long")
+
# --std=c99 makes libcurl not to compile
# -pedantic gives a lot of warnings on OpenSSL
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -Wno-variadic-macros")
@@ -56,11 +57,27 @@ elseif (MSVC)
endif()
+if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
+ ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+ # In FreeBSD/OpenBSD, the "/usr/local/" folder contains the ports and need to be imported
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/local/include")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/local/include")
+ SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")
+ SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L/usr/local/lib")
+endif()
+
+
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
- set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
- set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
+ ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
+ ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+
+ if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+ # The "--no-undefined" linker flag makes the shared libraries
+ # (plugins ModalityWorklists and ServeFolders) fail to compile on OpenBSD
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
+ endif()
if (NOT DEFINED ENABLE_PLUGINS_VERSION_SCRIPT OR
ENABLE_PLUGINS_VERSION_SCRIPT)
@@ -70,22 +87,39 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
# Remove the "-rdynamic" option
# http://www.mail-archive.com/cmake@cmake.org/msg08837.html
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
- link_libraries(uuid pthread rt)
+ link_libraries(uuid pthread)
+
+ if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+ link_libraries(rt)
+ endif()
+
+ if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" AND
+ NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+ link_libraries(dl)
+ endif()
if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
+ # The "--as-needed" linker flag is not available on FreeBSD
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--as-needed")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--as-needed")
+ endif()
+
+ if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" AND
+ NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+ # FreeBSD/OpenBSD have just one single interface for file
+ # handling, which is 64bit clean, so there is no need to define macro
+ # for LFS (Large File Support).
+ # https://ohse.de/uwe/articles/lfs.html
add_definitions(
-D_LARGEFILE64_SOURCE=1
-D_FILE_OFFSET_BITS=64
)
- link_libraries(dl)
endif()
CHECK_INCLUDE_FILES(uuid/uuid.h HAVE_UUID_H)
if (NOT HAVE_UUID_H)
- message(FATAL_ERROR "Please install the uuid-dev package")
+ message(FATAL_ERROR "Please install the uuid-dev package (or e2fsprogs if OpenBSD)")
endif()
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
@@ -145,6 +179,11 @@ elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
message(FATAL_ERROR "Please install the uuid-dev package")
endif()
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
+ message("Building using Emscripten (for WebAssembly or asm.js targets)")
+
+else()
+ message(FATAL_ERROR "Support your platform here")
endif()
@@ -155,15 +194,6 @@ if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase")
endif()
-if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
- # In FreeBSD, the "/usr/local/" folder contains the ports and need to be imported
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/local/include")
- SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -I/usr/local/include")
- SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")
- SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L/usr/local/lib")
-endif()
-
-
if (DEFINED ENABLE_PROFILING AND ENABLE_PROFILING)
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(WARNING "Enabling profiling on a non-debug build will not produce full information")
diff --git a/Resources/CMake/DcmtkConfiguration.cmake b/Resources/CMake/DcmtkConfiguration.cmake
index 0d88735..184369f 100644
--- a/Resources/CMake/DcmtkConfiguration.cmake
+++ b/Resources/CMake/DcmtkConfiguration.cmake
@@ -26,6 +26,8 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_DCMTK)
set(DCMTK_BINARY_DIR ${DCMTK_SOURCES_DIR}/)
set(DCMTK_CMAKE_INCLUDE ${DCMTK_SOURCES_DIR}/)
+ set(DCMTK_WITH_THREADS ON)
+
add_definitions(-DDCMTK_INSIDE_LOG4CPLUS=1)
endif()
@@ -149,7 +151,7 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_DCMTK)
)
endif()
- if (ENABLE_JPEG)
+ if (ENABLE_DCMTK_JPEG)
AUX_SOURCE_DIRECTORY(${DCMTK_SOURCES_DIR}/dcmjpeg/libsrc DCMTK_SOURCES)
AUX_SOURCE_DIRECTORY(${DCMTK_SOURCES_DIR}/dcmjpeg/libijg8 DCMTK_SOURCES)
AUX_SOURCE_DIRECTORY(${DCMTK_SOURCES_DIR}/dcmjpeg/libijg12 DCMTK_SOURCES)
@@ -177,7 +179,7 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_DCMTK)
endif()
- if (ENABLE_JPEG_LOSSLESS)
+ if (ENABLE_DCMTK_JPEG_LOSSLESS)
AUX_SOURCE_DIRECTORY(${DCMTK_SOURCES_DIR}/dcmjpls/libsrc DCMTK_SOURCES)
AUX_SOURCE_DIRECTORY(${DCMTK_SOURCES_DIR}/dcmjpls/libcharls DCMTK_SOURCES)
include_directories(
@@ -202,7 +204,8 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_DCMTK)
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR
${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD")
+ ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR
+ ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
list(REMOVE_ITEM DCMTK_SOURCES
${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc
${DCMTK_SOURCES_DIR}/oflog/libsrc/windebap.cc
diff --git a/Resources/CMake/GoogleTestConfiguration.cmake b/Resources/CMake/GoogleTestConfiguration.cmake
index b9074b4..aa6b2f1 100644
--- a/Resources/CMake/GoogleTestConfiguration.cmake
+++ b/Resources/CMake/GoogleTestConfiguration.cmake
@@ -1,5 +1,5 @@
-if (USE_GTEST_DEBIAN_SOURCE_PACKAGE)
- find_path(GTEST_DEBIAN_SOURCES_DIR
+if (USE_GOOGLE_TEST_DEBIAN_PACKAGE)
+ find_path(GOOGLE_TEST_DEBIAN_SOURCES_DIR
NAMES src/gtest-all.cc
PATHS
/usr/src/gtest
@@ -7,37 +7,40 @@ if (USE_GTEST_DEBIAN_SOURCE_PACKAGE)
PATH_SUFFIXES src
)
- find_path(GTEST_DEBIAN_INCLUDE_DIR
+ find_path(GOOGLE_TEST_DEBIAN_INCLUDE_DIR
NAMES gtest.h
PATHS
/usr/include/gtest
)
- message("Path to the Debian Google Test sources: ${GTEST_DEBIAN_SOURCES_DIR}")
- message("Path to the Debian Google Test includes: ${GTEST_DEBIAN_INCLUDE_DIR}")
+ message("Path to the Debian Google Test sources: ${GOOGLE_TEST_DEBIAN_SOURCES_DIR}")
+ message("Path to the Debian Google Test includes: ${GOOGLE_TEST_DEBIAN_INCLUDE_DIR}")
- set(GTEST_SOURCES ${GTEST_DEBIAN_SOURCES_DIR}/src/gtest-all.cc)
- include_directories(${GTEST_DEBIAN_SOURCES_DIR})
+ set(GOOGLE_TEST_SOURCES
+ ${GOOGLE_TEST_DEBIAN_SOURCES_DIR}/src/gtest-all.cc
+ )
+
+ include_directories(${GOOGLE_TEST_DEBIAN_SOURCES_DIR})
- if (NOT EXISTS ${GTEST_SOURCES} OR
- NOT EXISTS ${GTEST_DEBIAN_INCLUDE_DIR}/gtest.h)
+ if (NOT EXISTS ${GOOGLE_TEST_SOURCES} OR
+ NOT EXISTS ${GOOGLE_TEST_DEBIAN_INCLUDE_DIR}/gtest.h)
message(FATAL_ERROR "Please install the libgtest-dev package")
endif()
elseif (STATIC_BUILD OR NOT USE_SYSTEM_GOOGLE_TEST)
- set(GTEST_SOURCES_DIR ${CMAKE_BINARY_DIR}/gtest-1.7.0)
- set(GTEST_URL "http://www.orthanc-server.com/downloads/third-party/gtest-1.7.0.zip")
- set(GTEST_MD5 "2d6ec8ccdf5c46b05ba54a9fd1d130d7")
+ set(GOOGLE_TEST_SOURCES_DIR ${CMAKE_BINARY_DIR}/gtest-1.7.0)
+ set(GOOGLE_TEST_URL "http://www.orthanc-server.com/downloads/third-party/gtest-1.7.0.zip")
+ set(GOOGLE_TEST_MD5 "2d6ec8ccdf5c46b05ba54a9fd1d130d7")
- DownloadPackage(${GTEST_MD5} ${GTEST_URL} "${GTEST_SOURCES_DIR}")
+ DownloadPackage(${GOOGLE_TEST_MD5} ${GOOGLE_TEST_URL} "${GOOGLE_TEST_SOURCES_DIR}")
include_directories(
- ${GTEST_SOURCES_DIR}/include
- ${GTEST_SOURCES_DIR}
+ ${GOOGLE_TEST_SOURCES_DIR}/include
+ ${GOOGLE_TEST_SOURCES_DIR}
)
- set(GTEST_SOURCES
- ${GTEST_SOURCES_DIR}/src/gtest-all.cc
+ set(GOOGLE_TEST_SOURCES
+ ${GOOGLE_TEST_SOURCES_DIR}/src/gtest-all.cc
)
# https://code.google.com/p/googletest/issues/detail?id=412
@@ -45,14 +48,16 @@ elseif (STATIC_BUILD OR NOT USE_SYSTEM_GOOGLE_TEST)
add_definitions(/D _VARIADIC_MAX=10)
endif()
- source_group(ThirdParty\\GoogleTest REGULAR_EXPRESSION ${GTEST_SOURCES_DIR}/.*)
+ source_group(ThirdParty\\GoogleTest REGULAR_EXPRESSION ${GOOGLE_TEST_SOURCES_DIR}/.*)
else()
include(FindGTest)
- if (NOT GTEST_FOUND)
+ if (NOT GOOGLE_TEST_FOUND)
message(FATAL_ERROR "Unable to find GoogleTest")
endif()
- include_directories(${GTEST_INCLUDE_DIRS})
- link_libraries(${GTEST_LIBRARIES})
+ include_directories(${GOOGLE_TEST_INCLUDE_DIRS})
+
+ # The variable GOOGLE_TEST_LIBRARIES contains the shared library of
+ # Google Test
endif()
diff --git a/Resources/CMake/JsonCppConfiguration.cmake b/Resources/CMake/JsonCppConfiguration.cmake
index 1532a81..9fe93e9 100644
--- a/Resources/CMake/JsonCppConfiguration.cmake
+++ b/Resources/CMake/JsonCppConfiguration.cmake
@@ -48,9 +48,10 @@ else()
JSONCPP_VERSION_MAJOR ${JSONCPP_VERSION_MAJOR1})
message("JsonCpp major version: ${JSONCPP_VERSION_MAJOR}")
- if (CMAKE_COMPILER_IS_GNUCXX AND
+ if ((CMAKE_COMPILER_IS_GNUCXX OR
+ "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") AND
JSONCPP_VERSION_MAJOR GREATER 0)
- message("Switching to C++11 standard, as version of JsonCpp is >= 1.0.0")
+ message("Switching to C++11 standard in gcc/clang, as version of JsonCpp is >= 1.0.0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-deprecated-declarations")
endif()
else()
diff --git a/Resources/CMake/LibCurlConfiguration.cmake b/Resources/CMake/LibCurlConfiguration.cmake
index 390a1a7..c507acf 100644
--- a/Resources/CMake/LibCurlConfiguration.cmake
+++ b/Resources/CMake/LibCurlConfiguration.cmake
@@ -60,7 +60,8 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_CURL)
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR
${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
- ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD")
+ ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR
+ ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
SET(TMP_OS "x86_64")
else()
diff --git a/Resources/CMake/LibIconvConfiguration.cmake b/Resources/CMake/LibIconvConfiguration.cmake
index c4fe211..dfa3426 100644
--- a/Resources/CMake/LibIconvConfiguration.cmake
+++ b/Resources/CMake/LibIconvConfiguration.cmake
@@ -1,52 +1,96 @@
-set(LIBICONV_SOURCES_DIR ${CMAKE_BINARY_DIR}/libiconv-1.15)
-set(LIBICONV_URL "http://www.orthanc-server.com/downloads/third-party/libiconv-1.15.tar.gz")
-set(LIBICONV_MD5 "ace8b5f2db42f7b3b3057585e80d9808")
-
-DownloadPackage(${LIBICONV_MD5} ${LIBICONV_URL} "${LIBICONV_SOURCES_DIR}")
-
-# https://groups.google.com/d/msg/android-ndk/AS1nkxnk6m4/EQm09hD1tigJ
-add_definitions(
- -DBOOST_LOCALE_WITH_ICONV=1
- -DBUILDING_LIBICONV=1
- -DIN_LIBRARY=1
- -DLIBDIR=""
- -DICONV_CONST=
- )
-
-configure_file(
- ${LIBICONV_SOURCES_DIR}/srclib/localcharset.h
- ${LIBICONV_SOURCES_DIR}/include
- COPYONLY)
-
-set(HAVE_VISIBILITY 0)
-set(ICONV_CONST ${ICONV_CONST})
-set(USE_MBSTATE_T 1)
-set(BROKEN_WCHAR_H 0)
-set(EILSEQ)
-set(HAVE_WCHAR_T 1)
-configure_file(
- ${LIBICONV_SOURCES_DIR}/include/iconv.h.build.in
- ${LIBICONV_SOURCES_DIR}/include/iconv.h
- )
-unset(HAVE_VISIBILITY)
-unset(ICONV_CONST)
-unset(USE_MBSTATE_T)
-unset(BROKEN_WCHAR_H)
-unset(EILSEQ)
-unset(HAVE_WCHAR_T)
-
-# Create an empty "config.h" for libiconv
-file(WRITE ${LIBICONV_SOURCES_DIR}/include/config.h "")
-
-include_directories(
- ${LIBICONV_SOURCES_DIR}/include
- )
-
-list(APPEND BOOST_SOURCES
- ${LIBICONV_SOURCES_DIR}/lib/iconv.c
- ${LIBICONV_SOURCES_DIR}/lib/relocatable.c
- ${LIBICONV_SOURCES_DIR}/libcharset/lib/localcharset.c
- ${LIBICONV_SOURCES_DIR}/libcharset/lib/relocatable.c
- )
-
-source_group(ThirdParty\\libiconv REGULAR_EXPRESSION ${LIBICONV_SOURCES_DIR}/.*)
+if (NOT ENABLE_LOCALE)
+ message("Support for locales is disabled")
+
+elseif (NOT USE_BOOST_ICONV)
+ message("Not using libiconv")
+
+else()
+ message("Using libiconv")
+
+ if (STATIC_BUILD OR NOT USE_SYSTEM_LIBICONV)
+ set(LIBICONV_SOURCES_DIR ${CMAKE_BINARY_DIR}/libiconv-1.15)
+ set(LIBICONV_URL "http://www.orthanc-server.com/downloads/third-party/libiconv-1.15.tar.gz")
+ set(LIBICONV_MD5 "ace8b5f2db42f7b3b3057585e80d9808")
+
+ DownloadPackage(${LIBICONV_MD5} ${LIBICONV_URL} "${LIBICONV_SOURCES_DIR}")
+
+ # Disable the support of libiconv that is shipped by default with
+ # the C standard library on Linux. Setting this macro redirects
+ # calls from "iconv*()" to "libiconv*()" by defining macros in the
+ # C headers of "libiconv-1.15".
+ add_definitions(-DLIBICONV_PLUG=1)
+
+ # https://groups.google.com/d/msg/android-ndk/AS1nkxnk6m4/EQm09hD1tigJ
+ add_definitions(
+ -DBUILDING_LIBICONV=1
+ -DIN_LIBRARY=1
+ -DLIBDIR=""
+ -DICONV_CONST=
+ )
+
+ configure_file(
+ ${LIBICONV_SOURCES_DIR}/srclib/localcharset.h
+ ${LIBICONV_SOURCES_DIR}/include
+ COPYONLY)
+
+ set(HAVE_VISIBILITY 0)
+ set(ICONV_CONST ${ICONV_CONST})
+ set(USE_MBSTATE_T 1)
+ set(BROKEN_WCHAR_H 0)
+ set(EILSEQ)
+ set(HAVE_WCHAR_T 1)
+ configure_file(
+ ${LIBICONV_SOURCES_DIR}/include/iconv.h.build.in
+ ${LIBICONV_SOURCES_DIR}/include/iconv.h
+ )
+ unset(HAVE_VISIBILITY)
+ unset(ICONV_CONST)
+ unset(USE_MBSTATE_T)
+ unset(BROKEN_WCHAR_H)
+ unset(EILSEQ)
+ unset(HAVE_WCHAR_T)
+
+ # Create an empty "config.h" for libiconv
+ file(WRITE ${LIBICONV_SOURCES_DIR}/include/config.h "")
+
+ include_directories(
+ ${LIBICONV_SOURCES_DIR}/include
+ )
+
+ set(LIBICONV_SOURCES
+ ${LIBICONV_SOURCES_DIR}/lib/iconv.c
+ ${LIBICONV_SOURCES_DIR}/lib/relocatable.c
+ ${LIBICONV_SOURCES_DIR}/libcharset/lib/localcharset.c
+ ${LIBICONV_SOURCES_DIR}/libcharset/lib/relocatable.c
+ )
+
+ source_group(ThirdParty\\libiconv REGULAR_EXPRESSION ${LIBICONV_SOURCES_DIR}/.*)
+
+ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ add_definitions(-DHAVE_WORKING_O_NOFOLLOW=0)
+ else()
+ add_definitions(-DHAVE_WORKING_O_NOFOLLOW=1)
+ endif()
+
+ else()
+ CHECK_INCLUDE_FILE_CXX(iconv.h HAVE_ICONV_H)
+ if (NOT HAVE_ICONV_H)
+ message(FATAL_ERROR "Please install the libiconv-dev package")
+ endif()
+
+ # Check whether the support for libiconv is bundled within the
+ # standard C library
+ CHECK_FUNCTION_EXISTS(iconv_open HAVE_ICONV_LIB)
+ if (NOT HAVE_ICONV_LIB)
+ # No builtin support for libiconv, try and find an external library.
+ # Open question: Does this make sense on any platform?
+ CHECK_LIBRARY_EXISTS(iconv iconv_open "" HAVE_ICONV_LIB_2)
+ if (NOT HAVE_ICONV_LIB_2)
+ message(FATAL_ERROR "Please install the libiconv-dev package")
+ else()
+ link_libraries(iconv)
+ endif()
+ endif()
+
+ endif()
+endif()
diff --git a/Resources/CMake/LibP11Configuration.cmake b/Resources/CMake/LibP11Configuration.cmake
index 21ab70d..8dc7438 100644
--- a/Resources/CMake/LibP11Configuration.cmake
+++ b/Resources/CMake/LibP11Configuration.cmake
@@ -48,6 +48,7 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_LIBP11)
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
${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
list(APPEND LIBP11_SOURCES
${LIBP11_SOURCES_DIR}/src/atfork.c
diff --git a/Resources/CMake/OrthancFrameworkConfiguration.cmake b/Resources/CMake/OrthancFrameworkConfiguration.cmake
new file mode 100644
index 0000000..1100162
--- /dev/null
+++ b/Resources/CMake/OrthancFrameworkConfiguration.cmake
@@ -0,0 +1,509 @@
+##
+## This is a CMake configuration file that configures the core
+## libraries of Orthanc. This file can be used by external projects so
+## as to gain access to the Orthanc APIs (the most prominent examples
+## are currently "Stone of Orthanc" and "Orthanc for whole-slide
+## imaging plugin").
+##
+
+
+#####################################################################
+## Configuration of the components
+#####################################################################
+
+# Path to the root folder of the Orthanc distribution
+set(ORTHANC_ROOT ${CMAKE_CURRENT_LIST_DIR}/../..)
+
+# Some basic inclusions
+include(CheckIncludeFiles)
+include(CheckIncludeFileCXX)
+include(CheckFunctionExists)
+include(CheckLibraryExists)
+include(FindPythonInterp)
+
+include(${CMAKE_CURRENT_LIST_DIR}/AutoGeneratedCode.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/DownloadPackage.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/Compiler.cmake)
+
+
+#####################################################################
+## Disable unneeded macros
+#####################################################################
+
+if (NOT ENABLE_SQLITE)
+ unset(USE_SYSTEM_SQLITE CACHE)
+ add_definitions(-DORTHANC_ENABLE_SQLITE=0)
+endif()
+
+if (NOT ENABLE_CRYPTO_OPTIONS)
+ unset(ENABLE_SSL CACHE)
+ unset(ENABLE_PKCS11 CACHE)
+ unset(USE_SYSTEM_OPENSSL CACHE)
+ unset(USE_SYSTEM_LIBP11 CACHE)
+ add_definitions(
+ -DORTHANC_ENABLE_SSL=0
+ -DORTHANC_ENABLE_PKCS11=0
+ )
+endif()
+
+if (NOT ENABLE_WEB_CLIENT)
+ unset(USE_SYSTEM_CURL CACHE)
+ add_definitions(-DORTHANC_ENABLE_CURL=0)
+endif()
+
+if (NOT ENABLE_WEB_SERVER)
+ unset(ENABLE_CIVETWEB CACHE)
+ unset(USE_SYSTEM_CIVETWEB CACHE)
+ unset(USE_SYSTEM_MONGOOSE CACHE)
+ add_definitions(
+ -DORTHANC_ENABLE_CIVETWEB=0
+ -DORTHANC_ENABLE_MONGOOSE=0
+ )
+endif()
+
+if (NOT ENABLE_JPEG)
+ unset(USE_SYSTEM_LIBJPEG CACHE)
+ add_definitions(-DORTHANC_ENABLE_JPEG=0)
+endif()
+
+if (NOT ENABLE_PNG)
+ unset(USE_SYSTEM_LIBPNG CACHE)
+ add_definitions(-DORTHANC_ENABLE_PNG=0)
+endif()
+
+if (NOT ENABLE_LUA)
+ unset(USE_SYSTEM_LUA CACHE)
+ add_definitions(-DORTHANC_ENABLE_LUA=0)
+endif()
+
+if (NOT ENABLE_PUGIXML)
+ unset(USE_SYSTEM_PUGIXML CACHE)
+ add_definitions(-DORTHANC_ENABLE_PUGIXML=0)
+endif()
+
+if (NOT ENABLE_LOCALE)
+ unset(USE_SYSTEM_LIBICONV CACHE)
+ add_definitions(-DORTHANC_ENABLE_LOCALE=0)
+endif()
+
+if (NOT ENABLE_GOOGLE_TEST)
+ unset(USE_SYSTEM_GOOGLE_TEST CACHE)
+ unset(USE_GOOGLE_TEST_DEBIAN_PACKAGE CACHE)
+endif()
+
+if (NOT ENABLE_DCMTK)
+ add_definitions(
+ -DORTHANC_ENABLE_DCMTK=0
+ -DORTHANC_ENABLE_DCMTK_NETWORKING=0
+ )
+ unset(DCMTK_DICTIONARY_DIR CACHE)
+ unset(USE_DCMTK_360 CACHE)
+ unset(USE_DCMTK_362_PRIVATE_DIC CACHE)
+ unset(USE_SYSTEM_DCMTK CACHE)
+ unset(ENABLE_DCMTK_JPEG CACHE)
+ unset(ENABLE_DCMTK_JPEG_LOSSLESS CACHE)
+endif()
+
+
+#####################################################################
+## List of source files
+#####################################################################
+
+set(ORTHANC_CORE_SOURCES_INTERNAL
+ ${ORTHANC_ROOT}/Core/Cache/MemoryCache.cpp
+ ${ORTHANC_ROOT}/Core/ChunkedBuffer.cpp
+ ${ORTHANC_ROOT}/Core/Compression/DeflateBaseCompressor.cpp
+ ${ORTHANC_ROOT}/Core/Compression/GzipCompressor.cpp
+ ${ORTHANC_ROOT}/Core/Compression/HierarchicalZipWriter.cpp
+ ${ORTHANC_ROOT}/Core/Compression/ZipWriter.cpp
+ ${ORTHANC_ROOT}/Core/Compression/ZlibCompressor.cpp
+ ${ORTHANC_ROOT}/Core/DicomFormat/DicomArray.cpp
+ ${ORTHANC_ROOT}/Core/DicomFormat/DicomImageInformation.cpp
+ ${ORTHANC_ROOT}/Core/DicomFormat/DicomInstanceHasher.cpp
+ ${ORTHANC_ROOT}/Core/DicomFormat/DicomIntegerPixelAccessor.cpp
+ ${ORTHANC_ROOT}/Core/DicomFormat/DicomMap.cpp
+ ${ORTHANC_ROOT}/Core/DicomFormat/DicomTag.cpp
+ ${ORTHANC_ROOT}/Core/DicomFormat/DicomValue.cpp
+ ${ORTHANC_ROOT}/Core/Enumerations.cpp
+ ${ORTHANC_ROOT}/Core/Images/Font.cpp
+ ${ORTHANC_ROOT}/Core/Images/FontRegistry.cpp
+ ${ORTHANC_ROOT}/Core/Images/IImageWriter.cpp
+ ${ORTHANC_ROOT}/Core/Images/Image.cpp
+ ${ORTHANC_ROOT}/Core/Images/ImageAccessor.cpp
+ ${ORTHANC_ROOT}/Core/Images/ImageBuffer.cpp
+ ${ORTHANC_ROOT}/Core/Images/ImageProcessing.cpp
+ ${ORTHANC_ROOT}/Core/Logging.cpp
+ ${ORTHANC_ROOT}/Core/Toolbox.cpp
+ ${ORTHANC_ROOT}/Core/WebServiceParameters.cpp
+ )
+
+
+#####################################################################
+## Configuration of optional third-party dependencies
+#####################################################################
+
+
+##
+## Embedded database: SQLite
+##
+
+if (ENABLE_SQLITE)
+ include(${CMAKE_CURRENT_LIST_DIR}/SQLiteConfiguration.cmake)
+ add_definitions(-DORTHANC_ENABLE_SQLITE=1)
+
+ list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
+ ${ORTHANC_ROOT}/Core/SQLite/Connection.cpp
+ ${ORTHANC_ROOT}/Core/SQLite/FunctionContext.cpp
+ ${ORTHANC_ROOT}/Core/SQLite/Statement.cpp
+ ${ORTHANC_ROOT}/Core/SQLite/StatementId.cpp
+ ${ORTHANC_ROOT}/Core/SQLite/StatementReference.cpp
+ ${ORTHANC_ROOT}/Core/SQLite/Transaction.cpp
+ )
+endif()
+
+
+##
+## Cryptography: OpenSSL and libp11
+## Must be above "ENABLE_WEB_CLIENT" and "ENABLE_WEB_SERVER"
+##
+
+if (ENABLE_CRYPTO_OPTIONS)
+ if (ENABLE_SSL)
+ include(${CMAKE_CURRENT_LIST_DIR}/OpenSslConfiguration.cmake)
+ add_definitions(-DORTHANC_ENABLE_SSL=1)
+ else()
+ unset(USE_SYSTEM_OPENSSL CACHE)
+ add_definitions(-DORTHANC_ENABLE_SSL=0)
+ endif()
+
+ if (ENABLE_PKCS11)
+ if (ENABLE_SSL)
+ include(${CMAKE_CURRENT_LIST_DIR}/LibP11Configuration.cmake)
+
+ add_definitions(-DORTHANC_ENABLE_PKCS11=1)
+ list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
+ ${ORTHANC_ROOT}/Core/Pkcs11.cpp
+ )
+ else()
+ message(FATAL_ERROR "OpenSSL is required to enable PKCS#11 support")
+ endif()
+ else()
+ add_definitions(-DORTHANC_ENABLE_PKCS11=0)
+ endif()
+endif()
+
+
+##
+## HTTP client: libcurl
+##
+
+if (ENABLE_WEB_CLIENT)
+ include(${CMAKE_CURRENT_LIST_DIR}/LibCurlConfiguration.cmake)
+ add_definitions(-DORTHANC_ENABLE_CURL=1)
+
+ list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
+ ${ORTHANC_ROOT}/Core/HttpClient.cpp
+ )
+endif()
+
+
+##
+## HTTP server: Mongoose 3.8 or Civetweb
+##
+
+if (ENABLE_WEB_SERVER)
+ if (ENABLE_CIVETWEB)
+ include(${CMAKE_CURRENT_LIST_DIR}/CivetwebConfiguration.cmake)
+ add_definitions(
+ -DORTHANC_ENABLE_CIVETWEB=1
+ -DORTHANC_ENABLE_MONGOOSE=0
+ )
+ else()
+ include(${CMAKE_CURRENT_LIST_DIR}/MongooseConfiguration.cmake)
+ add_definitions(
+ -DORTHANC_ENABLE_CIVETWEB=0
+ -DORTHANC_ENABLE_MONGOOSE=1
+ )
+ endif()
+
+ list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
+ ${ORTHANC_ROOT}/Core/HttpServer/BufferHttpSender.cpp
+ ${ORTHANC_ROOT}/Core/HttpServer/FilesystemHttpHandler.cpp
+ ${ORTHANC_ROOT}/Core/HttpServer/FilesystemHttpSender.cpp
+ ${ORTHANC_ROOT}/Core/HttpServer/HttpContentNegociation.cpp
+ ${ORTHANC_ROOT}/Core/HttpServer/HttpFileSender.cpp
+ ${ORTHANC_ROOT}/Core/HttpServer/HttpOutput.cpp
+ ${ORTHANC_ROOT}/Core/HttpServer/HttpStreamTranscoder.cpp
+ ${ORTHANC_ROOT}/Core/HttpServer/HttpToolbox.cpp
+ ${ORTHANC_ROOT}/Core/HttpServer/MongooseServer.cpp
+ ${ORTHANC_ROOT}/Core/HttpServer/StringHttpOutput.cpp
+ ${ORTHANC_ROOT}/Core/RestApi/RestApi.cpp
+ ${ORTHANC_ROOT}/Core/RestApi/RestApiCall.cpp
+ ${ORTHANC_ROOT}/Core/RestApi/RestApiGetCall.cpp
+ ${ORTHANC_ROOT}/Core/RestApi/RestApiHierarchy.cpp
+ ${ORTHANC_ROOT}/Core/RestApi/RestApiOutput.cpp
+ ${ORTHANC_ROOT}/Core/RestApi/RestApiPath.cpp
+ )
+endif()
+
+
+##
+## JPEG support: libjpeg
+##
+
+if (ENABLE_JPEG)
+ include(${CMAKE_CURRENT_LIST_DIR}/LibJpegConfiguration.cmake)
+ add_definitions(-DORTHANC_ENABLE_JPEG=1)
+
+ list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
+ ${ORTHANC_ROOT}/Core/Images/JpegErrorManager.cpp
+ ${ORTHANC_ROOT}/Core/Images/JpegReader.cpp
+ ${ORTHANC_ROOT}/Core/Images/JpegWriter.cpp
+ )
+endif()
+
+
+##
+## PNG support: libpng (in conjunction with zlib)
+##
+
+if (ENABLE_PNG)
+ include(${CMAKE_CURRENT_LIST_DIR}/LibPngConfiguration.cmake)
+ add_definitions(-DORTHANC_ENABLE_PNG=1)
+
+ list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
+ ${ORTHANC_ROOT}/Core/Images/PngReader.cpp
+ ${ORTHANC_ROOT}/Core/Images/PngWriter.cpp
+ )
+endif()
+
+
+##
+## Lua support
+##
+
+if (ENABLE_LUA)
+ include(${CMAKE_CURRENT_LIST_DIR}/LuaConfiguration.cmake)
+ add_definitions(-DORTHANC_ENABLE_LUA=1)
+
+ list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
+ ${ORTHANC_ROOT}/Core/Lua/LuaContext.cpp
+ ${ORTHANC_ROOT}/Core/Lua/LuaFunctionCall.cpp
+ )
+endif()
+
+
+##
+## XML support: pugixml
+##
+
+if (ENABLE_PUGIXML)
+ include(${CMAKE_CURRENT_LIST_DIR}/PugixmlConfiguration.cmake)
+ add_definitions(-DORTHANC_ENABLE_PUGIXML=1)
+endif()
+
+
+##
+## Locale support: libiconv
+##
+
+if (ENABLE_LOCALE)
+ include(${CMAKE_CURRENT_LIST_DIR}/LibIconvConfiguration.cmake)
+ add_definitions(-DORTHANC_ENABLE_LOCALE=1)
+endif()
+
+
+##
+## Google Test for unit testing
+##
+
+if (ENABLE_GOOGLE_TEST)
+ include(${CMAKE_CURRENT_LIST_DIR}/GoogleTestConfiguration.cmake)
+endif()
+
+
+
+#####################################################################
+## Inclusion of mandatory third-party dependencies
+#####################################################################
+
+include(${CMAKE_CURRENT_LIST_DIR}/JsonCppConfiguration.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/ZlibConfiguration.cmake)
+
+# We put Boost as the last dependency, as it is the heaviest to
+# configure, which allows to quickly spot problems when configuring
+# static builds in other dependencies
+include(${CMAKE_CURRENT_LIST_DIR}/BoostConfiguration.cmake)
+
+
+#####################################################################
+## Optional configuration of DCMTK
+#####################################################################
+
+if (ENABLE_DCMTK)
+ if (NOT ENABLE_LOCALE)
+ message(FATAL_ERROR "Support for locales must be enabled if enabling DICOM support")
+ endif()
+
+ include(${CMAKE_CURRENT_LIST_DIR}/DcmtkConfiguration.cmake)
+
+ add_definitions(-DORTHANC_ENABLE_DCMTK=1)
+
+ if (ENABLE_DCMTK_JPEG)
+ add_definitions(-DORTHANC_ENABLE_DCMTK_JPEG=1)
+ else()
+ add_definitions(-DORTHANC_ENABLE_DCMTK_JPEG=0)
+ endif()
+
+ if (ENABLE_DCMTK_JPEG_LOSSLESS)
+ add_definitions(-DORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS=1)
+ else()
+ add_definitions(-DORTHANC_ENABLE_DCMTK_JPEG_LOSSLESS=0)
+ endif()
+
+ set(ORTHANC_DICOM_SOURCES_INTERNAL
+ ${ORTHANC_ROOT}/Core/DicomParsing/DicomDirWriter.cpp
+ ${ORTHANC_ROOT}/Core/DicomParsing/DicomModification.cpp
+ ${ORTHANC_ROOT}/Core/DicomParsing/FromDcmtkBridge.cpp
+ ${ORTHANC_ROOT}/Core/DicomParsing/ParsedDicomFile.cpp
+ ${ORTHANC_ROOT}/Core/DicomParsing/ToDcmtkBridge.cpp
+
+ ${ORTHANC_ROOT}/Core/DicomParsing/Internals/DicomFrameIndex.cpp
+ ${ORTHANC_ROOT}/Core/DicomParsing/Internals/DicomImageDecoder.cpp
+ )
+
+ if (ENABLE_DCMTK_NETWORKING)
+ add_definitions(-DORTHANC_ENABLE_DCMTK_NETWORKING=1)
+ list(APPEND ORTHANC_DICOM_SOURCES_INTERNAL
+ ${ORTHANC_ROOT}/Core/DicomNetworking/DicomFindAnswers.cpp
+ ${ORTHANC_ROOT}/Core/DicomNetworking/DicomServer.cpp
+ ${ORTHANC_ROOT}/Core/DicomNetworking/DicomUserConnection.cpp
+ ${ORTHANC_ROOT}/Core/DicomNetworking/RemoteModalityParameters.cpp
+ ${ORTHANC_ROOT}/Core/DicomNetworking/ReusableDicomUserConnection.cpp
+
+ ${ORTHANC_ROOT}/Core/DicomNetworking/Internals/CommandDispatcher.cpp
+ ${ORTHANC_ROOT}/Core/DicomNetworking/Internals/FindScp.cpp
+ ${ORTHANC_ROOT}/Core/DicomNetworking/Internals/MoveScp.cpp
+ ${ORTHANC_ROOT}/Core/DicomNetworking/Internals/StoreScp.cpp
+ )
+ else()
+ add_definitions(-DORTHANC_ENABLE_DCMTK_NETWORKING=0)
+ endif()
+
+ if (STANDALONE_BUILD AND NOT HAS_EMBEDDED_RESOURCES)
+ EmbedResources(
+ ${DCMTK_DICTIONARIES}
+ )
+ list(APPEND ORTHANC_DICOM_SOURCES_DEPENDENCIES
+ ${AUTOGENERATED_SOURCES}
+ )
+ endif()
+endif()
+
+
+#####################################################################
+## Configuration of the C/C++ macros
+#####################################################################
+
+add_definitions(
+ -DORTHANC_DATABASE_VERSION=${ORTHANC_DATABASE_VERSION}
+ -DORTHANC_DEFAULT_DICOM_ENCODING=Encoding_Latin1
+ -DORTHANC_ENABLE_BASE64=1
+ -DORTHANC_ENABLE_MD5=1
+ -DORTHANC_MAXIMUM_TAG_LENGTH=256
+ -DORTHANC_VERSION="${ORTHANC_VERSION}"
+ )
+
+
+if (ORTHANC_SANDBOXED)
+ add_definitions(
+ -DORTHANC_SANDBOXED=1
+ -DORTHANC_ENABLE_LOGGING=0
+ -DORTHANC_ENABLE_LOGGING_PLUGIN=0
+ )
+
+else()
+ add_definitions(
+ -DORTHANC_SANDBOXED=0
+ -DORTHANC_ENABLE_LOGGING=1
+ -DORTHANC_ENABLE_LOGGING_PLUGIN=0
+ )
+
+ list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
+ ${ORTHANC_ROOT}/Core/Cache/SharedArchive.cpp
+ ${ORTHANC_ROOT}/Core/FileStorage/FilesystemStorage.cpp
+ ${ORTHANC_ROOT}/Core/FileStorage/StorageAccessor.cpp
+ ${ORTHANC_ROOT}/Core/MultiThreading/BagOfTasksProcessor.cpp
+ ${ORTHANC_ROOT}/Core/MultiThreading/Mutex.cpp
+ ${ORTHANC_ROOT}/Core/MultiThreading/ReaderWriterLock.cpp
+ ${ORTHANC_ROOT}/Core/MultiThreading/RunnableWorkersPool.cpp
+ ${ORTHANC_ROOT}/Core/MultiThreading/Semaphore.cpp
+ ${ORTHANC_ROOT}/Core/MultiThreading/SharedMessageQueue.cpp
+ ${ORTHANC_ROOT}/Core/SystemToolbox.cpp
+ ${ORTHANC_ROOT}/Core/TemporaryFile.cpp
+ )
+endif()
+
+
+if (HAS_EMBEDDED_RESOURCES)
+ add_definitions(-DORTHANC_HAS_EMBEDDED_RESOURCES=1)
+
+ list(APPEND ORTHANC_CORE_SOURCES_INTERNAL
+ ${ORTHANC_ROOT}/Core/HttpServer/EmbeddedResourceHttpHandler.cpp
+ )
+else()
+ add_definitions(-DORTHANC_HAS_EMBEDDED_RESOURCES=0)
+endif()
+
+
+#####################################################################
+## Gathering of all the source code
+#####################################################################
+
+# The "xxx_INTERNAL" variables list the source code that belongs to
+# the Orthanc project. It can be used to configure precompiled headers
+# if using Microsoft Visual Studio.
+
+# The "xxx_DEPENDENCIES" variables list the source code coming from
+# third-party dependencies.
+
+
+set(ORTHANC_CORE_SOURCES_DEPENDENCIES
+ ${BOOST_SOURCES}
+ ${CIVETWEB_SOURCES}
+ ${CURL_SOURCES}
+ ${JSONCPP_SOURCES}
+ ${LIBICONV_SOURCES}
+ ${LIBJPEG_SOURCES}
+ ${LIBP11_SOURCES}
+ ${LIBPNG_SOURCES}
+ ${LUA_SOURCES}
+ ${MONGOOSE_SOURCES}
+ ${OPENSSL_SOURCES}
+ ${PUGIXML_SOURCES}
+ ${SQLITE_SOURCES}
+ ${ZLIB_SOURCES}
+
+ ${ORTHANC_ROOT}/Resources/ThirdParty/md5/md5.c
+ ${ORTHANC_ROOT}/Resources/ThirdParty/base64/base64.cpp
+
+ # This is the minizip distribution to create ZIP files using zlib
+ ${ORTHANC_ROOT}/Resources/ThirdParty/minizip/ioapi.c
+ ${ORTHANC_ROOT}/Resources/ThirdParty/minizip/zip.c
+ )
+
+set(ORTHANC_CORE_SOURCES
+ ${ORTHANC_CORE_SOURCES_INTERNAL}
+ ${ORTHANC_CORE_SOURCES_DEPENDENCIES}
+ )
+
+if (ENABLE_DCMTK)
+ list(APPEND ORTHANC_DICOM_SOURCES_DEPENDENCIES
+ ${DCMTK_SOURCES}
+ )
+
+ set(ORTHANC_DICOM_SOURCES
+ ${ORTHANC_DICOM_SOURCES_INTERNAL}
+ ${ORTHANC_DICOM_SOURCES_DEPENDENCIES}
+ )
+endif()
diff --git a/Resources/CMake/OrthancFrameworkParameters.cmake b/Resources/CMake/OrthancFrameworkParameters.cmake
new file mode 100644
index 0000000..9888e11
--- /dev/null
+++ b/Resources/CMake/OrthancFrameworkParameters.cmake
@@ -0,0 +1,96 @@
+#####################################################################
+## Versioning information
+#####################################################################
+
+# Version of the build, should always be "mainline" except in release branches
+set(ORTHANC_VERSION "1.3.1")
+
+# Version of the database schema. History:
+# * Orthanc 0.1.0 -> Orthanc 0.3.0 = no versioning
+# * Orthanc 0.3.1 = version 2
+# * Orthanc 0.4.0 -> Orthanc 0.7.2 = version 3
+# * Orthanc 0.7.3 -> Orthanc 0.8.4 = version 4
+# * Orthanc 0.8.5 -> Orthanc 0.9.4 = version 5
+# * Orthanc 0.9.5 -> mainline = version 6
+set(ORTHANC_DATABASE_VERSION 6)
+
+
+#####################################################################
+## CMake parameters tunable by the user
+#####################################################################
+
+# Support of static compilation
+set(ALLOW_DOWNLOADS OFF CACHE BOOL "Allow CMake to download packages")
+set(STATIC_BUILD OFF CACHE BOOL "Static build of the third-party libraries (necessary for Windows)")
+set(STANDALONE_BUILD ON CACHE BOOL "Standalone build (all the resources are embedded, necessary for releases)")
+
+# Generic parameters of the build
+set(ENABLE_CIVETWEB OFF CACHE BOOL "Use Civetweb instead of Mongoose (experimental)")
+set(ENABLE_PKCS11 OFF CACHE BOOL "Enable PKCS#11 for HTTPS client authentication using hardware security modules and smart cards")
+set(ENABLE_PROFILING OFF CACHE BOOL "Whether to enable the generation of profiling information with gprof")
+set(ENABLE_SSL ON CACHE BOOL "Include support for SSL")
+
+# Parameters to fine-tune linking against system libraries
+set(USE_SYSTEM_BOOST ON CACHE BOOL "Use the system version of Boost")
+set(USE_SYSTEM_CIVETWEB ON CACHE BOOL "Use the system version of Civetweb (experimental)")
+set(USE_SYSTEM_CURL ON CACHE BOOL "Use the system version of LibCurl")
+set(USE_SYSTEM_GOOGLE_TEST ON CACHE BOOL "Use the system version of Google Test")
+set(USE_SYSTEM_JSONCPP ON CACHE BOOL "Use the system version of JsonCpp")
+set(USE_SYSTEM_LIBICONV ON CACHE BOOL "Use the system version of libiconv")
+set(USE_SYSTEM_LIBJPEG ON CACHE BOOL "Use the system version of libjpeg")
+set(USE_SYSTEM_LIBP11 OFF CACHE BOOL "Use the system version of libp11 (PKCS#11 wrapper library)")
+set(USE_SYSTEM_LIBPNG ON CACHE BOOL "Use the system version of libpng")
+set(USE_SYSTEM_LUA ON CACHE BOOL "Use the system version of Lua")
+set(USE_SYSTEM_MONGOOSE ON CACHE BOOL "Use the system version of Mongoose")
+set(USE_SYSTEM_OPENSSL ON CACHE BOOL "Use the system version of OpenSSL")
+set(USE_SYSTEM_PUGIXML ON CACHE BOOL "Use the system version of Pugixml")
+set(USE_SYSTEM_SQLITE ON CACHE BOOL "Use the system version of SQLite")
+set(USE_SYSTEM_ZLIB ON CACHE BOOL "Use the system version of ZLib")
+
+# Parameters specific to DCMTK
+set(DCMTK_DICTIONARY_DIR "" CACHE PATH "Directory containing the DCMTK dictionaries \"dicom.dic\" and \"private.dic\" (only when using system version of DCMTK)")
+set(USE_DCMTK_360 OFF CACHE BOOL "Use older DCMTK version 3.6.0 in static builds (instead of default 3.6.2)")
+set(USE_DCMTK_362_PRIVATE_DIC ON CACHE BOOL "Use the dictionary of private tags from DCMTK 3.6.2 if using DCMTK 3.6.0")
+set(USE_SYSTEM_DCMTK ON CACHE BOOL "Use the system version of DCMTK")
+set(ENABLE_DCMTK_JPEG ON CACHE BOOL "Enable JPEG-LS (Lossless) decompression")
+set(ENABLE_DCMTK_JPEG_LOSSLESS ON CACHE BOOL "Enable JPEG-LS (Lossless) decompression")
+
+# Advanced and distribution-specific parameters
+set(USE_GOOGLE_TEST_DEBIAN_PACKAGE OFF CACHE BOOL "Use the sources of Google Test shipped with libgtest-dev (Debian only)")
+set(SYSTEM_MONGOOSE_USE_CALLBACKS ON CACHE BOOL "The system version of Mongoose uses callbacks (version >= 3.7)")
+set(USE_BOOST_ICONV ON CACHE BOOL "Use iconv instead of wconv (Windows only)")
+set(USE_PUGIXML ON CACHE BOOL "Use the Pugixml parser (turn off only for debug)")
+
+mark_as_advanced(USE_GOOGLE_TEST_DEBIAN_PACKAGE)
+mark_as_advanced(SYSTEM_MONGOOSE_USE_CALLBACKS)
+mark_as_advanced(USE_BOOST_ICONV)
+mark_as_advanced(USE_PUGIXML)
+
+
+#####################################################################
+## Internal CMake parameters to enable the optional subcomponents of
+## the Orthanc framework
+#####################################################################
+
+# These options must be set to "ON" if compiling Orthanc, but might be
+# set to "OFF" by third-party projects if their associated features
+# are not required
+
+set(ENABLE_CRYPTO_OPTIONS OFF CACHE INTERNAL "Show options related to cryptography")
+set(ENABLE_JPEG OFF CACHE INTERNAL "Enable support of JPEG")
+set(ENABLE_GOOGLE_TEST OFF CACHE INTERNAL "Enable support of Google Test")
+set(ENABLE_LOCALE OFF CACHE INTERNAL "Enable support for locales (notably in Boost)")
+set(ENABLE_LUA OFF CACHE INTERNAL "Enable support of Lua scripting")
+set(ENABLE_PNG OFF CACHE INTERNAL "Enable support of PNG")
+set(ENABLE_PUGIXML OFF CACHE INTERNAL "Enable support of XML through Pugixml")
+set(ENABLE_SQLITE OFF CACHE INTERNAL "Enable support of SQLite databases")
+set(ENABLE_WEB_CLIENT OFF CACHE INTERNAL "Enable Web client")
+set(ENABLE_WEB_SERVER OFF CACHE INTERNAL "Enable embedded Web server")
+set(ENABLE_DCMTK OFF CACHE INTERNAL "Enable DCMTK")
+set(ENABLE_DCMTK_NETWORKING OFF CACHE INTERNAL "Enable DICOM networking in DCMTK")
+
+set(HAS_EMBEDDED_RESOURCES OFF CACHE INTERNAL
+ "Whether resources are auto-generated using EmbedResources.py")
+
+set(ORTHANC_SANDBOXED OFF CACHE INTERNAL
+ "Whether Orthanc runs inside a sandboxed environment (such as Google NaCl or WebAssembly)")
diff --git a/Resources/CMake/PugixmlConfiguration.cmake b/Resources/CMake/PugixmlConfiguration.cmake
index 4d57b12..8b2715a 100644
--- a/Resources/CMake/PugixmlConfiguration.cmake
+++ b/Resources/CMake/PugixmlConfiguration.cmake
@@ -1,33 +1,26 @@
-if (USE_PUGIXML)
- add_definitions(-DORTHANC_ENABLE_PUGIXML=1)
+if (STATIC_BUILD OR NOT USE_SYSTEM_PUGIXML)
+ set(PUGIXML_SOURCES_DIR ${CMAKE_BINARY_DIR}/pugixml-1.4)
+ set(PUGIXML_MD5 "7c56c91cfe3ecdee248a8e4892ef5781")
+ set(PUGIXML_URL "http://www.orthanc-server.com/downloads/third-party/pugixml-1.4.tar.gz")
- if (STATIC_BUILD OR NOT USE_SYSTEM_PUGIXML)
- set(PUGIXML_SOURCES_DIR ${CMAKE_BINARY_DIR}/pugixml-1.4)
- set(PUGIXML_MD5 "7c56c91cfe3ecdee248a8e4892ef5781")
- set(PUGIXML_URL "http://www.orthanc-server.com/downloads/third-party/pugixml-1.4.tar.gz")
+ DownloadPackage(${PUGIXML_MD5} ${PUGIXML_URL} "${PUGIXML_SOURCES_DIR}")
- DownloadPackage(${PUGIXML_MD5} ${PUGIXML_URL} "${PUGIXML_SOURCES_DIR}")
+ include_directories(
+ ${PUGIXML_SOURCES_DIR}/src
+ )
- include_directories(
- ${PUGIXML_SOURCES_DIR}/src
- )
-
- set(PUGIXML_SOURCES
- #${PUGIXML_SOURCES_DIR}/src/vlog_is_on.cc
- ${PUGIXML_SOURCES_DIR}/src/pugixml.cpp
- )
-
- else()
- CHECK_INCLUDE_FILE_CXX(pugixml.hpp HAVE_PUGIXML_H)
- if (NOT HAVE_PUGIXML_H)
- message(FATAL_ERROR "Please install the libpugixml-dev package")
- endif()
-
- link_libraries(pugixml)
- endif()
+ set(PUGIXML_SOURCES
+ #${PUGIXML_SOURCES_DIR}/src/vlog_is_on.cc
+ ${PUGIXML_SOURCES_DIR}/src/pugixml.cpp
+ )
source_group(ThirdParty\\pugixml REGULAR_EXPRESSION ${PUGIXML_SOURCES_DIR}/.*)
else()
- add_definitions(-DORTHANC_ENABLE_PUGIXML=0)
+ CHECK_INCLUDE_FILE_CXX(pugixml.hpp HAVE_PUGIXML_H)
+ if (NOT HAVE_PUGIXML_H)
+ message(FATAL_ERROR "Please install the libpugixml-dev package")
+ endif()
+
+ link_libraries(pugixml)
endif()
diff --git a/Resources/CMake/SQLiteConfiguration.cmake b/Resources/CMake/SQLiteConfiguration.cmake
index 49ae259..6abec71 100644
--- a/Resources/CMake/SQLiteConfiguration.cmake
+++ b/Resources/CMake/SQLiteConfiguration.cmake
@@ -15,11 +15,11 @@ endif()
if (SQLITE_STATIC)
- SET(SQLITE_SOURCES_DIR ${CMAKE_BINARY_DIR}/sqlite-amalgamation-3071300)
- SET(SQLITE_MD5 "5fbeff9645ab035a1f580e90b279a16d")
- SET(SQLITE_URL "http://www.orthanc-server.com/downloads/third-party/sqlite-amalgamation-3071300.zip")
+ SET(SQLITE_SOURCES_DIR ${CMAKE_BINARY_DIR}/sqlite-amalgamation-3210000)
+ SET(SQLITE_MD5 "fe330e88d81e77e1e61554a370ae5001")
+ SET(SQLITE_URL "http://www.orthanc-server.com/downloads/third-party/sqlite-amalgamation-3210000.zip")
- add_definitions(-DORTHANC_SQLITE_VERSION=3007013)
+ add_definitions(-DORTHANC_SQLITE_VERSION=3021000)
DownloadPackage(${SQLITE_MD5} ${SQLITE_URL} "${SQLITE_SOURCES_DIR}")
diff --git a/Resources/CMake/VisualStudioPrecompiledHeaders.cmake b/Resources/CMake/VisualStudioPrecompiledHeaders.cmake
index 08e59a6..eb1df19 100644
--- a/Resources/CMake/VisualStudioPrecompiledHeaders.cmake
+++ b/Resources/CMake/VisualStudioPrecompiledHeaders.cmake
@@ -1,4 +1,4 @@
-macro(ADD_VISUAL_STUDIO_PRECOMPILED_HEADERS PrecompiledHeaders PrecompiledSource Sources)
+macro(ADD_VISUAL_STUDIO_PRECOMPILED_HEADERS PrecompiledHeaders PrecompiledSource Sources Target)
get_filename_component(PrecompiledBasename ${PrecompiledHeaders} NAME_WE)
set(PrecompiledBinary "${PrecompiledBasename}_$(ConfigurationName).pch")
@@ -10,5 +10,5 @@ macro(ADD_VISUAL_STUDIO_PRECOMPILED_HEADERS PrecompiledHeaders PrecompiledSource
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeaders}\" /FI\"${PrecompiledHeaders}\" /Fp\"${PrecompiledBinary}\""
OBJECT_DEPENDS "${PrecompiledBinary}")
- list(APPEND ${Sources} ${PrecompiledSource})
+ set(${Target} ${PrecompiledSource})
endmacro()
diff --git a/Resources/CMake/ZlibConfiguration.cmake b/Resources/CMake/ZlibConfiguration.cmake
index 4487c1e..84f1e3e 100644
--- a/Resources/CMake/ZlibConfiguration.cmake
+++ b/Resources/CMake/ZlibConfiguration.cmake
@@ -29,6 +29,15 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_ZLIB)
source_group(ThirdParty\\zlib REGULAR_EXPRESSION ${ZLIB_SOURCES_DIR}/.*)
+ if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
+ ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+ # "ioapi.c" from zlib (minizip) expects the "IOAPI_NO_64" macro to be set to "true"
+ # https://ohse.de/uwe/articles/lfs.html
+ add_definitions(
+ -DIOAPI_NO_64=1
+ )
+ endif()
+
else()
include(FindZLIB)
include_directories(${ZLIB_INCLUDE_DIRS})
diff --git a/Resources/Configuration.json b/Resources/Configuration.json
index 069c6cd..1bd93b5 100644
--- a/Resources/Configuration.json
+++ b/Resources/Configuration.json
@@ -171,6 +171,12 @@
// "clearcanvas" : [ "CLEARCANVAS", "192.168.1.1", 104, "ClearCanvas" ]
},
+ // Whether the Orthanc SCP allows incoming C-Echo requests, even
+ // from SCU modalities it does not know about (i.e. that are not
+ // listed in the "DicomModalities" option above). Orthanc 1.3.0
+ // is the only version to behave as if this argument was set to "false".
+ "DicomAlwaysAllowEcho" : true,
+
// Whether the Orthanc SCP allows incoming C-Store requests, even
// from SCU modalities it does not know about (i.e. that are not
// listed in the "DicomModalities" option above)
diff --git a/Resources/OldBuildInstructions.txt b/Resources/OldBuildInstructions.txt
index 3c390f7..9167bcc 100644
--- a/Resources/OldBuildInstructions.txt
+++ b/Resources/OldBuildInstructions.txt
@@ -32,7 +32,7 @@ Debian Wheezy (7.x)
# cmake -DALLOW_DOWNLOADS=ON \
-DUSE_SYSTEM_GOOGLE_LOG=OFF \
-DUSE_SYSTEM_MONGOOSE=OFF \
- -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
+ -DUSE_GOOGLE_TEST_DEBIAN_PACKAGE=ON \
-DUSE_SYSTEM_PUGIXML=OFF \
-DENABLE_JPEG=OFF \
-DENABLE_JPEG_LOSSLESS=OFF \
@@ -55,7 +55,7 @@ With JPEG:
-DALLOW_DOWNLOADS=ON \
-DUSE_SYSTEM_MONGOOSE=OFF \
-DUSE_SYSTEM_JSONCPP=OFF \
- -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
+ -DUSE_GOOGLE_TEST_DEBIAN_PACKAGE=ON \
-DUSE_SYSTEM_PUGIXML=OFF \
~/Orthanc
@@ -66,7 +66,7 @@ Without JPEG:
-DALLOW_DOWNLOADS=ON \
-DUSE_SYSTEM_MONGOOSE=OFF \
-DUSE_SYSTEM_JSONCPP=OFF \
- -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
+ -DUSE_GOOGLE_TEST_DEBIAN_PACKAGE=ON \
-DUSE_SYSTEM_PUGIXML=OFF \
-DENABLE_JPEG=OFF \
-DENABLE_JPEG_LOSSLESS=OFF \
@@ -85,7 +85,7 @@ SUPPORTED - Ubuntu 13.10
# cmake "-DDCMTK_LIBRARIES=wrap;oflog" \
-DALLOW_DOWNLOADS=ON \
-DUSE_SYSTEM_MONGOOSE=OFF \
- -DUSE_GTEST_DEBIAN_SOURCE_PACKAGE=ON \
+ -DUSE_GOOGLE_TEST_DEBIAN_PACKAGE=ON \
-DUSE_SYSTEM_PUGIXML=OFF \
-DENABLE_JPEG=OFF \
-DENABLE_JPEG_LOSSLESS=OFF \
diff --git a/Resources/Samples/OrthancFramework/MicroService/CMakeLists.txt b/Resources/Samples/OrthancFramework/MicroService/CMakeLists.txt
new file mode 100644
index 0000000..6dfd7b6
--- /dev/null
+++ b/Resources/Samples/OrthancFramework/MicroService/CMakeLists.txt
@@ -0,0 +1,16 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(Sample)
+
+include(${CMAKE_SOURCE_DIR}/../../../CMake/OrthancFrameworkParameters.cmake)
+
+set(ENABLE_WEB_SERVER ON)
+
+include(${CMAKE_SOURCE_DIR}/../../../CMake/OrthancFrameworkConfiguration.cmake)
+
+add_executable(Sample
+ ${ORTHANC_CORE_SOURCES}
+ Sample.cpp
+ )
+
+include_directories(${ORTHANC_ROOT}/Core)
diff --git a/Resources/Samples/OrthancFramework/MicroService/README.txt b/Resources/Samples/OrthancFramework/MicroService/README.txt
new file mode 100644
index 0000000..a92d992
--- /dev/null
+++ b/Resources/Samples/OrthancFramework/MicroService/README.txt
@@ -0,0 +1,2 @@
+This file shows how to create a simple Web service in C++ (similar to
+Python's Flask) using the Orthanc standalone framework.
diff --git a/Resources/Samples/OrthancFramework/MicroService/Sample.cpp b/Resources/Samples/OrthancFramework/MicroService/Sample.cpp
new file mode 100644
index 0000000..5736b16
--- /dev/null
+++ b/Resources/Samples/OrthancFramework/MicroService/Sample.cpp
@@ -0,0 +1,61 @@
+#include <stdio.h>
+
+#include <HttpServer/MongooseServer.h>
+#include <Logging.h>
+#include <RestApi/RestApi.h>
+#include <SystemToolbox.h>
+
+class MicroService : public Orthanc::RestApi
+{
+private:
+ static MicroService& GetSelf(Orthanc::RestApiCall& call)
+ {
+ return dynamic_cast<MicroService&>(call.GetContext());
+ }
+
+ void SayHello()
+ {
+ printf("Hello\n");
+ }
+
+ static void Hello(Orthanc::RestApiGetCall& call)
+ {
+ GetSelf(call).SayHello();
+
+ Json::Value value = Json::arrayValue;
+ value.append("World");
+
+ call.GetOutput().AnswerJson(value);
+ }
+
+public:
+ MicroService()
+ {
+ Register("/hello", Hello);
+ }
+};
+
+int main()
+{
+ Orthanc::Logging::Initialize();
+ Orthanc::Logging::EnableTraceLevel(true);
+
+ MicroService rest;
+
+ {
+ Orthanc::MongooseServer httpServer;
+ httpServer.SetPortNumber(8000);
+ httpServer.Register(rest);
+ httpServer.SetRemoteAccessAllowed(true);
+ httpServer.Start();
+
+ LOG(WARNING) << "Micro-service started on port " << httpServer.GetPortNumber();
+ Orthanc::SystemToolbox::ServerBarrier();
+ }
+
+ LOG(WARNING) << "Micro-service stopped";
+
+ Orthanc::Logging::Finalize();
+
+ return 0;
+}
diff --git a/Resources/Samples/Tools/CMakeLists.txt b/Resources/Samples/Tools/CMakeLists.txt
index c426f5e..408d890 100644
--- a/Resources/Samples/Tools/CMakeLists.txt
+++ b/Resources/Samples/Tools/CMakeLists.txt
@@ -8,32 +8,18 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
link_libraries(pthread dl)
endif()
+include(${CMAKE_SOURCE_DIR}/../../CMake/OrthancFrameworkParameters.cmake)
+
set(STATIC_BUILD ON)
set(ALLOW_DOWNLOADS ON)
-set(ORTHANC_ROOT ${CMAKE_SOURCE_DIR}/../../..)
-
-include(CheckIncludeFiles)
-include(CheckIncludeFileCXX)
-include(CheckLibraryExists)
-include(${ORTHANC_ROOT}/Resources/CMake/Compiler.cmake)
-include(${ORTHANC_ROOT}/Resources/CMake/DownloadPackage.cmake)
-include(${ORTHANC_ROOT}/Resources/CMake/BoostConfiguration.cmake)
-include(${ORTHANC_ROOT}/Resources/CMake/ZlibConfiguration.cmake)
-include(${ORTHANC_ROOT}/Resources/CMake/JsonCppConfiguration.cmake)
-
-add_definitions(
- -DORTHANC_ENABLE_BASE64=0
- -DORTHANC_ENABLE_MD5=0
- -DORTHANC_ENABLE_PUGIXML=0
- -DORTHANC_ENABLE_LOGGING=0
- -DORTHANC_SANDBOXED=0
- )
+include(${CMAKE_SOURCE_DIR}/../../CMake/OrthancFrameworkConfiguration.cmake)
add_library(CommonLibraries
${BOOST_SOURCES}
${JSONCPP_SOURCES}
${ORTHANC_ROOT}/Core/Enumerations.cpp
+ ${ORTHANC_ROOT}/Core/Logging.cpp
${ORTHANC_ROOT}/Core/SystemToolbox.cpp
${ORTHANC_ROOT}/Core/Toolbox.cpp
${ORTHANC_ROOT}/Resources/ThirdParty/md5/md5.c
diff --git a/TODO b/TODO
index 55a0c8b..019b512 100644
--- a/TODO
+++ b/TODO
@@ -20,6 +20,15 @@ General
* Option to enable DNS lookups in DICOM: https://goo.gl/woa35Z
+============
+Dependencies
+============
+
+* Switch from libiconv to libICU (http://site.icu-project.org/download),
+ as recommended by Boost:
+ http://www.boost.org/doc/libs/1_64_0/libs/locale/doc/html/building_boost_locale.html
+
+
========
REST API
========
@@ -67,6 +76,8 @@ Long-term
* Support DICOM TLS (cf. "--enable-tls" in storescp)
* Support Storage Commitment:
https://groups.google.com/forum/#!msg/orthanc-users/VZOn8St65jw/s8kg_OHesj0J
+* Support extended association:
+ https://groups.google.com/d/msg/orthanc-users/xD4d3mpc6ms/srF7E2goAAAJ
=======
diff --git a/UnitTestsSources/DicomMapTests.cpp b/UnitTestsSources/DicomMapTests.cpp
index 2aeb047..03d37d4 100644
--- a/UnitTestsSources/DicomMapTests.cpp
+++ b/UnitTestsSources/DicomMapTests.cpp
@@ -36,7 +36,7 @@
#include "../Core/OrthancException.h"
#include "../Core/DicomFormat/DicomMap.h"
-#include "../OrthancServer/FromDcmtkBridge.h"
+#include "../Core/DicomParsing/FromDcmtkBridge.h"
#include <memory>
@@ -220,3 +220,151 @@ TEST(DicomMap, Modules)
TestModule(ResourceType_Series, DicomModule_Series); // TODO
TestModule(ResourceType_Instance, DicomModule_Instance);
}
+
+
+TEST(DicomMap, Parse)
+{
+ DicomMap m;
+ float f;
+ double d;
+ int32_t i;
+ int64_t j;
+ uint32_t k;
+ uint64_t l;
+ std::string s;
+
+ m.SetValue(DICOM_TAG_PATIENT_NAME, " ", false); // Empty value
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
+
+ m.SetValue(DICOM_TAG_PATIENT_NAME, "0", true); // Binary value
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
+
+ ASSERT_FALSE(m.CopyToString(s, DICOM_TAG_PATIENT_NAME, false));
+ ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_PATIENT_NAME, true));
+ ASSERT_EQ("0", s);
+
+
+ // 2**31-1
+ m.SetValue(DICOM_TAG_PATIENT_NAME, "2147483647", false);
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
+ ASSERT_FLOAT_EQ(2147483647.0f, f);
+ ASSERT_DOUBLE_EQ(2147483647.0, d);
+ ASSERT_EQ(2147483647, i);
+ ASSERT_EQ(2147483647ll, j);
+ ASSERT_EQ(2147483647u, k);
+ ASSERT_EQ(2147483647ull, l);
+
+ // Test shortcuts
+ m.SetValue(DICOM_TAG_PATIENT_NAME, "42", false);
+ ASSERT_TRUE(m.ParseFloat(f, DICOM_TAG_PATIENT_NAME));
+ ASSERT_TRUE(m.ParseDouble(d, DICOM_TAG_PATIENT_NAME));
+ ASSERT_TRUE(m.ParseInteger32(i, DICOM_TAG_PATIENT_NAME));
+ ASSERT_TRUE(m.ParseInteger64(j, DICOM_TAG_PATIENT_NAME));
+ ASSERT_TRUE(m.ParseUnsignedInteger32(k, DICOM_TAG_PATIENT_NAME));
+ ASSERT_TRUE(m.ParseUnsignedInteger64(l, DICOM_TAG_PATIENT_NAME));
+ ASSERT_FLOAT_EQ(42.0f, f);
+ ASSERT_DOUBLE_EQ(42.0, d);
+ ASSERT_EQ(42, i);
+ ASSERT_EQ(42ll, j);
+ ASSERT_EQ(42u, k);
+ ASSERT_EQ(42ull, l);
+
+ ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_PATIENT_NAME, false));
+ ASSERT_EQ("42", s);
+ ASSERT_TRUE(m.CopyToString(s, DICOM_TAG_PATIENT_NAME, true));
+ ASSERT_EQ("42", s);
+
+
+ // 2**31
+ m.SetValue(DICOM_TAG_PATIENT_NAME, "2147483648", false);
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
+ ASSERT_FLOAT_EQ(2147483648.0f, f);
+ ASSERT_DOUBLE_EQ(2147483648.0, d);
+ ASSERT_EQ(2147483648ll, j);
+ ASSERT_EQ(2147483648u, k);
+ ASSERT_EQ(2147483648ull, l);
+
+ // 2**32-1
+ m.SetValue(DICOM_TAG_PATIENT_NAME, "4294967295", false);
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
+ ASSERT_FLOAT_EQ(4294967295.0f, f);
+ ASSERT_DOUBLE_EQ(4294967295.0, d);
+ ASSERT_EQ(4294967295ll, j);
+ ASSERT_EQ(4294967295u, k);
+ ASSERT_EQ(4294967295ull, l);
+
+ // 2**32
+ m.SetValue(DICOM_TAG_PATIENT_NAME, "4294967296", false);
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
+ ASSERT_FLOAT_EQ(4294967296.0f, f);
+ ASSERT_DOUBLE_EQ(4294967296.0, d);
+ ASSERT_EQ(4294967296ll, j);
+ ASSERT_EQ(4294967296ull, l);
+
+ m.SetValue(DICOM_TAG_PATIENT_NAME, "-1", false);
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
+ ASSERT_FLOAT_EQ(-1.0f, f);
+ ASSERT_DOUBLE_EQ(-1.0, d);
+ ASSERT_EQ(-1, i);
+ ASSERT_EQ(-1ll, j);
+
+ // -2**31
+ m.SetValue(DICOM_TAG_PATIENT_NAME, "-2147483648", false);
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
+ ASSERT_FLOAT_EQ(-2147483648.0f, f);
+ ASSERT_DOUBLE_EQ(-2147483648.0, d);
+ ASSERT_EQ(-2147483648, i);
+ ASSERT_EQ(-2147483648ll, j);
+
+ // -2**31 - 1
+ m.SetValue(DICOM_TAG_PATIENT_NAME, "-2147483649", false);
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseFloat(f));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseDouble(d));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger32(i));
+ ASSERT_TRUE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseInteger64(j));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger32(k));
+ ASSERT_FALSE(m.GetValue(DICOM_TAG_PATIENT_NAME).ParseUnsignedInteger64(l));
+ ASSERT_FLOAT_EQ(-2147483649.0f, f);
+ ASSERT_DOUBLE_EQ(-2147483649.0, d);
+ ASSERT_EQ(-2147483649ll, j);
+}
diff --git a/UnitTestsSources/FromDcmtkTests.cpp b/UnitTestsSources/FromDcmtkTests.cpp
index 57f9aeb..d0eeecc 100644
--- a/UnitTestsSources/FromDcmtkTests.cpp
+++ b/UnitTestsSources/FromDcmtkTests.cpp
@@ -34,10 +34,9 @@
#include "PrecompiledHeadersUnitTests.h"
#include "gtest/gtest.h"
-#include "../OrthancServer/FromDcmtkBridge.h"
-#include "../OrthancServer/ToDcmtkBridge.h"
-#include "../OrthancServer/OrthancInitialization.h"
-#include "../OrthancServer/DicomModification.h"
+#include "../Core/DicomParsing/FromDcmtkBridge.h"
+#include "../Core/DicomParsing/ToDcmtkBridge.h"
+#include "../Core/DicomParsing/DicomModification.h"
#include "../OrthancServer/ServerToolbox.h"
#include "../Core/OrthancException.h"
#include "../Core/Images/ImageBuffer.h"
@@ -47,8 +46,8 @@
#include "../Core/Images/ImageProcessing.h"
#include "../Core/Endianness.h"
#include "../Resources/EncodingTests.h"
-#include "../OrthancServer/DicomProtocol/DicomFindAnswers.h"
-#include "../OrthancServer/Internals/DicomImageDecoder.h"
+#include "../Core/DicomNetworking/DicomFindAnswers.h"
+#include "../Core/DicomParsing/Internals/DicomImageDecoder.h"
#include "../Plugins/Engine/PluginsEnumerations.h"
#include <dcmtk/dcmdata/dcelem.h>
@@ -264,6 +263,7 @@ TEST(FromDcmtkBridge, Enumerations)
// http://dicom.nema.org/medical/dicom/current/output/html/part03.html#table_C.12-5
ASSERT_TRUE(GetDicomEncoding(e, "ISO_IR 192")); ASSERT_EQ(Encoding_Utf8, e);
ASSERT_TRUE(GetDicomEncoding(e, "GB18030")); ASSERT_EQ(Encoding_Chinese, e);
+ ASSERT_TRUE(GetDicomEncoding(e, "GBK")); ASSERT_EQ(Encoding_Chinese, e);
}
@@ -395,7 +395,28 @@ namespace Orthanc
element.reset(FromDcmtkBridge::FromJson(DICOM_TAG_PATIENT_NAME, a, false, Encoding_Utf8));
Json::Value b;
- FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short, DicomToJsonFlags_Default, 0, Encoding_Ascii);
+ std::set<DicomTag> ignoreTagLength;
+ ignoreTagLength.insert(DICOM_TAG_PATIENT_ID);
+
+ FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short,
+ DicomToJsonFlags_Default, 0, Encoding_Ascii, ignoreTagLength);
+ ASSERT_TRUE(b.isMember("0010,0010"));
+ ASSERT_EQ("Hello", b["0010,0010"].asString());
+
+ FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short,
+ DicomToJsonFlags_Default, 3, Encoding_Ascii, ignoreTagLength);
+ ASSERT_TRUE(b["0010,0010"].isNull()); // "Hello" has more than 3 characters
+
+ FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Full,
+ DicomToJsonFlags_Default, 3, Encoding_Ascii, ignoreTagLength);
+ ASSERT_TRUE(b["0010,0010"].isObject());
+ ASSERT_EQ("PatientName", b["0010,0010"]["Name"].asString());
+ ASSERT_EQ("TooLong", b["0010,0010"]["Type"].asString());
+ ASSERT_TRUE(b["0010,0010"]["Value"].isNull());
+
+ ignoreTagLength.insert(DICOM_TAG_PATIENT_NAME);
+ FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short,
+ DicomToJsonFlags_Default, 3, Encoding_Ascii, ignoreTagLength);
ASSERT_EQ("Hello", b["0010,0010"].asString());
}
@@ -419,7 +440,9 @@ namespace Orthanc
element.reset(FromDcmtkBridge::FromJson(DICOM_TAG_PATIENT_NAME, a, true, Encoding_Utf8));
Json::Value b;
- FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short, DicomToJsonFlags_Default, 0, Encoding_Ascii);
+ std::set<DicomTag> ignoreTagLength;
+ FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short,
+ DicomToJsonFlags_Default, 0, Encoding_Ascii, ignoreTagLength);
ASSERT_EQ("Hello", b["0010,0010"].asString());
}
@@ -430,7 +453,9 @@ namespace Orthanc
{
Json::Value b;
- FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short, DicomToJsonFlags_Default, 0, Encoding_Ascii);
+ std::set<DicomTag> ignoreTagLength;
+ FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Short,
+ DicomToJsonFlags_Default, 0, Encoding_Ascii, ignoreTagLength);
ASSERT_EQ(Json::arrayValue, b["0008,1110"].type());
ASSERT_EQ(2u, b["0008,1110"].size());
@@ -447,7 +472,9 @@ namespace Orthanc
{
Json::Value b;
- FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Full, DicomToJsonFlags_Default, 0, Encoding_Ascii);
+ std::set<DicomTag> ignoreTagLength;
+ FromDcmtkBridge::ElementToJson(b, *element, DicomToJsonFormat_Full,
+ DicomToJsonFlags_Default, 0, Encoding_Ascii, ignoreTagLength);
Json::Value c;
ServerToolbox::SimplifyTags(c, b, DicomToJsonFormat_Human);
@@ -1062,20 +1089,20 @@ static void CheckEncoding(const ParsedDicomFile& dicom,
TEST(ParsedDicomFile, DicomMapEncodings1)
{
- Configuration::SetDefaultEncoding(Encoding_Ascii);
- ASSERT_EQ(Encoding_Ascii, Configuration::GetDefaultEncoding());
+ SetDefaultDicomEncoding(Encoding_Ascii);
+ ASSERT_EQ(Encoding_Ascii, GetDefaultDicomEncoding());
{
DicomMap m;
ParsedDicomFile dicom(m);
- ASSERT_EQ(1, dicom.GetDcmtkObject().getDataset()->card());
+ ASSERT_EQ(1u, dicom.GetDcmtkObject().getDataset()->card());
CheckEncoding(dicom, Encoding_Ascii);
}
{
DicomMap m;
ParsedDicomFile dicom(m, Encoding_Latin4);
- ASSERT_EQ(1, dicom.GetDcmtkObject().getDataset()->card());
+ ASSERT_EQ(1u, dicom.GetDcmtkObject().getDataset()->card());
CheckEncoding(dicom, Encoding_Latin4);
}
@@ -1083,7 +1110,7 @@ TEST(ParsedDicomFile, DicomMapEncodings1)
DicomMap m;
m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, "ISO_IR 148", false);
ParsedDicomFile dicom(m);
- ASSERT_EQ(1, dicom.GetDcmtkObject().getDataset()->card());
+ ASSERT_EQ(1u, dicom.GetDcmtkObject().getDataset()->card());
CheckEncoding(dicom, Encoding_Latin5);
}
@@ -1091,7 +1118,7 @@ TEST(ParsedDicomFile, DicomMapEncodings1)
DicomMap m;
m.SetValue(DICOM_TAG_SPECIFIC_CHARACTER_SET, "ISO_IR 148", false);
ParsedDicomFile dicom(m, Encoding_Latin1);
- ASSERT_EQ(1, dicom.GetDcmtkObject().getDataset()->card());
+ ASSERT_EQ(1u, dicom.GetDcmtkObject().getDataset()->card());
CheckEncoding(dicom, Encoding_Latin5);
}
}
diff --git a/UnitTestsSources/ImageTests.cpp b/UnitTestsSources/ImageTests.cpp
index 9c9be56..8c72f33 100644
--- a/UnitTestsSources/ImageTests.cpp
+++ b/UnitTestsSources/ImageTests.cpp
@@ -43,7 +43,7 @@
#include "../Core/Images/PngWriter.h"
#include "../Core/Toolbox.h"
#include "../Core/TemporaryFile.h"
-#include "../OrthancServer/OrthancInitialization.h"
+#include "../OrthancServer/OrthancInitialization.h" // For the FontRegistry
#include <stdint.h>
diff --git a/UnitTestsSources/JpegLosslessTests.cpp b/UnitTestsSources/JpegLosslessTests.cpp
index dc5a98f..95dd1ae 100644
--- a/UnitTestsSources/JpegLosslessTests.cpp
+++ b/UnitTestsSources/JpegLosslessTests.cpp
@@ -34,13 +34,13 @@
#include "PrecompiledHeadersUnitTests.h"
#include "gtest/gtest.h"
-#include "../OrthancServer/Internals/DicomImageDecoder.h"
+#include "../Core/DicomParsing/Internals/DicomImageDecoder.h"
#if ORTHANC_ENABLE_JPEG_LOSSLESS == 1
#include <dcmtk/dcmdata/dcfilefo.h>
-#include "../OrthancServer/ParsedDicomFile.h"
+#include "../Core/DicomParsing/ParsedDicomFile.h"
#include "../Core/OrthancException.h"
#include "../Core/Images/ImageBuffer.h"
#include "../Core/Images/PngWriter.h"
diff --git a/UnitTestsSources/LuaTests.cpp b/UnitTestsSources/LuaTests.cpp
index d3beb93..6c759aa 100644
--- a/UnitTestsSources/LuaTests.cpp
+++ b/UnitTestsSources/LuaTests.cpp
@@ -287,9 +287,14 @@ TEST(Lua, Http)
{
Orthanc::LuaContext lua;
-#if UNIT_TESTS_WITH_HTTP_CONNEXIONS == 1
- lua.Execute("JSON = loadstring(HttpGet('http://www.orthanc-server.com/downloads/third-party/JSON.lua')) ()");
- const std::string url("http://www.orthanc-server.com/downloads/third-party/Product.json");
+#if UNIT_TESTS_WITH_HTTP_CONNEXIONS == 1
+ // The "http://www.orthanc-server.com/downloads/third-party/" does
+ // not automatically redirect to HTTPS, so we cas use it even if the
+ // OpenSSL/HTTPS support is disabled in curl
+ const std::string BASE = "http://www.orthanc-server.com/downloads/third-party/";
+
+ lua.Execute("JSON = loadstring(HttpGet('" + BASE + "JSON.lua')) ()");
+ const std::string url(BASE + "Product.json");
#endif
std::string s;
diff --git a/UnitTestsSources/MultiThreadingTests.cpp b/UnitTestsSources/MultiThreadingTests.cpp
index 0b448b4..64379e4 100644
--- a/UnitTestsSources/MultiThreadingTests.cpp
+++ b/UnitTestsSources/MultiThreadingTests.cpp
@@ -129,7 +129,7 @@ TEST(MultiThreading, ReaderWriterLock)
-#include "../OrthancServer/DicomProtocol/ReusableDicomUserConnection.h"
+#include "../Core/DicomNetworking/ReusableDicomUserConnection.h"
TEST(ReusableDicomUserConnection, DISABLED_Basic)
{
diff --git a/UnitTestsSources/PluginsTests.cpp b/UnitTestsSources/PluginsTests.cpp
index a2ab865..b11e70f 100644
--- a/UnitTestsSources/PluginsTests.cpp
+++ b/UnitTestsSources/PluginsTests.cpp
@@ -65,8 +65,8 @@ TEST(SharedLibrary, Basic)
ASSERT_TRUE(l.HasFunction("dlclose"));
ASSERT_FALSE(l.HasFunction("world"));
-#elif defined(__FreeBSD__)
- // dlopen() in FreeBSD is supplied by libc, libc.so is
+#elif defined(__FreeBSD__) || defined(__OpenBSD__)
+ // dlopen() in FreeBSD/OpenBSD is supplied by libc, libc.so is
// a ldscript, so we can't actually use it. Use thread
// library instead - if it works - dlopen() is good.
SharedLibrary l("libpthread.so");
diff --git a/UnitTestsSources/RestApiTests.cpp b/UnitTestsSources/RestApiTests.cpp
index 7d0b690..8bdf7ff 100644
--- a/UnitTestsSources/RestApiTests.cpp
+++ b/UnitTestsSources/RestApiTests.cpp
@@ -66,8 +66,14 @@ TEST(HttpClient, Basic)
ASSERT_FALSE(c.IsVerbose());
#if UNIT_TESTS_WITH_HTTP_CONNEXIONS == 1
+ // The "http://www.orthanc-server.com/downloads/third-party/" does
+ // not automatically redirect to HTTPS, so we cas use it even if the
+ // OpenSSL/HTTPS support is disabled in curl
+ const std::string BASE = "http://www.orthanc-server.com/downloads/third-party/";
+
Json::Value v;
- c.SetUrl("http://www.orthanc-server.com/downloads/third-party/Product.json");
+ c.SetUrl(BASE + "Product.json");
+
c.Apply(v);
ASSERT_TRUE(v.type() == Json::objectValue);
ASSERT_TRUE(v.isMember("Description"));
diff --git a/UnitTestsSources/UnitTestsMain.cpp b/UnitTestsSources/UnitTestsMain.cpp
index 775ecc0..3905708 100644
--- a/UnitTestsSources/UnitTestsMain.cpp
+++ b/UnitTestsSources/UnitTestsMain.cpp
@@ -658,7 +658,7 @@ TEST(Toolbox, Enumerations)
-#if defined(__linux__)
+#if defined(__linux__) || defined(__OpenBSD__)
#include <endian.h>
#elif defined(__FreeBSD__)
#include <machine/endian.h>
@@ -700,7 +700,7 @@ TEST(Toolbox, Endianness)
* FreeBSD.
**/
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__OpenBSD__)
# if _BYTE_ORDER == _BIG_ENDIAN
ASSERT_EQ(Endianness_Big, Toolbox::DetectEndianness());
# else // _LITTLE_ENDIAN
@@ -977,7 +977,7 @@ TEST(Toolbox, AccessJson)
v = Json::objectValue;
ASSERT_EQ("nope", Toolbox::GetJsonStringField(v, "hello", "nope"));
ASSERT_EQ(-10, Toolbox::GetJsonIntegerField(v, "hello", -10));
- ASSERT_EQ(10, Toolbox::GetJsonUnsignedIntegerField(v, "hello", 10));
+ ASSERT_EQ(10u, Toolbox::GetJsonUnsignedIntegerField(v, "hello", 10));
ASSERT_TRUE(Toolbox::GetJsonBooleanField(v, "hello", true));
v["hello"] = "world";
@@ -995,7 +995,7 @@ TEST(Toolbox, AccessJson)
v["hello"] = 42;
ASSERT_THROW(Toolbox::GetJsonStringField(v, "hello", "nope"), OrthancException);
ASSERT_EQ(42, Toolbox::GetJsonIntegerField(v, "hello", -10));
- ASSERT_EQ(42, Toolbox::GetJsonUnsignedIntegerField(v, "hello", 10));
+ ASSERT_EQ(42u, Toolbox::GetJsonUnsignedIntegerField(v, "hello", 10));
ASSERT_THROW(Toolbox::GetJsonBooleanField(v, "hello", true), OrthancException);
v["hello"] = false;
diff --git a/UnitTestsSources/VersionsTests.cpp b/UnitTestsSources/VersionsTests.cpp
index b649b76..a201df0 100644
--- a/UnitTestsSources/VersionsTests.cpp
+++ b/UnitTestsSources/VersionsTests.cpp
@@ -44,6 +44,7 @@
#include <sqlite3.h>
#include <lua.h>
#include <jpeglib.h>
+#include <iconv.h>
#if ORTHANC_ENABLE_SSL == 1
#include <openssl/opensslv.h>
@@ -103,7 +104,7 @@ TEST(Versions, ZlibStatic)
TEST(Versions, BoostStatic)
{
- ASSERT_STREQ("1_64", BOOST_LIB_VERSION);
+ ASSERT_STREQ("1_65_1", BOOST_LIB_VERSION);
}
TEST(Versions, CurlStatic)
@@ -143,6 +144,13 @@ TEST(Version, LuaStatic)
ASSERT_STREQ("Lua 5.1.5", LUA_RELEASE);
}
+TEST(Version, LibIconvStatic)
+{
+ static const int major = 1;
+ static const int minor = 15;
+ ASSERT_EQ((major << 8) + minor, _LIBICONV_VERSION);
+}
+
#if ORTHANC_ENABLE_SSL == 1
TEST(Version, OpenSslStatic)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/orthanc.git
More information about the debian-med-commit
mailing list