Mercurial > hg > orthanc
comparison Core/Images/ImageProcessing.cpp @ 2482:509041cb57db
speedup by truncating instead of rounding
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 01 Mar 2018 09:29:06 +0100 |
parents | 878b59270859 |
children | be1dbb1dcdd6 |
comparison
equal
deleted
inserted
replaced
2481:8f3c2017b0e3 | 2482:509041cb57db |
---|---|
164 } | 164 } |
165 | 165 |
166 minValue = std::numeric_limits<PixelType>::max(); | 166 minValue = std::numeric_limits<PixelType>::max(); |
167 maxValue = std::numeric_limits<PixelType>::min(); | 167 maxValue = std::numeric_limits<PixelType>::min(); |
168 | 168 |
169 const unsigned int width = source.GetWidth(); | |
170 | |
169 for (unsigned int y = 0; y < source.GetHeight(); y++) | 171 for (unsigned int y = 0; y < source.GetHeight(); y++) |
170 { | 172 { |
171 const PixelType* p = reinterpret_cast<const PixelType*>(source.GetConstRow(y)); | 173 const PixelType* p = reinterpret_cast<const PixelType*>(source.GetConstRow(y)); |
172 | 174 |
173 for (unsigned int x = 0; x < source.GetWidth(); x++, p++) | 175 for (unsigned int x = 0; x < width; x++, p++) |
174 { | 176 { |
175 if (*p < minValue) | 177 if (*p < minValue) |
176 { | 178 { |
177 minValue = *p; | 179 minValue = *p; |
178 } | 180 } |
234 return; | 236 return; |
235 } | 237 } |
236 | 238 |
237 const int64_t minValue = std::numeric_limits<PixelType>::min(); | 239 const int64_t minValue = std::numeric_limits<PixelType>::min(); |
238 const int64_t maxValue = std::numeric_limits<PixelType>::max(); | 240 const int64_t maxValue = std::numeric_limits<PixelType>::max(); |
241 const unsigned int width = image.GetWidth(); | |
239 | 242 |
240 for (unsigned int y = 0; y < image.GetHeight(); y++) | 243 for (unsigned int y = 0; y < image.GetHeight(); y++) |
241 { | 244 { |
242 PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); | 245 PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); |
243 | 246 |
244 for (unsigned int x = 0; x < image.GetWidth(); x++, p++) | 247 for (unsigned int x = 0; x < width; x++, p++) |
245 { | 248 { |
246 int64_t v = boost::math::llround(static_cast<float>(*p) * factor); | 249 // The "round" operation is extremely costly. We use |
250 // truncation instead since Orthanc 1.3.2. | |
251 | |
252 //int64_t v = boost::math::llround(static_cast<float>(*p) * factor); | |
253 int64_t v = static_cast<int64_t>(static_cast<float>(*p) * factor); | |
247 | 254 |
248 if (v > maxValue) | 255 if (v > maxValue) |
249 { | 256 { |
250 *p = std::numeric_limits<PixelType>::max(); | 257 *p = std::numeric_limits<PixelType>::max(); |
251 } | 258 } |
265 template <typename PixelType> | 272 template <typename PixelType> |
266 void ShiftScaleInternal(ImageAccessor& image, | 273 void ShiftScaleInternal(ImageAccessor& image, |
267 float offset, | 274 float offset, |
268 float scaling) | 275 float scaling) |
269 { | 276 { |
270 const float minValue = static_cast<float>(std::numeric_limits<PixelType>::min()); | 277 const float minFloatValue = static_cast<float>(std::numeric_limits<PixelType>::min()); |
271 const float maxValue = static_cast<float>(std::numeric_limits<PixelType>::max()); | 278 const float maxFloatValue = static_cast<float>(std::numeric_limits<PixelType>::max()); |
272 | 279 const PixelType minPixelValue = std::numeric_limits<PixelType>::min(); |
273 for (unsigned int y = 0; y < image.GetHeight(); y++) | 280 const PixelType maxPixelValue = std::numeric_limits<PixelType>::max(); |
281 | |
282 const unsigned int height = image.GetHeight(); | |
283 const unsigned int width = image.GetWidth(); | |
284 | |
285 for (unsigned int y = 0; y < height; y++) | |
274 { | 286 { |
275 PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); | 287 PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y)); |
276 | 288 |
277 for (unsigned int x = 0; x < image.GetWidth(); x++, p++) | 289 for (unsigned int x = 0; x < width; x++, p++) |
278 { | 290 { |
279 float v = (static_cast<float>(*p) + offset) * scaling; | 291 float v = (static_cast<float>(*p) + offset) * scaling; |
280 | 292 |
281 if (v > maxValue) | 293 if (v > maxFloatValue) |
282 { | 294 { |
283 *p = std::numeric_limits<PixelType>::max(); | 295 *p = maxPixelValue; |
284 } | 296 } |
285 else if (v < minValue) | 297 else if (v < minFloatValue) |
286 { | 298 { |
287 *p = std::numeric_limits<PixelType>::min(); | 299 *p = minPixelValue; |
288 } | 300 } |
289 else | 301 else |
290 { | 302 { |
291 *p = static_cast<PixelType>(boost::math::iround(v)); | 303 // The "round" operation is extremely costly. We use |
304 // truncation instead since Orthanc 1.3.2. | |
305 | |
306 //*p = static_cast<PixelType>(boost::math::iround(v)); | |
307 *p = static_cast<PixelType>(v); | |
292 } | 308 } |
293 } | 309 } |
294 } | 310 } |
295 } | 311 } |
296 | 312 |