diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index bd6428127..8a7d6a524 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -145,6 +145,7 @@ void ffInfo::updateRawImage() int H = ri->get_height(); int W = ri->get_width(); ri->compress_image(0); + ri->set_prefilters(); int rSize = W * ((ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1) ? 1 : 3); acc_t **acc = new acc_t*[H]; @@ -165,6 +166,7 @@ void ffInfo::updateRawImage() if( !temp->loadRaw(true)) { temp->compress_image(0); //\ TODO would be better working on original, because is temporary + temp->set_prefilters(); nFiles++; if( ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1 ) { @@ -204,6 +206,7 @@ void ffInfo::updateRawImage() ri = nullptr; } else { ri->compress_image(0); + ri->set_prefilters(); } } diff --git a/rtengine/rawflatfield.cc b/rtengine/rawflatfield.cc index 22dbca852..0a6b3917e 100644 --- a/rtengine/rawflatfield.cc +++ b/rtengine/rawflatfield.cc @@ -263,13 +263,21 @@ void cfaboxblur(const float* const * riFlatFile, float* cfablur, int boxH, int b namespace rtengine { -void RawImageSource::processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, array2D &rawData, const float black[4]) +void RawImageSource::processFlatField(const procparams::RAWParams &raw, RawImage *riFlatFile, array2D &rawData, const float black[4]) { // BENCHFUN std::unique_ptr cfablur(new float[H * W]); const int BS = raw.ff_BlurRadius + (raw.ff_BlurRadius & 1); + std::array ffblack; + { + const auto tmpfilters = riFlatFile->get_filters(); + riFlatFile->set_filters(riFlatFile->prefilters); // we need 4 blacks for bayer processing + riFlatFile->get_colorsCoeff(nullptr, nullptr, ffblack.data(), false); + riFlatFile->set_filters(tmpfilters); + } + if (raw.ff_BlurType == procparams::RAWParams::getFlatFieldBlurTypeString(procparams::RAWParams::FlatFieldBlurType::V)) { cfaboxblur(riFlatFile->data, cfablur.get(), 2 * BS, 0, H, W); } else if (raw.ff_BlurType == procparams::RAWParams::getFlatFieldBlurTypeString(procparams::RAWParams::FlatFieldBlurType::H)) { @@ -291,7 +299,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra const int col = 2 * (W >> 2) + n; const int c = ri->get_colors() != 1 ? FC(row, col) : 0; const int c4 = ri->get_colors() != 1 ? ((c == 1 && !(row & 1)) ? 3 : c) : 0; - refcolor[m][n] = std::max(0.0f, cfablur[row * W + col] - black[c4]); + refcolor[m][n] = std::max(0.0f, cfablur[row * W + col] - ffblack[c4]); } float limitFactor = 1.f; @@ -314,7 +322,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra clippedBefore = true; break; } - const float tempval = (rawVal - black[c4]) * (refcolor[m][n] / std::max(1e-5f, cfablur[(row + m) * W + col + n] - black[c4])); + const float tempval = (rawVal - black[c4]) * (refcolor[m][n] / std::max(1e-5f, cfablur[(row + m) * W + col + n] - ffblack[c4])); maxval = std::max(maxval, tempval); } } @@ -363,6 +371,9 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra const vfloat blackv[2] = {_mm_set_ps(black[c4[0][1]], black[c4[0][0]], black[c4[0][1]], black[c4[0][0]]), _mm_set_ps(black[c4[1][1]], black[c4[1][0]], black[c4[1][1]], black[c4[1][0]]) }; + const vfloat ffblackv[2] = {_mm_set_ps(ffblack[c4[0][1]], ffblack[c4[0][0]], ffblack[c4[0][1]], ffblack[c4[0][0]]), + _mm_set_ps(ffblack[c4[1][1]], ffblack[c4[1][0]], ffblack[c4[1][1]], ffblack[c4[1][0]]) + }; const vfloat onev = F2V(1.f); const vfloat minValuev = F2V(minValue); @@ -375,10 +386,11 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra int col = 0; #ifdef __SSE2__ const vfloat rowBlackv = blackv[row & 1]; + const vfloat ffrowBlackv = ffblackv[row & 1]; const vfloat rowRefcolorv = refcolorv[row & 1]; for (; col < W - 3; col += 4) { - const vfloat blurv = LVFU(cfablur[row * W + col]) - rowBlackv; + const vfloat blurv = LVFU(cfablur[row * W + col]) - ffrowBlackv; vfloat vignettecorrv = rowRefcolorv / blurv; vignettecorrv = vself(vmaskf_le(blurv, minValuev), onev, vignettecorrv); const vfloat valv = LVFU(rawData[row][col]) - rowBlackv; @@ -388,7 +400,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra #endif for (; col < W; ++col) { - const float blur = cfablur[row * W + col] - black[c4[row & 1][col & 1]]; + const float blur = cfablur[row * W + col] - ffblack[c4[row & 1][col & 1]]; const float vignettecorr = blur <= minValue ? 1.f : refcolor[row & 1][col & 1] / blur; rawData[row][col] = (rawData[row][col] - black[c4[row & 1][col & 1]]) * vignettecorr + black[c4[row & 1][col & 1]]; } @@ -490,6 +502,10 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra const vfloat blackv[2] = {_mm_set_ps(black[c4[0][1]], black[c4[0][0]], black[c4[0][1]], black[c4[0][0]]), _mm_set_ps(black[c4[1][1]], black[c4[1][0]], black[c4[1][1]], black[c4[1][0]]) }; + const vfloat ffblackv[2] = {_mm_set_ps(ffblack[c4[0][1]], ffblack[c4[0][0]], ffblack[c4[0][1]], ffblack[c4[0][0]]), + _mm_set_ps(ffblack[c4[1][1]], ffblack[c4[1][0]], ffblack[c4[1][1]], ffblack[c4[1][0]]) + }; + const vfloat epsv = F2V(1e-5f); #endif @@ -501,10 +517,11 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra int col = 0; #ifdef __SSE2__ const vfloat rowBlackv = blackv[row & 1]; + const vfloat ffrowBlackv = ffblackv[row & 1]; for (; col < W - 3; col += 4) { - const vfloat linecorrv = SQRV(vmaxf(LVFU(cfablur[row * W + col]) - rowBlackv, epsv)) / - (vmaxf(LVFU(cfablur1[row * W + col]) - rowBlackv, epsv) * vmaxf(LVFU(cfablur2[row * W + col]) - rowBlackv, epsv)); + const vfloat linecorrv = SQRV(vmaxf(LVFU(cfablur[row * W + col]) - ffrowBlackv, epsv)) / + (vmaxf(LVFU(cfablur1[row * W + col]) - ffrowBlackv, epsv) * vmaxf(LVFU(cfablur2[row * W + col]) - ffrowBlackv, epsv)); const vfloat valv = LVFU(rawData[row][col]) - rowBlackv; STVFU(rawData[row][col], valv * linecorrv + rowBlackv); } @@ -512,8 +529,8 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra #endif for (; col < W; ++col) { - const float linecorr = SQR(std::max(1e-5f, cfablur[row * W + col] - black[c4[row & 1][col & 1]])) / - (std::max(1e-5f, cfablur1[row * W + col] - black[c4[row & 1][col & 1]]) * std::max(1e-5f, cfablur2[row * W + col] - black[c4[row & 1][col & 1]])); + const float linecorr = SQR(std::max(1e-5f, cfablur[row * W + col] - ffblack[c4[row & 1][col & 1]])) / + (std::max(1e-5f, cfablur1[row * W + col] - ffblack[c4[row & 1][col & 1]]) * std::max(1e-5f, cfablur2[row * W + col] - ffblack[c4[row & 1][col & 1]])); rawData[row][col] = (rawData[row][col] - black[c4[row & 1][col & 1]]) * linecorr + black[c4[row & 1][col & 1]]; } } diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index e65cadaa3..20658c04b 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -138,7 +138,7 @@ public: return rgbSourceModified; // tracks whether cached rgb output of demosaic has been modified } - void processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, array2D &rawData, const float black[4]); + void processFlatField(const procparams::RAWParams &raw, RawImage *riFlatFile, array2D &rawData, const float black[4]); void copyOriginalPixels(const procparams::RAWParams &raw, RawImage *ri, const RawImage *riDark, RawImage *riFlatFile, array2D &rawData ); void scaleColors (int winx, int winy, int winw, int winh, const procparams::RAWParams &raw, array2D &rawData); // raw for cblack void WBauto(bool extra, double &tempref, double &greenref, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) override;