Mercurial > hg > orthanc-wsi
changeset 586:28ad390fb2e3 annotations
rename Enumerations.h as FrameworkEnumerations.h to avoid clashes with Orthanc
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Fri, 04 Sep 2026 16:29:07 +0200 |
| parents | 8ab5ad68c04b |
| children | b5fff3e9cb7c |
| files | Applications/CMakeLists.txt Framework/Enumerations.cpp Framework/Enumerations.h Framework/FrameworkEnumerations.cpp Framework/FrameworkEnumerations.h Framework/Inputs/DicomPyramidInstance.h Framework/Inputs/ITiledPyramid.h Framework/Outputs/IPyramidWriter.h Framework/Outputs/MultiframeDicomWriter.h Framework/TiffReader.h ViewerPlugin/CMakeLists.txt ViewerPlugin/RawTile.h |
| diffstat | 12 files changed, 308 insertions(+), 307 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/CMakeLists.txt Fri Sep 04 16:25:01 2026 +0200 +++ b/Applications/CMakeLists.txt Fri Sep 04 16:29:07 2026 +0200 @@ -129,7 +129,7 @@ ${ORTHANC_WSI_DIR}/Framework/ColorSpaces.cpp ${ORTHANC_WSI_DIR}/Framework/DicomToolbox.cpp ${ORTHANC_WSI_DIR}/Framework/DicomizerParameters.cpp - ${ORTHANC_WSI_DIR}/Framework/Enumerations.cpp + ${ORTHANC_WSI_DIR}/Framework/FrameworkEnumerations.cpp ${ORTHANC_WSI_DIR}/Framework/ImageToolbox.cpp ${ORTHANC_WSI_DIR}/Framework/ImagedVolumeParameters.cpp ${ORTHANC_WSI_DIR}/Framework/Inputs/CytomineImage.cpp
--- a/Framework/Enumerations.cpp Fri Sep 04 16:25:01 2026 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,224 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2023 Osimis S.A., Belgium - * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium - * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#include "PrecompiledHeadersWSI.h" -#include "Enumerations.h" - -#include "Jpeg2000Reader.h" - -#include <Logging.h> -#include <OrthancException.h> -#include <SystemToolbox.h> -#include <Toolbox.h> - -#include <string.h> -#include <boost/algorithm/string/predicate.hpp> - -#define HEADER(s) reinterpret_cast<const void*>(s), sizeof(s) - 1 - -namespace OrthancWSI -{ - const char* EnumerationToString(ImageCompression compression) - { - switch (compression) - { - case ImageCompression_Unknown: - return "Unknown"; - - case ImageCompression_None: - return "Raw image"; - - case ImageCompression_Png: - return "PNG"; - - case ImageCompression_Jpeg: - return "JPEG"; - - case ImageCompression_Jpeg2000: - return "JPEG2000"; - - case ImageCompression_Tiff: - return "TIFF"; - - case ImageCompression_Dicom: - return "DICOM"; - - case ImageCompression_JpegLS: - return "JPEG-LS"; - - default: - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - } - - - static bool MatchHeader(const void* actual, - size_t actualSize, - const void* expected, - size_t expectedSize) - { - if (actualSize < expectedSize) - { - return false; - } - else - { - return memcmp(actual, expected, expectedSize) == 0; - } - } - - - ImageCompression DetectFormatFromFile(const std::string& path) - { - std::string lower; - Orthanc::Toolbox::ToLowerCase(lower, path); - - std::string header; - Orthanc::SystemToolbox::ReadHeader(header, path, 256); - - ImageCompression tmp = DetectFormatFromMemory(header.c_str(), header.size()); - if (tmp != ImageCompression_Unknown) - { - if (tmp == ImageCompression_Jpeg && - boost::algorithm::ends_with(lower, ".mrxs")) - { - /** - * Special case of MIRAX / 3DHISTECH images, that contain a JPEG - * thumbnail, and that are thus confused with JPEG. - * https://bitbucket.org/sjodogne/orthanc/issues/163/ - **/ - - LOG(WARNING) << "The file extension \".mrxs\" indicates a MIRAX / 3DHISTECH image, " - << "skipping auto-detection of the file format"; - return ImageCompression_Unknown; - } - else if (tmp == ImageCompression_Tiff && - boost::algorithm::ends_with(lower, ".ndpi")) - { - LOG(WARNING) << "The file extension \".ndpi\" indicates a Hamamatsu image, " - << "use the flag \"--force-openslide 1\" if you do not have enough RAM to store the entire image"; - return ImageCompression_Tiff; - } - else if (tmp == ImageCompression_Tiff && - boost::algorithm::ends_with(lower, ".scn")) - { - LOG(WARNING) << "The file extension \".scn\" indicates a Leica image, " - << "use the flag \"--reencode 1\" or \"--force-openslide 1\" if you encounter problems"; - return ImageCompression_Tiff; - } - else - { - return tmp; - } - } - - // Cannot detect the format using the header, fallback to the use - // of the filename extension - - if (boost::algorithm::ends_with(lower, ".jpeg") || - boost::algorithm::ends_with(lower, ".jpg")) - { - return ImageCompression_Jpeg; - } - - if (boost::algorithm::ends_with(lower, ".png")) - { - return ImageCompression_Png; - } - - if (boost::algorithm::ends_with(lower, ".tiff") || - boost::algorithm::ends_with(lower, ".tif")) - { - return ImageCompression_Tiff; - } - - if (boost::algorithm::ends_with(lower, ".jp2") || - boost::algorithm::ends_with(lower, ".j2k")) - { - return ImageCompression_Jpeg2000; - } - - if (boost::algorithm::ends_with(lower, ".dcm")) - { - return ImageCompression_Dicom; - } - - return ImageCompression_Unknown; - } - - - ImageCompression DetectFormatFromMemory(const void* buffer, - size_t size) - { - if (MatchHeader(buffer, size, HEADER("\377\330\377"))) - { - return ImageCompression_Jpeg; - } - - if (MatchHeader(buffer, size, HEADER("\xff\x4f\xff\x51")) || - MatchHeader(buffer, size, HEADER("\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"))) - { - return ImageCompression_Jpeg2000; - } - - if (MatchHeader(buffer, size, HEADER("\211PNG\r\n\032\n"))) - { - return ImageCompression_Png; - } - - if (MatchHeader(buffer, size, HEADER("\115\115\000\052")) || - MatchHeader(buffer, size, HEADER("\111\111\052\000")) || - MatchHeader(buffer, size, HEADER("\115\115\000\053\000\010\000\000")) || - MatchHeader(buffer, size, HEADER("\111\111\053\000\010\000\000\000"))) - { - return ImageCompression_Tiff; - } - - if (size >= 128 + 4 && - MatchHeader(reinterpret_cast<const uint8_t*>(buffer) + 128, size - 128, HEADER("DICM"))) - { - bool ok = true; - for (size_t i = 0; ok && i < 128; i++) - { - if (reinterpret_cast<const uint8_t*>(buffer)[i] != 0) - { - ok = false; - } - } - - if (ok) - { - return ImageCompression_Dicom; - } - } - - Jpeg2000Format jpeg2000 = Jpeg2000Reader::DetectFormatFromMemory(buffer, size); - if (jpeg2000 == Jpeg2000Format_JP2 || - jpeg2000 == Jpeg2000Format_J2K) - { - return ImageCompression_Jpeg2000; - } - - return ImageCompression_Unknown; - } -}
--- a/Framework/Enumerations.h Fri Sep 04 16:25:01 2026 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2023 Osimis S.A., Belgium - * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium - * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#pragma once - -#include <Enumerations.h> - -#include <stdint.h> -#include <string> - -namespace OrthancWSI -{ - static const char* const VL_WHOLE_SLIDE_MICROSCOPY_IMAGE_STORAGE_IOD = "1.2.840.10008.5.1.4.1.1.77.1.6"; - - // WARNING - Don't change the enum values below, as this would break - // serialization of "DicomPyramidInstance" - enum ImageCompression - { - ImageCompression_Unknown = 1, - ImageCompression_None = 2, - ImageCompression_Dicom = 3, - ImageCompression_Png = 4, - ImageCompression_Jpeg = 5, - ImageCompression_Jpeg2000 = 6, - ImageCompression_Tiff = 7, - ImageCompression_UseOrthancPreview = 8, - ImageCompression_JpegLS = 9 - }; - - enum OpticalPath - { - OpticalPath_None, - OpticalPath_Brightfield - }; - - const char* EnumerationToString(ImageCompression compression); - - ImageCompression DetectFormatFromFile(const std::string& path); - - ImageCompression DetectFormatFromMemory(const void* buffer, - size_t size); - - inline unsigned int CeilingDivision(unsigned int a, - unsigned int b) - { - if (a % b == 0) - { - return a / b; - } - else - { - return a / b + 1; - } - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/FrameworkEnumerations.cpp Fri Sep 04 16:29:07 2026 +0200 @@ -0,0 +1,224 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2023 Osimis S.A., Belgium + * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium + * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "PrecompiledHeadersWSI.h" +#include "FrameworkEnumerations.h" + +#include "Jpeg2000Reader.h" + +#include <Logging.h> +#include <OrthancException.h> +#include <SystemToolbox.h> +#include <Toolbox.h> + +#include <string.h> +#include <boost/algorithm/string/predicate.hpp> + +#define HEADER(s) reinterpret_cast<const void*>(s), sizeof(s) - 1 + +namespace OrthancWSI +{ + const char* EnumerationToString(ImageCompression compression) + { + switch (compression) + { + case ImageCompression_Unknown: + return "Unknown"; + + case ImageCompression_None: + return "Raw image"; + + case ImageCompression_Png: + return "PNG"; + + case ImageCompression_Jpeg: + return "JPEG"; + + case ImageCompression_Jpeg2000: + return "JPEG2000"; + + case ImageCompression_Tiff: + return "TIFF"; + + case ImageCompression_Dicom: + return "DICOM"; + + case ImageCompression_JpegLS: + return "JPEG-LS"; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + } + + + static bool MatchHeader(const void* actual, + size_t actualSize, + const void* expected, + size_t expectedSize) + { + if (actualSize < expectedSize) + { + return false; + } + else + { + return memcmp(actual, expected, expectedSize) == 0; + } + } + + + ImageCompression DetectFormatFromFile(const std::string& path) + { + std::string lower; + Orthanc::Toolbox::ToLowerCase(lower, path); + + std::string header; + Orthanc::SystemToolbox::ReadHeader(header, path, 256); + + ImageCompression tmp = DetectFormatFromMemory(header.c_str(), header.size()); + if (tmp != ImageCompression_Unknown) + { + if (tmp == ImageCompression_Jpeg && + boost::algorithm::ends_with(lower, ".mrxs")) + { + /** + * Special case of MIRAX / 3DHISTECH images, that contain a JPEG + * thumbnail, and that are thus confused with JPEG. + * https://bitbucket.org/sjodogne/orthanc/issues/163/ + **/ + + LOG(WARNING) << "The file extension \".mrxs\" indicates a MIRAX / 3DHISTECH image, " + << "skipping auto-detection of the file format"; + return ImageCompression_Unknown; + } + else if (tmp == ImageCompression_Tiff && + boost::algorithm::ends_with(lower, ".ndpi")) + { + LOG(WARNING) << "The file extension \".ndpi\" indicates a Hamamatsu image, " + << "use the flag \"--force-openslide 1\" if you do not have enough RAM to store the entire image"; + return ImageCompression_Tiff; + } + else if (tmp == ImageCompression_Tiff && + boost::algorithm::ends_with(lower, ".scn")) + { + LOG(WARNING) << "The file extension \".scn\" indicates a Leica image, " + << "use the flag \"--reencode 1\" or \"--force-openslide 1\" if you encounter problems"; + return ImageCompression_Tiff; + } + else + { + return tmp; + } + } + + // Cannot detect the format using the header, fallback to the use + // of the filename extension + + if (boost::algorithm::ends_with(lower, ".jpeg") || + boost::algorithm::ends_with(lower, ".jpg")) + { + return ImageCompression_Jpeg; + } + + if (boost::algorithm::ends_with(lower, ".png")) + { + return ImageCompression_Png; + } + + if (boost::algorithm::ends_with(lower, ".tiff") || + boost::algorithm::ends_with(lower, ".tif")) + { + return ImageCompression_Tiff; + } + + if (boost::algorithm::ends_with(lower, ".jp2") || + boost::algorithm::ends_with(lower, ".j2k")) + { + return ImageCompression_Jpeg2000; + } + + if (boost::algorithm::ends_with(lower, ".dcm")) + { + return ImageCompression_Dicom; + } + + return ImageCompression_Unknown; + } + + + ImageCompression DetectFormatFromMemory(const void* buffer, + size_t size) + { + if (MatchHeader(buffer, size, HEADER("\377\330\377"))) + { + return ImageCompression_Jpeg; + } + + if (MatchHeader(buffer, size, HEADER("\xff\x4f\xff\x51")) || + MatchHeader(buffer, size, HEADER("\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"))) + { + return ImageCompression_Jpeg2000; + } + + if (MatchHeader(buffer, size, HEADER("\211PNG\r\n\032\n"))) + { + return ImageCompression_Png; + } + + if (MatchHeader(buffer, size, HEADER("\115\115\000\052")) || + MatchHeader(buffer, size, HEADER("\111\111\052\000")) || + MatchHeader(buffer, size, HEADER("\115\115\000\053\000\010\000\000")) || + MatchHeader(buffer, size, HEADER("\111\111\053\000\010\000\000\000"))) + { + return ImageCompression_Tiff; + } + + if (size >= 128 + 4 && + MatchHeader(reinterpret_cast<const uint8_t*>(buffer) + 128, size - 128, HEADER("DICM"))) + { + bool ok = true; + for (size_t i = 0; ok && i < 128; i++) + { + if (reinterpret_cast<const uint8_t*>(buffer)[i] != 0) + { + ok = false; + } + } + + if (ok) + { + return ImageCompression_Dicom; + } + } + + Jpeg2000Format jpeg2000 = Jpeg2000Reader::DetectFormatFromMemory(buffer, size); + if (jpeg2000 == Jpeg2000Format_JP2 || + jpeg2000 == Jpeg2000Format_J2K) + { + return ImageCompression_Jpeg2000; + } + + return ImageCompression_Unknown; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/FrameworkEnumerations.h Fri Sep 04 16:29:07 2026 +0200 @@ -0,0 +1,75 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2023 Osimis S.A., Belgium + * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium + * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include <Enumerations.h> + +#include <stdint.h> +#include <string> + +namespace OrthancWSI +{ + static const char* const VL_WHOLE_SLIDE_MICROSCOPY_IMAGE_STORAGE_IOD = "1.2.840.10008.5.1.4.1.1.77.1.6"; + + // WARNING - Don't change the enum values below, as this would break + // serialization of "DicomPyramidInstance" + enum ImageCompression + { + ImageCompression_Unknown = 1, + ImageCompression_None = 2, + ImageCompression_Dicom = 3, + ImageCompression_Png = 4, + ImageCompression_Jpeg = 5, + ImageCompression_Jpeg2000 = 6, + ImageCompression_Tiff = 7, + ImageCompression_UseOrthancPreview = 8, + ImageCompression_JpegLS = 9 + }; + + enum OpticalPath + { + OpticalPath_None, + OpticalPath_Brightfield + }; + + const char* EnumerationToString(ImageCompression compression); + + ImageCompression DetectFormatFromFile(const std::string& path); + + ImageCompression DetectFormatFromMemory(const void* buffer, + size_t size); + + inline unsigned int CeilingDivision(unsigned int a, + unsigned int b) + { + if (a % b == 0) + { + return a / b; + } + else + { + return a / b + 1; + } + } +}
--- a/Framework/Inputs/DicomPyramidInstance.h Fri Sep 04 16:25:01 2026 +0200 +++ b/Framework/Inputs/DicomPyramidInstance.h Fri Sep 04 16:29:07 2026 +0200 @@ -25,7 +25,7 @@ #include "../../Resources/Orthanc/Stone/IOrthancConnection.h" #include "../BackgroundColor.h" -#include "../Enumerations.h" +#include "../FrameworkEnumerations.h" #include <boost/noncopyable.hpp> #include <vector>
--- a/Framework/Inputs/ITiledPyramid.h Fri Sep 04 16:25:01 2026 +0200 +++ b/Framework/Inputs/ITiledPyramid.h Fri Sep 04 16:29:07 2026 +0200 @@ -24,7 +24,7 @@ #pragma once #include "../BackgroundColor.h" -#include "../Enumerations.h" +#include "../FrameworkEnumerations.h" #include <Compatibility.h> #include <Images/ImageAccessor.h>
--- a/Framework/Outputs/IPyramidWriter.h Fri Sep 04 16:25:01 2026 +0200 +++ b/Framework/Outputs/IPyramidWriter.h Fri Sep 04 16:29:07 2026 +0200 @@ -23,7 +23,8 @@ #pragma once -#include "../Enumerations.h" +#include "../FrameworkEnumerations.h" + #include <Images/ImageAccessor.h> #include <boost/noncopyable.hpp>
--- a/Framework/Outputs/MultiframeDicomWriter.h Fri Sep 04 16:25:01 2026 +0200 +++ b/Framework/Outputs/MultiframeDicomWriter.h Fri Sep 04 16:29:07 2026 +0200 @@ -23,7 +23,7 @@ #pragma once -#include "../Enumerations.h" +#include "../FrameworkEnumerations.h" #include <Compatibility.h> // For std::unique_ptr #include <ChunkedBuffer.h>
--- a/Framework/TiffReader.h Fri Sep 04 16:25:01 2026 +0200 +++ b/Framework/TiffReader.h Fri Sep 04 16:29:07 2026 +0200 @@ -23,7 +23,7 @@ #pragma once -#include "Enumerations.h" +#include "FrameworkEnumerations.h" #include <tiff.h> #include <tiffio.h>
--- a/ViewerPlugin/CMakeLists.txt Fri Sep 04 16:25:01 2026 +0200 +++ b/ViewerPlugin/CMakeLists.txt Fri Sep 04 16:29:07 2026 +0200 @@ -211,7 +211,7 @@ ${ORTHANC_WSI_DIR}/Framework/BackgroundColor.cpp ${ORTHANC_WSI_DIR}/Framework/ColorSpaces.cpp ${ORTHANC_WSI_DIR}/Framework/DicomToolbox.cpp - ${ORTHANC_WSI_DIR}/Framework/Enumerations.cpp + ${ORTHANC_WSI_DIR}/Framework/FrameworkEnumerations.cpp ${ORTHANC_WSI_DIR}/Framework/ImageToolbox.cpp ${ORTHANC_WSI_DIR}/Framework/Inputs/DecodedPyramidCache.cpp ${ORTHANC_WSI_DIR}/Framework/Inputs/DecodedTiledPyramid.cpp
--- a/ViewerPlugin/RawTile.h Fri Sep 04 16:25:01 2026 +0200 +++ b/ViewerPlugin/RawTile.h Fri Sep 04 16:29:07 2026 +0200 @@ -23,7 +23,7 @@ #pragma once -#include "../Framework/Enumerations.h" +#include "../Framework/FrameworkEnumerations.h" #include "../Framework/Inputs/ITiledPyramid.h" #include <orthanc/OrthancCPlugin.h>
