From 38f0a2360f71aa475d8cda5c15fe655cf14daab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Tue, 19 May 2020 10:22:33 +0200 Subject: [PATCH 1/7] Make `wavelet_decomposition` const-correct --- rtengine/FTblockDN.cc | 58 ++++++++++++-------------- rtengine/cplx_wavelet_dec.h | 81 ++++++++++++++++++++++++++----------- rtengine/improcfun.h | 36 ++++++++--------- rtengine/ipwavelet.cc | 52 ++++++++++++------------ 4 files changed, 128 insertions(+), 99 deletions(-) diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 89e4c1b8d..b261b1ed2 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -1111,9 +1111,6 @@ BENCHFUN } if (execwavelet) {//gain time if user choose only median sliders L <=1 slider chrom master < 1 - wavelet_decomposition* Ldecomp; - wavelet_decomposition* adecomp; - int levwav = 5; float maxreal = max(realred, realblue); @@ -1154,9 +1151,9 @@ BENCHFUN levwav = min(maxlev2, levwav); // if (settings->verbose) printf("levwavelet=%i noisevarA=%f noisevarB=%f \n",levwav, noisevarab_r, noisevarab_b); - Ldecomp = new wavelet_decomposition(labdn->L[0], labdn->W, labdn->H, levwav, 1, 1, max(1, denoiseNestedLevels)); + const std::unique_ptr Ldecomp(new wavelet_decomposition(labdn->L[0], labdn->W, labdn->H, levwav, 1, 1, max(1, denoiseNestedLevels))); - if (Ldecomp->memoryAllocationFailed) { + if (Ldecomp->memory_allocation_failed()) { memoryAllocationFailed = true; } @@ -1175,7 +1172,7 @@ BENCHFUN int Wlvl_L = Ldecomp->level_W(lvl); int Hlvl_L = Ldecomp->level_H(lvl); - float ** WavCoeffs_L = Ldecomp->level_coeffs(lvl); + const float* const* WavCoeffs_L = Ldecomp->level_coeffs(lvl); if (!denoiseMethodRgb) { madL[lvl][dir - 1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); @@ -1192,9 +1189,9 @@ BENCHFUN float chmaxresid = 0.f; float chmaxresidtemp = 0.f; - adecomp = new wavelet_decomposition(labdn->a[0], labdn->W, labdn->H, levwav, 1, 1, max(1, denoiseNestedLevels)); + std::unique_ptr adecomp(new wavelet_decomposition(labdn->a[0], labdn->W, labdn->H, levwav, 1, 1, max(1, denoiseNestedLevels))); - if (adecomp->memoryAllocationFailed) { + if (adecomp->memory_allocation_failed()) { memoryAllocationFailed = true; } @@ -1226,12 +1223,12 @@ BENCHFUN adecomp->reconstruct(labdn->a[0]); } - delete adecomp; + adecomp.reset(); if (!memoryAllocationFailed) { - wavelet_decomposition* bdecomp = new wavelet_decomposition(labdn->b[0], labdn->W, labdn->H, levwav, 1, 1, max(1, denoiseNestedLevels)); + std::unique_ptr bdecomp(new wavelet_decomposition(labdn->b[0], labdn->W, labdn->H, levwav, 1, 1, max(1, denoiseNestedLevels))); - if (bdecomp->memoryAllocationFailed) { + if (bdecomp->memory_allocation_failed()) { memoryAllocationFailed = true; } @@ -1266,7 +1263,7 @@ BENCHFUN bdecomp->reconstruct(labdn->b[0]); } - delete bdecomp; + bdecomp.reset(); if (!memoryAllocationFailed) { if (denoiseLuminance) { @@ -1306,8 +1303,6 @@ BENCHFUN } } } - - delete Ldecomp; } if (!memoryAllocationFailed) { @@ -2194,7 +2189,7 @@ void ImProcFunctions::Noise_residualAB(const wavelet_decomposition &WaveletCoeff const int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); const int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); - float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); + const float* const* WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); const float madC = SQR(denoiseMethodRgb ? MadRgb(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab) : Mad(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); resid += madC; @@ -2209,7 +2204,7 @@ void ImProcFunctions::Noise_residualAB(const wavelet_decomposition &WaveletCoeff chmaxresid = maxresid; } -bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels) +bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition& WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels) { int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5); const float eps = 0.01f; @@ -2260,7 +2255,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W int Wlvl_L = WaveletCoeffs_L.level_W(lvl); int Hlvl_L = WaveletCoeffs_L.level_H(lvl); - float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); + float* const* WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); if (lvl == maxlvl - 1) { // int edge = 0; @@ -2392,8 +2387,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W } -bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels) - +bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition& WaveletCoeffs_L, wavelet_decomposition& WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels) { int maxlvl = WaveletCoeffs_L.maxlevel(); @@ -2449,7 +2443,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition & // compute median absolute deviation (MAD) of detail coefficients as robust noise estimator int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); - float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); + const float* const* WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); if (!denoiseMethodRgb) { madab[lvl][dir - 1] = SQR(Mad(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); @@ -2468,8 +2462,8 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition & int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); - float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); - float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); + float* const* WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); + float* const* WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); if (lvl == maxlvl - 1) { ShrinkAllAB(WaveletCoeffs_L, WaveletCoeffs_ab, buffer, lvl, dir, noisevarchrom, noisevar_ab, useNoiseCCurve, autoch, denoiseMethodRgb, madL[lvl], nullptr, 0, madab[lvl], true); @@ -2563,7 +2557,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition & } -bool ImProcFunctions::WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels)//mod JD +bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition& WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels)//mod JD { @@ -2624,7 +2618,7 @@ bool ImProcFunctions::WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoe } -bool ImProcFunctions::WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, +bool ImProcFunctions::WaveletDenoiseAllAB(wavelet_decomposition& WaveletCoeffs_L, wavelet_decomposition& WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels)//mod JD { @@ -2688,7 +2682,7 @@ bool ImProcFunctions::WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCo -void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, +void ImProcFunctions::ShrinkAllL(wavelet_decomposition& WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge) { @@ -2702,7 +2696,7 @@ void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, f const int W_L = WaveletCoeffs_L.level_W(level); const int H_L = WaveletCoeffs_L.level_H(level); - float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(level); + float* const* WavCoeffs_L = WaveletCoeffs_L.level_coeffs(level); const float mad_L = madL[dir - 1] ; const float levelFactor = mad_L * 5.f / static_cast(level + 1); @@ -2779,7 +2773,7 @@ void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, f } -void ImProcFunctions::ShrinkAllAB(const wavelet_decomposition & WaveletCoeffs_L, const wavelet_decomposition & WaveletCoeffs_ab, float **buffer, int level, int dir, +void ImProcFunctions::ShrinkAllAB(wavelet_decomposition& WaveletCoeffs_L, wavelet_decomposition& WaveletCoeffs_ab, float **buffer, int level, int dir, float * noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * variC, int local, float * madaab, bool madCalculated) @@ -2798,8 +2792,8 @@ void ImProcFunctions::ShrinkAllAB(const wavelet_decomposition & WaveletCoeffs_L, int W_ab = WaveletCoeffs_ab.level_W(level); int H_ab = WaveletCoeffs_ab.level_H(level); - float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(level); - float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(level); + float* const* WavCoeffs_L = WaveletCoeffs_L.level_coeffs(level); + float* const* WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(level); float madab; float mad_L = madL[dir - 1]; @@ -2918,7 +2912,7 @@ void ImProcFunctions::ShrinkAllAB(const wavelet_decomposition & WaveletCoeffs_L, delete [] nvc; } -void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, +void ImProcFunctions::ShrinkAll_info(const float* const* WavCoeffs_a, const float* const* WavCoeffs_b, int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float & chaut, int &Nb, float & redaut, float & blueaut, float & maxredaut, float & maxblueaut, float & minredaut, float & minblueaut, int schoice, int lvl, float & chromina, float & sigma, float & lumema, float & sigma_L, float & redyel, float & skinc, float & nsknc, float & maxchred, float & maxchblue, float & minchred, float & minchblue, int &nb, float & chau, float & chred, float & chblue, bool denoiseMethodRgb) @@ -3048,8 +3042,8 @@ void ImProcFunctions::WaveletDenoiseAll_info(int levwav, const wavelet_decomposi int Wlvl_ab = WaveletCoeffs_a.level_W(lvl); int Hlvl_ab = WaveletCoeffs_a.level_H(lvl); - float ** WavCoeffs_a = WaveletCoeffs_a.level_coeffs(lvl); - float ** WavCoeffs_b = WaveletCoeffs_b.level_coeffs(lvl); + const float* const* WavCoeffs_a = WaveletCoeffs_a.level_coeffs(lvl); + const float* const* WavCoeffs_b = WaveletCoeffs_b.level_coeffs(lvl); ShrinkAll_info(WavCoeffs_a, WavCoeffs_b, Wlvl_ab, Hlvl_ab, noisevarlum, noisevarchrom, noisevarhue, chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, diff --git a/rtengine/cplx_wavelet_dec.h b/rtengine/cplx_wavelet_dec.h index c127a7adf..61305294d 100644 --- a/rtengine/cplx_wavelet_dec.h +++ b/rtengine/cplx_wavelet_dec.h @@ -33,37 +33,38 @@ class wavelet_decomposition : public NonCopyable { public: - - typedef float internal_type; - float *coeff0; - bool memoryAllocationFailed; - -private: - - static const int maxlevels = 10;//should be greater than any conceivable order of decimation - - int lvltot, subsamp; - int m_w, m_h;//dimensions - - int wavfilt_len, wavfilt_offset; - float *wavfilt_anal; - float *wavfilt_synth; - - - wavelet_level * wavelet_decomp[maxlevels]; - -public: + using internal_type = float; template wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling, int skipcrop = 1, int numThreads = 1, int Daub4Len = 6); ~wavelet_decomposition(); - internal_type ** level_coeffs(int level) const + bool memory_allocation_failed() const + { + return memoryAllocationFailed; + } + + const internal_type* const* level_coeffs(int level) const { return wavelet_decomp[level]->subbands(); } + internal_type* const* level_coeffs(int level) + { + return wavelet_decomp[level]->subbands(); + } + + const internal_type* get_coeff0() const + { + return coeff0; + } + + internal_type* get_coeff0() + { + return coeff0; + } + int level_W(int level) const { return wavelet_decomp[level]->width(); @@ -88,13 +89,47 @@ public: { return subsamp; } + template void reconstruct(E * dst, const float blend = 1.f); + +private: + static const int maxlevels = 10; // should be greater than any conceivable order of decimation + + int lvltot; + int subsamp; + // Dimensions + int m_w; + int m_h; + + int wavfilt_len; + int wavfilt_offset; + internal_type* wavfilt_anal; + internal_type* wavfilt_synth; + + internal_type* coeff0; + bool memoryAllocationFailed; + + wavelet_level* wavelet_decomp[maxlevels]; }; template -wavelet_decomposition::wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling, int skipcrop, int numThreads, int Daub4Len) - : coeff0(nullptr), memoryAllocationFailed(false), lvltot(0), subsamp(subsampling), m_w(width), m_h(height) +wavelet_decomposition::wavelet_decomposition( + E * src, + int width, + int height, + int maxlvl, + int subsampling, + int skipcrop, + int numThreads, + int Daub4Len +) : + lvltot(0), + subsamp(subsampling), + m_w(width), + m_h(height), + coeff0(nullptr), + memoryAllocationFailed(false) { //initialize wavelet filters diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index b7d7c41e5..8c713b836 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -204,29 +204,29 @@ public: void Tile_calc(int tilesize, int overlap, int kall, int imwidth, int imheight, int &numtiles_W, int &numtiles_H, int &tilewidth, int &tileheight, int &tileWskip, int &tileHskip); void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveSH & waOpacityCurveSH, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip); - void WaveletcontAllL(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_L, const Wavblcurve & wavblcurve, + void WaveletcontAllL(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition& WaveletCoeffs_L, const Wavblcurve & wavblcurve, struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili); - void WaveletcontAllLfinal(const wavelet_decomposition &WaveletCoeffs_L, const cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); - void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_a, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, + void WaveletcontAllLfinal(wavelet_decomposition& WaveletCoeffs_L, const cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); + void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition& WaveletCoeffs_a, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab); - void WaveletAandBAllAB(const wavelet_decomposition &WaveletCoeffs_a, const wavelet_decomposition &WaveletCoeffs_b, + void WaveletAandBAllAB(wavelet_decomposition& WaveletCoeffs_a, wavelet_decomposition& WaveletCoeffs_b, const cont_params &cp, FlatCurve* hhcurve, bool hhutili); - void ContAllL(float **koeLi, float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, + void ContAllL(float** koeLi, float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * lab, const float* const* varhue, const float* const* varchrom, float* const* WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili); - void finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp, + void finalContAllL(float* const* WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp, int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); - void ContAllAB(LabImage * lab, int maxlvl, float **varhue, float **varchrom, float ** WavCoeffs_a, float * WavCoeffs_a0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, + void ContAllAB(LabImage * lab, int maxlvl, float **varhue, float **varchrom, float* const* WavCoeffs_a, float * WavCoeffs_a0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, int W_ab, int H_ab, const bool useChannelA, float *meanab, float *sigmaab); void Evaluate2(const wavelet_decomposition &WaveletCoeffs_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN); - void Eval2(float ** WavCoeffs_L, int level, + void Eval2(const float* const* WavCoeffs_L, int level, int W_L, int H_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN); void calceffect(int level, float *mean, float *sigma, float *mea, float effect, float offs); - void Aver(float * HH_Coeffs, int datalen, float &averagePlus, float &averageNeg, float &max, float &min); - void Sigma(float * HH_Coeffs, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg); - void calckoe(float ** WavCoeffs_LL, const cont_params& cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = nullptr); + void Aver(const float* HH_Coeffs, int datalen, float &averagePlus, float &averageNeg, float &max, float &min); + void Sigma(const float* HH_Coeffs, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg); + void calckoe(const float* const* WavCoeffs_LL, const cont_params& cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = nullptr); void Median_Denoise(float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); void Median_Denoise(float **src, float **dst, float upperBound, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); @@ -240,18 +240,18 @@ public: const wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float & minblueaut, int schoice, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); - bool WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels); - bool WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); + bool WaveletDenoiseAllL(wavelet_decomposition& WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels); + bool WaveletDenoiseAllAB(wavelet_decomposition& WaveletCoeffs_L, wavelet_decomposition& WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); - bool WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels); - bool WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); + bool WaveletDenoiseAll_BiShrinkL(wavelet_decomposition& WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels); + bool WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition& WaveletCoeffs_L, wavelet_decomposition& WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); - void ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge); - void ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, + void ShrinkAllL(wavelet_decomposition& WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge); + void ShrinkAllAB(wavelet_decomposition& WaveletCoeffs_L, wavelet_decomposition& WaveletCoeffs_ab, float **buffer, int level, int dir, float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * variC, int local, float * madaab = nullptr, bool madCalculated = false); - void ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, + void ShrinkAll_info(const float* const* WavCoeffs_a, const float* const* WavCoeffs_b, int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, int lvl, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); void Noise_residualAB(const wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb); diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 47bd0f08a..e620ddff1 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -897,7 +897,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (levwavL > 0) { const std::unique_ptr Ldecomp(new wavelet_decomposition(labco->data, labco->W, labco->H, levwavL, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); - if (!Ldecomp->memoryAllocationFailed) { + if (!Ldecomp->memory_allocation_failed()) { float madL[10][3]; // float madL[8][3]; @@ -910,7 +910,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const int Wlvl_L = Ldecomp->level_W(lvl); int Hlvl_L = Ldecomp->level_H(lvl); - float ** WavCoeffs_L = Ldecomp->level_coeffs(lvl); + const float* const* WavCoeffs_L = Ldecomp->level_coeffs(lvl); madL[lvl][dir - 1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); @@ -1291,7 +1291,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (levwava > 0) { const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); - if (!adecomp->memoryAllocationFailed) { + if (!adecomp->memory_allocation_failed()) { if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f )) { WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ @@ -1328,7 +1328,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (levwavb > 0) { const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); - if (!bdecomp->memoryAllocationFailed) { + if (!bdecomp->memory_allocation_failed()) { if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f )) { WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ @@ -1360,7 +1360,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); - if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { + if (!adecomp->memory_allocation_failed() && !bdecomp->memory_allocation_failed()) { if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f)) { WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ @@ -1655,7 +1655,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } -void ImProcFunctions::Aver(float * RESTRICT DataList, int datalen, float &averagePlus, float &averageNeg, float &max, float &min) +void ImProcFunctions::Aver(const float* RESTRICT DataList, int datalen, float &averagePlus, float &averageNeg, float &max, float &min) { //find absolute mean @@ -1710,7 +1710,7 @@ void ImProcFunctions::Aver(float * RESTRICT DataList, int datalen, float &averag } -void ImProcFunctions::Sigma(float * RESTRICT DataList, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg) +void ImProcFunctions::Sigma(const float* RESTRICT DataList, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg) { int countP = 0, countN = 0; double variP = 0.0, variN = 0.0; // use double precision for large summations @@ -1755,7 +1755,7 @@ void ImProcFunctions::Evaluate2(const wavelet_decomposition &WaveletCoeffs_L, int Wlvl_L = WaveletCoeffs_L.level_W(lvl); int Hlvl_L = WaveletCoeffs_L.level_H(lvl); - float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); + const float* const* WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); Eval2(WavCoeffs_L, lvl, Wlvl_L, Hlvl_L, mean, meanN, sigma, sigmaN, MaxP, MaxN); } @@ -1814,7 +1814,7 @@ void ImProcFunctions::calceffect(int level, float *mean, float *sigma, float *me mea[9] = offs * mean[level] + effect * 2.5f * sigma[level]; //99% } -void ImProcFunctions::Eval2(float ** WavCoeffs_L, int level, +void ImProcFunctions::Eval2(const float* const* WavCoeffs_L, int level, int W_L, int H_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN) { @@ -2015,29 +2015,29 @@ void ImProcFunctions::EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterate } } -void ImProcFunctions::WaveletcontAllLfinal(const wavelet_decomposition &WaveletCoeffs_L, const cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL) +void ImProcFunctions::WaveletcontAllLfinal(wavelet_decomposition& WaveletCoeffs_L, const cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL) { int maxlvl = WaveletCoeffs_L.maxlevel(); - float * WavCoeffs_L0 = WaveletCoeffs_L.coeff0; + float* WavCoeffs_L0 = WaveletCoeffs_L.get_coeff0(); for (int dir = 1; dir < 4; dir++) { for (int lvl = 0; lvl < maxlvl; lvl++) { int Wlvl_L = WaveletCoeffs_L.level_W(lvl); int Hlvl_L = WaveletCoeffs_L.level_H(lvl); - float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); + float* const* WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); finalContAllL(WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, mean, sigma, MaxP, waOpacityCurveWL); } } } -void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_L, const Wavblcurve & wavblcurve, +void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition& WaveletCoeffs_L, const Wavblcurve & wavblcurve, struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili) { const int maxlvl = WaveletCoeffs_L.maxlevel(); const int W_L = WaveletCoeffs_L.level_W(0); const int H_L = WaveletCoeffs_L.level_H(0); - float * WavCoeffs_L0 = WaveletCoeffs_L.coeff0; + float* WavCoeffs_L0 = WaveletCoeffs_L.get_coeff0(); float contrast = cp.contrast; double avedbl = 0.0; // use double precision for large summations @@ -2307,7 +2307,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * for (int lvl = 0; lvl < 4; lvl++) { for (int dir = 1; dir < 4; dir++) { - float ** WavCoeffs_LL = WaveletCoeffs_L.level_coeffs(lvl); + const float* const* WavCoeffs_LL = WaveletCoeffs_L.level_coeffs(lvl); calckoe(WavCoeffs_LL, cp, koeLi, lvl, dir, WaveletCoeffs_L.level_W(lvl), WaveletCoeffs_L.level_H(lvl), edd, maxkoeLi, tmC); // return convolution KoeLi and maxkoeLi of level 0 1 2 3 and Dir Horiz, Vert, Diag } @@ -2430,7 +2430,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * int Wlvl_L = WaveletCoeffs_L.level_W(lvl); int Hlvl_L = WaveletCoeffs_L.level_H(lvl); - float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); + float* const* WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); // ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, waOpacityCurveSH, ChCurve, Chutili); @@ -2525,7 +2525,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } } -void ImProcFunctions::WaveletAandBAllAB(const wavelet_decomposition &WaveletCoeffs_a, const wavelet_decomposition &WaveletCoeffs_b, +void ImProcFunctions::WaveletAandBAllAB(wavelet_decomposition& WaveletCoeffs_a, wavelet_decomposition& WaveletCoeffs_b, const cont_params &cp, FlatCurve* hhCurve, bool hhutili) { // StopWatch Stop1("WaveletAandBAllAB"); @@ -2533,8 +2533,8 @@ void ImProcFunctions::WaveletAandBAllAB(const wavelet_decomposition &WaveletCoef int W_L = WaveletCoeffs_a.level_W(0); int H_L = WaveletCoeffs_a.level_H(0); - float * WavCoeffs_a0 = WaveletCoeffs_a.coeff0; - float * WavCoeffs_b0 = WaveletCoeffs_b.coeff0; + float* WavCoeffs_a0 = WaveletCoeffs_a.get_coeff0(); + float* WavCoeffs_b0 = WaveletCoeffs_b.get_coeff0(); #ifdef _OPENMP #pragma omp parallel num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif @@ -2591,7 +2591,7 @@ void ImProcFunctions::WaveletAandBAllAB(const wavelet_decomposition &WaveletCoef } -void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_ab, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, +void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition& WaveletCoeffs_ab, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab) { @@ -2599,7 +2599,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float int W_L = WaveletCoeffs_ab.level_W(0); int H_L = WaveletCoeffs_ab.level_H(0); - float * WavCoeffs_ab0 = WaveletCoeffs_ab.coeff0; + float* WavCoeffs_ab0 = WaveletCoeffs_ab.get_coeff0(); #ifdef _OPENMP #pragma omp parallel num_threads(wavNestedLevels) if (wavNestedLevels>1) @@ -2748,7 +2748,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); - float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); + float* const* WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA, meanab, sigmaab); int minWL = min(Wlvl_ab, Hlvl_ab); @@ -2828,7 +2828,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void ImProcFunctions::calckoe(float ** WavCoeffs_LL, const cont_params& cp, float *koeLi[12], int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC) +void ImProcFunctions::calckoe(const float* const* WavCoeffs_LL, const cont_params& cp, float *koeLi[12], int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC) { int borderL = 2; @@ -2966,7 +2966,7 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, const cont_params& cp, floa } -void ImProcFunctions::finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp, +void ImProcFunctions::finalContAllL(float* const* WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp, int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL) { if (cp.diagcurv && cp.finena && MaxP[level] > 0.f && mean[level] != 0.f && sigma[level] != 0.f) { //curve @@ -3120,7 +3120,7 @@ void ImProcFunctions::finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, } -void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * labco, float ** varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, +void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * labco, const float* const* varhue, const float* const* varchrom, float* const* WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili) { assert(level >= 0); @@ -3907,7 +3907,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz // choicelevel = choicelevel == -1 ? 4 : choicelevel; } -void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, float **varchrom, float ** WavCoeffs_ab, float * WavCoeffs_ab0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, +void ImProcFunctions::ContAllAB(LabImage * labco, int maxlvl, float ** varhue, float **varchrom, float* const* WavCoeffs_ab, float * WavCoeffs_ab0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, int W_ab, int H_ab, const bool useChannelA, float *meanab, float *sigmaab) { float cpMul = cp.mul[level]; From 41675913d6192a8971c7b105f6d8c1dd4a204346 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 31 May 2020 17:27:44 +0200 Subject: [PATCH 2/7] Cleanups and also some speedups for RT 5.9, to be continued --- rtengine/imagedata.cc | 4 +- rtengine/improccoordinator.cc | 2 +- rtengine/improcfun.h | 8 +- rtengine/ipwavelet.cc | 259 ++++++++++------------------------ rtengine/rawimage.cc | 3 +- rtexif/rtexif.cc | 20 ++- rtgui/filecatalog.cc | 2 + rtgui/main.cc | 9 +- rtgui/thumbnail.cc | 2 +- 9 files changed, 96 insertions(+), 213 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index a631a6c8d..5a76e4531 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -536,7 +536,7 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* if (mnote->getTag ("FocalLengthIn35mmFilm")) { focal_len35mm = mnote->getTag ("FocalLengthIn35mmFilm")->toDouble (); } - } else if (mnote && (!make.compare (0, 4, "SONY") || !make.compare (0, 6, "KONICA"))) { + } else if (!make.compare (0, 4, "SONY") || !make.compare (0, 6, "KONICA")) { if (mnote->getTag ("LensID")) { lens = mnote->getTag ("LensID")->valueToString (); if (lens == "Unknown") { @@ -554,7 +554,7 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* if (lens == "Unknown") { lens_from_make_and_model(); } - } else if (mnote && !make.compare (0, 9, "Panasonic")) { + } else if (!make.compare (0, 9, "Panasonic")) { if (mnote->getTag ("LensType")) { std::string panalens = mnote->getTag("LensType")->valueToString(); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 6b50f3d3d..c4f191475 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -153,12 +153,12 @@ ImProcCoordinator::ImProcCoordinator() : pdSharpenAutoRadiusListener(nullptr), frameCountListener(nullptr), imageTypeListener(nullptr), + filmNegListener(nullptr), actListener(nullptr), adnListener(nullptr), awavListener(nullptr), dehaListener(nullptr), hListener(nullptr), - filmNegListener(nullptr), resultValid(false), params(new procparams::ProcParams), lastOutputProfile("BADFOOD"), diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index b7d7c41e5..d942afb07 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -187,9 +187,9 @@ public: void dirpyrequalizer(LabImage* lab, int scale); //Emil's wavelet - void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0); + void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, const struct cont_params& cp, int W_L, int H_L, float max0); void CompressDR(float *Source, int W_L, int H_L, float Compression, float DetailBoost); - void ContrastResid(float * WavCoeffs_L0, struct cont_params &cp, int W_L, int H_L, float max0, float min0); + void ContrastResid(float * WavCoeffs_L0, const struct cont_params &cp, int W_L, int H_L, float max0); void EPDToneMap(LabImage *lab, unsigned int Iterates = 0, int skip = 1); void EPDToneMapCIE(CieImage *ncie, float a_w, float c_, int Wid, int Hei, float minQ, float maxQ, unsigned int Iterates = 0, int skip = 1); @@ -211,7 +211,7 @@ public: struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab); void WaveletAandBAllAB(const wavelet_decomposition &WaveletCoeffs_a, const wavelet_decomposition &WaveletCoeffs_b, const cont_params &cp, FlatCurve* hhcurve, bool hhutili); - void ContAllL(float **koeLi, float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, + void ContAllL(float **koeLi, float maxkoeLi, bool lipschitz, int maxlvl, LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili); void finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, const cont_params &cp, int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); @@ -226,7 +226,7 @@ public: void Aver(float * HH_Coeffs, int datalen, float &averagePlus, float &averageNeg, float &max, float &min); void Sigma(float * HH_Coeffs, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg); - void calckoe(float ** WavCoeffs_LL, const cont_params& cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = nullptr); + void calckoe(float ** WavCoeffs_LL, const cont_params& cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float& maxkoeLi, float **tmC = nullptr); void Median_Denoise(float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); void Median_Denoise(float **src, float **dst, float upperBound, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 47bd0f08a..f17c8f8b9 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -110,7 +110,6 @@ struct cont_params { bool lip3; bool tonemap; bool diag; - int TMmeth; float tmstrength; float balan; float sigmafin; @@ -1344,12 +1343,6 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } else {// a and b int levwavab = levwav; - if (!exblurab && cp.chrores == 0.f && cp.blurcres == 0.f && !hhutili && params->wavelet.CLmethod == "all") { // no processing of residual ab => we probably can reduce the number of levels - while (levwavab > 0 && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavab - 1] == 0.f)) || (cp.CHmet != 2 && (levwavab == 10 || (!cp.curv || cp.mulC[levwavab - 1] == 0.f))))) && (!cp.opaRG || levwavab == 10 || (cp.opaRG && cp.mulopaRG[levwavab - 1] == 0.f)) && ((levwavab == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavab - 1] == 0.f)))) { - levwavab--; - } - } - if (cp.chromfi > 0.f || cp.chromco > 0.f) { if (levwavab < 7) { levwavab = 7; @@ -1916,102 +1909,72 @@ void ImProcFunctions::CompressDR(float *Source, int W_L, int H_L, float Compress } -void ImProcFunctions::ContrastResid(float * WavCoeffs_L0, struct cont_params &cp, int W_L, int H_L, float max0, float min0) +void ImProcFunctions::ContrastResid(float * WavCoeffs_L0, const cont_params &cp, int W_L, int H_L, float max0) { - float stren = cp.tmstrength; - float gamm = params->wavelet.gamma; - cp.TMmeth = 2; //default after testing - - if (cp.TMmeth == 1) { - min0 = 0.0f; - max0 = 32768.f; - } else if (cp.TMmeth == 2) { - min0 = 0.0f; - } + const float stren = cp.tmstrength; + const float gamm = params->wavelet.gamma; #ifdef _OPENMP #pragma omp parallel for #endif for (int i = 0; i < W_L * H_L; i++) { - WavCoeffs_L0[i] = (WavCoeffs_L0[i] - min0) / max0; - WavCoeffs_L0[i] *= gamm; - } - - float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents. - float DetailBoost = stren; - - if (stren < 0.0f) { - DetailBoost = 0.0f; //Go with effect of exponent only if uncompressing. + WavCoeffs_L0[i] *= (gamm / max0); } + const float Compression = std::exp(-stren); //This modification turns numbers symmetric around 0 into exponents. + const float DetailBoost = std::max(stren, 0.f); //Go with effect of exponent only if uncompressing. CompressDR(WavCoeffs_L0, W_L, H_L, Compression, DetailBoost); - + max0 /= gamm; #ifdef _OPENMP #pragma omp parallel for // removed schedule(dynamic,10) #endif for (int ii = 0; ii < W_L * H_L; ii++) { - WavCoeffs_L0[ii] = WavCoeffs_L0[ii] * max0 * (1.f / gamm) + min0; + WavCoeffs_L0[ii] *= max0; } } - - - -void ImProcFunctions::EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0) +void ImProcFunctions::EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, const cont_params& cp, int W_L, int H_L, float max0) { - float stren = cp.tmstrength; - float edgest = params->wavelet.edgs; - float sca = params->wavelet.scale; - float gamm = params->wavelet.gamma; - int rew = 0; //params->epd.reweightingIterates; + const float stren = cp.tmstrength; + const float edgest = params->wavelet.edgs; + const float sca = params->wavelet.scale; + const float gamm = params->wavelet.gamma; + constexpr int rew = 0; //params->epd.reweightingIterates; + EdgePreservingDecomposition epd2(W_L, H_L); - cp.TMmeth = 2; //default after testing - if (cp.TMmeth == 1) { - min0 = 0.0f; - max0 = 32768.f; - } else if (cp.TMmeth == 2) { - min0 = 0.0f; - } - - // max0=32768.f; #ifdef _OPENMP #pragma omp parallel for #endif for (int i = 0; i < W_L * H_L; i++) { - WavCoeffs_L0[i] = (WavCoeffs_L0[i] - min0) / max0; - WavCoeffs_L0[i] *= gamm; + WavCoeffs_L0[i] *= (gamm / max0); } - float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents. - float DetailBoost = stren; - - if (stren < 0.0f) { - DetailBoost = 0.0f; //Go with effect of exponent only if uncompressing. - } + const float Compression = std::exp(-stren); //This modification turns numbers symmetric around 0 into exponents. + const float DetailBoost = std::max(stren, 0.f); //Go with effect of exponent only if uncompressing. //Auto select number of iterates. Note that p->EdgeStopping = 0 makes a Gaussian blur. if (Iterates == 0) { Iterates = (unsigned int)(edgest * 15.0f); } + epd2.CompressDynamicRange(WavCoeffs_L0, sca / skip, edgest, Compression, DetailBoost, Iterates, rew); - epd2.CompressDynamicRange(WavCoeffs_L0, (float)sca / skip, edgest, Compression, DetailBoost, Iterates, rew); - + max0 /= gamm; //Restore past range, also desaturate a bit per Mantiuk's Color correction for tone mapping. #ifdef _OPENMP #pragma omp parallel for // removed schedule(dynamic,10) #endif for (int ii = 0; ii < W_L * H_L; ii++) { - WavCoeffs_L0[ii] = WavCoeffs_L0[ii] * max0 * (1.f / gamm) + min0; + WavCoeffs_L0[ii] *= max0; } } @@ -2039,96 +2002,35 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * const int H_L = WaveletCoeffs_L.level_H(0); float * WavCoeffs_L0 = WaveletCoeffs_L.coeff0; - float contrast = cp.contrast; + const float contrast = cp.contrast; double avedbl = 0.0; // use double precision for large summations float max0 = 0.f; - float min0 = FLT_MAX; - if (contrast != 0.f || (cp.tonemap && cp.resena)) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step + if (contrast != 0.f || (cp.tonemap && cp.resena)) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step #ifdef _OPENMP - #pragma omp parallel for reduction(+:avedbl) num_threads(wavNestedLevels) if (wavNestedLevels>1) + #pragma omp parallel for reduction(+:avedbl) reduction(max:max0) num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif for (int i = 0; i < W_L * H_L; i++) { avedbl += static_cast(WavCoeffs_L0[i]); + max0 = std::max(WavCoeffs_L0[i], max0); } - -#ifdef _OPENMP - #pragma omp parallel num_threads(wavNestedLevels) if (wavNestedLevels>1) -#endif - { - float lminL = FLT_MAX; - float lmaxL = 0.f; - -#ifdef _OPENMP - #pragma omp for -#endif - - for (int i = 0; i < W_L * H_L; i++) { - if (WavCoeffs_L0[i] < lminL) { - lminL = WavCoeffs_L0[i]; - } - - if (WavCoeffs_L0[i] > lmaxL) { - lmaxL = WavCoeffs_L0[i]; - } - - } - -#ifdef _OPENMP - #pragma omp critical -#endif - { - if (lminL < min0) { - min0 = lminL; - } - - if (lmaxL > max0) { - max0 = lmaxL; - } - } - - } - } - //tone mapping - if (cp.tonemap && cp.contmet == 2 && cp.resena) { + if (cp.tonemap && cp.contmet == 2 && cp.resena) { //iterate = 5 - EPDToneMapResid(WavCoeffs_L0, 0, skip, cp, W_L, H_L, max0, min0); - + EPDToneMapResid(WavCoeffs_L0, 0, skip, cp, W_L, H_L, max0); } //end tonemapping max0 /= 327.68f; - min0 /= 327.68f; - float ave = avedbl / (double)(W_L * H_L); - float avg = ave / 32768.f; - float *koeLi[12]; - float maxkoeLi[12]; + const float ave = avedbl / (W_L * H_L); + const float avg = LIM01(ave / 32768.f); - float *koeLibuffer = nullptr; - - for (int y = 0; y < 12; y++) { - maxkoeLi[y] = 0.f; //9 - } - - koeLibuffer = new float[12 * H_L * W_L]; //12 - - for (int i = 0; i < 12; i++) { //9 - koeLi[i] = &koeLibuffer[i * W_L * H_L]; - } - - for (int j = 0; j < 12; j++) //9 - for (int i = 0; i < W_L * H_L; i++) { - koeLi[j][i] = 0.f; - } - - avg = LIM01(avg); - double contreal = 0.6 * contrast; + const double contreal = 0.6 * contrast; DiagonalCurve resid_contrast({ DCT_NURBS, 0, 0, @@ -2137,43 +2039,29 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * 1, 1 }); + if (contrast != 0.f && cp.resena && max0 > 0.f) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step #ifdef _OPENMP - #pragma omp parallel num_threads(wavNestedLevels) if (wavNestedLevels>1) -#endif - { - if (contrast != 0.f && cp.resena && max0 > 0.f) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step - { - -#ifdef _OPENMP - #pragma omp for + #pragma omp parallel for num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif - for (int i = 0; i < W_L * H_L; i++) { - float buf = LIM01(WavCoeffs_L0[i] / 32768.f); - buf = resid_contrast.getVal(buf); - buf *= 32768.f; - WavCoeffs_L0[i] = buf; - } - } - } - - - if (cp.tonemap && cp.contmet == 1 && cp.resena) { - float maxp = max0 * 256.f; - float minp = min0 * 256.f; -#ifdef _OPENMP - #pragma omp single -#endif - ContrastResid(WavCoeffs_L0, cp, W_L, H_L, maxp, minp); + for (int i = 0; i < W_L * H_L; i++) { + float buf = LIM01(WavCoeffs_L0[i] / 32768.f); + buf = resid_contrast.getVal(buf); + buf *= 32768.f; + WavCoeffs_L0[i] = buf; } } - if ((cp.conres >= 0.f || cp.conresH >= 0.f) && cp.resena && !cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step - LabImage *temp = nullptr; - temp = new LabImage(W_L, H_L); + if (cp.tonemap && cp.contmet == 1 && cp.resena) { + const float maxp = max0 * 256.f; + ContrastResid(WavCoeffs_L0, cp, W_L, H_L, maxp); + } + + if ((cp.conres >= 0.f || cp.conresH >= 0.f) && cp.resena && !cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step + std::unique_ptr temp(new LabImage(W_L, H_L)); #ifdef _OPENMP - #pragma omp for + #pragma omp parallel for num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif for (int i = 0; i < H_L; i++) { @@ -2182,12 +2070,10 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } } - { - ImProcFunctions::shadowsHighlights(temp, true, 1, cp.conresH, cp.conres, cp.radius, skip, cp.thH, cp.th); - } + ImProcFunctions::shadowsHighlights(temp.get(), true, 1, cp.conresH, cp.conres, cp.radius, skip, cp.thH, cp.th); #ifdef _OPENMP - #pragma omp for + #pragma omp parallel for num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif for (int i = 0; i < H_L; i++) { @@ -2195,18 +2081,11 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * WavCoeffs_L0[i * W_L + j] = temp->L[i][j]; } } - - delete temp; - } -#ifdef _OPENMP - #pragma omp barrier -#endif - if ((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena && cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step #ifdef _OPENMP - #pragma omp for nowait + #pragma omp parallel for #endif for (int i = 0; i < W_L * H_L; i++) { @@ -2277,6 +2156,20 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * int n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n32; n0 = n1 = n2 = n3 = n4 = n5 = n6 = n7 = n8 = n9 = n10 = n32 = 0; + float *koeLi[12]; + + std::unique_ptr koeLibuffer(new float[12 * H_L * W_L]); + + for (int i = 0; i < 12; i++) { + koeLi[i] = &koeLibuffer[i * W_L * H_L]; + } + + for (int j = 0; j < 12; j++) { + for (int i = 0; i < W_L * H_L; i++) { + koeLi[j][i] = 0.f; + } + } + #ifdef _OPENMP #pragma omp parallel num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif @@ -2291,10 +2184,10 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * constexpr float eddlow = 15.f; float eddlipinfl = 0.005f * cp.edgsens + 0.4f; float eddlipampl = 1.f + cp.edgampl / 50.f; - + float maxkoeLi = 0.f; if (cp.detectedge) { //enabled Lipschitz control...more memory..more time... - float *tmCBuffer = new float[H_L * W_L]; + std::unique_ptr tmCBuffer(new float[H_L * W_L]); float *tmC[H_L]; for (int i = 0; i < H_L; i++) { @@ -2313,8 +2206,6 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } } - delete [] tmCBuffer; - float aamp = 1.f + cp.eddetthrHi / 100.f; for (int lvl = 0; lvl < 4; lvl++) { @@ -2432,7 +2323,6 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); -// ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, waOpacityCurveSH, ChCurve, Chutili); int minWL = min(Wlvl_L, Hlvl_L); @@ -2518,11 +2408,6 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } } } - - //delete edge detection - if (koeLibuffer) { - delete [] koeLibuffer; - } } void ImProcFunctions::WaveletAandBAllAB(const wavelet_decomposition &WaveletCoeffs_a, const wavelet_decomposition &WaveletCoeffs_b, @@ -2828,7 +2713,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void ImProcFunctions::calckoe(float ** WavCoeffs_LL, const cont_params& cp, float *koeLi[12], int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC) +void ImProcFunctions::calckoe(float ** WavCoeffs_LL, const cont_params& cp, float *koeLi[12], int level, int dir, int W_L, int H_L, float edd, float& maxkoeLi, float **tmC) { int borderL = 2; @@ -2954,13 +2839,13 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, const cont_params& cp, floa koeLi[level * 3 + dir - 1][i * W_L + j] = rtengine::min(thr2, std::fabs(tmC[i][j] / temp)); // limit maxi //it will be more complicated to calculate both Wh and Wv, but we have also Wd==> pseudo Lipschitz - if (koeLi[level * 3 + dir - 1][i * W_L + j] > maxkoeLi[level * 3 + dir - 1]) { - maxkoeLi[level * 3 + dir - 1] = koeLi[level * 3 + dir - 1][i * W_L + j]; + if (koeLi[level * 3 + dir - 1][i * W_L + j] > maxkoeLi) { + maxkoeLi = koeLi[level * 3 + dir - 1][i * W_L + j]; } - float diff = maxkoeLi[level * 3 + dir - 1] - koeLi[level * 3 + dir - 1][i * W_L + j]; + float diff = maxkoeLi - koeLi[level * 3 + dir - 1][i * W_L + j]; diff *= diffFactor; - koeLi[level * 3 + dir - 1][i * W_L + j] = maxkoeLi[level * 3 + dir - 1] - diff; + koeLi[level * 3 + dir - 1][i * W_L + j] = maxkoeLi - diff; } } @@ -3120,7 +3005,7 @@ void ImProcFunctions::finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, } -void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * labco, float ** varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, +void ImProcFunctions::ContAllL(float *koeLi[12], float maxkoeLi, bool lipschitz, int maxlvl, LabImage * labco, float ** varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveSH & waOpacityCurveSH, FlatCurve* ChCurve, bool Chutili) { assert(level >= 0); @@ -3376,7 +3261,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz if (lipschitz) { if (level < 4) { - edge = 1.f + (edgePrecalc - 1.f) * (koeLi[level * 3][k]) / (1.f + 0.9f * maxkoeLi[level * 3 + dir - 1]); + edge = 1.f + (edgePrecalc - 1.f) * (koeLi[level * 3][k]) / (1.f + 0.9f * maxkoeLi); } else { edge = edgePrecalc; } @@ -3482,7 +3367,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz if (lipschitz) { if (level < 4) { - edge = 1.f + (edgePrecalc - 1.f) * (koeLi[level * 3][k]) / (1.f + 0.9f * maxkoeLi[level * 3 + dir - 1]); + edge = 1.f + (edgePrecalc - 1.f) * (koeLi[level * 3][k]) / (1.f + 0.9f * maxkoeLi); } else { edge = edgePrecalc; } diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index c2df70468..859486010 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -497,11 +497,10 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro // dcraw needs this global variable to hold pixel data image = (dcrawImage_t)calloc (static_cast(height) * static_cast(width) * sizeof * image + meta_length, 1); - meta_data = (char *) (image + static_cast(height) * static_cast(width)); - if(!image) { return 200; } + meta_data = (char *) (image + static_cast(height) * static_cast(width)); /* Issue 2467 if (setjmp (failure)) { diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index 95b46c2b9..b4a4650c9 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -3059,18 +3059,16 @@ void ExifManager::parse (bool isRaw, bool skipIgnored, bool parseJpeg) bool frameRootDetected = false; - if(!frameRootDetected) { - std::vector risTagList = root->findTags("RawImageSegmentation"); - if (!risTagList.empty()) { - for (auto ris : risTagList) { - frames.push_back(ris->getParent()); - frameRootDetected = true; + std::vector risTagList = root->findTags("RawImageSegmentation"); + if (!risTagList.empty()) { + for (auto ris : risTagList) { + frames.push_back(ris->getParent()); + frameRootDetected = true; - #if PRINT_METADATA_TREE - printf("\n--------------- FRAME (RAWIMAGESEGMENTATION) ---------------\n\n"); - ris->getParent()->printAll (); - #endif - } +#if PRINT_METADATA_TREE + printf("\n--------------- FRAME (RAWIMAGESEGMENTATION) ---------------\n\n"); + ris->getParent()->printAll (); +#endif } } diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 102c17daf..42a2263e2 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -2446,6 +2446,8 @@ bool FileCatalog::handleShortcutKey (GdkEventKey* event) case GDK_KEY_underscore: zoomOut(); return true; + default: // do nothing, avoids a cppcheck false positive + break; } } diff --git a/rtgui/main.cc b/rtgui/main.cc index 63669f49c..b6edb3c63 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -440,7 +440,7 @@ int main (int argc, char **argv) if (argc > 1) { if (!remote && !Glib::file_test (argv1, Glib::FILE_TEST_EXISTS ) && !Glib::file_test (argv1, Glib::FILE_TEST_IS_DIR)) { - bool stdoutRedirecttoConsole = (GetFileType (GetStdHandle (STD_OUTPUT_HANDLE)) == 0x0000); + const bool stdoutRedirecttoConsole = (GetFileType (GetStdHandle (STD_OUTPUT_HANDLE)) == 0x0000); // open console, if stdout is invalid if (stdoutRedirecttoConsole) { // check if parameter -w was passed. @@ -472,10 +472,9 @@ int main (int argc, char **argv) cursorInfo.bVisible = false; SetConsoleCursorInfo ( GetStdHandle ( STD_OUTPUT_HANDLE ), &cursorInfo ); - if (stdoutRedirecttoConsole) { // if stdout is Redirect to console, we also redirect stderr to console - freopen ( "CON", "w", stdout ) ; - freopen ( "CON", "w", stderr ) ; - } + // we also redirect stderr to console + freopen ( "CON", "w", stdout ) ; + freopen ( "CON", "w", stderr ) ; freopen ( "CON", "r", stdin ) ; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 7452c9d72..059a1ed94 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -873,7 +873,7 @@ void Thumbnail::_loadThumbnail(bool firstTrial) if (!succ && firstTrial) { _generateThumbnailImage (); - if (cfs.supported && firstTrial) { + if (cfs.supported) { _loadThumbnail (false); } From 48648170e9b8b64ba72ceb0b0c3cef317e7ae7cd Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 2 Jun 2020 19:46:13 +0200 Subject: [PATCH 3/7] Some more cleanups --- rtengine/ipwavelet.cc | 13 ++++--------- rtexif/rtexif.cc | 13 +++++-------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index f17c8f8b9..144b307e5 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -50,6 +50,7 @@ #endif #include "cplx_wavelet_dec.h" +#pragma GCC diagnostic warning "-Wdouble-promotion" namespace rtengine { @@ -2059,7 +2060,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } if ((cp.conres >= 0.f || cp.conresH >= 0.f) && cp.resena && !cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step - std::unique_ptr temp(new LabImage(W_L, H_L)); + const std::unique_ptr temp(new LabImage(W_L, H_L)); #ifdef _OPENMP #pragma omp parallel for num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif @@ -2158,18 +2159,12 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * float *koeLi[12]; - std::unique_ptr koeLibuffer(new float[12 * H_L * W_L]); + const std::unique_ptr koeLibuffer(new float[12 * H_L * W_L]()); for (int i = 0; i < 12; i++) { koeLi[i] = &koeLibuffer[i * W_L * H_L]; } - for (int j = 0; j < 12; j++) { - for (int i = 0; i < W_L * H_L; i++) { - koeLi[j][i] = 0.f; - } - } - #ifdef _OPENMP #pragma omp parallel num_threads(wavNestedLevels) if (wavNestedLevels>1) #endif @@ -2187,7 +2182,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * float maxkoeLi = 0.f; if (cp.detectedge) { //enabled Lipschitz control...more memory..more time... - std::unique_ptr tmCBuffer(new float[H_L * W_L]); + const std::unique_ptr tmCBuffer(new float[H_L * W_L]); float *tmC[H_L]; for (int i = 0; i < H_L; i++) { diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index b4a4650c9..c0038c067 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -3059,17 +3059,14 @@ void ExifManager::parse (bool isRaw, bool skipIgnored, bool parseJpeg) bool frameRootDetected = false; - std::vector risTagList = root->findTags("RawImageSegmentation"); - if (!risTagList.empty()) { - for (auto ris : risTagList) { - frames.push_back(ris->getParent()); - frameRootDetected = true; + for (auto ris : root->findTags("RawImageSegmentation")) { + frames.push_back(ris->getParent()); + frameRootDetected = true; #if PRINT_METADATA_TREE - printf("\n--------------- FRAME (RAWIMAGESEGMENTATION) ---------------\n\n"); - ris->getParent()->printAll (); + printf("\n--------------- FRAME (RAWIMAGESEGMENTATION) ---------------\n\n"); + ris->getParent()->printAll (); #endif - } } if(!frameRootDetected) { From f0ddd42d6d44daf2eb9e487bc20a43a7ddd29d22 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 13 Jun 2020 19:13:41 +0200 Subject: [PATCH 4/7] Crash caused by Tone Mapping, fixes #5171 --- rtengine/EdgePreservingDecomposition.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtengine/EdgePreservingDecomposition.cc b/rtengine/EdgePreservingDecomposition.cc index 04459e88a..82e486438 100644 --- a/rtengine/EdgePreservingDecomposition.cc +++ b/rtengine/EdgePreservingDecomposition.cc @@ -939,7 +939,7 @@ void EdgePreservingDecomposition::CompressDynamicRange(float *Source, float Scal cev = xexpf(LVFU(Source[i]) + LVFU(u[i]) * (tempv)) - epsv; uev = xexpf(LVFU(u[i])) - epsv; sourcev = xexpf(LVFU(Source[i])) - epsv; - _mm_storeu_ps( &Source[i], cev + DetailBoostv * (sourcev - uev) ); + _mm_storeu_ps( &Source[i], vmaxf(cev + DetailBoostv * (sourcev - uev), ZEROV)); } } @@ -947,7 +947,7 @@ void EdgePreservingDecomposition::CompressDynamicRange(float *Source, float Scal float ce = xexpf(Source[i] + u[i] * (temp)) - eps; float ue = xexpf(u[i]) - eps; Source[i] = xexpf(Source[i]) - eps; - Source[i] = ce + DetailBoost * (Source[i] - ue); + Source[i] = std::max(ce + DetailBoost * (Source[i] - ue), 0.f); } #else @@ -959,7 +959,7 @@ void EdgePreservingDecomposition::CompressDynamicRange(float *Source, float Scal float ce = xexpf(Source[i] + u[i] * (temp)) - eps; float ue = xexpf(u[i]) - eps; Source[i] = xexpf(Source[i]) - eps; - Source[i] = ce + DetailBoost * (Source[i] - ue); + Source[i] = std::max(ce + DetailBoost * (Source[i] - ue), 0.f); } #endif From 7046a9be932a7adf3a2e622599885ca1ef38a4d5 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 14 Jun 2020 16:48:06 +0200 Subject: [PATCH 5/7] Next try to fix a crash caused by tone mapping, #5171 --- rtengine/EdgePreservingDecomposition.cc | 6 +- rtengine/improcfun.cc | 114 +++++++----------------- 2 files changed, 35 insertions(+), 85 deletions(-) diff --git a/rtengine/EdgePreservingDecomposition.cc b/rtengine/EdgePreservingDecomposition.cc index 82e486438..457eff5ac 100644 --- a/rtengine/EdgePreservingDecomposition.cc +++ b/rtengine/EdgePreservingDecomposition.cc @@ -939,7 +939,7 @@ void EdgePreservingDecomposition::CompressDynamicRange(float *Source, float Scal cev = xexpf(LVFU(Source[i]) + LVFU(u[i]) * (tempv)) - epsv; uev = xexpf(LVFU(u[i])) - epsv; sourcev = xexpf(LVFU(Source[i])) - epsv; - _mm_storeu_ps( &Source[i], vmaxf(cev + DetailBoostv * (sourcev - uev), ZEROV)); + _mm_storeu_ps( &Source[i], cev + DetailBoostv * (sourcev - uev)); } } @@ -947,7 +947,7 @@ void EdgePreservingDecomposition::CompressDynamicRange(float *Source, float Scal float ce = xexpf(Source[i] + u[i] * (temp)) - eps; float ue = xexpf(u[i]) - eps; Source[i] = xexpf(Source[i]) - eps; - Source[i] = std::max(ce + DetailBoost * (Source[i] - ue), 0.f); + Source[i] = ce + DetailBoost * (Source[i] - ue); } #else @@ -959,7 +959,7 @@ void EdgePreservingDecomposition::CompressDynamicRange(float *Source, float Scal float ce = xexpf(Source[i] + u[i] * (temp)) - eps; float ue = xexpf(u[i]) - eps; Source[i] = xexpf(Source[i]) - eps; - Source[i] = std::max(ce + DetailBoost * (Source[i] - ue), 0.f); + Source[i] = ce + DetailBoost * (Source[i] - ue); } #endif diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index aa5515e79..997589d91 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -5231,123 +5231,73 @@ void ImProcFunctions::EPDToneMapCIE (CieImage *ncie, float a_w, float c_, int Wi } -//Map tones by way of edge preserving decomposition. Is this the right way to include source? -//#include "EdgePreservingDecomposition.cc" -void ImProcFunctions::EPDToneMap (LabImage *lab, unsigned int Iterates, int skip) +//Map tones by way of edge preserving decomposition. +void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip) { - //Hasten access to the parameters. -// EPDParams *p = (EPDParams *)(¶ms->epd); - //Enabled? Leave now if not. -// if(!p->enabled) return; if (!params->epd.enabled) { return; } -/* - if (params->wavelet.enabled && params->wavelet.tmrs != 0) { - return; - } -*/ - float stren = params->epd.strength; - float edgest = params->epd.edgeStopping; - float sca = params->epd.scale; - float gamm = params->epd.gamma; - float rew = params->epd.reweightingIterates; + + const float stren = params->epd.strength; + const float edgest = params->epd.edgeStopping; + const float sca = params->epd.scale; + const float gamm = params->epd.gamma; + const float rew = params->epd.reweightingIterates; //Pointers to whole data and size of it. float *L = lab->L[0]; float *a = lab->a[0]; float *b = lab->b[0]; - size_t N = lab->W * lab->H; - EdgePreservingDecomposition epd (lab->W, lab->H); + const size_t N = lab->W * lab->H; + + EdgePreservingDecomposition epd(lab->W, lab->H); //Due to the taking of logarithms, L must be nonnegative. Further, scale to 0 to 1 using nominal range of L, 0 to 15 bit. - float minL = FLT_MAX; - float maxL = 0.f; + float minL = L[0]; + float maxL = L[0]; #ifdef _OPENMP - #pragma omp parallel + #pragma omp parallel for reduction(min:minL) reduction(max:maxL) #endif - { - float lminL = FLT_MAX; - float lmaxL = 0.f; -#ifdef _OPENMP - #pragma omp for -#endif - - for (size_t i = 0; i < N; i++) { - if (L[i] < lminL) { - lminL = L[i]; - } - - if (L[i] > lmaxL) { - lmaxL = L[i]; - } - } - -#ifdef _OPENMP - #pragma omp critical -#endif - { - if (lminL < minL) { - minL = lminL; - } - - if (lmaxL > maxL) { - maxL = lmaxL; - } - } + for (size_t i = 1; i < N; i++) { + minL = std::min(minL, L[i]); + maxL = std::max(maxL, L[i]); } - if (minL > 0.0f) { - minL = 0.0f; //Disable the shift if there are no negative numbers. I wish there were just no negative numbers to begin with. + if (maxL == 0.f) { // black input => do nothing + return; } - if (maxL == 0.f) { // avoid division by zero - maxL = 1.f; - } + minL = std::min(minL, 0.f); //Disable the shift if there are no negative numbers. I wish there were just no negative numbers to begin with. #ifdef _OPENMP #pragma omp parallel for #endif - - for (size_t i = 0; i < N; ++i) - //{L[i] = (L[i] - minL)/32767.0f; - { - L[i] = (L[i] - minL) / maxL; - L[i] *= gamm; + for (size_t i = 0; i < N; ++i) { + L[i] = (L[i] - minL) * (gamm / maxL); } //Some interpretations. - float Compression = expf (-stren); //This modification turns numbers symmetric around 0 into exponents. - float DetailBoost = stren; - - if (stren < 0.0f) { - DetailBoost = 0.0f; //Go with effect of exponent only if uncompressing. - } + const float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents. + const float DetailBoost = std::max(stren, 0.f); //Go with effect of exponent only if uncompressing. //Auto select number of iterates. Note that p->EdgeStopping = 0 makes a Gaussian blur. if (Iterates == 0) { - Iterates = (unsigned int) (edgest * 15.0f); + Iterates = edgest * 15.f; } - /* Debuggery. Saves L for toying with outside of RT. - char nm[64]; - sprintf(nm, "%ux%ufloat.bin", lab->W, lab->H); - FILE *f = fopen(nm, "wb"); - fwrite(L, N, sizeof(float), f); - fclose(f);*/ - - epd.CompressDynamicRange (L, sca / float (skip), edgest, Compression, DetailBoost, Iterates, rew); + epd.CompressDynamicRange (L, sca / skip, edgest, Compression, DetailBoost, Iterates, rew); //Restore past range, also desaturate a bit per Mantiuk's Color correction for tone mapping. - float s = (1.0f + 38.7889f) * powf (Compression, 1.5856f) / (1.0f + 38.7889f * powf (Compression, 1.5856f)); -#ifdef _OPENMP - #pragma omp parallel for // removed schedule(dynamic,10) -#endif + const float s = (1.f + 38.7889f) * std::pow(Compression, 1.5856f) / (1.f + 38.7889f * std::pow(Compression, 1.5856f)); + maxL /= gamm; +#ifdef _OPENMP + #pragma omp parallel for +#endif for (size_t ii = 0; ii < N; ++ii) { a[ii] *= s; b[ii] *= s; - L[ii] = L[ii] * maxL * (1.f / gamm) + minL; + L[ii] = std::min(std::max(L[ii] * maxL + minL, 0.0001f), 32768.f); } } From 11f81d2153407a805ede7bddaa75201e74bbb34f Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 14 Jun 2020 17:56:32 +0200 Subject: [PATCH 6/7] Try solution suggested by Jacques --- rtengine/improcfun.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 997589d91..ac0b96152 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -5240,7 +5240,7 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip) } const float stren = params->epd.strength; - const float edgest = params->epd.edgeStopping; + const float edgest = std::min(params->epd.edgeStopping, params->localContrast.enabled ? 3.2 : 4.0); const float sca = params->epd.scale; const float gamm = params->epd.gamma; const float rew = params->epd.reweightingIterates; @@ -5297,7 +5297,7 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip) for (size_t ii = 0; ii < N; ++ii) { a[ii] *= s; b[ii] *= s; - L[ii] = std::min(std::max(L[ii] * maxL + minL, 0.0001f), 32768.f); + L[ii] = L[ii] * maxL + minL; } } From 1ffae4c70603768b7db211d564057c8050eda23d Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 14 Jun 2020 18:26:59 +0200 Subject: [PATCH 7/7] Change max edge stopping to 3 when local contrast enabled --- rtengine/improcfun.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index ac0b96152..c17cabb43 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -5240,7 +5240,7 @@ void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip) } const float stren = params->epd.strength; - const float edgest = std::min(params->epd.edgeStopping, params->localContrast.enabled ? 3.2 : 4.0); + const float edgest = std::min(params->epd.edgeStopping, params->localContrast.enabled ? 3.0 : 4.0); const float sca = params->epd.scale; const float gamm = params->epd.gamma; const float rew = params->epd.reweightingIterates;