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