Mercurial > hg > orthanc-wsi
changeset 384:63936f094eaa
merge
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 07 Apr 2025 18:41:34 +0200 |
parents | 30959cb91e89 (current diff) 50cb2a69655f (diff) |
children | 87701a7be3f4 |
files | Framework/Inputs/DicomPyramidInstance.cpp Framework/Inputs/DicomPyramidLevel.cpp |
diffstat | 11 files changed, 127 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/CMakeLists.txt Mon Apr 07 18:40:34 2025 +0200 +++ b/Applications/CMakeLists.txt Mon Apr 07 18:41:34 2025 +0200 @@ -19,7 +19,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8...4.0) project(OrthancWSIApplications) include(${CMAKE_SOURCE_DIR}/../Resources/CMake/Version.cmake)
--- a/Framework/Enumerations.h Mon Apr 07 18:40:34 2025 +0200 +++ b/Framework/Enumerations.h Mon Apr 07 18:41:34 2025 +0200 @@ -42,7 +42,8 @@ ImageCompression_Png = 4, ImageCompression_Jpeg = 5, ImageCompression_Jpeg2000 = 6, - ImageCompression_Tiff = 7 + ImageCompression_Tiff = 7, + ImageCompression_UseOrthancPreview = 8 }; enum OpticalPath
--- a/Framework/ImageToolbox.cpp Mon Apr 07 18:40:34 2025 +0200 +++ b/Framework/ImageToolbox.cpp Mon Apr 07 18:41:34 2025 +0200 @@ -356,5 +356,54 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } } + + + bool HasPngSignature(const std::string& buffer) + { + if (buffer.size() < 8) + { + return false; + } + else + { + // https://en.wikipedia.org/wiki/PNG#File_header + // https://en.wikipedia.org/wiki/List_of_file_signatures + const uint8_t* p = reinterpret_cast<const uint8_t*>(buffer.data()); + return (p[0] == 0x89 && + p[1] == 0x50 && + p[2] == 0x4e && + p[3] == 0x47 && + p[4] == 0x0d && + p[5] == 0x0a && + p[6] == 0x1a && + p[7] == 0x0a); + } + } + + + bool HasJpegSignature(const std::string& buffer) + { + if (buffer.size() < 18) + { + return false; + } + else + { + // https://en.wikipedia.org/wiki/List_of_file_signatures + const uint8_t* p = reinterpret_cast<const uint8_t*>(buffer.data()); + if (p[0] != 0xff || + p[1] != 0xd8 || + p[2] != 0xff) + { + return false; + } + + // This is only a rough guess! + return (p[3] == 0xdb || + p[3] == 0xe0 || + p[3] == 0xee || + p[3] == 0xe1); + } + } } }
--- a/Framework/ImageToolbox.h Mon Apr 07 18:40:34 2025 +0200 +++ b/Framework/ImageToolbox.h Mon Apr 07 18:41:34 2025 +0200 @@ -77,5 +77,9 @@ void ConvertJpegYCbCrToRgb(Orthanc::ImageAccessor& image /* inplace */); ImageCompression Convert(Orthanc::MimeType type); + + bool HasPngSignature(const std::string& buffer); + + bool HasJpegSignature(const std::string& buffer); } }
--- a/Framework/Inputs/DicomPyramidInstance.cpp Mon Apr 07 18:40:34 2025 +0200 +++ b/Framework/Inputs/DicomPyramidInstance.cpp Mon Apr 07 18:41:34 2025 +0200 @@ -82,6 +82,10 @@ { return ImageCompression_Jpeg2000; } + else if (s == "1.2.840.10008.1.2.4.80") + { + return ImageCompression_UseOrthancPreview; + } else { LOG(ERROR) << "Unsupported transfer syntax: " << s;
--- a/Framework/Inputs/DicomPyramidLevel.cpp Mon Apr 07 18:40:34 2025 +0200 +++ b/Framework/Inputs/DicomPyramidLevel.cpp Mon Apr 07 18:41:34 2025 +0200 @@ -132,15 +132,39 @@ assert(tile.instance_ != NULL); DicomPyramidInstance& instance = *tile.instance_; - std::string uri = ("/instances/" + instance.GetInstanceId() + - "/frames/" + boost::lexical_cast<std::string>(tile.frame_) + "/raw"); - - orthanc.RestApiGet(raw, uri); - compression = instance.GetImageCompression(orthanc); format = instance.GetPixelFormat(); - return true; + if (compression == ImageCompression_UseOrthancPreview) + { + // If the WSI viewer plugin has no built-in support for this transfer syntax, + // use the decoding primitives offered by the Orthanc core + std::string uri = ("/instances/" + instance.GetInstanceId() + + "/frames/" + boost::lexical_cast<std::string>(tile.frame_) + "/preview"); + orthanc.RestApiGet(raw, uri); + + if (ImageToolbox::HasPngSignature(raw)) // In theory, Orthanc should always generate PNG by default + { + compression = ImageCompression_Png; + return true; + } + else if (ImageToolbox::HasJpegSignature(raw)) + { + compression = ImageCompression_Jpeg; + return true; + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Cannot decode a preview image generated by the Orthanc core"); + } + } + else + { + std::string uri = ("/instances/" + instance.GetInstanceId() + + "/frames/" + boost::lexical_cast<std::string>(tile.frame_) + "/raw"); + orthanc.RestApiGet(raw, uri); + return true; + } } else {
--- a/NEWS Mon Apr 07 18:40:34 2025 +0200 +++ b/NEWS Mon Apr 07 18:41:34 2025 +0200 @@ -3,6 +3,7 @@ * Support windowing when rendering grayscale images using on-the-fly deep zoom * Added tolerance to imaged volume width/height by looking only at the finest level +* Added support for JPEG-LS transfer syntax in the Web viewer plugin Version 3.1 (2025-03-17)
--- a/Resources/Orthanc/CMake/Compiler.cmake Mon Apr 07 18:40:34 2025 +0200 +++ b/Resources/Orthanc/CMake/Compiler.cmake Mon Apr 07 18:41:34 2025 +0200 @@ -22,6 +22,16 @@ # This file sets all the compiler-related flags +if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + # Since Orthanc 1.12.7 that allows CMake 4.0, builds for macOS + # require the C++ standard to be explicitly set to C++11. Do *not* + # do this on GNU/Linux, as third-party system libraries could have + # been compiled with higher versions of the C++ standard. + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) +endif() + # Save the current compiler flags to the cache every time cmake configures the project set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "compiler flags" FORCE)
--- a/Resources/Orthanc/CMake/DownloadOrthancFramework.cmake Mon Apr 07 18:40:34 2025 +0200 +++ b/Resources/Orthanc/CMake/DownloadOrthancFramework.cmake Mon Apr 07 18:41:34 2025 +0200 @@ -169,6 +169,8 @@ set(ORTHANC_FRAMEWORK_MD5 "5bb69f092981fdcfc11dec0a0f9a7db3") elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.12.6") set(ORTHANC_FRAMEWORK_MD5 "0e971f32f4f3e4951e0f3b5de49a3da6") + elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.12.7") + set(ORTHANC_FRAMEWORK_MD5 "f27c27d7a7a694dab1fd7f0a99d9715a") # Below this point are development snapshots that were used to # release some plugin, before an official release of the Orthanc @@ -501,7 +503,15 @@ include(CheckIncludeFile) include(CheckIncludeFileCXX) - include(FindPythonInterp) + + if(CMAKE_VERSION VERSION_GREATER "3.11") + find_package(Python REQUIRED COMPONENTS Interpreter) + set(PYTHON_EXECUTABLE ${Python_EXECUTABLE}) + else() + include(FindPythonInterp) + find_package(PythonInterp REQUIRED) + endif() + include(${CMAKE_CURRENT_LIST_DIR}/Compiler.cmake) include(${CMAKE_CURRENT_LIST_DIR}/DownloadPackage.cmake) include(${CMAKE_CURRENT_LIST_DIR}/AutoGeneratedCode.cmake)
--- a/ViewerPlugin/CMakeLists.txt Mon Apr 07 18:40:34 2025 +0200 +++ b/ViewerPlugin/CMakeLists.txt Mon Apr 07 18:41:34 2025 +0200 @@ -19,7 +19,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8...4.0) project(OrthancWSIPlugin) include(${CMAKE_SOURCE_DIR}/../Resources/CMake/Version.cmake)
--- a/ViewerPlugin/RawTile.cpp Mon Apr 07 18:40:34 2025 +0200 +++ b/ViewerPlugin/RawTile.cpp Mon Apr 07 18:41:34 2025 +0200 @@ -31,6 +31,7 @@ #include <Compatibility.h> // For std::unique_ptr #include <Images/ImageProcessing.h> #include <Images/JpegReader.h> +#include <Images/PngReader.h> #include <Images/PngWriter.h> #include <MultiThreading/Semaphore.h> #include <OrthancException.h> @@ -78,6 +79,19 @@ return decoded.release(); } + case ImageCompression_Png: + { + /** + * This is used if the DICOM instance has a transfer syntax + * that is not natively supported by the WSI viewer plugin, in + * which case the tile comes from the "/preview" route of the + * REST API of Orthanc. + **/ + std::unique_ptr<Orthanc::PngReader> decoded(new Orthanc::PngReader); + decoded->ReadFromMemory(tile_); + return decoded.release(); + } + default: throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); }