Fattal: remove nondeterminism due to openmp and use a more robust comparison for finding the max luminance
Addresses #4306 and at least mitigates it
This commit is contained in:
parent
dbcfc9d91a
commit
3c50e8ff5b
@ -1055,8 +1055,9 @@ inline int find_fast_dim (int dim)
|
|||||||
{
|
{
|
||||||
// as per the FFTW docs:
|
// as per the FFTW docs:
|
||||||
//
|
//
|
||||||
// FFTW is generally best at handling sizes of the form 2a 3b 5c 7d 11e
|
// FFTW is generally best at handling sizes of the form
|
||||||
// 13f, where e+f is either 0 or 1.
|
// 2^a 3^b 5^c 7^d 11^e 13^f,
|
||||||
|
// where e+f is either 0 or 1.
|
||||||
//
|
//
|
||||||
// Here, we try to round up to the nearest dim that can be expressed in
|
// Here, we try to round up to the nearest dim that can be expressed in
|
||||||
// the above form. This is not exhaustive, but should be ok for pictures
|
// the above form. This is not exhaustive, but should be ok for pictures
|
||||||
@ -1125,39 +1126,32 @@ void ImProcFunctions::ToneMapFattal02 (Imagefloat *rgb)
|
|||||||
constexpr float c = 65500.f;
|
constexpr float c = 65500.f;
|
||||||
return rgb->r(y, x) < c && rgb->g(y, x) < c && rgb->b(y, x) < c;
|
return rgb->r(y, x) < c && rgb->g(y, x) < c && rgb->b(y, x) < c;
|
||||||
};
|
};
|
||||||
|
|
||||||
TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix (params->icm.working);
|
TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix (params->icm.working);
|
||||||
|
|
||||||
float max_Y = 0.f;
|
float max_Y = 0.f;
|
||||||
int max_x = 0, max_y = 0;
|
int max_x = 0, max_y = 0;
|
||||||
|
|
||||||
#ifdef _OPENMP
|
const auto biggerY =
|
||||||
#pragma omp parallel if (multiThread)
|
[](float cur_Y, float prev_Y) -> bool
|
||||||
#endif
|
{
|
||||||
{
|
if (!prev_Y) {
|
||||||
float max_YThr = 0.f;
|
return true;
|
||||||
int max_xThr = 0, max_yThr = 0;
|
}
|
||||||
#ifdef _OPENMP
|
float e = (cur_Y - prev_Y) / max(cur_Y, prev_Y);
|
||||||
#pragma omp for schedule(dynamic,16) nowait
|
return e >= 0.05;
|
||||||
#endif
|
};
|
||||||
|
|
||||||
for (int y = 0; y < h; y++) {
|
for (int y = 0; y < h; y++) {
|
||||||
for (int x = 0; x < w; x++) {
|
for (int x = 0; x < w; x++) {
|
||||||
Yr (x, y) = std::max (luminance (rgb->r (y, x), rgb->g (y, x), rgb->b (y, x), ws), min_luminance); // clip really black pixels
|
Yr (x, y) = std::max (luminance (rgb->r (y, x), rgb->g (y, x), rgb->b (y, x), ws), min_luminance); // clip really black pixels
|
||||||
if (Yr(x, y) > max_YThr && unclipped(y, x)) {
|
if (biggerY(Yr(x, y), max_Y) && unclipped(y, x)) {
|
||||||
max_YThr = Yr(x, y);
|
max_Y = Yr(x, y);
|
||||||
max_xThr = x;
|
max_x = x;
|
||||||
max_yThr = y;
|
max_y = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef _OPENMP
|
|
||||||
#pragma omp critical
|
|
||||||
#endif
|
|
||||||
if (max_YThr > max_Y) {
|
|
||||||
max_Y = max_YThr;
|
|
||||||
max_x = max_xThr;
|
|
||||||
max_y = max_yThr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// median filter on the deep shadows, to avoid boosting noise
|
// median filter on the deep shadows, to avoid boosting noise
|
||||||
// because w2 >= w and h2 >= h, we can use the L buffer as temporary buffer for Median_Denoise()
|
// because w2 >= w and h2 >= h, we can use the L buffer as temporary buffer for Median_Denoise()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user