diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 6e2f4e37c..555a47506 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -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); } } }