Mercurial > hg > orthanc
comparison Core/Images/ImageProcessing.cpp @ 2488:345725b9350c
back to rounding to fix integration tests
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 13 Mar 2018 17:02:30 +0100 |
parents | be1dbb1dcdd6 |
children | e91bab2d8c75 |
comparison
equal
deleted
inserted
replaced
2487:be1dbb1dcdd6 | 2488:345725b9350c |
---|---|
225 } | 225 } |
226 } | 226 } |
227 | 227 |
228 | 228 |
229 | 229 |
230 template <typename PixelType> | 230 template <typename PixelType, |
231 bool UseRound> | |
231 void MultiplyConstantInternal(ImageAccessor& image, | 232 void MultiplyConstantInternal(ImageAccessor& image, |
232 float factor) | 233 float factor) |
233 { | 234 { |
234 if (std::abs(factor - 1.0f) <= std::numeric_limits<float>::epsilon()) | 235 if (std::abs(factor - 1.0f) <= std::numeric_limits<float>::epsilon()) |
235 { | 236 { |
244 { | 245 { |
245 PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); | 246 PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); |
246 | 247 |
247 for (unsigned int x = 0; x < width; x++, p++) | 248 for (unsigned int x = 0; x < width; x++, p++) |
248 { | 249 { |
249 // The "round" operation is extremely costly. We use | 250 int64_t v; |
250 // truncation instead since Orthanc 1.3.2. | 251 if (UseRound) |
251 | 252 { |
252 //int64_t v = boost::math::llround(static_cast<float>(*p) * factor); | 253 // The "round" operation is very costly |
253 int64_t v = static_cast<int64_t>(static_cast<float>(*p) * factor); | 254 v = boost::math::llround(static_cast<float>(*p) * factor); |
255 } | |
256 else | |
257 { | |
258 v = static_cast<int64_t>(static_cast<float>(*p) * factor); | |
259 } | |
254 | 260 |
255 if (v > maxValue) | 261 if (v > maxValue) |
256 { | 262 { |
257 *p = std::numeric_limits<PixelType>::max(); | 263 *p = std::numeric_limits<PixelType>::max(); |
258 } | 264 } |
267 } | 273 } |
268 } | 274 } |
269 } | 275 } |
270 | 276 |
271 | 277 |
272 template <typename PixelType> | 278 template <typename PixelType, |
279 bool UseRound> | |
273 void ShiftScaleInternal(ImageAccessor& image, | 280 void ShiftScaleInternal(ImageAccessor& image, |
274 float offset, | 281 float offset, |
275 float scaling) | 282 float scaling) |
276 { | 283 { |
277 const float minFloatValue = static_cast<float>(std::numeric_limits<PixelType>::min()); | 284 const float minFloatValue = static_cast<float>(std::numeric_limits<PixelType>::min()); |
296 } | 303 } |
297 else if (v < minFloatValue) | 304 else if (v < minFloatValue) |
298 { | 305 { |
299 *p = minPixelValue; | 306 *p = minPixelValue; |
300 } | 307 } |
301 else | 308 else if (UseRound) |
302 { | 309 { |
303 // The "round" operation is extremely costly. We use | 310 // The "round" operation is very costly |
304 // truncation instead since Orthanc 1.3.2. | 311 *p = static_cast<PixelType>(boost::math::iround(v)); |
305 | 312 } |
306 //*p = static_cast<PixelType>(boost::math::iround(v)); | 313 else |
314 { | |
307 *p = static_cast<PixelType>(v); | 315 *p = static_cast<PixelType>(v); |
308 } | 316 } |
309 } | 317 } |
310 } | 318 } |
311 } | 319 } |
804 } | 812 } |
805 } | 813 } |
806 | 814 |
807 | 815 |
808 void ImageProcessing::MultiplyConstant(ImageAccessor& image, | 816 void ImageProcessing::MultiplyConstant(ImageAccessor& image, |
809 float factor) | 817 float factor, |
818 bool useRound) | |
810 { | 819 { |
811 switch (image.GetFormat()) | 820 switch (image.GetFormat()) |
812 { | 821 { |
813 case PixelFormat_Grayscale8: | 822 case PixelFormat_Grayscale8: |
814 MultiplyConstantInternal<uint8_t>(image, factor); | 823 if (useRound) |
824 { | |
825 MultiplyConstantInternal<uint8_t, true>(image, factor); | |
826 } | |
827 else | |
828 { | |
829 MultiplyConstantInternal<uint8_t, false>(image, factor); | |
830 } | |
815 return; | 831 return; |
816 | 832 |
817 case PixelFormat_Grayscale16: | 833 case PixelFormat_Grayscale16: |
818 MultiplyConstantInternal<uint16_t>(image, factor); | 834 if (useRound) |
835 { | |
836 MultiplyConstantInternal<uint16_t, true>(image, factor); | |
837 } | |
838 else | |
839 { | |
840 MultiplyConstantInternal<uint16_t, false>(image, factor); | |
841 } | |
819 return; | 842 return; |
820 | 843 |
821 case PixelFormat_SignedGrayscale16: | 844 case PixelFormat_SignedGrayscale16: |
822 MultiplyConstantInternal<int16_t>(image, factor); | 845 if (useRound) |
846 { | |
847 MultiplyConstantInternal<int16_t, true>(image, factor); | |
848 } | |
849 else | |
850 { | |
851 MultiplyConstantInternal<int16_t, false>(image, factor); | |
852 } | |
823 return; | 853 return; |
824 | 854 |
825 default: | 855 default: |
826 throw OrthancException(ErrorCode_NotImplemented); | 856 throw OrthancException(ErrorCode_NotImplemented); |
827 } | 857 } |
828 } | 858 } |
829 | 859 |
830 | 860 |
831 void ImageProcessing::ShiftScale(ImageAccessor& image, | 861 void ImageProcessing::ShiftScale(ImageAccessor& image, |
832 float offset, | 862 float offset, |
833 float scaling) | 863 float scaling, |
864 bool useRound) | |
834 { | 865 { |
835 switch (image.GetFormat()) | 866 switch (image.GetFormat()) |
836 { | 867 { |
837 case PixelFormat_Grayscale8: | 868 case PixelFormat_Grayscale8: |
838 ShiftScaleInternal<uint8_t>(image, offset, scaling); | 869 if (useRound) |
870 { | |
871 ShiftScaleInternal<uint8_t, true>(image, offset, scaling); | |
872 } | |
873 else | |
874 { | |
875 ShiftScaleInternal<uint8_t, false>(image, offset, scaling); | |
876 } | |
839 return; | 877 return; |
840 | 878 |
841 case PixelFormat_Grayscale16: | 879 case PixelFormat_Grayscale16: |
842 ShiftScaleInternal<uint16_t>(image, offset, scaling); | 880 if (useRound) |
881 { | |
882 ShiftScaleInternal<uint16_t, true>(image, offset, scaling); | |
883 } | |
884 else | |
885 { | |
886 ShiftScaleInternal<uint16_t, false>(image, offset, scaling); | |
887 } | |
843 return; | 888 return; |
844 | 889 |
845 case PixelFormat_SignedGrayscale16: | 890 case PixelFormat_SignedGrayscale16: |
846 ShiftScaleInternal<int16_t>(image, offset, scaling); | 891 if (useRound) |
892 { | |
893 ShiftScaleInternal<int16_t, true>(image, offset, scaling); | |
894 } | |
895 else | |
896 { | |
897 ShiftScaleInternal<int16_t, false>(image, offset, scaling); | |
898 } | |
847 return; | 899 return; |
848 | 900 |
849 default: | 901 default: |
850 throw OrthancException(ErrorCode_NotImplemented); | 902 throw OrthancException(ErrorCode_NotImplemented); |
851 } | 903 } |