Mercurial > hg > orthanc
changeset 3525:8c66c9c2257b
fix ImageProcessing::ShiftScale() on float images
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 25 Sep 2019 17:16:54 +0200 |
parents | d96379a965de |
children | f07352e0375c |
files | Core/DicomParsing/Internals/DicomImageDecoder.cpp Core/Images/ImageProcessing.cpp |
diffstat | 2 files changed, 36 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/Core/DicomParsing/Internals/DicomImageDecoder.cpp Tue Sep 24 18:06:56 2019 +0200 +++ b/Core/DicomParsing/Internals/DicomImageDecoder.cpp Wed Sep 25 17:16:54 2019 +0200 @@ -357,6 +357,8 @@ static void CopyPixels(ImageAccessor& target, const DicomIntegerPixelAccessor& source) { + // WARNING - "::min()" should be replaced by "::lowest()" if + // dealing with float or double (which is not the case so far) const PixelType minValue = std::numeric_limits<PixelType>::min(); const PixelType maxValue = std::numeric_limits<PixelType>::max();
--- a/Core/Images/ImageProcessing.cpp Tue Sep 24 18:06:56 2019 +0200 +++ b/Core/Images/ImageProcessing.cpp Wed Sep 25 17:16:54 2019 +0200 @@ -60,6 +60,9 @@ static void ConvertInternal(ImageAccessor& target, const ImageAccessor& source) { + // WARNING - "::min()" should be replaced by "::lowest()" if + // dealing with float or double (which is not the case so far) + assert(sizeof(TargetType) <= 2); // Safeguard to remember about "float/double" const TargetType minValue = std::numeric_limits<TargetType>::min(); const TargetType maxValue = std::numeric_limits<TargetType>::max(); @@ -142,6 +145,9 @@ { assert(source.GetFormat() == PixelFormat_RGB24); + // WARNING - "::min()" should be replaced by "::lowest()" if + // dealing with float or double (which is not the case so far) + assert(sizeof(TargetType) <= 2); // Safeguard to remember about "float/double" const TargetType minValue = std::numeric_limits<TargetType>::min(); const TargetType maxValue = std::numeric_limits<TargetType>::max(); @@ -227,7 +233,8 @@ template <typename PixelType> static void GetMinMaxValueInternal(PixelType& minValue, PixelType& maxValue, - const ImageAccessor& source) + const ImageAccessor& source, + const PixelType LowestValue = std::numeric_limits<PixelType>::min()) { // Deal with the special case of empty image if (source.GetWidth() == 0 || @@ -239,7 +246,7 @@ } minValue = std::numeric_limits<PixelType>::max(); - maxValue = std::numeric_limits<PixelType>::min(); + maxValue = LowestValue; const unsigned int height = source.GetHeight(); const unsigned int width = source.GetWidth(); @@ -274,6 +281,9 @@ return; } + // WARNING - "::min()" should be replaced by "::lowest()" if + // dealing with float or double (which is not the case so far) + assert(sizeof(PixelType) <= 2); // Safeguard to remember about "float/double" const int64_t minValue = std::numeric_limits<PixelType>::min(); const int64_t maxValue = std::numeric_limits<PixelType>::max(); @@ -316,6 +326,9 @@ return; } + // WARNING - "::min()" should be replaced by "::lowest()" if + // dealing with float or double (which is not the case so far) + assert(sizeof(PixelType) <= 2); // Safeguard to remember about "float/double" const int64_t minValue = std::numeric_limits<PixelType>::min(); const int64_t maxValue = std::numeric_limits<PixelType>::max(); @@ -360,12 +373,13 @@ bool UseRound> static void ShiftScaleInternal(ImageAccessor& image, float offset, - float scaling) + float scaling, + const PixelType LowestValue = std::numeric_limits<PixelType>::min()) { - const float minFloatValue = static_cast<float>(std::numeric_limits<PixelType>::min()); - const float maxFloatValue = static_cast<float>(std::numeric_limits<PixelType>::max()); - const PixelType minPixelValue = std::numeric_limits<PixelType>::min(); + const PixelType minPixelValue = LowestValue; const PixelType maxPixelValue = std::numeric_limits<PixelType>::max(); + const float minFloatValue = static_cast<float>(LowestValue); + const float maxFloatValue = static_cast<float>(maxPixelValue); const unsigned int height = image.GetHeight(); const unsigned int width = image.GetWidth(); @@ -969,7 +983,14 @@ { assert(sizeof(float) == 4); float a, b; - GetMinMaxValueInternal<float>(a, b, image); + + /** + * WARNING - On floating-point types, the minimal value is + * "-FLT_MAX" (as implemented by "::lowest()"), not "FLT_MIN" + * (as implemented by "::min()") + * https://en.cppreference.com/w/cpp/types/numeric_limits + **/ + GetMinMaxValueInternal<float>(a, b, image, -std::numeric_limits<float>::max()); minValue = a; maxValue = b; break; @@ -1093,11 +1114,11 @@ case PixelFormat_Float32: if (useRound) { - ShiftScaleInternal<float, true>(image, offset, scaling); + ShiftScaleInternal<float, true>(image, offset, scaling, -std::numeric_limits<float>::max()); } else { - ShiftScaleInternal<float, false>(image, offset, scaling); + ShiftScaleInternal<float, false>(image, offset, scaling, -std::numeric_limits<float>::max()); } return; @@ -1832,6 +1853,10 @@ size_t verticalAnchor, float normalization) { + // WARNING - "::min()" should be replaced by "::lowest()" if + // dealing with float or double (which is not the case so far) + assert(sizeof(RawPixel) <= 2); // Safeguard to remember about "float/double" + const unsigned int width = image.GetWidth(); const unsigned int height = image.GetHeight();