Partially reverting my last commit. When using large exponents, huge raw values could cause segfaults in ImProcFunctions:rgbProc (specifically in shadowToneCurve), and in Amaze demosaic.

Re-added the clipping check on raw values, but with a higher threshold. This way, raw clipping is less frequent in highlight areas (so those can be used as spots for exponents calculation), but the threshold is low enough to avoid the segfaults.
Not a very clean solution, need to find a better one...
This commit is contained in:
rom9 2019-06-26 00:14:03 +02:00
parent 22f6297a5b
commit 157d83d169

View File

@ -263,11 +263,14 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ
printf("Median calc time us: %d\n", t3.etime(t2));
}
constexpr float CLIP_VAL = 20 * MAX_OUT_VALUE;
t3.set();
if (ri->getSensorType() == ST_BAYER) {
#ifdef __SSE2__
const vfloat onev = F2V(1.f);
const vfloat clipv = F2V(CLIP_VAL);
#endif
#ifdef _OPENMP
@ -284,20 +287,21 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ
const vfloat expsv = _mm_setr_ps(exps0, exps1, exps0, exps1);
const vfloat multsv = _mm_setr_ps(mult0, mult1, mult0, mult1);
for (; col < W - 3; col += 4) {
STVFU(rawData[row][col], multsv * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv));
STVFU(rawData[row][col], vminf(multsv * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv), clipv));
}
#endif // __SSE2__
for (; col < W - 1; col += 2) {
rawData[row][col] = mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0);
rawData[row][col + 1] = mult1 * pow_F(rtengine::max(rawData[row][col + 1], 1.f), exps1);
rawData[row][col] = rtengine::min(mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0), CLIP_VAL);
rawData[row][col + 1] = rtengine::min(mult1 * pow_F(rtengine::max(rawData[row][col + 1], 1.f), exps1), CLIP_VAL);
}
if (col < W) {
rawData[row][col] = mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0);
rawData[row][col] = rtengine::min(mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0), CLIP_VAL);
}
}
} else if (ri->getSensorType() == ST_FUJI_XTRANS) {
#ifdef __SSE2__
const vfloat onev = F2V(1.f);
const vfloat clipv = F2V(CLIP_VAL);
#endif
#ifdef _OPENMP
@ -330,18 +334,18 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ
const vfloat multsv1 = _mm_setr_ps(multsc[4], multsc[5], multsc[0], multsc[1]);
const vfloat multsv2 = _mm_setr_ps(multsc[2], multsc[3], multsc[4], multsc[5]);
for (; col < W - 11; col += 12) {
STVFU(rawData[row][col], multsv0 * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv0));
STVFU(rawData[row][col + 4], multsv1 * pow_F(vmaxf(LVFU(rawData[row][col + 4]), onev), expsv1));
STVFU(rawData[row][col + 8], multsv2 * pow_F(vmaxf(LVFU(rawData[row][col + 8]), onev), expsv2));
STVFU(rawData[row][col], vminf(multsv0 * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv0), clipv));
STVFU(rawData[row][col + 4], vminf(multsv1 * pow_F(vmaxf(LVFU(rawData[row][col + 4]), onev), expsv1), clipv));
STVFU(rawData[row][col + 8], vminf(multsv2 * pow_F(vmaxf(LVFU(rawData[row][col + 8]), onev), expsv2), clipv));
}
#endif // __SSE2__
for (; col < W - 5; col += 6) {
for (int c = 0; c < 6; ++c) {
rawData[row][col + c] = multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]);
rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]), CLIP_VAL);
}
}
for (int c = 0; col < W; col++, c++) {
rawData[row][col + c] = multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]);
rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]), CLIP_VAL);
}
}
}