Mercurial > hg > orthanc
changeset 6583:5ea702bd43e1
merge
| author | Alain Mazy <am@orthanc.team> |
|---|---|
| date | Wed, 11 Feb 2026 16:28:03 +0100 |
| parents | b33dc28b890f (current diff) fa7123b2930a (diff) |
| children | 7a51327f5432 |
| files | |
| diffstat | 14 files changed, 372 insertions(+), 70 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Wed Feb 11 16:27:45 2026 +0100 +++ b/NEWS Wed Feb 11 16:28:03 2026 +0100 @@ -21,6 +21,12 @@ now returns all resources that do not have any label attached, instead of returning all resources. This applies to the default SQLite DB and will apply to the next PostgreSQL plugin (v10.1). +Plugins +------- + +* When listing the contents of a folder in WebDAV, it is possible to use the special value + ORTHANC_PLUGINS_WEBDAV_UNKNOWN_FILE_SIZE if the file size is unknown prior to download. + Maintenance -----------
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancFramework/Sources/CompatibilityMath.h Wed Feb 11 16:28:03 2026 +0100 @@ -0,0 +1,258 @@ +/** + * 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 Lesser General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#if defined(BOOST_MATH_ROUND_HPP) +# error You should not manually include <boost/math/special_functions/round.hpp> +#endif + +#include "Compatibility.h" + + +#ifdef __EMSCRIPTEN__ +/* + Avoid such errors: + ------------------ + + .../boost/math/special_functions/round.hpp:118:12: warning: implicit conversion from 'std::__2::numeric_limits<long long>::type' (aka 'long long') to 'float' changes value from 9223372036854775807 to 9223372036854775808 [-Wimplicit-int-float-conversion] + .../boost/math/special_functions/round.hpp:125:11: note: in instantiation of function template specialization 'boost::math::llround<float, boost::math::policies::policy<boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy> >' requested here + + .../boost/math/special_functions/round.hpp:86:12: warning: implicit conversion from 'std::__2::numeric_limits<int>::type' (aka 'int') to 'float' changes value from 2147483647 to 2147483648 [-Wimplicit-int-float-conversion] + .../boost/math/special_functions/round.hpp:93:11: note: in instantiation of function template specialization 'boost::math::iround<float, boost::math::policies::policy<boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy> >' requested here +*/ +# pragma GCC diagnostic ignored "-Wimplicit-int-float-conversion" +#endif + + +#if defined(_MSC_VER) + +/** + * This is for compatibility with Microsoft Visual Studio <= 2015. + * Indeed, Boost 1.89.0 does not support MSVC 14.0, as can be seen in + * this file: + * https://www.boost.org/doc/libs/1_89_0/boost/math/tools/config.hpp + **/ + +#include <cfloat> // For _isnan() +#include <cmath> // For _isnanf() +#include <limits> + +namespace Orthanc +{ + namespace Math + { + namespace Internals + { + ORTHANC_FORCE_INLINE + float RoundFloat(float v) + { + if (v >= 0.0f) + { + return std::floor(v + 0.5f); + } + else + { + return std::ceil(v - 0.5f); + } + } + + ORTHANC_FORCE_INLINE + double RoundDouble(double v) + { + if (v >= 0.0) + { + return std::floor(v + 0.5); + } + else + { + return std::ceil(v - 0.5); + } + } + + template <typename T> + ORTHANC_FORCE_INLINE + bool RoundFloatWithChecks(T& target, + float source) + { +#if defined(_WIN64) + // The functions "_isnanf()" and "_finitef()" are only available if targeting x64 + if (_isnanf(source) || + !_finitef(source)) + { + return false; + } +#else + if (_isnan(static_cast<double>(source)) || + !_finite(static_cast<double>(source))) + { + return false; + } +#endif + + const float rounded = RoundFloat(source); + if (rounded < static_cast<float>(std::numeric_limits<T>::min()) || + rounded > static_cast<float>(std::numeric_limits<T>::max())) + { + return false; + } + else + { + target = static_cast<T>(rounded); + return true; + } + } + + template <typename T> + ORTHANC_FORCE_INLINE + bool RoundDoubleWithChecks(T& target, + double source) + { + if (_isnan(source) || + !_finite(source)) + { + return false; + } + else + { + const double rounded = RoundDouble(source); + if (rounded < static_cast<double>(std::numeric_limits<T>::min()) || + rounded > static_cast<double>(std::numeric_limits<T>::max())) + { + return false; + } + else + { + target = static_cast<T>(rounded); + return true; + } + } + } + } + + ORTHANC_FORCE_INLINE + int iround(float v) + { + return static_cast<int>(Internals::RoundFloat(v)); + } + + ORTHANC_FORCE_INLINE + int iround(double v) + { + return static_cast<int>(Internals::RoundDouble(v)); + } + + ORTHANC_FORCE_INLINE + long long llround(float v) + { + return static_cast<long long>(Internals::RoundFloat(v)); + } + + ORTHANC_FORCE_INLINE + long long llround(double v) + { + return static_cast<long long>(Internals::RoundDouble(v)); + } + + ORTHANC_FORCE_INLINE + bool llround(long long& target, + float source) + { + return Internals::RoundFloatWithChecks<long long>(target, source); + } + + ORTHANC_FORCE_INLINE + long long llround(long long& target, + double source) + { + return Internals::RoundDoubleWithChecks<long long>(target, source); + } + } +} + +#else + +#include <boost/math/special_functions/round.hpp> + +namespace Orthanc +{ + namespace Math + { + ORTHANC_FORCE_INLINE + int iround(float v) + { + return boost::math::iround<float>(v); + } + + ORTHANC_FORCE_INLINE + int iround(double v) + { + return boost::math::iround<double>(v); + } + + ORTHANC_FORCE_INLINE + long long llround(float v) + { + return boost::math::llround<float>(v); + } + + ORTHANC_FORCE_INLINE + long long llround(double v) + { + return boost::math::llround<double>(v); + } + + ORTHANC_FORCE_INLINE + bool llround(long long& target, + float source) + { + try + { + target = boost::math::llround<float>(source); + return true; + } + catch (boost::math::rounding_error&) + { + return false; + } + } + + ORTHANC_FORCE_INLINE + long long llround(long long& target, + double source) + { + try + { + target = boost::math::llround<double>(source); + return true; + } + catch (boost::math::rounding_error&) + { + return false; + } + } + } +} + +#endif
--- a/OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.cpp Wed Feb 11 16:27:45 2026 +0100 +++ b/OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.cpp Wed Feb 11 16:28:03 2026 +0100 @@ -25,13 +25,13 @@ #include "../PrecompiledHeaders.h" #include "DicomWebJsonVisitor.h" +#include "../CompatibilityMath.h" #include "../Logging.h" #include "../OrthancException.h" +#include "../SerializationToolbox.h" #include "../Toolbox.h" -#include "../SerializationToolbox.h" #include "FromDcmtkBridge.h" -#include <boost/math/special_functions/round.hpp> #include <boost/lexical_cast.hpp> @@ -329,10 +329,9 @@ Json::Value DicomWebJsonVisitor::FormatDouble(double value) { - try + long long a; + if (Math::llround(a, value)) { - long long a = boost::math::llround<double>(value); - double d = fabs(value - static_cast<double>(a)); if (d <= std::numeric_limits<double>::epsilon() * 100.0) @@ -344,7 +343,7 @@ return Json::Value(value); } } - catch (boost::math::rounding_error&) + else { // Can occur if "long long" is too small to receive this value // (e.g. infinity) @@ -352,12 +351,12 @@ } } - Json::Value DicomWebJsonVisitor::FormatDecimalString(double value, const std::string& originalString) + Json::Value DicomWebJsonVisitor::FormatDecimalString(double value, + const std::string& originalString) { - try + long long a; + if (Math::llround(a, value)) { - long long a = boost::math::llround<double>(value); - double d = fabs(value - static_cast<double>(a)); if (d <= std::numeric_limits<double>::epsilon() * 100.0) @@ -369,7 +368,7 @@ return Json::Value(originalString); // keep the original string to avoid rounding errors e.g, transforming "0.143" into 0.14299999999999 } } - catch (boost::math::rounding_error&) + else { // Can occur if "long long" is too small to receive this value // (e.g. infinity)
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp Wed Feb 11 16:27:45 2026 +0100 +++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp Wed Feb 11 16:28:03 2026 +0100 @@ -138,7 +138,6 @@ #include <dcmtk/dcmdata/dcpxitem.h> -#include <boost/math/special_functions/round.hpp> #include <dcmtk/dcmdata/dcostrmb.h> #include <boost/algorithm/string/predicate.hpp>
--- a/OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp Wed Feb 11 16:27:45 2026 +0100 +++ b/OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp Wed Feb 11 16:28:03 2026 +0100 @@ -166,12 +166,20 @@ IWebDavBucket::File::File(const std::string& displayName) : Resource(displayName), + hasContentLength_(false), contentLength_(0), mime_(MimeType_Binary) { } + void IWebDavBucket::File::SetContentLength(uint64_t contentLength) + { + hasContentLength_ = true; + contentLength_ = contentLength; + } + + void IWebDavBucket::File::Format(pugi::xml_node& node, const std::string& parentPath) const { @@ -189,11 +197,14 @@ pugi::xml_node prop = node.first_element_by_path("D:propstat/D:prop"); prop.append_child("D:resourcetype"); - std::string s = boost::lexical_cast<std::string>(contentLength_); - prop.append_child("D:getcontentlength").append_child(pugi::node_pcdata).set_value(s.c_str()); + std::string s = EnumerationToString(mime_); + prop.append_child("D:getcontenttype").append_child(pugi::node_pcdata).set_value(s.c_str()); - s = EnumerationToString(mime_); - prop.append_child("D:getcontenttype").append_child(pugi::node_pcdata).set_value(s.c_str()); + if (hasContentLength_) + { + s = boost::lexical_cast<std::string>(contentLength_); + prop.append_child("D:getcontentlength").append_child(pugi::node_pcdata).set_value(s.c_str()); + } }
--- a/OrthancFramework/Sources/HttpServer/IWebDavBucket.h Wed Feb 11 16:27:45 2026 +0100 +++ b/OrthancFramework/Sources/HttpServer/IWebDavBucket.h Wed Feb 11 16:28:03 2026 +0100 @@ -92,16 +92,14 @@ class File : public Resource { private: + bool hasContentLength_; uint64_t contentLength_; MimeType mime_; public: explicit File(const std::string& displayName); - void SetContentLength(uint64_t contentLength) - { - contentLength_ = contentLength; - } + void SetContentLength(uint64_t contentLength); void SetMimeType(MimeType mime) {
--- a/OrthancFramework/Sources/Images/ImageProcessing.cpp Wed Feb 11 16:27:45 2026 +0100 +++ b/OrthancFramework/Sources/Images/ImageProcessing.cpp Wed Feb 11 16:28:03 2026 +0100 @@ -25,26 +25,15 @@ #include "../PrecompiledHeaders.h" #include "ImageProcessing.h" +#include "../CompatibilityMath.h" +#include "../OrthancException.h" #include "Image.h" #include "ImageTraits.h" #include "PixelTraits.h" -#include "../OrthancException.h" - -#ifdef __EMSCRIPTEN__ -/* - Avoid this error: - ----------------- - .../boost/math/special_functions/round.hpp:118:12: warning: implicit conversion from 'std::__2::numeric_limits<long long>::type' (aka 'long long') to 'float' changes value from 9223372036854775807 to 9223372036854775808 [-Wimplicit-int-float-conversion] - .../mnt/c/osi/dev/orthanc/Core/Images/ImageProcessing.cpp:333:28: note: in instantiation of function template specialization 'boost::math::llround<float>' requested here - .../mnt/c/osi/dev/orthanc/Core/Images/ImageProcessing.cpp:1006:9: note: in instantiation of function template specialization 'Orthanc::MultiplyConstantInternal<unsigned char, true>' requested here -*/ -#pragma GCC diagnostic ignored "-Wimplicit-int-float-conversion" -#endif - -#include <boost/math/special_functions/round.hpp> #include <algorithm> #include <cassert> +#include <cmath> #include <limits> #include <list> #include <map> @@ -384,7 +373,7 @@ { assert(sizeof(long long) == sizeof(int64_t)); // The "round" operation is very costly - v = boost::math::llround(static_cast<float>(*p) * factor); + v = Math::llround(static_cast<float>(*p) * factor); } else { @@ -464,7 +453,7 @@ { // The "round" operation is very costly assert(sizeof(TargetType) < sizeof(int)); - *p = static_cast<TargetType>(boost::math::iround(v)); + *p = static_cast<TargetType>(Math::iround(v)); } else { @@ -2716,7 +2705,7 @@ if (UseRound) { assert(sizeof(RawPixel) < sizeof(int)); - *p = static_cast<RawPixel>(boost::math::iround(accumulator)); + *p = static_cast<RawPixel>(Math::iround(accumulator)); } else { @@ -2868,8 +2857,8 @@ static_cast<float>(target.GetWidth()) / cw, static_cast<float>(target.GetHeight()) / ch); - unsigned int sw = std::min(static_cast<unsigned int>(boost::math::iround(cw * r)), target.GetWidth()); - unsigned int sh = std::min(static_cast<unsigned int>(boost::math::iround(ch * r)), target.GetHeight()); + unsigned int sw = std::min(static_cast<unsigned int>(Math::iround(cw * r)), target.GetWidth()); + unsigned int sh = std::min(static_cast<unsigned int>(Math::iround(ch * r)), target.GetHeight()); Image resized(target.GetFormat(), sw, sh, false); @@ -2913,10 +2902,10 @@ static_cast<float>(height) / static_cast<float>(source.GetHeight())); unsigned int resizedWidth = static_cast<unsigned int>( - boost::math::iround(ratio * static_cast<float>(source.GetWidth()))); + Math::iround(ratio * static_cast<float>(source.GetWidth()))); unsigned int resizedHeight = static_cast<unsigned int>( - boost::math::iround(ratio * static_cast<float>(source.GetHeight()))); + Math::iround(ratio * static_cast<float>(source.GetHeight()))); std::unique_ptr<ImageAccessor> resized(FitSize(source, resizedWidth, resizedHeight));
--- a/OrthancFramework/Sources/JobsEngine/JobInfo.cpp Wed Feb 11 16:27:45 2026 +0100 +++ b/OrthancFramework/Sources/JobsEngine/JobInfo.cpp Wed Feb 11 16:28:03 2026 +0100 @@ -24,27 +24,11 @@ #include "../PrecompiledHeaders.h" -#ifdef __EMSCRIPTEN__ -/* -Avoid this error: - -.../boost/math/special_functions/round.hpp:118:12: warning: implicit conversion from 'std::__2::numeric_limits<long long>::type' (aka 'long long') to 'float' changes value from 9223372036854775807 to 9223372036854775808 [-Wimplicit-int-float-conversion] -.../boost/math/special_functions/round.hpp:125:11: note: in instantiation of function template specialization 'boost::math::llround<float, boost::math::policies::policy<boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy> >' requested here -.../orthanc/Core/JobsEngine/JobInfo.cpp:69:44: note: in instantiation of function template specialization 'boost::math::llround<float>' requested here - -.../boost/math/special_functions/round.hpp:86:12: warning: implicit conversion from 'std::__2::numeric_limits<int>::type' (aka 'int') to 'float' changes value from 2147483647 to 2147483648 [-Wimplicit-int-float-conversion] -.../boost/math/special_functions/round.hpp:93:11: note: in instantiation of function template specialization 'boost::math::iround<float, boost::math::policies::policy<boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy, boost::math::policies::default_policy> >' requested here -.../orthanc/Core/JobsEngine/JobInfo.cpp:133:39: note: in instantiation of function template specialization 'boost::math::iround<float>' requested here -*/ -#pragma GCC diagnostic ignored "-Wimplicit-int-float-conversion" -#endif - #include "JobInfo.h" +#include "../CompatibilityMath.h" #include "../OrthancException.h" -// This "include" is mandatory for Release builds using Linux Standard Base -#include <boost/math/special_functions/round.hpp> namespace Orthanc { @@ -79,7 +63,7 @@ if (progress > 0.01f && ms > 0.01f) { - long long remaining = boost::math::llround(ms / progress * (1.0f - progress)); + long long remaining = Math::llround(ms / progress * (1.0f - progress)); eta_ = timestamp_ + boost::posix_time::milliseconds(remaining); hasEta_ = true; } @@ -189,7 +173,7 @@ target["Timestamp"] = boost::posix_time::to_iso_string(timestamp_); target["CreationTime"] = boost::posix_time::to_iso_string(creationTime_); target["EffectiveRuntime"] = static_cast<double>(runtime_.total_milliseconds()) / 1000.0; - target["Progress"] = boost::math::iround(status_.GetProgress() * 100.0f); + target["Progress"] = Math::iround(status_.GetProgress() * 100.0f); if (status_.HasUserData()) {
--- a/OrthancFramework/Sources/MetricsRegistry.cpp Wed Feb 11 16:27:45 2026 +0100 +++ b/OrthancFramework/Sources/MetricsRegistry.cpp Wed Feb 11 16:28:03 2026 +0100 @@ -27,10 +27,10 @@ #include "ChunkedBuffer.h" #include "Compatibility.h" +#include "CompatibilityMath.h" #include "Logging.h" #include "OrthancException.h" -#include <boost/math/special_functions/round.hpp> namespace Orthanc { @@ -339,7 +339,7 @@ virtual void UpdateFloat(float value) ORTHANC_OVERRIDE { - value_.Update(boost::math::llround(value), GetPolicy()); + value_.Update(Orthanc::Math::llround(value), GetPolicy()); } virtual void UpdateInteger(int64_t value) ORTHANC_OVERRIDE
--- a/OrthancFramework/Sources/RestApi/RestApi.cpp Wed Feb 11 16:27:45 2026 +0100 +++ b/OrthancFramework/Sources/RestApi/RestApi.cpp Wed Feb 11 16:28:03 2026 +0100 @@ -25,12 +25,12 @@ #include "../PrecompiledHeaders.h" #include "RestApi.h" +#include "../CompatibilityMath.h" #include "../HttpServer/StringHttpOutput.h" #include "../Logging.h" #include "../OrthancException.h" #include <boost/algorithm/string/replace.hpp> -#include <boost/math/special_functions/round.hpp> #include <stdlib.h> // To define "_exit()" under Windows #include <stdio.h> @@ -356,7 +356,7 @@ LOG(WARNING) << "The documentation of the REST API contains " << GetSuccessPathsCount() << " paths over a total of " << GetTotalPathsCount() << " paths " - << "(coverage: " << static_cast<unsigned int>(boost::math::iround(coverage)) << "%)"; + << "(coverage: " << static_cast<unsigned int>(Math::iround(coverage)) << "%)"; } };
--- a/OrthancFramework/UnitTestsSources/FrameworkTests.cpp Wed Feb 11 16:27:45 2026 +0100 +++ b/OrthancFramework/UnitTestsSources/FrameworkTests.cpp Wed Feb 11 16:28:03 2026 +0100 @@ -35,6 +35,7 @@ #include <gtest/gtest.h> +#include "../Sources/CompatibilityMath.h" #include "../Sources/DicomFormat/DicomTag.h" #include "../Sources/HttpServer/HttpToolbox.h" #include "../Sources/Logging.h" @@ -51,6 +52,7 @@ #endif #include <ctype.h> +#include <limits> using namespace Orthanc; @@ -1855,3 +1857,46 @@ ASSERT_TRUE(b.GetContent().isString()); ASSERT_EQ("Hello", b.GetContent().asString()); } + + +TEST(Math, Rounding) +{ + ASSERT_EQ(42, Math::iround(42.005f)); + ASSERT_EQ(42, Math::iround(41.995f)); + ASSERT_EQ(-42, Math::iround(-42.005f)); + ASSERT_EQ(-42, Math::iround(-41.995f)); + + ASSERT_EQ(43, Math::iround(43.005)); + ASSERT_EQ(43, Math::iround(42.995)); + ASSERT_EQ(-43, Math::iround(-43.005)); + ASSERT_EQ(-43, Math::iround(-42.995)); + + ASSERT_EQ(44ll, Math::llround(44.005f)); + ASSERT_EQ(44ll, Math::llround(43.995f)); + ASSERT_EQ(-44ll, Math::llround(-44.005f)); + ASSERT_EQ(-44ll, Math::llround(-43.995f)); + + ASSERT_EQ(45ll, Math::llround(45.005)); + ASSERT_EQ(45ll, Math::llround(44.995)); + ASSERT_EQ(-45ll, Math::llround(-45.005)); + ASSERT_EQ(-45ll, Math::llround(-44.995)); + + long long a; + ASSERT_TRUE(Math::llround(a, 46.005f)); ASSERT_EQ(46ll, a); + ASSERT_TRUE(Math::llround(a, 45.995f)); ASSERT_EQ(46ll, a); + ASSERT_TRUE(Math::llround(a, -46.005f)); ASSERT_EQ(-46ll, a); + ASSERT_TRUE(Math::llround(a, -45.995f)); ASSERT_EQ(-46ll, a); + + ASSERT_FALSE(Math::llround(a, std::numeric_limits<float>::quiet_NaN())); + ASSERT_FALSE(Math::llround(a, std::numeric_limits<float>::infinity())); + ASSERT_FALSE(Math::llround(a, 1e20f /* float too large */)); + + ASSERT_TRUE(Math::llround(a, 47.005)); ASSERT_EQ(47ll, a); + ASSERT_TRUE(Math::llround(a, 46.995)); ASSERT_EQ(47ll, a); + ASSERT_TRUE(Math::llround(a, -47.005)); ASSERT_EQ(-47ll, a); + ASSERT_TRUE(Math::llround(a, -46.995)); ASSERT_EQ(-47ll, a); + + ASSERT_FALSE(Math::llround(a, std::numeric_limits<double>::quiet_NaN())); + ASSERT_FALSE(Math::llround(a, std::numeric_limits<double>::infinity())); + ASSERT_FALSE(Math::llround(a, 1e20 /* double too large */)); +}
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Wed Feb 11 16:27:45 2026 +0100 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Wed Feb 11 16:28:03 2026 +0100 @@ -69,7 +69,6 @@ #include "PluginsEnumerations.h" #include "PluginsJob.h" -#include <boost/math/special_functions/round.hpp> #include <boost/regex.hpp> #include <dcmtk/dcmdata/dcdicent.h> #include <dcmtk/dcmnet/dimse.h> @@ -263,7 +262,11 @@ { std::unique_ptr<File> f(new File(displayName)); f->SetCreationTime(boost::posix_time::from_iso_string(creationTime)); - f->SetContentLength(contentSize); + + if (contentSize != ORTHANC_PLUGINS_WEBDAV_UNKNOWN_FILE_SIZE) + { + f->SetContentLength(contentSize); + } if (mimeType == NULL || std::string(mimeType).empty())
--- a/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Wed Feb 11 16:27:45 2026 +0100 +++ b/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Wed Feb 11 16:28:03 2026 +0100 @@ -222,6 +222,10 @@ ** Definition of the Orthanc Plugin API. ********************************************************************/ + +#define ORTHANC_PLUGINS_WEBDAV_UNKNOWN_FILE_SIZE ((uint64_t) -1) /* New in Orthanc 1.12.11 */ + + /** @{ */ #ifdef __cplusplus @@ -9498,11 +9502,17 @@ * This function declares a file while returning the content of a * WebDAV folder. * + * Starting with Orthanc 1.12.11, if the file size is unknown + * because the file must be generated on-the-fly, you can set the + * size argument to the special value ORTHANC_PLUGINS_WEBDAV_UNKNOWN_FILE_SIZE. + * In this case, the WebDAV property "D:getcontentlength" will not be filled. + * * @param collection Context of the collection. * @param name Base name of the file. * @param dateTime The date and time of creation of the file. * Check out the documentation of OrthancPluginWebDavRetrieveFile() for more information. - * @param size Size of the file. + * @param size Size of the file. Can be set to ORTHANC_PLUGINS_WEBDAV_UNKNOWN_FILE_SIZE + * if unknown. * @param mimeType The MIME type of the file. If empty or set to `NULL`, * Orthanc will do a best guess depending on the file extension. * @return 0 if success, other value if error.
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Wed Feb 11 16:27:45 2026 +0100 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Wed Feb 11 16:28:03 2026 +0100 @@ -38,6 +38,7 @@ #include "../../../OrthancFramework/Sources/Logging.h" #include "../../../OrthancFramework/Sources/MultiThreading/Semaphore.h" #include "../../../OrthancFramework/Sources/SerializationToolbox.h" +#include "../../../OrthancFramework/Sources/CompatibilityMath.h" #include "../OrthancConfiguration.h" #include "../Search/DatabaseLookup.h" @@ -47,7 +48,6 @@ #include "../SliceOrdering.h" // This "include" is mandatory for Release builds using Linux Standard Base -#include <boost/math/special_functions/round.hpp> #include <boost/shared_ptr.hpp> #include "../../../OrthancFramework/Sources/FileStorage/StorageAccessor.h" @@ -1170,8 +1170,8 @@ ratio = static_cast<float>(argHeight) / static_cast<float>(decoded->GetHeight()); } - targetWidth = boost::math::iround(ratio * static_cast<float>(decoded->GetWidth())); - targetHeight = boost::math::iround(ratio * static_cast<float>(decoded->GetHeight())); + targetWidth = Math::iround(ratio * static_cast<float>(decoded->GetWidth())); + targetHeight = Math::iround(ratio * static_cast<float>(decoded->GetHeight())); } if (decoded->GetFormat() == PixelFormat_RGB24 || decoded->GetFormat() == PixelFormat_RGB48)
