Little cosmetics for the new rt_algo.*
This commit is contained in:
parent
bb72322a2d
commit
3dfa59e77f
@ -17,38 +17,41 @@
|
|||||||
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cmath>
|
|
||||||
#include <cassert>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <cassert>
|
||||||
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "rt_algo.h"
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
void findMinMaxPercentile (const float *data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multithread)
|
|
||||||
{
|
|
||||||
// we need to find the (minPrct*size) smallest value and the (maxPrct*size) smallest value in data
|
|
||||||
// We use a histogram based search for speed and to reduce memory usage
|
|
||||||
// memory usage of this method is histoSize * sizeof(uint32_t) * (t + 1) byte,
|
|
||||||
// where t is the number of threads and histoSize is in [1;65536]
|
|
||||||
// The current implementation is not guaranteed to work correctly if size > 2^32 (4294967296)
|
|
||||||
assert (minPrct <= maxPrct);
|
|
||||||
|
|
||||||
if(size == 0) {
|
void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multithread)
|
||||||
|
{
|
||||||
|
// We need to find the (minPrct*size) smallest value and the (maxPrct*size) smallest value in data.
|
||||||
|
// We use a histogram based search for speed and to reduce memory usage.
|
||||||
|
// Memory usage of this method is histoSize * sizeof(uint32_t) * (t + 1) byte,
|
||||||
|
// where t is the number of threads and histoSize is in [1;65536].
|
||||||
|
// The current implementation is not guaranteed to work correctly if size > 2^32 (4294967296).
|
||||||
|
assert(minPrct <= maxPrct);
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t numThreads = 1;
|
size_t numThreads = 1;
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
// Because we have an overhead in the critical region of the main loop for each thread
|
// Because we have an overhead in the critical region of the main loop for each thread
|
||||||
// we make a rough calculation to reduce the number of threads for small data size
|
// we make a rough calculation to reduce the number of threads for small data size.
|
||||||
// This also works fine for the minmax loop
|
// This also works fine for the minmax loop.
|
||||||
if(multithread) {
|
if (multithread) {
|
||||||
size_t maxThreads = omp_get_max_threads();
|
const size_t maxThreads = omp_get_max_threads();
|
||||||
while (size > numThreads * numThreads * 16384 && numThreads < maxThreads) {
|
while (size > numThreads * numThreads * 16384 && numThreads < maxThreads) {
|
||||||
++numThreads;
|
++numThreads;
|
||||||
}
|
}
|
||||||
@ -66,14 +69,14 @@ void findMinMaxPercentile (const float *data, size_t size, float minPrct, float&
|
|||||||
maxVal = std::max(maxVal, data[i]);
|
maxVal = std::max(maxVal, data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(std::fabs(maxVal - minVal) == 0.f) { // fast exit, also avoids division by zero in calculation of scale factor
|
if (std::fabs(maxVal - minVal) == 0.f) { // fast exit, also avoids division by zero in calculation of scale factor
|
||||||
minOut = maxOut = minVal;
|
minOut = maxOut = minVal;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// caution: currently this works correctly only for histoSize in range[1;65536]
|
// Caution: Currently this works correctly only for histoSize in range[1;65536].
|
||||||
// for small data size (i.e. thumbnails) we reduce the size of the histogram to the size of data
|
// For small data size (i.e. thumbnails) we reduce the size of the histogram to the size of data.
|
||||||
const unsigned int histoSize = std::min(static_cast<size_t>(65536), size);
|
const unsigned int histoSize = std::min<size_t>(65536, size);
|
||||||
|
|
||||||
// calculate scale factor to use full range of histogram
|
// calculate scale factor to use full range of histogram
|
||||||
const float scale = (histoSize - 1) / (maxVal - minVal);
|
const float scale = (histoSize - 1) / (maxVal - minVal);
|
||||||
@ -81,11 +84,11 @@ void findMinMaxPercentile (const float *data, size_t size, float minPrct, float&
|
|||||||
// We need one main histogram
|
// We need one main histogram
|
||||||
std::vector<uint32_t> histo(histoSize, 0);
|
std::vector<uint32_t> histo(histoSize, 0);
|
||||||
|
|
||||||
if(numThreads == 1) {
|
if (numThreads == 1) {
|
||||||
// just one thread => use main histogram
|
// just one thread => use main histogram
|
||||||
for (size_t i = 0; i < size; ++i) {
|
for (size_t i = 0; i < size; ++i) {
|
||||||
// we have to subtract minVal and multiply with scale to get the data in [0;histosize] range
|
// we have to subtract minVal and multiply with scale to get the data in [0;histosize] range
|
||||||
histo[ (uint16_t) (scale * (data[i] - minVal))]++;
|
histo[static_cast<uint16_t>(scale * (data[i] - minVal))]++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
@ -98,10 +101,9 @@ void findMinMaxPercentile (const float *data, size_t size, float minPrct, float&
|
|||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp for nowait
|
#pragma omp for nowait
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (size_t i = 0; i < size; ++i) {
|
for (size_t i = 0; i < size; ++i) {
|
||||||
// we have to subtract minVal and multiply with scale to get the data in [0;histosize] range
|
// we have to subtract minVal and multiply with scale to get the data in [0;histosize] range
|
||||||
histothr[ (uint16_t) (scale * (data[i] - minVal))]++;
|
histothr[static_cast<uint16_t>(scale * (data[i] - minVal))]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
@ -113,7 +115,7 @@ void findMinMaxPercentile (const float *data, size_t size, float minPrct, float&
|
|||||||
#pragma omp simd
|
#pragma omp simd
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(size_t i = 0; i < histoSize; ++i) {
|
for (size_t i = 0; i < histoSize; ++i) {
|
||||||
histo[i] += histothr[i];
|
histo[i] += histothr[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,9 +132,9 @@ void findMinMaxPercentile (const float *data, size_t size, float minPrct, float&
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (k > 0) { // interpolate
|
if (k > 0) { // interpolate
|
||||||
size_t count_ = count - histo[k - 1];
|
const size_t count_ = count - histo[k - 1];
|
||||||
float c0 = count - threshmin;
|
const float c0 = count - threshmin;
|
||||||
float c1 = threshmin - count_;
|
const float c1 = threshmin - count_;
|
||||||
minOut = (c1 * k + c0 * (k - 1)) / (c0 + c1);
|
minOut = (c1 * k + c0 * (k - 1)) / (c0 + c1);
|
||||||
} else {
|
} else {
|
||||||
minOut = k;
|
minOut = k;
|
||||||
@ -148,9 +150,9 @@ void findMinMaxPercentile (const float *data, size_t size, float minPrct, float&
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (k > 0) { // interpolate
|
if (k > 0) { // interpolate
|
||||||
size_t count_ = count - histo[k - 1];
|
const size_t count_ = count - histo[k - 1];
|
||||||
float c0 = count - threshmax;
|
const float c0 = count - threshmax;
|
||||||
float c1 = threshmax - count_;
|
const float c1 = threshmax - count_;
|
||||||
maxOut = (c1 * k + c0 * (k - 1)) / (c0 + c1);
|
maxOut = (c1 * k + c0 * (k - 1)) / (c0 + c1);
|
||||||
} else {
|
} else {
|
||||||
maxOut = k;
|
maxOut = k;
|
||||||
@ -158,6 +160,6 @@ void findMinMaxPercentile (const float *data, size_t size, float minPrct, float&
|
|||||||
// go back to original range
|
// go back to original range
|
||||||
maxOut /= scale;
|
maxOut /= scale;
|
||||||
maxOut += minVal;
|
maxOut += minVal;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
void findMinMaxPercentile (const float *data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multiThread = true);
|
|
||||||
|
void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multiThread = true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user