diff --git a/rtdata/languages/default b/rtdata/languages/default index 5026a80f7..b4dade718 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -833,11 +833,11 @@ HISTORY_MSG_580;Local - Denoise HISTORY_MSG_581;Local - deNoise lum f 1 HISTORY_MSG_582;Local - deNoise lum c HISTORY_MSG_583;Local - deNoise lum detail -HISTORY_MSG_584;Local - deNoise Equalizer white-black +HISTORY_MSG_584;Local - deNoise equalizer White-Black HISTORY_MSG_585;Local - deNoise chro f HISTORY_MSG_586;Local - deNoise chro c HISTORY_MSG_587;Local - deNoise chro detail -HISTORY_MSG_588;Local - deNoise Equalizer blue-red +HISTORY_MSG_588;Local - deNoise equalizer Blue-Red HISTORY_MSG_589;Local - deNoise bilateral HISTORY_MSG_590;Local - deNoise Scope HISTORY_MSG_591;Local - Avoid color shift @@ -1288,18 +1288,35 @@ HISTORY_MSG_WAVBL;Blur levels HISTORY_MSG_WAVCHROMCO;Chroma coarse HISTORY_MSG_WAVCHROMFI;Chroma fine HISTORY_MSG_WAVCLARI;Clarity +HISTORY_MSG_WAVDENLH;Level 5 +HISTORY_MSG_WAVDENOISE;Local contrast +HISTORY_MSG_WAVDENOISEH;High levels Local contrast +HISTORY_MSG_WAVDENMET;Local equalizer +HISTORY_MSG_WAVDETEND;Details soft HISTORY_MSG_WAVEDGS;Edge stopping +HISTORY_MSG_WAVGUIDH;Local contrast-Hue equalizer +HISTORY_MSG_WAVHUE;Equalizer hue +HISTORY_MSG_WAVLEVDEN;High level local contrast +HISTORY_MSG_WAVLEVSIGM;Radius +HISTORY_MSG_WAVLIMDEN;Interaction 56 14 HISTORY_MSG_WAVLOWTHR;Threshold low contrast HISTORY_MSG_WAVMERGEC;Merge C HISTORY_MSG_WAVMERGEL;Merge L +HISTORY_MSG_WAVMIXMET;Reference local contrast HISTORY_MSG_WAVOFFSET;Offset HISTORY_MSG_WAVOLDSH;Old algorithm +HISTORY_MSG_WAVQUAMET;Denoise mode HISTORY_MSG_WAVRADIUS;Radius shadows-highlights HISTORY_MSG_WAVSCALE;Scale HISTORY_MSG_WAVSHOWMASK;Show wavelet mask HISTORY_MSG_WAVSIGMA;Attenuation response +HISTORY_MSG_WAVSIGM;Sigma HISTORY_MSG_WAVSOFTRAD;Soft radius clarity HISTORY_MSG_WAVSOFTRADEND;Soft radius final +HISTORY_MSG_WAVSLIMET;Method +HISTORY_MSG_WAVTHRDEN;Threshold local contrast +HISTORY_MSG_WAVTHREND;Threshold local contrast +HISTORY_MSG_WAVSTREND;Strength soft HISTORY_MSG_WAVUSHAMET;Clarity method HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s @@ -3259,8 +3276,8 @@ TP_WAVELET_BALANCE;Contrast balance d/v-h TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chroma or residual tone mapping are activated, the effect due to balance is amplified. TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the vertical, horizontal and diagonal wavelet directions: .\nActivating contrast, chroma or residual tone mapping amplifies the effect due to balance TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chroma balance. -TP_WAVELET_BALCHROM;Denoise equalizer blue-yellow red-green -TP_WAVELET_BALLUM;Denoise Equalizer White-Black +TP_WAVELET_BALCHROM;Denoise equalizer Blue-Yellow Red-Green +TP_WAVELET_BALLUM;Denoise equalizer White-Black TP_WAVELET_BANONE;None TP_WAVELET_BASLI;Slider TP_WAVELET_BATYPE;Contrast balance method @@ -3323,6 +3340,33 @@ TP_WAVELET_DAUB10;D10 - medium TP_WAVELET_DAUB14;D14 - high TP_WAVELET_DAUBLOCAL;Wavelet Edge performance TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the first levels. However the quality is not strictly related to this coefficient and can vary depending on image and use. +TP_WAVELET_DENOISE;Guide curve based on Local contrast +TP_WAVELET_DENOISEGUID;Guided threshold based on hue +TP_WAVELET_DENOISEH;High levels Curve Local contrast +TP_WAVELET_DENOISEHUE;Denoise equalizer Hue +TP_WAVELET_DENCONTRAST;Local contrast Equalizer +TP_WAVELET_DENEQUAL;1 2 3 4 Equal +TP_WAVELET_DEN14PLUS;1 4 High +TP_WAVELET_DEN14LOW;1 4 Low +TP_WAVELET_DEN12PLUS;1 2 High +TP_WAVELET_DEN12LOW;1 2 Low +TP_WAVELET_DEN5THR;Guided threshold +//TP_WAVELET_DENH;Low levels (1234)- Finest details +//TP_WAVELET_DENLH;Guided threshold by detail levels 1-4 +//TP_WAVELET_DENL;High levels - Coarsest details +TP_WAVELET_DENH;Threshold +TP_WAVELET_DENLH;Guided threshold by detail levels 1-4 +TP_WAVELET_DENL;Correction structure +TP_WAVELET_DENLOCAL_TOOLTIP;Use a curve in order to guide the denoising according to the local contrast.\nThe areas are denoised, the structures are maintained +TP_WAVELET_DENMIX_TOOLTIP;Balances the action of the guide taking into account the original image and the denoised image +TP_WAVELET_DENQUA;Mode +TP_WAVELET_DENSLILAB;Method +TP_WAVELET_DENSLI;Slider +TP_WAVELET_DENCURV;Curve +TP_WAVELET_DENSIGMA_TOOLTIP;Adapts the shape of the guide +TP_WAVELET_DENWAVHUE_TOOLTIP;Amplify or reduce denoising depending on the color +TP_WAVELET_DENWAVGUID_TOOLTIP;Uses hue to reduce or increase the action of the guided filter +TP_WAVELET_DETEND;Details TP_WAVELET_DIRFRAME;Directional contrast TP_WAVELET_DONE;Vertical TP_WAVELET_DTHR;Diagonal @@ -3352,6 +3396,8 @@ TP_WAVELET_FINAL;Final Touchup TP_WAVELET_FINCFRAME;Final local contrast TP_WAVELET_FINCOAR_TOOLTIP;The left (positive) part of the curve acts on the finer levels (increase).\nThe 2 points on the abscissa represent the respective action limits of finer and coarser levels 5 and 6 (default).\nThe right (negative) part of the curve acts on the coarser levels (increase).\nAvoid moving the left part of the curve with negative values. Avoid moving the right part of the curve with positives values TP_WAVELET_FINEST;Finest +TP_WAVELET_FINTHR_TOOLTIP;Uses local contrast to reduce or increase the action of the guided filter +TP_WAVELET_GUIDFRAME;Final smoothing (guided filter) TP_WAVELET_HIGHLIGHT;Finer levels luminance range TP_WAVELET_HS1;Whole luminance range TP_WAVELET_HS2;Selective luminance range @@ -3364,18 +3410,24 @@ TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight TP_WAVELET_LABEL;Wavelet Levels TP_WAVELET_LARGEST;Coarsest TP_WAVELET_LEVCH;Chroma +TP_WAVELET_LEVDEN;Level 5-6 denoise TP_WAVELET_LEVDIR_ALL;All levels, in all directions TP_WAVELET_LEVDIR_INF;Finer detail levels, including selected level TP_WAVELET_LEVDIR_ONE;One level TP_WAVELET_LEVDIR_SUP;Coarser detail levels, excluding selected level TP_WAVELET_LEVELS;Wavelet levels +TP_WAVELET_LEVELLOW;Radius 1-4 +TP_WAVELET_LEVELHIGH;Radius 5-6 +TP_WAVELET_LEVELSIGM;Radius TP_WAVELET_LEVELS_TOOLTIP;Choose the number of wavelet decomposition levels for the image.\nMore levels require more RAM and require a longer processing time. TP_WAVELET_LEVF;Contrast TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +TP_WAVELET_LEVFOUR;Level 5-6 denoise and guided threshold TP_WAVELET_LEVONE;Level 2 TP_WAVELET_LEVTHRE;Level 4 TP_WAVELET_LEVTWO;Level 3 TP_WAVELET_LEVZERO;Level 1 +TP_WAVELET_LIMDEN;Interaction levels 56 on levels 14 TP_WAVELET_LINKEDG;Link to Edge Sharpness Strength TP_WAVELET_LIPST;Enhanced algoritm TP_WAVELET_LOWLIGHT;Coarser levels luminance range @@ -3387,9 +3439,14 @@ TP_WAVELET_MEDILEV_TOOLTIP;When you enable Edge Detection, it is recommanded:\n- TP_WAVELET_MERGEC;Merge chroma TP_WAVELET_MERGEL;Merge Luma TP_WAVELET_NEUTRAL;Neutral +TP_WAVELET_MIXCONTRAST;Reference local contrast +TP_WAVELET_MIXDENOISE;Denoise +TP_WAVELET_MIXNOISE;Noise +TP_WAVELET_MIXMIX;Mixed 50% noise - 50% denoise +TP_WAVELET_MIXMIX70;Mixed 30% noise - 70% denoise TP_WAVELET_NOIS;Denoise TP_WAVELET_NOISE;Denoise and Refine -TP_WAVELET_NOISE_TOOLTIP;If level 4 luminance denoise superior to 20, mode Agressive is used.\nIf chrominance coarse superior to 20, mode Agressive is used. +TP_WAVELET_NOISE_TOOLTIP;If level 4 luminance denoise superior to 50, mode Agressive is used.\nIf chrominance coarse superior to 20, mode Agressive is used. TP_WAVELET_NPHIGH;High TP_WAVELET_NPLOW;Low TP_WAVELET_NPNONE;None @@ -3404,6 +3461,8 @@ TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the w TP_WAVELET_PASTEL;Pastel chroma TP_WAVELET_PROC;Process TP_WAVELET_PROTAB;Protection +TP_WAVELET_QUAAGRES;Agressive +TP_WAVELET_QUACONSER;Conservative TP_WAVELET_RADIUS;Radius shadows - highlight TP_WAVELET_RANGEAB;Range a and b % TP_WAVELET_RE1;Reinforced @@ -3422,6 +3481,7 @@ TP_WAVELET_SHA;Sharp mask TP_WAVELET_SHFRAME;Shadows/Highlights TP_WAVELET_SHOWMASK;Show wavelet 'mask' TP_WAVELET_SIGMA;Attenuation response +TP_WAVELET_SIGM;Radius TP_WAVELET_SIGMAFIN;Attenuation response TP_WAVELET_SIGMA_TOOLTIP;The effect of the contrast sliders is stronger in medium contrast details, and weaker in high and low contrast details.\n With this slider you can control how quickly the effect dampens towards the extreme contrasts.\n The higher the slider is set, the wider the range of contrasts which will get a strong change, and the higher the risk to generate artifacts.\n .The lower it is, the more the effect will be pinpointed towards a narrow range of contrast values TP_WAVELET_SKIN;Skin targetting/protection @@ -3430,9 +3490,13 @@ TP_WAVELET_SKY;Hue targetting/protection TP_WAVELET_SKY_TOOLTIP;Allows you to target or protect a range of hues.\nAt -100 selected hues are targetted.\nAt 0 all hues are treated equally.\nAt +100 selected hues are protected while all other hues are targetted. TP_WAVELET_SOFTRAD;Soft radius TP_WAVELET_STREN;Refine +TP_WAVELET_STREND;Strength TP_WAVELET_STRENGTH;Strength TP_WAVELET_SUPE;Extra TP_WAVELET_THR;Shadows threshold +TP_WAVELET_THREND;Local contrast threshold +TP_WAVELET_THRDEN_TOOLTIP;Generates a stepped curve in order to guide the denoising according to the local contrast.\nThe areas are denoised, the structures are maintained +TP_WAVELET_THRDEN_TOOLTIP;Generates a stepped denoise curve based on local contrast.\nReduces noise in uniform areas and preserves image structure TP_WAVELET_THRESHOLD;Finer levels TP_WAVELET_THRESHOLD2;Coarser levels TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels from the chosen value to the selected number of ‘wavelet levels’ will be affected by the Shadow luminance range. diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index a2929acbb..d43fa6baa 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -2099,12 +2099,12 @@ float ImProcFunctions::Mad(const float * DataList, const int datalen) } //computes Median Absolute Deviation - //DataList values should mostly have abs val < 256 because we are in Lab mode - int histo[256] ALIGNED64 = {0}; + //DataList values should mostly have abs val < 256 because we are in Lab mode (32768) + int histo[32768] ALIGNED64 = {0}; //calculate histogram of absolute values of wavelet coeffs for (int i = 0; i < datalen; ++i) { - histo[static_cast(rtengine::min(255.f, fabsf(DataList[i])))]++; + histo[static_cast(rtengine::min(32768.f, fabsf(DataList[i])))]++; } //find median of histogram @@ -2196,6 +2196,10 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition& Wavelet maxlvl = 4; //for refine denoise edge wavelet } + if (edge == 6) { + maxlvl = 6; //for wavelet denoise + } + if (edge == 2) { maxlvl = 7; //for locallab denoise } @@ -2264,7 +2268,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition& Wavelet for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) { nvl[i] = 0.f; } - if ((edge == 1 || edge == 2 || edge == 3 || edge == 5) && vari) { + if ((edge == 1 || edge == 2 || edge == 3 || edge == 5 || edge == 6) && vari) { // nvl = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer if ((edge == 1 || edge == 3)) { for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) { @@ -2272,7 +2276,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition& Wavelet } } - if (edge == 2 || edge == 4 || edge == 5) { + if (edge == 2 || edge == 4 || edge == 5 || edge == 6) { for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) { nvl[i] = vari[lvl] * SQR(noisevarlum[i]); } @@ -2550,6 +2554,10 @@ bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition& WaveletCoeffs_L, maxlvl = 4; //for refine denoise edge wavelet } + if (edge == 6) { + maxlvl = 6; //for wavelet denoise + } + if (edge == 2) { maxlvl = 7; //for locallab denoise } @@ -2565,7 +2573,6 @@ bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition& WaveletCoeffs_L, maxHL = WaveletCoeffs_L.level_H(lvl); } } - bool memoryAllocationFailed = false; #ifdef _OPENMP #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) @@ -2690,15 +2697,15 @@ void ImProcFunctions::ShrinkAllL(wavelet_decomposition& WaveletCoeffs_L, float * nvl[i] = 0.f; } - if ((edge == 1 || edge == 2 || edge == 3 || edge == 5) && vari) { + if ((edge == 1 || edge == 2 || edge == 3 || edge == 5 || edge == 6) && vari) { // nvl = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer if ((edge == 1 || edge == 3)) { for (int i = 0; i < W_L * H_L; ++i) { nvl[i] = vari[level]; //* SQR(1.f + 4.f * noisevarchrom[p]); } - } + } - if (edge == 2 || edge == 4 || edge == 5) { + if (edge == 2 || edge == 4 || edge == 5 || edge == 6) { for (int i = 0; i < W_L * H_L; ++i) { nvl[i] = vari[level] * SQR(noisevarlum[i]); } diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index c89d2bdb0..0d191c087 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1231,6 +1231,8 @@ void Crop::update(int todo) } WavCurve wavCLVCurve; + WavCurve wavdenoise; + WavCurve wavdenoiseh; Wavblcurve wavblcurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveSH waOpacityCurveSH; @@ -1240,7 +1242,7 @@ void Crop::update(int todo) LUTf wavclCurve; - params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + params.wavelet.getCurves(wavCLVCurve, wavdenoise, wavdenoiseh, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); LabImage *unshar = nullptr; Glib::ustring provis; LabImage *provradius = nullptr; @@ -1267,7 +1269,7 @@ void Crop::update(int todo) provis = params.wavelet.CLmethod; params.wavelet.CLmethod = "all"; - parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); + parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavdenoise, wavdenoiseh, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); unshar = new LabImage(*labnCrop, true); params.wavelet.CLmethod = provis; @@ -1284,7 +1286,7 @@ void Crop::update(int todo) // parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); - parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); + parent->ipf.ip_wavelet(labnCrop, labnCrop, kall, WaveParams, wavCLVCurve, wavdenoise, wavdenoiseh, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, parent->wavclCurve, skip); if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { WaveParams.expcontrast = procont; @@ -1406,6 +1408,7 @@ void Crop::update(int todo) } + } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index fc9d215b7..a538391c4 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1277,7 +1277,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if ((params->wavelet.enabled)) { WaveletParams WaveParams = params->wavelet; - WaveParams.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + WaveParams.getCurves(wavCLVCurve, wavdenoise, wavdenoiseh, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); int kall = 0; LabImage *unshar = nullptr; Glib::ustring provis; @@ -1301,7 +1301,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { provis = params->wavelet.CLmethod; params->wavelet.CLmethod = "all"; - ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); + ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavdenoise, wavdenoiseh, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); unshar = new LabImage(*nprevl, true); params->wavelet.CLmethod = provis; @@ -1314,7 +1314,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) WaveParams.expnoise = false; } - ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); + ipf.ip_wavelet(nprevl, nprevl, kall, WaveParams, wavCLVCurve, wavdenoise, wavdenoiseh, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, scale); if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { @@ -1435,6 +1435,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) delete unshar; unshar = NULL; + + /* if (WaveParams.softrad > 0.f) { array2D ble(pW, pH); diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index ab57a4419..d90ee68ae 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -139,6 +139,8 @@ protected: NoiseCurve noiseLCurve; NoiseCurve noiseCCurve; WavCurve wavCLVCurve; + WavCurve wavdenoise; + WavCurve wavdenoiseh; Wavblcurve wavblcurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveSH waOpacityCurveSH; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index a702dfbd8..d3ee81701 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -368,7 +368,7 @@ public: //Wavelet and denoise 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 ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavCurve & wavdenoise, WavCurve & wavdenoiseh, 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, 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); diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 21fffb76c..8ab63c940 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -80,7 +80,7 @@ struct cont_params { float b_lsl, t_lsl, b_rsl, t_rsl; float b_lhl, t_lhl, b_rhl, t_rhl; float edg_low, edg_mean, edg_sd, edg_max; - float lev0s, lev0n, lev1s, lev1n, lev2s, lev2n, lev3s, lev3n; + float lev0s, lev0n, lev1s, lev1n, lev2s, lev2n, lev3s, lev3n, lev4n, lev4t; float b_lpast, t_lpast, b_rpast, t_rpast; float b_lsat, t_lsat, b_rsat, t_rsat; int rad; @@ -96,6 +96,8 @@ struct cont_params { bool opaRG; bool edgcurv; bool diagcurv; + bool denoicurv; + bool denoicurvh; int CHmet; int CHSLmet; int EDmet; @@ -118,6 +120,10 @@ struct cont_params { float sigmaton; float sigmacol; float sigmadir; + int denmet; + int mixmet; + int quamet; + int slimet; int ite; int contmet; bool opaW; @@ -160,6 +166,13 @@ struct cont_params { float b_low; float rangeab; float protab; + float sigmm; + float sigmm14; + float sigmm56; + float levden; + float thrden; + float limden; + int complex; }; int wavNestedLevels = 1; @@ -200,7 +213,7 @@ std::unique_ptr ImProcFunctions::buildMeaLut(const float inVals[11], const return std::unique_ptr(new LUTf(lutVals)); } -void ImProcFunctions::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 ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavCurve & wavdenoise, WavCurve & wavdenoiseh, const Wavblcurve & wavblcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveSH & waOpacityCurveSH, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, const LUTf &wavclCurve, int skip) { @@ -211,11 +224,43 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const {wiprof[2][0], wiprof[2][1], wiprof[2][2]} }; const int imheight = lab->H, imwidth = lab->W; + int levwavL; + //Flat curve for H=f(H) in final touchup for guidedfilter + FlatCurve* wavguidCurve = new FlatCurve(params->wavelet.wavguidcurve); //curve H=f(H) + bool wavguidutili = false; + + if (!wavguidCurve || wavguidCurve->isIdentity()) { + if (wavguidCurve) { + delete wavguidCurve; + wavguidCurve = nullptr; + } + } else { + wavguidutili = true; + } +//flat curve for equalizer H + FlatCurve* wavhueCurve = new FlatCurve(params->wavelet.wavhuecurve); //curve H=f(H) + bool wavhueutili = false; + + if (!wavhueCurve || wavhueCurve->isIdentity()) { + if (wavhueCurve) { + delete wavhueCurve; + wavhueCurve = nullptr; + } + } else { + wavhueutili = true; + } struct cont_params cp; cp.avoi = params->wavelet.avoid; + if (params->wavelet.complexmethod == "normal") { + cp.complex = 0; + } else if (params->wavelet.complexmethod == "expert") { + cp.complex = 1; + } + + if (params->wavelet.Medgreinf == "more") { cp.reinforce = 1; } else if (params->wavelet.Medgreinf == "none") { @@ -244,6 +289,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.sigmaton = params->wavelet.sigmaton; cp.sigmacol = params->wavelet.sigmacol; cp.sigmadir = params->wavelet.sigmadir; + cp.sigmm = params->wavelet.sigm; + cp.levden = params->wavelet.levden; + cp.thrden = 0.01f * params->wavelet.thrden; + cp.limden = params->wavelet.limden; if (params->wavelet.TMmethod == "cont") { cp.contmet = 1; @@ -251,6 +300,41 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.contmet = 2; } + + if (params->wavelet.denmethod == "equ") { + cp.denmet = 0; + } else if (params->wavelet.denmethod == "high") { + cp.denmet = 1; + } else if (params->wavelet.denmethod == "low") { + cp.denmet = 2; + } else if (params->wavelet.denmethod == "12high") { + cp.denmet = 3; + } else if (params->wavelet.denmethod == "12low") { + cp.denmet = 4; + } + + if (params->wavelet.mixmethod == "nois") { + cp.mixmet = 0; + } else if (params->wavelet.mixmethod == "mix") { + cp.mixmet = 1; + } else if (params->wavelet.mixmethod == "mix7") { + cp.mixmet = 2; + } else if (params->wavelet.mixmethod == "den") { + cp.mixmet = 3; + } + + if (params->wavelet.quamethod == "cons") { + cp.quamet = 0; + } else if (params->wavelet.quamethod == "agre") { + cp.quamet = 1; + } + + if (params->wavelet.slimethod == "sli") { + cp.slimet = 0; + } else if (params->wavelet.slimethod == "cur") { + cp.slimet = 1; + } + if (params->wavelet.BAmethod != "none") { cp.bam = true; @@ -341,6 +425,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.curv = false; cp.edgcurv = false; cp.diagcurv = false; + cp.denoicurv = false; + cp.denoicurvh = false; cp.opaRG = false; cp.opaBY = false; cp.opaW = false; @@ -425,6 +511,28 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.diagcurv = true; } + if (wavdenoise) { + for (int i = 0; i < 500; i++) { + if (wavdenoise[i] != 1.0) { + cp.denoicurv = true; + break; + } + } + } + + if(cp.complex == 0) { + wavdenoiseh = wavdenoise; + } + + if (wavdenoiseh) { + for (int i = 0; i < 500; i++) { + if (wavdenoiseh[i] != 1.0) { + cp.denoicurvh = true; + break; + } + } + } + for (int m = 0; m < maxmul; m++) { cp.mul[m] = waparams.c[m]; } @@ -531,6 +639,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.lev2n = static_cast(params->wavelet.level2noise.getTop()); cp.lev3s = static_cast(params->wavelet.level3noise.getBottom()); cp.lev3n = static_cast(params->wavelet.level3noise.getTop()); + cp.lev4n = static_cast(params->wavelet.leveldenoise.getTop()); + cp.lev4t = 0.01f * static_cast(params->wavelet.leveldenoise.getBottom()); + cp.sigmm14 = static_cast(params->wavelet.levelsigm.getTop()); + cp.sigmm56 = static_cast(params->wavelet.levelsigm.getBottom()); cp.detectedge = params->wavelet.medianlev; int minwin = rtengine::min(imwidth, imheight); @@ -561,8 +673,11 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const maxlevelcrop = 5; } - + int levwav = params->wavelet.thres; + if(params->wavelet.expnoise) { + levwav = 6; + } if (levwav == 9 && cp.mul[9] != 0) { levwav = 10; @@ -714,6 +829,12 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const float sigmaN[10]; float MaxP[10]; float MaxN[10]; + float meand[10]; + float meanNd[10]; + float sigmad[10]; + float sigmaNd[10]; + float MaxPd[10]; + float MaxNd[10]; float meanab[10]; float meanNab[10]; @@ -877,7 +998,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const int datalen = labco->W * labco->H; - int levwavL = levwav; + levwavL = levwav; bool ref0 = false; if ((cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f || cp.lev3s > 0.f) && cp.noiseena) { @@ -914,8 +1035,17 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } - if (levwavL < 4) { - levwavL = 4; //to allow edge => I always allocate 3 (4) levels..because if user select wavelet it is to do something !! + if (levwavL < 5 && cp.noiseena) { + levwavL = 6; //to allow edge and denoise => I always allocate 3 (4) levels..because if user select wavelet it is to do something !! + } +/* + if(cp.denoicurvh || cp.levdenhigh > 0.01f) { + levwavL = levwav; + } +*/ + float th = 0.01f * (float) waparams.thrend; + if(th > 0.f) { + levwavL = levwav; } if (settings->verbose) { @@ -926,6 +1056,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)); + // const std::unique_ptr Ldecomp2(new wavelet_decomposition(labco->data, labco->W, labco->H, levwavL, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!Ldecomp->memory_allocation_failed()) { float madL[10][3]; @@ -945,7 +1076,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const madL[lvl][dir - 1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); if (settings->verbose) { - printf("sqrt madL=%f lvl=%i dir=%i\n", sqrt(madL[lvl][dir - 1]), lvl, dir - 1); + printf("Luminance noise estimate (sqr) madL=%.0f lvl=%i dir=%i\n", madL[lvl][dir - 1], lvl, dir - 1); } } } @@ -954,6 +1085,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if ((cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f || cp.lev3s > 0.f) && cp.noiseena) { ref = true; + } bool contr = false; @@ -964,82 +1096,372 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } - if (cp.val > 0 || ref || contr) { //edge - Evaluate2(*Ldecomp, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavNestedLevels); + // if (cp.val > 0 || ref || contr || cp.denoicurv || cp.denoicurvh || cp.noiseena || cp.levdenlow > 0.f || cp.thrden > 0.f ) { //edge + if (cp.val > 0 || ref || contr || cp.denoicurv || cp.denoicurvh || cp.noiseena || cp.thrden > 0.f ) { //edge + Evaluate2(*Ldecomp, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavNestedLevels); } //init for edge and denoise - float vari[4]; + float vari[6]; vari[0] = 0.8f * SQR((cp.lev0n / 125.f) * (1.f + cp.lev0n / 25.f)); vari[1] = 0.8f * SQR((cp.lev1n / 125.f) * (1.f + cp.lev1n / 25.f)); vari[2] = 0.8f * SQR((cp.lev2n / 125.f) * (1.f + cp.lev2n / 25.f)); vari[3] = 0.8f * SQR((cp.lev3n / 125.f) * (1.f + cp.lev3n / 25.f)); + vari[4] = 0.8f * SQR((cp.lev4n / 125.f) * (1.f + cp.lev4n / 25.f)); + vari[5] = 0.8f * SQR((cp.lev4n / 125.f) * (1.f + cp.lev4n / 25.f)); float kr3 = 1.f; if (cp.lev3n < 10.f) { - kr3 = 0.f; + kr3 = 0.3f; } else if (cp.lev3n < 30.f) { - kr3 = 0.5f; + kr3 = 0.6f; } else if (cp.lev3n < 70.f) { - kr3 = 0.7f; + kr3 = 0.8f; } else { kr3 = 1.f; } - if ((cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f || cp.lev3n > 0.1f) && cp.noiseena) { - int edge = 5; + float kr4 = 1.f; + + if (cp.lev4n < 10.f) { + kr4 = 0.6f; + } else if (cp.lev4n < 30.f) { + kr4 = 0.8f; + } else if (cp.lev4n < 70.f) { + kr4 = 0.9f; + } else { + kr4 = 1.f; + } + + if ((cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f || cp.lev3n > 0.1f || cp.lev4n > 0.1f) && cp.noiseena) { + int edge = 6; vari[0] = rtengine::max(0.000001f, vari[0]); vari[1] = rtengine::max(0.000001f, vari[1]); vari[2] = rtengine::max(0.000001f, vari[2]); vari[3] = rtengine::max(0.000001f, kr3 * vari[3]); - - if (settings->verbose) { - printf("LUM var0=%f var1=%f var2=%f var3=%f\n", vari[0], vari[1], vari[2], vari[3]); - } + vari[4] = rtengine::max(0.000001f, kr4 * vari[4]); + vari[5] = rtengine::max(0.000001f, kr4 * vari[5]); + + const std::unique_ptr Ldecomp2(new wavelet_decomposition(labco->data, labco->W, labco->H, levwavL, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + if(!Ldecomp2->memory_allocation_failed()){ + if (settings->verbose) { + printf("LUM var0=%f var1=%f var2=%f var3=%f var4=%f\n", vari[0], vari[1], vari[2], vari[3], vari[4]); + } // float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL - int GWL = labco->W; - int GHL = labco->H; - float* noisevarlum = new float[GHL * GWL]; - int GW2L = (GWL + 1) / 2; + int GWL = labco->W; + int GHL = labco->H; + float* noisevarlum = new float[GHL * GWL]; + float* noisevarhue = new float[GHL * GWL]; + int GW2L = (GWL + 1) / 2; - float nvlh[13] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 0.7f, 0.5f}; //high value - float nvll[13] = {0.1f, 0.15f, 0.2f, 0.25f, 0.3f, 0.35f, 0.4f, 0.45f, 0.7f, 0.8f, 1.f, 1.f, 1.f}; //low value + float nvlh[13] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 0.7f, 0.5f}; //high value + float nvll[13] = {0.1f, 0.15f, 0.2f, 0.25f, 0.3f, 0.35f, 0.4f, 0.45f, 0.7f, 0.8f, 1.f, 1.f, 1.f}; //low value - float seuillow = 3000.f;//low - float seuilhigh = 18000.f;//high - int i = 10 - cp.ballum; - float ac = (nvlh[i] - nvll[i]) / (seuillow - seuilhigh); - float bc = nvlh[i] - seuillow * ac; + float seuillow = 3000.f;//low + float seuilhigh = 18000.f;//high + int i = 10 - cp.ballum; + float ac = (nvlh[i] - nvll[i]) / (seuillow - seuilhigh); + float bc = nvlh[i] - seuillow * ac; #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for #endif - for (int ir = 0; ir < GHL; ir++) - for (int jr = 0; jr < GWL; jr++) { - float lN = labco->L[ir][jr]; + for (int ir = 0; ir < GHL; ir++) + for (int jr = 0; jr < GWL; jr++) { + float lN = labco->L[ir][jr]; - if (lN < seuillow) { - noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvlh[i]; - } else if (lN < seuilhigh) { - noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = ac * lN + bc; - } else { - noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvll[i]; + if (lN < seuillow) { + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvlh[i]; + } else if (lN < seuilhigh) { + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = ac * lN + bc; + } else { + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvll[i]; + } } + + if(wavhueutili) { +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int ir = 0; ir < GHL; ir++) + for (int jr = 0; jr < GWL; jr++) { + float hueG = xatan2f(labco->b[ir][jr], labco->a[ir][jr]); + noisevarhue[(ir >> 1)*GW2L + (jr >> 1)] = 1.f + 2.f * (static_cast(wavhueCurve->getVal(Color::huelab_to_huehsv2(hueG))) - 0.5f); + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] *= noisevarhue[(ir >> 1)*GW2L + (jr >> 1)]; + } } - if (cp.lev3n < 20.f) { - WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1); - } else { - WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL, vari, edge, 1); + - WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1); + + if(cp.quamet == 0) { + if (settings->verbose) { + printf("denoise standard\n"); + } + WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1); + } else { + if (settings->verbose) { + printf("denoise bishrink\n"); + } + WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL, vari, edge, 1); + + WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1); + } + delete[] noisevarlum; + + //evaluate after denoise + Evaluate2(*Ldecomp, meand, meanNd, sigmad, sigmaNd, MaxPd, MaxNd, wavNestedLevels); + //for level 0 1 2 3 + float thr = 0.f; + float thrend = cp.thrden; //cp.levdenlow; + if(thrend < 0.02f) thr = 0.5f; + else if(thrend < 0.05f) thr = 0.2f; + else thr = 0.f; + + FlatCurve wavlow({ + FCT_MinMaxCPoints, + 0, 1, 0.35, 0.35,thrend, 1.0, 0.35, 0.35, thrend + 0.01f, thr, 0.35, 0.35, 1, thr, 0.35, 0.35 + }); + //for level 4 + float thrhigh = 0.f; + float threndhigh = cp.lev4t; //cp.levdenlow; + if(threndhigh < 0.02f) thrhigh = 0.5f; + else if(threndhigh < 0.05f) thrhigh = 0.2f; + else thrhigh = 0.f; + + FlatCurve wavhigh({ + FCT_MinMaxCPoints, + 0, 1, 0.35, 0.35,threndhigh, 1.0, 0.35, 0.35, threndhigh + 0.01f, thrhigh, 0.35, 0.35, 1, thrhigh, 0.35, 0.35 + }); + + float thrmed = 0.f; + float threndmed = 1.f - cp.limden; + if(threndmed < 0.02f) thrmed = 0.5f; + else if(threndmed < 0.05f) thrmed = 0.2f; + else thrmed = 0.f; + + FlatCurve wavmed({ + FCT_MinMaxCPoints, + 0, 1, 0.35, 0.35,threndmed, 1.0, 0.35, 0.35, threndmed + 0.01f, thrmed, 0.35, 0.35, 1, thrmed, 0.35, 0.35 + }); + + float siglh[10]; + float levref = 6; + //levref = levwavL-1; + if(cp.complex == 1){ + for (int level = 0; level < levref; level++) { + if(level > 3) { + siglh[level] = cp.sigmm56; + } else { + siglh[level] = cp.sigmm14; + } + } + } else { + levref = 4; + for (int level = 0; level < levref; level++) { + siglh[level] = cp.sigmm; + } + } + +// printf("sig0=%f sig1=%f sig2=%f sig3=%f sig4=%f sig5=%f\n", siglh[0], siglh[1],siglh[2],siglh[3],siglh[4],siglh[5]); + + + bool execut = false; + + if(cp.slimet == 0) { + // if(cp.levdenlow > 0.f) { + if(cp.thrden > 0.f) { + execut = true; + } + } else { + if(cp.denoicurv) { + execut = true; + } + } + // } + if (execut) { + for (int dir = 1; dir < 4; dir++) { + for (int level = 0; level < levref; level++) { + int Wlvl_L = Ldecomp->level_W(level); + int Hlvl_L = Ldecomp->level_H(level); + float* const* WavCoeffs_L = Ldecomp->level_coeffs(level);//first decomp denoised + float* const* WavCoeffs_L2 = Ldecomp2->level_coeffs(level);//second decomp before denoise + int k4 = 3; + int k5 = 3; + if(cp.complex == 1){ + k4= 4; + k5= 5; + } + auto WavL0 = Ldecomp->level_coeffs(0)[dir]; + auto WavL1 = Ldecomp->level_coeffs(1)[dir]; + auto WavL2 = Ldecomp->level_coeffs(2)[dir]; + auto WavL3 = Ldecomp->level_coeffs(3)[dir]; + auto WavL4 = Ldecomp->level_coeffs(k4)[dir]; + auto WavL5 = Ldecomp->level_coeffs(k5)[dir]; + //not denoise + const auto WavL02 = Ldecomp2->level_coeffs(0)[dir]; + const auto WavL12 = Ldecomp2->level_coeffs(1)[dir]; + const auto WavL22 = Ldecomp2->level_coeffs(2)[dir]; + const auto WavL32 = Ldecomp2->level_coeffs(3)[dir]; + const auto WavL42 = Ldecomp2->level_coeffs(k4)[dir]; + const auto WavL52 = Ldecomp2->level_coeffs(k5)[dir]; + if (settings->verbose) { + printf("level=%i mean=%.0f meanden=%.0f sigma=%.0f sigmaden=%.0f Max=%.0f Maxden=%.0f\n", level, mean[level], meand[level], sigma[level], sigmad[level],MaxP[level], MaxPd[level]); + } + + //find local contrast + float tempmean = 0.f; + float tempsig = 0.f; + float tempmax = 0.f; + if(cp.mixmet == 0){ + tempmean = mean[level]; + tempsig = sigma[level]; + tempmax = MaxP[level]; + } else if(cp.mixmet == 1){ + tempmean = 0.5f * mean[level] + 0.5f * meand[level] ; + tempsig = 0.5f * sigma[level] + 0.5f * sigmad[level] ; + tempmax = 0.5f * MaxP[level] + 0.5f * MaxPd[level] ; + } else if(cp.mixmet == 2){ + tempmean = 0.3f * mean[level] + 0.7f * meand[level] ; + tempsig = 0.3f * sigma[level] + 0.7f * sigmad[level] ; + tempmax = 0.3f * MaxP[level] + 0.7f * MaxPd[level] ; + } else if(cp.mixmet == 3){ + tempmean = meand[level]; + tempsig = sigmad[level]; + tempmax = MaxPd[level]; + } + + if (MaxP[level] > 0.f && mean[level] != 0.f && sigma[level] != 0.f) { //curve + float insigma = 0.666f; //SD + float logmax = log(tempmax); //log Max + //cp.sigmm change the "wider" of sigma + float rapX = (tempmean + siglh[level] * tempsig) / (tempmax); //rapport between sD / max + float inx = log(insigma); + float iny = log(rapX); + float rap = inx / iny; //koef + float asig = 0.166f / (tempsig * siglh[level]); + float bsig = 0.5f - asig * tempmean; + float amean = 0.5f / (tempmean); + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, Wlvl_L * 16) num_threads(wavNestedLevels) if (wavNestedLevels>1) +#endif + + for (int i = 0; i < Wlvl_L * Hlvl_L; i++) { + float absciss; + float tempwav = 0.f; + if(cp.mixmet == 0){ + tempwav = WavCoeffs_L2[dir][i]; + } else if(cp.mixmet == 1){ + tempwav = 0.5f * WavCoeffs_L[dir][i] + 0.5f * WavCoeffs_L2[dir][i]; + } else if(cp.mixmet == 2){ + tempwav = 0.7f * WavCoeffs_L[dir][i] + 0.3f * WavCoeffs_L2[dir][i]; + } else if(cp.mixmet == 3){ + tempwav = WavCoeffs_L[dir][i]; + } + + if (std::fabs(tempwav) >= (tempmean + siglh[level] * tempsig)) { //for max + float valcour = xlogf(std::fabs(tempwav)); + float valc = valcour - logmax; + float vald = valc * rap; + absciss = xexpf(vald); + } else if (std::fabs(tempwav) >= tempmean) { + absciss = asig * std::fabs(tempwav) + bsig; + } else { + absciss = amean * std::fabs(tempwav); + float k = siglh[level]; + if(siglh[level] > 1.f) { + k = SQR(siglh[level]); + } + float abs = pow(2.f * absciss, (1.f / k)); + absciss = 0.5f * abs; + } + float kc = 0.f; + if(cp.slimet == 0) { + kc = wavlow.getVal(absciss) -1.f; + } else { + kc = wavdenoise[absciss * 500.f] - 1.f; + } + + float kchigh = 0.f; + kchigh = wavhigh.getVal(absciss) -1.f; + kchigh = -SQR(kchigh); + + float kcmed = 0.f; + kcmed = wavmed.getVal(absciss) -1.f; + kcmed = -SQR(kcmed); + + if(kc < 0) { + kc = -SQR(kc);//approximation to simulate sliders denoise + } + //equalizer for levels 0 1 and 3... 1.33 and 0.75 arbitrary values + if(cp.denmet == 1) { + if(level == 0 || level == 3) { + kc *= 1.7f; + } + } else if(cp.denmet == 2) { + if(level == 0 || level == 3) { + kc *= 0.3f; + } + } else if(cp.denmet == 3) { + if(level == 0 || level == 1) { + kc *= 1.7f; + } + } else if(cp.denmet == 4) { + if(level == 0 || level == 1) { + kc *= 0.3f; + } + } + + float reduceeffect = kc <= 0.f ? 1.f : 1.2f;//1.2 allows to increase denoise (not used) + + float kinterm = 1.f + reduceeffect * kc; + kinterm = kinterm <= 0.f ? 0.01f : kinterm; + + float kintermhigh = 1.f + reduceeffect * kchigh; + kintermhigh = kintermhigh <= 0.f ? 0.01f : kintermhigh; + + float kintermed = 1.f + reduceeffect * kcmed; + kintermed = kintermed <= 0.f ? 0.01f : kintermed; + + float kintermlow = kinterm; + if(level < 4) { + WavL0[i] = WavL02[i] + (WavL0[i] - WavL02[i]) * kintermlow; + WavL1[i] = WavL12[i] + (WavL1[i] - WavL12[i]) * kintermlow; + WavL2[i] = WavL22[i] + (WavL2[i] - WavL22[i]) * kintermlow; + WavL3[i] = WavL32[i] + (WavL3[i] - WavL32[i]) * kintermlow; + } + if(cp.complex == 1){ + if(cp.limden > 0.f) { + WavL0[i] = WavL02[i] + (WavL0[i] - WavL02[i]) * kintermed; + WavL1[i] = WavL12[i] + (WavL1[i] - WavL12[i]) * kintermed; + WavL2[i] = WavL22[i] + (WavL2[i] - WavL22[i]) * kintermed; + WavL3[i] = WavL32[i] + (WavL3[i] - WavL32[i]) * kintermed; + } + WavL4[i] = WavL42[i] + (WavL4[i] - WavL42[i]) * kintermhigh; + WavL5[i] = WavL52[i] + (WavL5[i] - WavL52[i]) * kintermhigh; + } + } + } + } + } + if (settings->verbose) { + Evaluate2(*Ldecomp, meand, meanNd, sigmad, sigmaNd, MaxPd, MaxNd, wavNestedLevels); + for (int dir = 1; dir < 4; dir++) { + for (int level = 0; level < levref; level++) { + printf("AFTER LC level=%i mean=%.0f meanden=%.0f sigma=%.0f sigmaden=%.0f Max=%.0f Maxden=%.0f\n", level, mean[level], meand[level], sigma[level], sigmad[level],MaxP[level], MaxPd[level]); + } + } + } + + } + delete[] noisevarhue; } - } - + } //Flat curve for Contrast=f(H) in levels FlatCurve* ChCurve = new FlatCurve(params->wavelet.Chcurve); //curve C=f(H) bool Chutili = false; @@ -1322,7 +1744,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, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memory_allocation_failed()) { - if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f )) { + if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.quamet == 0 )) { WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ @@ -1359,7 +1781,9 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const 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->memory_allocation_failed()) { - if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f )) { + // if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f )) { + if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.quamet == 0)) { + WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); @@ -1385,7 +1809,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const 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->memory_allocation_failed() && !bdecomp->memory_allocation_failed()) { - if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f)) { + if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.quamet == 0)) { WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); @@ -1394,7 +1818,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab, wavNestedLevels); WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); - if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.chromco < 2.f)) { + if (cp.noiseena && ((cp.chromfi > 0.f || cp.chromco > 0.f) && cp.quamet == 0)) { WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); } else if (cp.chromfi > 0.f && cp.chromco >= 2.f){ WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); @@ -1422,6 +1846,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (usechrom) { Ldecomp->reconstruct(labco->data, cp.strength); } + if (settings->verbose) { + printf("OK END\n"); + } + } } @@ -1626,8 +2054,30 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } if (waparams.softradend > 0.f && cp.finena) { - array2D ble(lab->W, lab->H); - array2D guid(lab->W, lab->H); + float guid = waparams.softradend; + float strend = waparams.strend; + float detend = (float) waparams.detend; + float thrend = 0.01f * (float) waparams.thrend; + int ww = lab->W; + int hh = lab->H; + array2D LL(ww, hh); + array2D LLbef(ww, hh); + array2D LAbef(ww, hh); + array2D LBbef(ww, hh); + array2D guide(ww, hh); + const float blend = LIM01(float(strend) / 100.f); + float mean[10]; + float meanN[10]; + float sigma[10]; + float sigmaN[10]; + float MaxP[10]; + float MaxN[10]; + float meang[10]; + float meanNg[10]; + float sigmag[10]; + float sigmaNg[10]; + float MaxPg[10]; + float MaxNg[10]; bool multiTh = false; @@ -1639,31 +2089,142 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const #pragma omp parallel for #endif - - for (int ir = 0; ir < lab->H; ir++) { - for (int jr = 0; jr < lab->W; jr++) { - guid[ir][jr] = Color::L2Y(lab->L[ir][jr]) / 32768.f; - ble[ir][jr] = Color::L2Y(dst->L[ir][jr]) / 32768.f; + for (int y = 0; y < hh; y++) { + for (int x = 0; x < ww; x++) { + LL[y][x] = dst->L[y][x]; + LLbef[y][x] = dst->L[y][x]; + LAbef[y][x] = dst->a[y][x]; + LBbef[y][x] = dst->b[y][x]; + float ll = LL[y][x] / 32768.f; + guide[y][x] = xlin2log(rtengine::max(ll, 0.f), 10.f); } } + array2D iL(ww, hh, LL, 0); + int r = rtengine::max(int(guid / skip), 1); - constexpr double epsilmax = 0.002; - constexpr double epsilmin = 0.0005; - constexpr double aepsil = 0.01f * (epsilmax - epsilmin); - constexpr double bepsil = epsilmin; - const double epsil = aepsil * waparams.softradend + bepsil; - - const float blur = 10.f / scale * (0.001f + 0.8f * waparams.softradend); - - rtengine::guidedFilter(guid, ble, ble, blur, epsil, multiTh); - + const float epsil = 0.001f * std::pow(2, - detend); + rtengine::guidedFilterLog(guide, 10.f, LL, r, epsil, multiTh); + //take Hue to modulate LL + //LL in function of LLbef and Labef Lbbef + if(wavguidutili) { #ifdef _OPENMP #pragma omp parallel for #endif + for (int y = 0; y < hh ; y++) { + for (int x = 0; x < ww; x++) { + float hueG = xatan2f(LBbef[y][x], LAbef[y][x]); + float valparam = 1.f * (static_cast(wavguidCurve->getVal(Color::huelab_to_huehsv2(hueG))) - 0.5f); + LL[y][x] = LLbef[y][x] + (LL[y][x] - LLbef[y][x]) * (1.f + valparam); + } + } + } + //end hue + +// printf("LEVWAV=%i\n", levwavL); + + if (thrend > 0.f) { + //2 decomposition LL after guidefilter and dst before (perhaps dst no need) + const std::unique_ptr LdecompLL(new wavelet_decomposition(LL[0], ww, hh, levwavL, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + const std::unique_ptr Ldecompdst(new wavelet_decomposition(dst->L[0], ww, hh, levwavL, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + if (!LdecompLL->memory_allocation_failed() && !Ldecompdst->memory_allocation_failed()) { - for (int ir = 0; ir < lab->H; ir++) { - for (int jr = 0; jr < lab->W; jr++) { - dst->L[ir][jr] = Color::computeXYZ2LabY(32768.f * ble[ir][jr]); + Evaluate2(*LdecompLL, meang, meanNg, sigmag, sigmaNg, MaxPg, MaxNg, wavNestedLevels); + Evaluate2(*Ldecompdst, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavNestedLevels); + float sig = 2.f; + float thr = 0.f; + if(thrend < 0.02f) thr = 0.5f; + else if(thrend < 0.1f) thr = 0.2f; + else thr = 0.f; + + FlatCurve wavguid({ + FCT_MinMaxCPoints, + 0, 1, 0.35, 0.35,thrend, 1.0, 0.35, 0.35, thrend + 0.01f, thr, 0.35, 0.35, 1, thr, 0.35, 0.35 + }); + + for (int dir = 1; dir < 4; dir++) { + for (int level = 0; level < levwavL-1; level++) { + int Wlvl_L = LdecompLL->level_W(level); + int Hlvl_L = LdecompLL->level_H(level); + float* const* WavCoeffs_L = LdecompLL->level_coeffs(level);//first decomp denoised + float* const* WavCoeffs_L2 = Ldecompdst->level_coeffs(level);//second decomp before denoise + if (settings->verbose) { + printf("level=%i mean=%.0f meanden=%.0f sigma=%.0f sigmaden=%.0f Max=%.0f Maxden=%.0f\n", level, mean[level], meang[level], sigma[level], sigmag[level],MaxP[level], MaxPg[level]); + } + + //find local contrast + float tempmean = 0.f; + float tempsig = 0.f; + float tempmax = 0.f; + tempmean = 0.3f * mean[level] + 0.7f * meang[level] ; + tempsig = 0.3f * sigma[level] + 0.7f * sigmag[level] ; + tempmax = 0.3f * MaxP[level] + 0.7f * MaxPg[level] ; + + if (MaxP[level] > 0.f && mean[level] != 0.f && sigma[level] != 0.f) { //curve + float insigma = 0.666f; //SD + float logmax = log(tempmax); //log Max + //cp.sigmm change the "wider" of sigma + float rapX = (tempmean + sig * tempsig) / (tempmax); //rapport between sD / max + float inx = log(insigma); + float iny = log(rapX); + float rap = inx / iny; //koef + float asig = 0.166f / (tempsig * sig); + float bsig = 0.5f - asig * tempmean; + float amean = 0.5f / (tempmean); + + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, Wlvl_L * 16) num_threads(wavNestedLevels) if (wavNestedLevels>1) +#endif + + for (int i = 0; i < Wlvl_L * Hlvl_L; i++) { + float absciss; + float tempwav = 0.f; + tempwav = 0.7f * WavCoeffs_L[dir][i] + 0.3f * WavCoeffs_L2[dir][i]; + + if (std::fabs(tempwav) >= (tempmean + sig * tempsig)) { //for max + float valcour = xlogf(std::fabs(tempwav)); + float valc = valcour - logmax; + float vald = valc * rap; + absciss = xexpf(vald); + } else if (std::fabs(tempwav) >= tempmean) { + absciss = asig * std::fabs(tempwav) + bsig; + } else { + absciss = amean * std::fabs(tempwav); + float k = sig; + if(sig > 1.f) { + k = SQR(sig); + } + float abs = pow(2.f * absciss, (1.f / k)); + absciss = 0.5f * abs; + } + float kc = wavguid.getVal(absciss) -1.f; + + if(kc < 0) { + kc = -SQR(kc);//approximation to simulate sliders denoise + } + float reduceeffect = kc <= 0.f ? 1.f : 1.2f;//1.2 allows to increase denoise (not used) + + float kinterm = 1.f + reduceeffect * kc; + kinterm = kinterm <= 0.f ? 0.01f : kinterm; + float prov = WavCoeffs_L2[dir][i];//save before denoise + WavCoeffs_L[dir][i] = prov + (WavCoeffs_L[dir][i] - prov) * kinterm;//only apply local contrast on difference between denoise and normal + } + } + } + } + LdecompLL->reconstruct(LL[0], cp.strength); + } + } + + + //end local contrast +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int y = 0; y < hh ; y++) { + for (int x = 0; x < ww; x++) { + LL[y][x] = intp(blend, LL[y][x] , iL[y][x]); + dst->L[y][x] = LL[y][x]; } } } @@ -2967,11 +3528,11 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float maxkoeLi, bool lipschitz, for (int sc = 0; sc < 10; sc++) { scaleskip[sc] = scales[sc] / skip; } - +/* if (settings->verbose) { printf("level=%i mean=%f sigma=%f maxp=%f\n", level, mean[level], sigma[level], MaxP[level]); } - +*/ constexpr float t_r = 40.f; constexpr float t_l = 10.f; constexpr float b_r = 75.f; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index d7ead7513..ab7924cd3 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2204,6 +2204,36 @@ WaveletParams::WaveletParams() : 0.35, 0.35 }, + wavdenoise{ + static_cast(FCT_MinMaxCPoints), + 0.0, + 1.0, + 0.35, + 0.35, + 0.50, + 1.0, + 0.35, + 0.35, + 1.0, + 1.0, + 0.35, + 0.35 + }, + wavdenoiseh{ + static_cast(FCT_MinMaxCPoints), + 0.0, + 1.0, + 0.35, + 0.35, + 0.50, + 1.0, + 0.35, + 0.35, + 1.0, + 1.0, + 0.35, + 0.35 + }, blcurve{ static_cast(FCT_MinMaxCPoints), 0.0, @@ -2339,6 +2369,12 @@ WaveletParams::WaveletParams() : hhcurve{ FCT_Linear }, + wavguidcurve{ + FCT_Linear + }, + wavhuecurve{ + FCT_Linear + }, Chcurve{ FCT_Linear }, @@ -2357,6 +2393,10 @@ WaveletParams::WaveletParams() : greenhigh(0), bluehigh(0), ballum(7.), + sigm(1.0), + levden(0.), + thrden(0.), + limden(0.), balchrom(0.), chromfi(0.), chromco(0.), @@ -2364,6 +2404,9 @@ WaveletParams::WaveletParams() : mergeC(20.), softrad(0.), softradend(0.), + strend(50.), + detend(0), + thrend(0), lipst(false), avoid(false), showmask(false), @@ -2398,6 +2441,10 @@ WaveletParams::WaveletParams() : Backmethod("grey"), Tilesmethod("full"), complexmethod("normal"), + denmethod("equ"), + mixmethod("mix"), + slimethod("sli"), + quamethod("cons"), daubcoeffmethod("4_"), CHmethod("without"), Medgreinf("less"), @@ -2454,7 +2501,9 @@ WaveletParams::WaveletParams() : level0noise(0, 0, false), level1noise(0, 0, false), level2noise(0, 0, false), - level3noise(0, 0, false) + level3noise(0, 0, false), + leveldenoise(0, 0, false), + levelsigm(1, 1, false) { } @@ -2462,6 +2511,8 @@ bool WaveletParams::operator ==(const WaveletParams& other) const { return ccwcurve == other.ccwcurve + && wavdenoise == other.wavdenoise + && wavdenoiseh == other.wavdenoiseh && blcurve == other.blcurve && opacityCurveRG == other.opacityCurveRG && opacityCurveSH == other.opacityCurveSH @@ -2469,6 +2520,8 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && opacityCurveW == other.opacityCurveW && opacityCurveWL == other.opacityCurveWL && hhcurve == other.hhcurve + && wavguidcurve == other.wavguidcurve + && wavhuecurve == other.wavhuecurve && Chcurve == other.Chcurve && wavclCurve == other.wavclCurve && enabled == other.enabled @@ -2483,6 +2536,10 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && greenhigh == other.greenhigh && bluehigh == other.bluehigh && ballum == other.ballum + && sigm == other.sigm + && levden == other.levden + && thrden == other.thrden + && limden == other.limden && balchrom == other.balchrom && chromfi == other.chromfi && chromco == other.chromco @@ -2490,6 +2547,9 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && mergeC == other.mergeC && softrad == other.softrad && softradend == other.softradend + && strend == other.strend + && detend == other.detend + && thrend == other.thrend && lipst == other.lipst && avoid == other.avoid && showmask == other.showmask @@ -2531,6 +2591,10 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && Backmethod == other.Backmethod && Tilesmethod == other.Tilesmethod && complexmethod == other.complexmethod + && denmethod == other.denmethod + && mixmethod == other.mixmethod + && slimethod == other.slimethod + && quamethod == other.quamethod && daubcoeffmethod == other.daubcoeffmethod && CHmethod == other.CHmethod && Medgreinf == other.Medgreinf @@ -2587,7 +2651,9 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && level0noise == other.level0noise && level1noise == other.level1noise && level2noise == other.level2noise - && level3noise == other.level3noise; + && level3noise == other.level3noise + && leveldenoise == other.leveldenoise + && levelsigm == other.levelsigm; } bool WaveletParams::operator !=(const WaveletParams& other) const @@ -2597,6 +2663,8 @@ bool WaveletParams::operator !=(const WaveletParams& other) const void WaveletParams::getCurves( WavCurve& cCurve, + WavCurve& wavdenoise, + WavCurve& wavdenoiseh, Wavblcurve& tCurve, WavOpacityCurveRG& opacityCurveLUTRG, WavOpacityCurveSH& opacityCurveLUTSH, @@ -2606,6 +2674,8 @@ void WaveletParams::getCurves( ) const { cCurve.Set(this->ccwcurve); + wavdenoise.Set(this->wavdenoise); + wavdenoiseh.Set(this->wavdenoiseh); tCurve.Set(this->blcurve); opacityCurveLUTRG.Set(this->opacityCurveRG); opacityCurveLUTSH.Set(this->opacityCurveSH); @@ -5997,6 +6067,10 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.thres, "Wavelet", "MaxLev", wavelet.thres, keyFile); saveToKeyfile(!pedited || pedited->wavelet.Tilesmethod, "Wavelet", "TilesMethod", wavelet.Tilesmethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.complexmethod, "Wavelet", "complexMethod", wavelet.complexmethod, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.denmethod, "Wavelet", "denMethod", wavelet.denmethod, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.mixmethod, "Wavelet", "mixMethod", wavelet.mixmethod, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.slimethod, "Wavelet", "sliMethod", wavelet.slimethod, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.quamethod, "Wavelet", "quaMethod", wavelet.quamethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.daubcoeffmethod, "Wavelet", "DaubMethod", wavelet.daubcoeffmethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.CLmethod, "Wavelet", "ChoiceLevMethod", wavelet.CLmethod, keyFile); saveToKeyfile(!pedited || pedited->wavelet.Backmethod, "Wavelet", "BackMethod", wavelet.Backmethod, keyFile); @@ -6009,6 +6083,10 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.bluemed, "Wavelet", "CBbluemed", wavelet.bluemed, keyFile); saveToKeyfile(!pedited || pedited->wavelet.bluelow, "Wavelet", "CBbluelow", wavelet.bluelow, keyFile); saveToKeyfile(!pedited || pedited->wavelet.ballum, "Wavelet", "Ballum", wavelet.ballum, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.sigm, "Wavelet", "Sigm", wavelet.sigm, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.levden, "Wavelet", "Levden", wavelet.levden, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.thrden, "Wavelet", "Thrden", wavelet.thrden, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.limden, "Wavelet", "Limden", wavelet.limden, keyFile); saveToKeyfile(!pedited || pedited->wavelet.balchrom, "Wavelet", "Balchrom", wavelet.balchrom, keyFile); saveToKeyfile(!pedited || pedited->wavelet.chromfi, "Wavelet", "Chromfine", wavelet.chromfi, keyFile); saveToKeyfile(!pedited || pedited->wavelet.chromco, "Wavelet", "Chromcoarse", wavelet.chromco, keyFile); @@ -6016,6 +6094,9 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.mergeC, "Wavelet", "MergeC", wavelet.mergeC, keyFile); saveToKeyfile(!pedited || pedited->wavelet.softrad, "Wavelet", "Softrad", wavelet.softrad, keyFile); saveToKeyfile(!pedited || pedited->wavelet.softradend, "Wavelet", "Softradend", wavelet.softradend, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.strend, "Wavelet", "Strend", wavelet.strend, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.detend, "Wavelet", "Detend", wavelet.detend, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.thrend, "Wavelet", "Thrend", wavelet.thrend, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expcontrast, "Wavelet", "Expcontrast", wavelet.expcontrast, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expchroma, "Wavelet", "Expchroma", wavelet.expchroma, keyFile); saveToKeyfile(!pedited || pedited->wavelet.expedge, "Wavelet", "Expedge", wavelet.expedge, keyFile); @@ -6053,6 +6134,8 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.level1noise, "Wavelet", "Level1noise", wavelet.level1noise.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.level2noise, "Wavelet", "Level2noise", wavelet.level2noise.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.level3noise, "Wavelet", "Level3noise", wavelet.level3noise.toVector(), keyFile); + saveToKeyfile(!pedited || pedited->wavelet.leveldenoise, "Wavelet", "Leveldenoise", wavelet.leveldenoise.toVector(), keyFile); + saveToKeyfile(!pedited || pedited->wavelet.levelsigm, "Wavelet", "Levelsigm", wavelet.levelsigm.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.threshold, "Wavelet", "ThresholdHighlight", wavelet.threshold, keyFile); saveToKeyfile(!pedited || pedited->wavelet.threshold2, "Wavelet", "ThresholdShadow", wavelet.threshold2, keyFile); saveToKeyfile(!pedited || pedited->wavelet.edgedetect, "Wavelet", "Edgedetect", wavelet.edgedetect, keyFile); @@ -6077,9 +6160,13 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.opacityCurveRG, "Wavelet", "OpacityCurveRG", wavelet.opacityCurveRG, keyFile); saveToKeyfile(!pedited || pedited->wavelet.opacityCurveSH, "Wavelet", "Levalshc", wavelet.opacityCurveSH, keyFile); saveToKeyfile(!pedited || pedited->wavelet.opacityCurveBY, "Wavelet", "OpacityCurveBY", wavelet.opacityCurveBY, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.wavdenoise, "Wavelet", "wavdenoise", wavelet.wavdenoise, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.wavdenoiseh, "Wavelet", "wavdenoiseh", wavelet.wavdenoiseh, keyFile); saveToKeyfile(!pedited || pedited->wavelet.opacityCurveW, "Wavelet", "OpacityCurveW", wavelet.opacityCurveW, keyFile); saveToKeyfile(!pedited || pedited->wavelet.opacityCurveWL, "Wavelet", "OpacityCurveWL", wavelet.opacityCurveWL, keyFile); saveToKeyfile(!pedited || pedited->wavelet.hhcurve, "Wavelet", "HHcurve", wavelet.hhcurve, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.wavguidcurve, "Wavelet", "Wavguidcurve", wavelet.wavguidcurve, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.wavhuecurve, "Wavelet", "Wavhuecurve", wavelet.wavhuecurve, keyFile); saveToKeyfile(!pedited || pedited->wavelet.Chcurve, "Wavelet", "CHcurve", wavelet.Chcurve, keyFile); saveToKeyfile(!pedited || pedited->wavelet.wavclCurve, "Wavelet", "WavclCurve", wavelet.wavclCurve, keyFile); saveToKeyfile(!pedited || pedited->wavelet.median, "Wavelet", "Median", wavelet.median, keyFile); @@ -7836,6 +7923,10 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "CBbluemed", pedited, wavelet.bluemed, pedited->wavelet.bluemed); assignFromKeyfile(keyFile, "Wavelet", "CBbluelow", pedited, wavelet.bluelow, pedited->wavelet.bluelow); assignFromKeyfile(keyFile, "Wavelet", "Ballum", pedited, wavelet.ballum, pedited->wavelet.ballum); + assignFromKeyfile(keyFile, "Wavelet", "Sigm", pedited, wavelet.sigm, pedited->wavelet.sigm); + assignFromKeyfile(keyFile, "Wavelet", "Levden", pedited, wavelet.levden, pedited->wavelet.levden); + assignFromKeyfile(keyFile, "Wavelet", "Thrden", pedited, wavelet.thrden, pedited->wavelet.thrden); + assignFromKeyfile(keyFile, "Wavelet", "Limden", pedited, wavelet.limden, pedited->wavelet.limden); assignFromKeyfile(keyFile, "Wavelet", "Balchrom", pedited, wavelet.balchrom, pedited->wavelet.balchrom); assignFromKeyfile(keyFile, "Wavelet", "Chromfine", pedited, wavelet.chromfi, pedited->wavelet.chromfi); assignFromKeyfile(keyFile, "Wavelet", "Chromcoarse", pedited, wavelet.chromco, pedited->wavelet.chromco); @@ -7843,6 +7934,9 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "MergeC", pedited, wavelet.mergeC, pedited->wavelet.mergeC); assignFromKeyfile(keyFile, "Wavelet", "Softrad", pedited, wavelet.softrad, pedited->wavelet.softrad); assignFromKeyfile(keyFile, "Wavelet", "Softradend", pedited, wavelet.softradend, pedited->wavelet.softradend); + assignFromKeyfile(keyFile, "Wavelet", "Strend", pedited, wavelet.strend, pedited->wavelet.strend); + assignFromKeyfile(keyFile, "Wavelet", "Detend", pedited, wavelet.detend, pedited->wavelet.detend); + assignFromKeyfile(keyFile, "Wavelet", "Thrend", pedited, wavelet.thrend, pedited->wavelet.thrend); assignFromKeyfile(keyFile, "Wavelet", "Lipst", pedited, wavelet.lipst, pedited->wavelet.lipst); assignFromKeyfile(keyFile, "Wavelet", "AvoidColorShift", pedited, wavelet.avoid, pedited->wavelet.avoid); assignFromKeyfile(keyFile, "Wavelet", "Showmask", pedited, wavelet.showmask, pedited->wavelet.showmask); @@ -7869,6 +7963,10 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "BackMethod", pedited, wavelet.Backmethod, pedited->wavelet.Backmethod); assignFromKeyfile(keyFile, "Wavelet", "TilesMethod", pedited, wavelet.Tilesmethod, pedited->wavelet.Tilesmethod); assignFromKeyfile(keyFile, "Wavelet", "complexMethod", pedited, wavelet.complexmethod, pedited->wavelet.complexmethod); + assignFromKeyfile(keyFile, "Wavelet", "denMethod", pedited, wavelet.denmethod, pedited->wavelet.denmethod); + assignFromKeyfile(keyFile, "Wavelet", "mixMethod", pedited, wavelet.mixmethod, pedited->wavelet.mixmethod); + assignFromKeyfile(keyFile, "Wavelet", "sliMethod", pedited, wavelet.slimethod, pedited->wavelet.slimethod); + assignFromKeyfile(keyFile, "Wavelet", "quaMethod", pedited, wavelet.quamethod, pedited->wavelet.quamethod); assignFromKeyfile(keyFile, "Wavelet", "DaubMethod", pedited, wavelet.daubcoeffmethod, pedited->wavelet.daubcoeffmethod); assignFromKeyfile(keyFile, "Wavelet", "CHromaMethod", pedited, wavelet.CHmethod, pedited->wavelet.CHmethod); assignFromKeyfile(keyFile, "Wavelet", "Medgreinf", pedited, wavelet.Medgreinf, pedited->wavelet.Medgreinf); @@ -7917,9 +8015,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveRG", pedited, wavelet.opacityCurveRG, pedited->wavelet.opacityCurveRG); assignFromKeyfile(keyFile, "Wavelet", "Levalshc", pedited, wavelet.opacityCurveSH, pedited->wavelet.opacityCurveSH); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveBY", pedited, wavelet.opacityCurveBY, pedited->wavelet.opacityCurveBY); + assignFromKeyfile(keyFile, "Wavelet", "wavdenoise", pedited, wavelet.wavdenoise, pedited->wavelet.wavdenoise); + assignFromKeyfile(keyFile, "Wavelet", "wavdenoiseh", pedited, wavelet.wavdenoiseh, pedited->wavelet.wavdenoiseh); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveW", pedited, wavelet.opacityCurveW, pedited->wavelet.opacityCurveW); assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveWL", pedited, wavelet.opacityCurveWL, pedited->wavelet.opacityCurveWL); assignFromKeyfile(keyFile, "Wavelet", "HHcurve", pedited, wavelet.hhcurve, pedited->wavelet.hhcurve); + assignFromKeyfile(keyFile, "Wavelet", "Wavguidcurve", pedited, wavelet.wavguidcurve, pedited->wavelet.wavguidcurve); + assignFromKeyfile(keyFile, "Wavelet", "Wavhuecurve", pedited, wavelet.wavhuecurve, pedited->wavelet.wavhuecurve); assignFromKeyfile(keyFile, "Wavelet", "CHcurve", pedited, wavelet.Chcurve, pedited->wavelet.Chcurve); assignFromKeyfile(keyFile, "Wavelet", "WavclCurve", pedited, wavelet.wavclCurve, pedited->wavelet.wavclCurve); @@ -8031,6 +8133,30 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } + if (keyFile.has_key("Wavelet", "Leveldenoise")) { + const std::vector thresh = keyFile.get_double_list("Wavelet", "Leveldenoise"); + + if (thresh.size() >= 2) { + wavelet.leveldenoise.setValues(thresh[0], thresh[1]); + } + + if (pedited) { + pedited->wavelet.leveldenoise = true; + } + } + + if (keyFile.has_key("Wavelet", "Levelsigm")) { + const std::vector thresh = keyFile.get_double_list("Wavelet", "Levelsigm"); + + if (thresh.size() >= 2) { + wavelet.levelsigm.setValues(thresh[0], thresh[1]); + } + + if (pedited) { + pedited->wavelet.levelsigm = true; + } + } + if (keyFile.has_key("Wavelet", "Pastlev")) { const std::vector thresh = keyFile.get_integer_list("Wavelet", "Pastlev"); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 0e70e8821..c435e317a 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1725,6 +1725,8 @@ private: struct WaveletParams { std::vector ccwcurve; + std::vector wavdenoise; + std::vector wavdenoiseh; std::vector blcurve; std::vector levelshc; std::vector opacityCurveRG; @@ -1733,6 +1735,8 @@ struct WaveletParams { std::vector opacityCurveW; std::vector opacityCurveWL; std::vector hhcurve; + std::vector wavguidcurve; + std::vector wavhuecurve; std::vector Chcurve; std::vector wavclCurve; bool enabled; @@ -1747,6 +1751,10 @@ struct WaveletParams { int greenhigh; int bluehigh; double ballum; + double sigm; + double levden; + double thrden; + double limden; double balchrom; double chromfi; double chromco; @@ -1754,6 +1762,9 @@ struct WaveletParams { double mergeC; double softrad; double softradend; + double strend; + int detend; + double thrend; bool lipst; bool avoid; @@ -1792,6 +1803,10 @@ struct WaveletParams { Glib::ustring Backmethod; Glib::ustring Tilesmethod; Glib::ustring complexmethod; + Glib::ustring denmethod; + Glib::ustring mixmethod; + Glib::ustring slimethod; + Glib::ustring quamethod; Glib::ustring daubcoeffmethod; Glib::ustring CHmethod; Glib::ustring Medgreinf; @@ -1849,6 +1864,8 @@ struct WaveletParams { Threshold level1noise; Threshold level2noise; Threshold level3noise; + Threshold leveldenoise; + Threshold levelsigm; WaveletParams(); @@ -1857,6 +1874,8 @@ struct WaveletParams { void getCurves( WavCurve& cCurve, + WavCurve& wavdenoise, + WavCurve& wavdenoiseh, Wavblcurve& tCurve, WavOpacityCurveRG& opacityCurveLUTRG, WavOpacityCurveSH& opacityCurveLUTSH, diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 7b8575635..1455b0c64 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1364,6 +1364,8 @@ private: LabImage *unshar = nullptr; WaveletParams WaveParams = params.wavelet; WavCurve wavCLVCurve; + WavCurve wavdenoise; + WavCurve wavdenoiseh; Wavblcurve wavblcurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveSH waOpacityCurveSH; @@ -1388,14 +1390,14 @@ private: provradius = new LabImage(*labView, true); } - params.wavelet.getCurves(wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + params.wavelet.getCurves(wavCLVCurve, wavdenoise, wavdenoiseh, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); CurveFactory::diagonalCurve2Lut(params.wavelet.wavclCurve, wavclCurve, 1); if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { const Glib::ustring provis = params.wavelet.CLmethod; params.wavelet.CLmethod = "all"; - ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); + ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavdenoise, wavdenoiseh, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); unshar = new LabImage(*labView, true); params.wavelet.CLmethod = provis; @@ -1407,7 +1409,7 @@ private: WaveParams.expnoise = false; } - ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); + ipf.ip_wavelet(labView, labView, 2, WaveParams, wavCLVCurve, wavdenoise, wavdenoiseh, wavblcurve, waOpacityCurveRG, waOpacityCurveSH, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, 1); if ((WaveParams.ushamethod == "sharp" || WaveParams.ushamethod == "clari") && WaveParams.expclari && WaveParams.CLmethod != "all") { WaveParams.expcontrast = procont; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 3cd93064e..5b8188f80 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -515,6 +515,10 @@ void ParamsEdited::set(bool v) wavelet.bluelow = v; wavelet.lipst = v; wavelet.ballum = v; + wavelet.sigm = v; + wavelet.levden = v; + wavelet.thrden = v; + wavelet.limden = v; wavelet.balchrom = v; wavelet.chromfi = v; wavelet.chromco = v; @@ -522,6 +526,9 @@ void ParamsEdited::set(bool v) wavelet.mergeC = v; wavelet.softrad = v; wavelet.softradend = v; + wavelet.strend = v; + wavelet.detend = v; + wavelet.thrend = v; wavelet.Medgreinf = v; wavelet.ushamethod = v; wavelet.avoid = v; @@ -533,6 +540,10 @@ void ParamsEdited::set(bool v) wavelet.Backmethod = v; wavelet.Tilesmethod = v; wavelet.complexmethod = v; + wavelet.denmethod = v; + wavelet.mixmethod = v; + wavelet.slimethod = v; + wavelet.quamethod = v; wavelet.daubcoeffmethod = v; wavelet.CHmethod = v; wavelet.CHSLmethod = v; @@ -586,14 +597,20 @@ void ParamsEdited::set(bool v) wavelet.level1noise = v; wavelet.level2noise = v; wavelet.level3noise = v; + wavelet.leveldenoise = v; + wavelet.levelsigm = v; wavelet.ccwcurve = v; wavelet.blcurve = v; wavelet.opacityCurveSH = v; wavelet.opacityCurveRG = v; wavelet.opacityCurveBY = v; + wavelet.wavdenoise = v; + wavelet.wavdenoiseh = v; wavelet.opacityCurveW = v; wavelet.opacityCurveWL = v; wavelet.hhcurve = v; + wavelet.wavguidcurve = v; + wavelet.wavhuecurve = v; wavelet.Chcurve = v; wavelet.wavclCurve = v; @@ -1666,6 +1683,10 @@ void ParamsEdited::initFrom(const std::vector& wavelet.lipst = wavelet.lipst && p.wavelet.lipst == other.wavelet.lipst; wavelet.bluehigh = wavelet.bluehigh && p.wavelet.bluehigh == other.wavelet.bluehigh; wavelet.ballum = wavelet.ballum && p.wavelet.ballum == other.wavelet.ballum; + wavelet.sigm = wavelet.sigm && p.wavelet.sigm == other.wavelet.sigm; + wavelet.levden = wavelet.levden && p.wavelet.levden == other.wavelet.levden; + wavelet.thrden = wavelet.thrden && p.wavelet.thrden == other.wavelet.thrden; + wavelet.limden = wavelet.limden && p.wavelet.limden == other.wavelet.limden; wavelet.balchrom = wavelet.balchrom && p.wavelet.balchrom == other.wavelet.balchrom; wavelet.chromfi = wavelet.chromfi && p.wavelet.chromfi == other.wavelet.chromfi; wavelet.chromco = wavelet.chromco && p.wavelet.chromco == other.wavelet.chromco; @@ -1673,6 +1694,9 @@ void ParamsEdited::initFrom(const std::vector& wavelet.mergeC = wavelet.mergeC && p.wavelet.mergeC == other.wavelet.mergeC; wavelet.softrad = wavelet.softrad && p.wavelet.softrad == other.wavelet.softrad; wavelet.softradend = wavelet.softradend && p.wavelet.softradend == other.wavelet.softradend; + wavelet.strend = wavelet.strend && p.wavelet.strend == other.wavelet.strend; + wavelet.detend = wavelet.detend && p.wavelet.detend == other.wavelet.detend; + wavelet.thrend = wavelet.thrend && p.wavelet.thrend == other.wavelet.thrend; wavelet.ushamethod = wavelet.ushamethod && p.wavelet.ushamethod == other.wavelet.ushamethod; wavelet.avoid = wavelet.avoid && p.wavelet.avoid == other.wavelet.avoid; wavelet.showmask = wavelet.showmask && p.wavelet.showmask == other.wavelet.showmask; @@ -1683,6 +1707,10 @@ void ParamsEdited::initFrom(const std::vector& wavelet.Backmethod = wavelet.Backmethod && p.wavelet.Backmethod == other.wavelet.Backmethod; wavelet.Tilesmethod = wavelet.Tilesmethod && p.wavelet.Tilesmethod == other.wavelet.Tilesmethod; wavelet.complexmethod = wavelet.complexmethod && p.wavelet.complexmethod == other.wavelet.complexmethod; + wavelet.denmethod = wavelet.denmethod && p.wavelet.denmethod == other.wavelet.denmethod; + wavelet.mixmethod = wavelet.mixmethod && p.wavelet.mixmethod == other.wavelet.mixmethod; + wavelet.slimethod = wavelet.slimethod && p.wavelet.slimethod == other.wavelet.slimethod; + wavelet.quamethod = wavelet.quamethod && p.wavelet.quamethod == other.wavelet.quamethod; wavelet.daubcoeffmethod = wavelet.daubcoeffmethod && p.wavelet.daubcoeffmethod == other.wavelet.daubcoeffmethod; wavelet.CHmethod = wavelet.CHmethod && p.wavelet.CHmethod == other.wavelet.CHmethod; wavelet.CHSLmethod = wavelet.CHSLmethod && p.wavelet.CHSLmethod == other.wavelet.CHSLmethod; @@ -1735,6 +1763,8 @@ void ParamsEdited::initFrom(const std::vector& wavelet.level1noise = wavelet.level1noise && p.wavelet.level1noise == other.wavelet.level1noise; wavelet.level2noise = wavelet.level2noise && p.wavelet.level2noise == other.wavelet.level2noise; wavelet.level3noise = wavelet.level3noise && p.wavelet.level3noise == other.wavelet.level3noise; + wavelet.leveldenoise = wavelet.leveldenoise && p.wavelet.leveldenoise == other.wavelet.leveldenoise; + wavelet.levelsigm = wavelet.levelsigm && p.wavelet.levelsigm == other.wavelet.levelsigm; wavelet.pastlev = wavelet.pastlev && p.wavelet.pastlev == other.wavelet.pastlev; wavelet.satlev = wavelet.satlev && p.wavelet.satlev == other.wavelet.satlev; wavelet.ccwcurve = wavelet.ccwcurve && p.wavelet.ccwcurve == other.wavelet.ccwcurve; @@ -1742,10 +1772,14 @@ void ParamsEdited::initFrom(const std::vector& wavelet.opacityCurveSH = wavelet.opacityCurveSH && p.wavelet.opacityCurveSH == other.wavelet.opacityCurveSH; wavelet.opacityCurveRG = wavelet.opacityCurveRG && p.wavelet.opacityCurveRG == other.wavelet.opacityCurveRG; wavelet.opacityCurveBY = wavelet.opacityCurveBY && p.wavelet.opacityCurveBY == other.wavelet.opacityCurveBY; + wavelet.wavdenoise = wavelet.wavdenoise && p.wavelet.wavdenoise == other.wavelet.wavdenoise; + wavelet.wavdenoiseh = wavelet.wavdenoiseh && p.wavelet.wavdenoiseh == other.wavelet.wavdenoiseh; wavelet.opacityCurveW = wavelet.opacityCurveW && p.wavelet.opacityCurveW == other.wavelet.opacityCurveW; wavelet.opacityCurveWL = wavelet.opacityCurveWL && p.wavelet.opacityCurveWL == other.wavelet.opacityCurveWL; wavelet.wavclCurve = wavelet.wavclCurve && p.wavelet.wavclCurve == other.wavelet.wavclCurve; wavelet.hhcurve = wavelet.hhcurve && p.wavelet.hhcurve == other.wavelet.hhcurve; + wavelet.wavguidcurve = wavelet.wavguidcurve && p.wavelet.wavguidcurve == other.wavelet.wavguidcurve; + wavelet.wavhuecurve = wavelet.wavhuecurve && p.wavelet.wavhuecurve == other.wavelet.wavhuecurve; wavelet.Chcurve = wavelet.Chcurve && p.wavelet.Chcurve == other.wavelet.Chcurve; wavelet.skinprotect = wavelet.skinprotect && p.wavelet.skinprotect == other.wavelet.skinprotect; // wavelet.enacont = wavelet.enacont && p.wavelet.enacont == other.wavelet.enacont; @@ -5510,6 +5544,22 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.ballum = mods.wavelet.ballum; } + if (wavelet.sigm) { + toEdit.wavelet.sigm = mods.wavelet.sigm; + } + + if (wavelet.levden) { + toEdit.wavelet.levden = mods.wavelet.levden; + } + + if (wavelet.thrden) { + toEdit.wavelet.thrden = mods.wavelet.thrden; + } + + if (wavelet.limden) { + toEdit.wavelet.limden = mods.wavelet.limden; + } + if (wavelet.balchrom) { toEdit.wavelet.balchrom = mods.wavelet.balchrom; } @@ -5538,6 +5588,18 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.softradend = mods.wavelet.softradend; } + if (wavelet.strend) { + toEdit.wavelet.strend = mods.wavelet.strend; + } + + if (wavelet.detend) { + toEdit.wavelet.detend = mods.wavelet.detend; + } + + if (wavelet.thrend) { + toEdit.wavelet.thrend = mods.wavelet.thrend; + } + if (wavelet.lipst) { toEdit.wavelet.lipst = mods.wavelet.lipst; } @@ -5586,6 +5648,22 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.complexmethod = mods.wavelet.complexmethod; } + if (wavelet.denmethod) { + toEdit.wavelet.denmethod = mods.wavelet.denmethod; + } + + if (wavelet.mixmethod) { + toEdit.wavelet.mixmethod = mods.wavelet.mixmethod; + } + + if (wavelet.slimethod) { + toEdit.wavelet.slimethod = mods.wavelet.slimethod; + } + + if (wavelet.quamethod) { + toEdit.wavelet.quamethod = mods.wavelet.quamethod; + } + if (wavelet.daubcoeffmethod) { toEdit.wavelet.daubcoeffmethod = mods.wavelet.daubcoeffmethod; } @@ -5682,6 +5760,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.level3noise = mods.wavelet.level3noise; } + if (wavelet.leveldenoise) { + toEdit.wavelet.leveldenoise = mods.wavelet.leveldenoise; + } + + if (wavelet.levelsigm) { + toEdit.wavelet.levelsigm = mods.wavelet.levelsigm; + } + if (wavelet.pastlev) { toEdit.wavelet.pastlev = mods.wavelet.pastlev; } @@ -5710,6 +5796,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.opacityCurveBY = mods.wavelet.opacityCurveBY; } + if (wavelet.wavdenoise) { + toEdit.wavelet.wavdenoise = mods.wavelet.wavdenoise; + } + + if (wavelet.wavdenoiseh) { + toEdit.wavelet.wavdenoiseh = mods.wavelet.wavdenoiseh; + } + if (wavelet.opacityCurveW) { toEdit.wavelet.opacityCurveW = mods.wavelet.opacityCurveW; } @@ -5722,6 +5816,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.hhcurve = mods.wavelet.hhcurve; } + if (wavelet.wavguidcurve) { + toEdit.wavelet.wavguidcurve = mods.wavelet.wavguidcurve; + } + + if (wavelet.wavhuecurve) { + toEdit.wavelet.wavhuecurve = mods.wavelet.wavhuecurve; + } + if (wavelet.Chcurve) { toEdit.wavelet.Chcurve = mods.wavelet.Chcurve; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index f8230a577..f0ef04b1c 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -1041,6 +1041,10 @@ struct WaveletParamsEdited { bool Backmethod; bool Tilesmethod; bool complexmethod; + bool denmethod; + bool mixmethod; + bool slimethod; + bool quamethod; bool daubcoeffmethod; bool Dirmethod; bool sigma; @@ -1087,14 +1091,20 @@ struct WaveletParamsEdited { bool level1noise; bool level2noise; bool level3noise; + bool leveldenoise; + bool levelsigm; bool ccwcurve; bool blcurve; bool opacityCurveSH; bool opacityCurveBY; + bool wavdenoise; + bool wavdenoiseh; bool opacityCurveRG; bool opacityCurveW; bool opacityCurveWL; bool hhcurve; + bool wavguidcurve; + bool wavhuecurve; bool Chcurve; bool pastlev; bool satlev; @@ -1106,6 +1116,10 @@ struct WaveletParamsEdited { bool greenhigh; bool bluehigh; bool ballum; + bool sigm; + bool levden; + bool thrden; + bool limden; bool balchrom; bool chromfi; bool chromco; @@ -1113,6 +1127,9 @@ struct WaveletParamsEdited { bool mergeC; bool softrad; bool softradend; + bool strend; + bool detend; + bool thrend; bool expcontrast; bool expchroma; bool expedge; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 19d458dad..78fa49144 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . * - * 2014 - 2019Jacques Desmis + * 2014 - 2020 Jacques Desmis */ #include "wavelet.h" @@ -29,6 +29,7 @@ #include "eventmapper.h" #include "labgrid.h" #include "../rtengine/color.h" +#include using namespace rtengine; using namespace rtengine::procparams; @@ -72,6 +73,10 @@ Wavelet::Wavelet() : separatoredge(Gtk::manage(new Gtk::HSeparator())), opaCurveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_COLORT"))), opacityCurveEditorG(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_OPACITY"))), + CurveEditorwavnoise(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_DENOISE"))), + CurveEditorwavnoiseh(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_DENOISEH"))), + CurveEditorwavguid(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_DENOISEGUID"))), + CurveEditorwavhue(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_DENOISEHUE"))), opacityCurveEditorW(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_OPACITYW"))), opacityCurveEditorWL(new CurveEditorGroup(options.lastWaveletCurvesDir, M("TP_WAVELET_OPACITYWL"))), median(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_MEDI")))), @@ -99,7 +104,7 @@ Wavelet::Wavelet() : gamma(Gtk::manage(new Adjuster(M("TP_WAVELET_COMPGAMMA"), 0.4, 2.0, 0.01, 1.0))), sup(Gtk::manage(new Adjuster(M("TP_WAVELET_SUPE"), -100, 350, 1, 0))), sky(Gtk::manage(new Adjuster(M("TP_WAVELET_SKY"), -100., 100.0, 1., 0.))), - thres(Gtk::manage(new Adjuster(M("TP_WAVELET_LEVELS"), 4, 9, 1, 7))),//3 + thres(Gtk::manage(new Adjuster(M("TP_WAVELET_LEVELS"), 5, 9, 1, 7))),//3 chroma(Gtk::manage(new Adjuster(M("TP_WAVELET_CHRO"), 1, 9, 1, 5))), chro(Gtk::manage(new Adjuster(M("TP_WAVELET_CHR"), 0., 100., 1., 0.))), contrast(Gtk::manage(new Adjuster(M("TP_WAVELET_CONTRA"), -100, 100, 1, 0))), @@ -131,6 +136,12 @@ Wavelet::Wavelet() : level1noise(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_LEVONE"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., nullptr, false))), level2noise(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_LEVTWO"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., nullptr, false))), level3noise(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_LEVTHRE"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., nullptr, false))), + leveldenoise(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_LEVFOUR"), 0., 100., 0., M("TP_WAVELET_DEN5THR"), 1, 0., 100., 0., M("TP_WAVELET_NOIS"), 1., nullptr, false))), + levelsigm(Gtk::manage(new ThresholdAdjuster(M("TP_WAVELET_LEVELSIGM"), 0.05, 3., 1., M("TP_WAVELET_LEVELHIGH"), 1, 0.05, 3., 1., M("TP_WAVELET_LEVELLOW"), 1., nullptr, false))), + sigm(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGM"), 0.05, 3.5, 0.01, 1.))), + levden(Gtk::manage(new Adjuster(M("TP_WAVELET_LEVDEN"), 0., 100., 0.5, 0.))), + thrden(Gtk::manage(new Adjuster(M("TP_WAVELET_DENLH"), 0., 100., 0.5, 0.))), + limden(Gtk::manage(new Adjuster(M("TP_WAVELET_LIMDEN"), 0., 1., 0.01, 0.))), threshold(Gtk::manage(new Adjuster(M("TP_WAVELET_THRESHOLD"), 1, 9, 1, 4))), // threshold2(Gtk::manage(new Adjuster(M("TP_WAVELET_THRESHOLD2"), 1, 9, 1, 4))), threshold2(Gtk::manage(new Adjuster(M("TP_WAVELET_THRESHOLD2"), 3, 9, 1, 5))), @@ -146,7 +157,10 @@ Wavelet::Wavelet() : mergeL(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEL"), -50, 100, 1, 20))), mergeC(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEC"), -50, 100, 1, 20))), softrad(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))), - softradend(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))), + softradend(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 1000., 1., 0.))), + strend(Gtk::manage(new Adjuster(M("TP_WAVELET_STREND"), 0.0, 100., 1.0, 50.))), + detend(Gtk::manage(new Adjuster(M("TP_WAVELET_DETEND"), -10, 10, 1, 0))), + thrend(Gtk::manage(new Adjuster(M("TP_WAVELET_THREND"), 0.0, 100., 0.5, 0.))), chrwav(Gtk::manage(new Adjuster(M("TP_WAVELET_CHRWAV"), 0., 100., 0.5, 0.))), Lmethod(Gtk::manage(new MyComboBoxText())), CHmethod(Gtk::manage(new MyComboBoxText())), @@ -164,6 +178,10 @@ Wavelet::Wavelet() : Dirmethod(Gtk::manage(new MyComboBoxText())), Medgreinf(Gtk::manage(new MyComboBoxText())), ushamethod(Gtk::manage(new MyComboBoxText())), + denmethod(Gtk::manage(new MyComboBoxText())), + mixmethod(Gtk::manage(new MyComboBoxText())), + quamethod(Gtk::manage(new MyComboBoxText())), + slimethod(Gtk::manage(new MyComboBoxText())), chanMixerHLFrame(Gtk::manage(new Gtk::Frame(M("TP_COLORTONING_HIGHLIGHT")))), chanMixerMidFrame(Gtk::manage(new Gtk::Frame(M("TP_COLORTONING_MIDTONES")))), chanMixerShadowsFrame(Gtk::manage(new Gtk::Frame(M("TP_COLORTONING_SHADOWS")))), @@ -175,6 +193,7 @@ Wavelet::Wavelet() : fincFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_FINCFRAME")))), dirFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_DIRFRAME")))), tonFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_TONFRAME")))), + guidFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_GUIDFRAME")))), wavLabels(Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER))), labmC(Gtk::manage(new Gtk::Label(M("TP_WAVELET_CTYPE") + ":"))), labmNP(Gtk::manage(new Gtk::Label(M("TP_WAVELET_NPTYPE") + ":"))), @@ -193,6 +212,10 @@ Wavelet::Wavelet() : neutrHBox(Gtk::manage(new Gtk::HBox())), usharpHBox(Gtk::manage(new Gtk::HBox())), ctboxch(Gtk::manage(new Gtk::HBox())), + quaHBox(Gtk::manage(new Gtk::HBox())), + sliHBox(Gtk::manage(new Gtk::HBox())), + denHBox(Gtk::manage(new Gtk::HBox())), + mixHBox(Gtk::manage(new Gtk::HBox())), ctboxBA(Gtk::manage(new Gtk::VBox())) { @@ -232,6 +255,24 @@ Wavelet::Wavelet() : EvWavprotab = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_PROTAB"); EvWavlevelshc = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_LEVELSHC"); EvWavcomplexmet = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_COMPLEX"); + EvWavsigm = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSIGM"); + EvWavdenoise = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVDENOISE"); + EvWavdenmethod = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVDENMET"); + EvWavmixmethod = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVMIXMET"); + EvWavquamethod = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVQUAMET"); + EvWavlevden = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVLEVDEN"); + EvWavdenoiseh = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVDENOISEH"); + EvWavstrend = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSTREND"); + EvWavdetend = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVDETEND"); + EvWavlevdenois = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVDENLH"); + EvWavslimethod = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSLIMET"); + EvWavthrend = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVTHREND"); + EvWavguid = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVGUIDH"); + EvWavhue = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVHUE"); + EvWavthrden = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVTHRDEN"); + EvWavlevelsigm = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVLEVELSIGM"); + EvWavlimden = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVLIMDEN"); + labgrid = Gtk::manage(new LabGrid(EvWavLabGridValue, M("TP_WAVELET_LABGRID_VALUES"))); @@ -447,7 +488,7 @@ Wavelet::Wavelet() : curveEditorC->set_tooltip_text(M("TP_WAVELET_FINCOAR_TOOLTIP")); - opacityShapeSH = static_cast(curveEditorC->addCurve(CT_Flat, "", nullptr, false, false)); + opacityShapeSH = static_cast(curveEditorC->addCurve(CT_Flat, "", nullptr, false, false)); opacityShapeSH->setIdentityValue(0.); opacityShapeSH->setResetCurve(FlatCurveType(default_params.opacityCurveSH.at(0)), default_params.opacityCurveSH); @@ -605,13 +646,121 @@ Wavelet::Wavelet() : level3noise->setAdjusterListener(this); level3noise->setUpdatePolicy(RTUP_DYNAMIC); + + leveldenoise->setAdjusterListener(this); + leveldenoise->setUpdatePolicy(RTUP_DYNAMIC); + + levelsigm->setAdjusterListener(this); + levelsigm->setUpdatePolicy(RTUP_DYNAMIC); + ballum->setAdjusterListener(this); + sigm->setAdjusterListener(this); + levden->setAdjusterListener(this); + thrden->setAdjusterListener(this); + limden->setAdjusterListener(this); + CurveEditorwavnoise->setCurveListener(this); + CurveEditorwavnoiseh->setCurveListener(this); + CurveEditorwavguid->setCurveListener(this); + CurveEditorwavhue->setCurveListener(this); + + quamethod->append(M("TP_WAVELET_QUACONSER")); + quamethod->append(M("TP_WAVELET_QUAAGRES")); + quamethodconn = quamethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::quamethodChanged)); +// quamethod->set_tooltip_text(M("TP_WAVELET_DENQUA_TOOLTIP")); + Gtk::Label* const quaLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_DENQUA") + ":")); + quaHBox->pack_start(*quaLabel, Gtk::PACK_SHRINK, 4); + quaHBox->pack_start(*quamethod); + + slimethod->append(M("TP_WAVELET_DENSLI")); + slimethod->append(M("TP_WAVELET_DENCURV")); + slimethodconn = slimethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::slimethodChanged)); +// slimethod->set_tooltip_text(M("TP_WAVELET_DENSLI_TOOLTIP")); + Gtk::Label* const sliLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_DENSLILAB") + ":")); + sliHBox->pack_start(*sliLabel, Gtk::PACK_SHRINK, 4); + sliHBox->pack_start(*slimethod); + + + denmethod->append(M("TP_WAVELET_DENEQUAL")); + denmethod->append(M("TP_WAVELET_DEN14PLUS")); + denmethod->append(M("TP_WAVELET_DEN14LOW")); + denmethod->append(M("TP_WAVELET_DEN12PLUS")); + denmethod->append(M("TP_WAVELET_DEN12LOW")); + denmethodconn = denmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::denmethodChanged)); + denmethod->set_tooltip_text(M("TP_WAVELET_DENEQUAL_TOOLTIP")); +// Gtk::HBox* const denHBox = Gtk::manage(new Gtk::HBox()); + Gtk::Label* const denLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_DENCONTRAST") + ":")); + denHBox->pack_start(*denLabel, Gtk::PACK_SHRINK, 4); + denHBox->pack_start(*denmethod); + + mixmethod->append(M("TP_WAVELET_MIXNOISE")); + mixmethod->append(M("TP_WAVELET_MIXMIX")); + mixmethod->append(M("TP_WAVELET_MIXMIX70")); + mixmethod->append(M("TP_WAVELET_MIXDENOISE")); + mixmethodconn = mixmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::mixmethodChanged)); + mixmethod->set_tooltip_text(M("TP_WAVELET_DENMIX_TOOLTIP")); + Gtk::Label* const mixLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_MIXCONTRAST") + ":")); + mixHBox->pack_start(*mixLabel, Gtk::PACK_SHRINK, 4); + mixHBox->pack_start(*mixmethod); + + wavdenoise = static_cast(CurveEditorwavnoise->addCurve(CT_Flat, "", nullptr, false, false)); + wavdenoise->setIdentityValue(0.); + wavdenoise->setResetCurve(FlatCurveType(default_params.wavdenoise.at(0)), default_params.wavdenoise); + CurveEditorwavnoise->set_tooltip_text(M("TP_WAVELET_DENLOCAL_TOOLTIP")); + + CurveEditorwavnoise->curveListComplete(); + CurveEditorwavnoise->show(); + const std::vector milestones4 = makeWholeHueRange(); + + wavdenoiseh = static_cast(CurveEditorwavnoiseh->addCurve(CT_Flat, "", nullptr, false, false)); + wavdenoiseh->setIdentityValue(0.); + wavdenoiseh->setResetCurve(FlatCurveType(default_params.wavdenoiseh.at(0)), default_params.wavdenoiseh); + CurveEditorwavnoiseh->set_tooltip_text(M("TP_WAVELET_DENLOCAL_TOOLTIP")); + CurveEditorwavnoiseh->curveListComplete(); + CurveEditorwavnoiseh->show(); + + wavhue = static_cast(CurveEditorwavhue->addCurve(CT_Flat, M("TP_WAVELET_CURVEEDITOR_HH"))); +// wavhue->setTooltip(M("TP_WAVELET_WAVHUE_HH_TOOLTIP")); + wavhue->setCurveColorProvider(this, 5); + CurveEditorwavhue->set_tooltip_text(M("TP_WAVELET_DENWAVHUE_TOOLTIP")); + CurveEditorwavhue->curveListComplete(); + wavhue->setBottomBarBgGradient(milestones4); + + + + + wavguidf = static_cast(CurveEditorwavguid->addCurve(CT_Flat, M("TP_WAVELET_CURVEEDITOR_HH"))); +// wavguidf->setTooltip(M("TP_WAVELET_WAVGUID_HH_TOOLTIP")); + wavguidf->setCurveColorProvider(this, 5); + CurveEditorwavguid->set_tooltip_text(M("TP_WAVELET_DENWAVGUID_TOOLTIP")); + CurveEditorwavguid->curveListComplete(); + wavguidf->setBottomBarBgGradient(milestones4); + + + + levelsigm->set_tooltip_text(M("TP_WAVELET_DENSIGMA_TOOLTIP")); +// levden->set_tooltip_text(M("TP_WAVELET_DENLEV_TOOLTIP")); + thrden->set_tooltip_text(M("TP_WAVELET_THRDEN_TOOLTIP")); +// limden->set_tooltip_text(M("TP_WAVELET_LIMDEN_TOOLTIP")); noiseBox->pack_start(*ballum); + noiseBox->pack_start(*CurveEditorwavhue); noiseBox->pack_start(*level0noise, Gtk::PACK_SHRINK, 0); noiseBox->pack_start(*level1noise, Gtk::PACK_SHRINK, 0); noiseBox->pack_start(*level2noise, Gtk::PACK_SHRINK, 0); noiseBox->pack_start(*level3noise, Gtk::PACK_SHRINK, 0); + // noiseBox->pack_start(*levden); + noiseBox->pack_start(*leveldenoise, Gtk::PACK_SHRINK, 0); + noiseBox->pack_start(*thrden); + noiseBox->pack_start(*quaHBox); + noiseBox->pack_start(*sliHBox); + noiseBox->pack_start(*denHBox); + noiseBox->pack_start(*mixHBox); + noiseBox->pack_start(*levelsigm, Gtk::PACK_SHRINK, 0); + noiseBox->pack_start(*limden); + noiseBox->pack_start(*sigm); + noiseBox->pack_start(*CurveEditorwavnoise); +// noiseBox->pack_start(*CurveEditorwavnoiseh); + balchrom->setAdjusterListener(this); chromfi->setAdjusterListener(this); @@ -624,7 +773,7 @@ Wavelet::Wavelet() : chroBox->pack_start(*chromco); chroFrame->add(*chroBox); noiseBox->pack_start(*chroFrame); - noiseBox->set_tooltip_text(M("TP_WAVELET_NOISE_TOOLTIP")); +// noiseBox->set_tooltip_text(M("TP_WAVELET_NOISE_TOOLTIP")); //Clarity @@ -1043,6 +1192,9 @@ Wavelet::Wavelet() : balance->setAdjusterListener(this); balance->set_tooltip_text(M("TP_WAVELET_BALANCE_TOOLTIP")); softradend->setAdjusterListener(this); + strend->setAdjusterListener(this); + detend->setAdjusterListener(this); + thrend->setAdjusterListener(this); opacityCurveEditorW->setCurveListener(this); @@ -1108,7 +1260,18 @@ Wavelet::Wavelet() : finalBox->pack_start(*fincFrame); finalBox->pack_start(*curveEditorG, Gtk::PACK_SHRINK, 4); - finalBox->pack_start(*softradend); + thrend->set_tooltip_text(M("TP_WAVELET_FINTHR_TOOLTIP")); + + guidFrame->set_label_align(0.025, 0.5); + ToolParamBlock* const guidBox = Gtk::manage(new ToolParamBlock()); + guidBox->pack_start(*softradend); + guidBox->pack_start(*strend); + guidBox->pack_start(*detend); + guidBox->pack_start(*thrend); + guidBox->pack_start(*CurveEditorwavguid); + guidFrame->add(*guidBox); + finalBox->pack_start(*guidFrame); + //----------------------------- @@ -1167,6 +1330,10 @@ Wavelet::~Wavelet() delete opaCurveEditorG; delete curveEditorC; delete opacityCurveEditorG; + delete CurveEditorwavnoise; + delete CurveEditorwavnoiseh; + delete CurveEditorwavguid; + delete CurveEditorwavhue; delete curveEditorbl; delete CCWcurveEditorG; delete curveEditorRES; @@ -1253,6 +1420,10 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) Backmethodconn.block(true); Tilesmethodconn.block(true); complexmethodconn.block(true); + denmethodconn.block(true); + mixmethodconn.block(true); + slimethodconn.block(true); + quamethodconn.block(true); daubcoeffmethodconn.block(true); Dirmethodconn.block(true); CHmethodconn.block(true); @@ -1380,6 +1551,39 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) complexmethod->set_active(1); } + if (pp->wavelet.denmethod == "equ") { + denmethod->set_active(0); + } else if (pp->wavelet.denmethod == "high") { + denmethod->set_active(1); + } else if (pp->wavelet.denmethod == "low") { + denmethod->set_active(2); + } else if (pp->wavelet.denmethod == "12high") { + denmethod->set_active(3); + } else if (pp->wavelet.denmethod == "12low") { + denmethod->set_active(4); + } + + if (pp->wavelet.mixmethod == "nois") { + mixmethod->set_active(0); + } else if (pp->wavelet.mixmethod == "mix") { + mixmethod->set_active(1); + } else if (pp->wavelet.mixmethod == "mix7") { + mixmethod->set_active(2); + } else if (pp->wavelet.mixmethod == "den") { + mixmethod->set_active(3); + } + + if (pp->wavelet.slimethod == "sli") { + slimethod->set_active(0); + } else if (pp->wavelet.slimethod == "cur") { + slimethod->set_active(1); + } + + if (pp->wavelet.quamethod == "cons") { + quamethod->set_active(0); + } else if (pp->wavelet.quamethod == "agre") { + quamethod->set_active(1); + } //Tilesmethod->set_active (2); if (pp->wavelet.Tilesmethod == "full") { @@ -1420,11 +1624,15 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) ccshape->setCurve(pp->wavelet.ccwcurve); blshape->setCurve(pp->wavelet.blcurve); opacityShapeRG->setCurve(pp->wavelet.opacityCurveRG); + wavdenoise->setCurve(pp->wavelet.wavdenoise); + wavdenoiseh->setCurve(pp->wavelet.wavdenoiseh); opacityShapeSH->setCurve(pp->wavelet.opacityCurveSH); opacityShapeBY->setCurve(pp->wavelet.opacityCurveBY); opacityShape->setCurve(pp->wavelet.opacityCurveW); opacityShapeWL->setCurve(pp->wavelet.opacityCurveWL); hhshape->setCurve(pp->wavelet.hhcurve); + wavguidf->setCurve(pp->wavelet.wavguidcurve); + wavhue->setCurve(pp->wavelet.wavhuecurve); Chshape->setCurve(pp->wavelet.Chcurve); clshape->setCurve(pp->wavelet.wavclCurve); expcontrast->setEnabled(pp->wavelet.expcontrast); @@ -1534,8 +1742,15 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) mergeC->setValue(pp->wavelet.mergeC); softrad->setValue(pp->wavelet.softrad); softradend->setValue(pp->wavelet.softradend); + strend->setValue(pp->wavelet.strend); + detend->setValue(pp->wavelet.detend); + thrend->setValue(pp->wavelet.thrend); labgrid->setParams(pp->wavelet.labgridALow / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridBLow / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridAHigh / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridBHigh / WaveletParams::LABGRID_CORR_MAX, false); + sigm->setValue(pp->wavelet.sigm); + levden->setValue(pp->wavelet.levden); + thrden->setValue(pp->wavelet.thrden); + limden->setValue(pp->wavelet.limden); ballum->setValue(pp->wavelet.ballum); balchrom->setValue(pp->wavelet.balchrom); chromfi->setValue(pp->wavelet.chromfi); @@ -1544,6 +1759,8 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) level1noise->setValue(pp->wavelet.level1noise); level2noise->setValue(pp->wavelet.level2noise); level3noise->setValue(pp->wavelet.level3noise); + leveldenoise->setValue(pp->wavelet.leveldenoise); + levelsigm->setValue(pp->wavelet.levelsigm); strength->setValue(pp->wavelet.strength); balance->setValue(pp->wavelet.balance); iter->setValue(pp->wavelet.iter); @@ -1585,6 +1802,21 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) complexmethod->set_active_text(M("GENERAL_UNCHANGED")); } + if (!pedited->wavelet.denmethod) { + denmethod->set_active_text(M("GENERAL_UNCHANGED")); + } + + if (!pedited->wavelet.mixmethod) { + mixmethod->set_active_text(M("GENERAL_UNCHANGED")); + } + + if (!pedited->wavelet.slimethod) { + slimethod->set_active_text(M("GENERAL_UNCHANGED")); + } + + if (!pedited->wavelet.quamethod) { + quamethod->set_active_text(M("GENERAL_UNCHANGED")); + } if (!pedited->wavelet.Tilesmethod) { Tilesmethod->set_active_text(M("GENERAL_UNCHANGED")); @@ -1650,9 +1882,13 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) opacityShapeRG->setCurve(pp->wavelet.opacityCurveRG); opacityShapeSH->setCurve(pp->wavelet.opacityCurveSH); opacityShapeBY->setCurve(pp->wavelet.opacityCurveBY); + wavdenoise->setCurve(pp->wavelet.wavdenoise); + wavdenoiseh->setCurve(pp->wavelet.wavdenoiseh); opacityShape->setCurve(pp->wavelet.opacityCurveW); opacityShapeWL->setCurve(pp->wavelet.opacityCurveWL); hhshape->setUnChanged(!pedited->wavelet.hhcurve); + wavguidf->setUnChanged(!pedited->wavelet.wavguidcurve); + wavhue->setUnChanged(!pedited->wavelet.wavhuecurve); Chshape->setUnChanged(!pedited->wavelet.Chcurve); clshape->setUnChanged(!pedited->wavelet.wavclCurve); avoid->set_inconsistent(!pedited->wavelet.avoid); @@ -1703,7 +1939,14 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) mergeC->setEditedState(pedited->wavelet.mergeC ? Edited : UnEdited); softrad->setEditedState(pedited->wavelet.softrad ? Edited : UnEdited); softradend->setEditedState(pedited->wavelet.softradend ? Edited : UnEdited); + strend->setEditedState(pedited->wavelet.strend ? Edited : UnEdited); + detend->setEditedState(pedited->wavelet.detend ? Edited : UnEdited); + thrend->setEditedState(pedited->wavelet.thrend ? Edited : UnEdited); + sigm->setEditedState(pedited->wavelet.sigm ? Edited : UnEdited); + levden->setEditedState(pedited->wavelet.levden ? Edited : UnEdited); + thrden->setEditedState(pedited->wavelet.thrden ? Edited : UnEdited); + limden->setEditedState(pedited->wavelet.limden ? Edited : UnEdited); ballum->setEditedState(pedited->wavelet.ballum ? Edited : UnEdited); balchrom->setEditedState(pedited->wavelet.balchrom ? Edited : UnEdited); chromfi->setEditedState(pedited->wavelet.chromfi ? Edited : UnEdited); @@ -1737,6 +1980,8 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) level1noise->setEditedState(pedited->wavelet.level1noise ? Edited : UnEdited); level2noise->setEditedState(pedited->wavelet.level2noise ? Edited : UnEdited); level3noise->setEditedState(pedited->wavelet.level3noise ? Edited : UnEdited); + leveldenoise->setEditedState(pedited->wavelet.leveldenoise ? Edited : UnEdited); + levelsigm->setEditedState(pedited->wavelet.levelsigm ? Edited : UnEdited); for (int i = 0; i < 9; i++) { correction[i]->setEditedState(pedited->wavelet.c[i] ? Edited : UnEdited); @@ -1824,6 +2069,10 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) Backmethodconn.block(false); Tilesmethodconn.block(false); complexmethodconn.block(false); + denmethodconn.block(false); + mixmethodconn.block(false); + slimethodconn.block(false); + quamethodconn.block(false); daubcoeffmethodconn.block(false); CHmethodconn.block(false); CHSLmethodconn.block(false); @@ -1853,9 +2102,13 @@ void Wavelet::setEditProvider(EditDataProvider *provider) opacityShapeRG->setEditProvider(provider); opacityShapeSH->setEditProvider(provider); opacityShapeBY->setEditProvider(provider); + wavdenoise->setEditProvider(provider); + wavdenoiseh->setEditProvider(provider); opacityShape->setEditProvider(provider); opacityShapeWL->setEditProvider(provider); hhshape->setEditProvider(provider); + wavguidf->setEditProvider(provider); + wavhue->setEditProvider(provider); Chshape->setEditProvider(provider); clshape->setEditProvider(provider); } @@ -1926,20 +2179,30 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.level1noise = level1noise->getValue (); pp->wavelet.level2noise = level2noise->getValue (); pp->wavelet.level3noise = level3noise->getValue (); + pp->wavelet.leveldenoise = leveldenoise->getValue (); + pp->wavelet.levelsigm = levelsigm->getValue (); pp->wavelet.ccwcurve = ccshape->getCurve(); pp->wavelet.blcurve = blshape->getCurve(); pp->wavelet.opacityCurveRG = opacityShapeRG->getCurve(); pp->wavelet.opacityCurveSH = opacityShapeSH->getCurve(); pp->wavelet.opacityCurveBY = opacityShapeBY->getCurve(); + pp->wavelet.wavdenoise = wavdenoise->getCurve(); + pp->wavelet.wavdenoiseh = wavdenoiseh->getCurve(); pp->wavelet.opacityCurveW = opacityShape->getCurve(); pp->wavelet.opacityCurveWL = opacityShapeWL->getCurve(); pp->wavelet.hhcurve = hhshape->getCurve(); + pp->wavelet.wavguidcurve = wavguidf->getCurve(); + pp->wavelet.wavhuecurve = wavhue->getCurve(); pp->wavelet.Chcurve = Chshape->getCurve(); pp->wavelet.pastlev = pastlev->getValue (); pp->wavelet.satlev = satlev->getValue (); pp->wavelet.strength = (int) strength->getValue(); pp->wavelet.balance = (int) balance->getValue(); pp->wavelet.balchrom = balchrom->getValue(); + pp->wavelet.sigm = sigm->getValue(); + pp->wavelet.levden = levden->getValue(); + pp->wavelet.thrden = thrden->getValue(); + pp->wavelet.limden = limden->getValue(); pp->wavelet.ballum = ballum->getValue(); pp->wavelet.chromfi = chromfi->getValue(); pp->wavelet.chromco = chromco->getValue(); @@ -1959,6 +2222,9 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.mergeC = mergeC->getValue(); pp->wavelet.softrad = softrad->getValue(); pp->wavelet.softradend = softradend->getValue(); + pp->wavelet.strend = strend->getValue(); + pp->wavelet.detend = detend->getIntValue(); + pp->wavelet.thrend = thrend->getValue(); pp->wavelet.expcontrast = expcontrast->getEnabled(); pp->wavelet.expchroma = expchroma->getEnabled(); pp->wavelet.expedge = expedge->getEnabled(); @@ -2004,6 +2270,10 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.Backmethod = Backmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.Tilesmethod = Tilesmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.complexmethod = complexmethod->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->wavelet.denmethod = denmethod->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->wavelet.mixmethod = mixmethod->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->wavelet.slimethod = slimethod->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->wavelet.quamethod = quamethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.daubcoeffmethod = daubcoeffmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.CHmethod = CHmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.CHSLmethod = CHSLmethod->get_active_text() != M("GENERAL_UNCHANGED"); @@ -2058,12 +2328,18 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.level1noise = level1noise->getEditedState(); pedited->wavelet.level2noise = level2noise->getEditedState(); pedited->wavelet.level3noise = level3noise->getEditedState(); + pedited->wavelet.leveldenoise = leveldenoise->getEditedState(); + pedited->wavelet.levelsigm = levelsigm->getEditedState(); pedited->wavelet.opacityCurveRG = !opacityShapeRG->isUnChanged(); pedited->wavelet.opacityCurveSH = !opacityShapeSH->isUnChanged(); pedited->wavelet.opacityCurveBY = !opacityShapeBY->isUnChanged(); + pedited->wavelet.wavdenoise = !wavdenoise->isUnChanged(); + pedited->wavelet.wavdenoiseh = !wavdenoiseh->isUnChanged(); pedited->wavelet.opacityCurveW = !opacityShape->isUnChanged(); pedited->wavelet.opacityCurveWL = !opacityShapeWL->isUnChanged(); pedited->wavelet.hhcurve = !hhshape->isUnChanged(); + pedited->wavelet.wavguidcurve = !wavguidf->isUnChanged(); + pedited->wavelet.wavhuecurve = !wavhue->isUnChanged(); pedited->wavelet.Chcurve = !Chshape->isUnChanged(); pedited->wavelet.bllev = bllev->getEditedState(); pedited->wavelet.pastlev = pastlev->getEditedState(); @@ -2075,6 +2351,10 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.bluemed = bluemed->getEditedState(); pedited->wavelet.greenhigh = greenhigh->getEditedState(); pedited->wavelet.bluehigh = bluehigh->getEditedState(); + pedited->wavelet.sigm = sigm->getEditedState(); + pedited->wavelet.levden = levden->getEditedState(); + pedited->wavelet.thrden = thrden->getEditedState(); + pedited->wavelet.limden = limden->getEditedState(); pedited->wavelet.ballum = ballum->getEditedState(); pedited->wavelet.balchrom = balchrom->getEditedState(); pedited->wavelet.chromfi = chromfi->getEditedState(); @@ -2083,6 +2363,9 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.mergeC = mergeC->getEditedState(); pedited->wavelet.softrad = softrad->getEditedState(); pedited->wavelet.softradend = softradend->getEditedState(); + pedited->wavelet.strend = strend->getEditedState(); + pedited->wavelet.detend = detend->getEditedState(); + pedited->wavelet.thrend = thrend->getEditedState(); pedited->wavelet.balance = balance->getEditedState(); pedited->wavelet.iter = iter->getEditedState(); pedited->wavelet.sigmafin = sigmafin->getEditedState(); @@ -2213,6 +2496,40 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.complexmethod = "expert"; } + if (denmethod->get_active_row_number() == 0) { + pp->wavelet.denmethod = "equ"; + } else if (denmethod->get_active_row_number() == 1) { + pp->wavelet.denmethod = "high"; + } else if (denmethod->get_active_row_number() == 2) { + pp->wavelet.denmethod = "low"; + } else if (denmethod->get_active_row_number() == 3) { + pp->wavelet.denmethod = "12high"; + } else if (denmethod->get_active_row_number() == 4) { + pp->wavelet.denmethod = "12low"; + } + + if (mixmethod->get_active_row_number() == 0) { + pp->wavelet.mixmethod = "nois"; + } else if (mixmethod->get_active_row_number() == 1) { + pp->wavelet.mixmethod = "mix"; + } else if (mixmethod->get_active_row_number() == 2) { + pp->wavelet.mixmethod = "mix7"; + } else if (mixmethod->get_active_row_number() == 3) { + pp->wavelet.mixmethod = "den"; + } + + if (slimethod->get_active_row_number() == 0) { + pp->wavelet.slimethod = "sli"; + } else if (slimethod->get_active_row_number() == 1) { + pp->wavelet.slimethod = "cur"; + } + + if (quamethod->get_active_row_number() == 0) { + pp->wavelet.quamethod = "cons"; + } else if (quamethod->get_active_row_number() == 1) { + pp->wavelet.quamethod = "agre"; + } + if (daubcoeffmethod->get_active_row_number() == 0) { pp->wavelet.daubcoeffmethod = "2_"; } else if (daubcoeffmethod->get_active_row_number() == 1) { @@ -2252,12 +2569,20 @@ void Wavelet::curveChanged(CurveEditor* ce) listener->panelChanged(EvWavlevelshc, M("HISTORY_CUSTOMCURVE")); } else if (ce == opacityShapeBY) { listener->panelChanged(EvWavOpac, M("HISTORY_CUSTOMCURVE")); + } else if (ce == wavdenoise) { + listener->panelChanged(EvWavdenoise, M("HISTORY_CUSTOMCURVE")); + } else if (ce == wavdenoiseh) { + listener->panelChanged(EvWavdenoiseh, M("HISTORY_CUSTOMCURVE")); } else if (ce == opacityShape) { listener->panelChanged(EvWavopacity, M("HISTORY_CUSTOMCURVE")); } else if (ce == opacityShapeWL) { listener->panelChanged(EvWavopacityWL, M("HISTORY_CUSTOMCURVE")); } else if (ce == hhshape) { listener->panelChanged(EvWavHHCurve, M("HISTORY_CUSTOMCURVE")); + } else if (ce == wavguidf) { + listener->panelChanged(EvWavguid, M("HISTORY_CUSTOMCURVE")); + } else if (ce == wavhue) { + listener->panelChanged(EvWavhue, M("HISTORY_CUSTOMCURVE")); } else if (ce == Chshape) { listener->panelChanged(EvWavCHCurve, M("HISTORY_CUSTOMCURVE")); } else if (ce == clshape) { @@ -2331,6 +2656,12 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit level1noise->setDefault (defParams->wavelet.level1noise); level2noise->setDefault (defParams->wavelet.level2noise); level3noise->setDefault (defParams->wavelet.level3noise); + leveldenoise->setDefault (defParams->wavelet.leveldenoise); + levelsigm->setDefault (defParams->wavelet.levelsigm); + sigm->setDefault(defParams->wavelet.sigm); + levden->setDefault(defParams->wavelet.levden); + thrden->setDefault(defParams->wavelet.thrden); + limden->setDefault(defParams->wavelet.limden); ballum->setDefault(defParams->wavelet.ballum); balchrom->setDefault(defParams->wavelet.balchrom); chromfi->setDefault(defParams->wavelet.chromfi); @@ -2347,6 +2678,9 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit mergeC->setDefault(defParams->wavelet.mergeC); softrad->setDefault(defParams->wavelet.softrad); softradend->setDefault(defParams->wavelet.softradend); + strend->setDefault(defParams->wavelet.strend); + detend->setDefault(defParams->wavelet.detend); + thrend->setDefault(defParams->wavelet.thrend); if (pedited) { greenlow->setDefaultEditedState(pedited->wavelet.greenlow ? Edited : UnEdited); @@ -2359,6 +2693,13 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit mergeC->setDefaultEditedState(pedited->wavelet.mergeC ? Edited : UnEdited); softrad->setDefaultEditedState(pedited->wavelet.softrad ? Edited : UnEdited); softradend->setDefaultEditedState(pedited->wavelet.softradend ? Edited : UnEdited); + strend->setDefaultEditedState(pedited->wavelet.strend ? Edited : UnEdited); + detend->setDefaultEditedState(pedited->wavelet.detend ? Edited : UnEdited); + thrend->setDefaultEditedState(pedited->wavelet.thrend ? Edited : UnEdited); + sigm->setDefaultEditedState(pedited->wavelet.sigm ? Edited : UnEdited); + levden->setDefaultEditedState(pedited->wavelet.levden ? Edited : UnEdited); + thrden->setDefaultEditedState(pedited->wavelet.thrden ? Edited : UnEdited); + limden->setDefaultEditedState(pedited->wavelet.limden ? Edited : UnEdited); ballum->setDefaultEditedState(pedited->wavelet.ballum ? Edited : UnEdited); balchrom->setDefaultEditedState(pedited->wavelet.balchrom ? Edited : UnEdited); chromfi->setDefaultEditedState(pedited->wavelet.chromfi ? Edited : UnEdited); @@ -2420,6 +2761,8 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit level1noise->setDefaultEditedState(pedited->wavelet.level1noise ? Edited : UnEdited); level2noise->setDefaultEditedState(pedited->wavelet.level2noise ? Edited : UnEdited); level3noise->setDefaultEditedState(pedited->wavelet.level3noise ? Edited : UnEdited); + leveldenoise->setDefaultEditedState(pedited->wavelet.leveldenoise ? Edited : UnEdited); + levelsigm->setDefaultEditedState(pedited->wavelet.levelsigm ? Edited : UnEdited); for (int i = 0; i < 9; i++) { correction[i]->setDefaultEditedState(pedited->wavelet.c[i] ? Edited : UnEdited); @@ -2473,6 +2816,8 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit level1noise->setDefaultEditedState(Irrelevant); level2noise->setDefaultEditedState(Irrelevant); level3noise->setDefaultEditedState(Irrelevant); + leveldenoise->setDefaultEditedState(Irrelevant); + levelsigm->setDefaultEditedState(Irrelevant); pastlev->setDefaultEditedState(Irrelevant); satlev->setDefaultEditedState(Irrelevant); strength->setDefaultEditedState(Irrelevant); @@ -2511,6 +2856,13 @@ void Wavelet::adjusterChanged(ThresholdAdjuster* a, double newBottom, double new } else if (a == level3noise) { listener->panelChanged(EvWavlev3nois, Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS") + ": %1" + "\n" + M("TP_WAVELET_STREN") + ": %2"), int(newTop), int(newBottom))); + } else if (a == leveldenoise) { + listener->panelChanged(EvWavlevdenois, + Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS") + ": %1" + "\n" + M("TP_WAVELET_DEN5THR") + ": %2"), int(newTop), int(newBottom))); + } else if (a == levelsigm) { + usleep(150); + listener->panelChanged(EvWavlevelsigm, + Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_LEVELLOW") + ": %1" + "\n" + M("TP_WAVELET_LEVELHIGH") + ": %2"), (newTop), (newBottom))); } } @@ -2896,6 +3248,15 @@ void Wavelet::convertParamToNormal() //denoise chromfi->setValue(def_params.chromfi); chromco->setValue(def_params.chromco); + denmethod->set_active(0); + mixmethod->set_active(2); + slimethod->set_active(0); + levelsigm->setValue(def_params.levelsigm); + leveldenoise->setValue(def_params.leveldenoise); + limden->setValue(def_params.limden); + +// quamethod->set_active(0); +// sigm->setValue(def_params.sigm); //toning exptoning->setEnabled(def_params.exptoning); //gamut @@ -2945,6 +3306,17 @@ void Wavelet::updateGUIToMode(int mode) blurFrame->hide(); cbenab->hide(); sigmafin->hide(); + denHBox->hide(); + mixHBox->hide(); + sliHBox->hide(); + sigm->show(); + levelsigm->hide(); + CurveEditorwavnoiseh->hide(); + CurveEditorwavnoise->hide(); + // levden->hide(); + thrden->show(); + leveldenoise->hide(); + limden->hide(); } else { offset->show(); sigma->show(); @@ -2962,6 +3334,28 @@ void Wavelet::updateGUIToMode(int mode) blurFrame->show(); cbenab->show(); sigmafin->show(); + denHBox->hide(); + mixHBox->show(); + sigm->hide(); + levelsigm->show(); + limden->show(); + // levden->show(); + sliHBox->show(); + if (slimethod->get_active_row_number() == 0){ + leveldenoise->show(); + thrden->show(); + CurveEditorwavnoiseh->hide(); + CurveEditorwavnoise->hide(); + } else { + thrden->hide(); + leveldenoise->show(); + CurveEditorwavnoiseh->show(); + CurveEditorwavnoise->show(); + } + disableListener(); + denmethod->set_active(0); + enableListener(); + } } @@ -2982,7 +3376,54 @@ void Wavelet::complexmethodChanged() } } +void Wavelet::denmethodChanged() +{ + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavdenmethod, denmethod->get_active_text()); + } +} + +void Wavelet::mixmethodChanged() +{ + + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavmixmethod, mixmethod->get_active_text()); + } +} + +void Wavelet::slimethodChanged() +{ + + if (slimethod->get_active_row_number() == 0 && complexmethod->get_active_row_number() == 0) { + updateGUIToMode(0); + convertParamToNormal(); + leveldenoise->show(); + } else if (slimethod->get_active_row_number() == 0 && complexmethod->get_active_row_number() == 1){ + updateGUIToMode(1); + leveldenoise->show(); + CurveEditorwavnoiseh->hide(); + CurveEditorwavnoise->hide(); + } else if (slimethod->get_active_row_number() == 1 && complexmethod->get_active_row_number() == 1){ + updateGUIToMode(1); + leveldenoise->show(); + CurveEditorwavnoiseh->show(); + CurveEditorwavnoise->show(); + } + + + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavslimethod, slimethod->get_active_text()); + } +} + +void Wavelet::quamethodChanged() +{ + + if (listener && (multiImage || getEnabled())) { + listener->panelChanged(EvWavquamethod, quamethod->get_active_text()); + } +} void Wavelet::TilesmethodChanged() { @@ -3066,6 +3507,10 @@ void Wavelet::setBatchMode(bool batchMode) Backmethod->append(M("GENERAL_UNCHANGED")); Tilesmethod->append(M("GENERAL_UNCHANGED")); complexmethod->append(M("GENERAL_UNCHANGED")); + denmethod->append(M("GENERAL_UNCHANGED")); + mixmethod->append(M("GENERAL_UNCHANGED")); + slimethod->append(M("GENERAL_UNCHANGED")); + quamethod->append(M("GENERAL_UNCHANGED")); daubcoeffmethod->append(M("GENERAL_UNCHANGED")); CHmethod->append(M("GENERAL_UNCHANGED")); Medgreinf->append(M("GENERAL_UNCHANGED")); @@ -3081,6 +3526,10 @@ void Wavelet::setBatchMode(bool batchMode) opaCurveEditorG->setBatchMode(batchMode); curveEditorC->setBatchMode(batchMode); opacityCurveEditorG->setBatchMode(batchMode); + CurveEditorwavnoise->setBatchMode(batchMode); + CurveEditorwavnoiseh->setBatchMode(batchMode); + CurveEditorwavguid->setBatchMode(batchMode); + CurveEditorwavhue->setBatchMode(batchMode); opacityCurveEditorW->setBatchMode(batchMode); opacityCurveEditorWL->setBatchMode(batchMode); curveEditorbl->setBatchMode(batchMode); @@ -3141,6 +3590,8 @@ void Wavelet::setBatchMode(bool batchMode) level1noise->showEditedCB(); level2noise->showEditedCB(); level3noise->showEditedCB(); + leveldenoise->showEditedCB(); + levelsigm->showEditedCB(); ToolPanel::setBatchMode(batchMode); @@ -3309,6 +3760,14 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWavbluehigh, bluehigh->getTextValue()); } else if (a == ballum) { listener->panelChanged(EvWavballum, ballum->getTextValue()); + } else if (a == sigm) { + listener->panelChanged(EvWavsigm, sigm->getTextValue()); + } else if (a == levden) { + listener->panelChanged(EvWavlevden, levden->getTextValue()); + } else if (a == thrden) { + listener->panelChanged(EvWavthrden, thrden->getTextValue()); + } else if (a == limden) { + listener->panelChanged(EvWavlimden, limden->getTextValue()); } else if (a == balchrom) { listener->panelChanged(EvWavbalchrom, balchrom->getTextValue()); } else if (a == chromfi) { @@ -3323,6 +3782,12 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWavsoftrad, softrad->getTextValue()); } else if (a == softradend) { listener->panelChanged(EvWavsoftradend, softradend->getTextValue()); + } else if (a == strend) { + listener->panelChanged(EvWavstrend, strend->getTextValue()); + } else if (a == detend) { + listener->panelChanged(EvWavdetend, detend->getTextValue()); + } else if (a == thrend) { + listener->panelChanged(EvWavthrend, thrend->getTextValue()); } else if (a == greenmed) { listener->panelChanged(EvWavgreenmed, greenmed->getTextValue()); } else if (a == bluemed) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index a497d2c4f..c7e002a64 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . * - * 2014 Jacques Desmis + * 2014 2020 Jacques Desmis */ #pragma once @@ -102,6 +102,23 @@ private: rtengine::ProcEvent EvWavprotab; rtengine::ProcEvent EvWavlevelshc; rtengine::ProcEvent EvWavcomplexmet; + rtengine::ProcEvent EvWavsigm; + rtengine::ProcEvent EvWavdenoise; + rtengine::ProcEvent EvWavdenmethod; + rtengine::ProcEvent EvWavmixmethod; + rtengine::ProcEvent EvWavquamethod; + rtengine::ProcEvent EvWavlevden; + rtengine::ProcEvent EvWavdenoiseh; + rtengine::ProcEvent EvWavstrend; + rtengine::ProcEvent EvWavdetend; + rtengine::ProcEvent EvWavlevdenois; + rtengine::ProcEvent EvWavslimethod; + rtengine::ProcEvent EvWavthrend; + rtengine::ProcEvent EvWavguid; + rtengine::ProcEvent EvWavhue; + rtengine::ProcEvent EvWavthrden; + rtengine::ProcEvent EvWavlevelsigm; + rtengine::ProcEvent EvWavlimden; LabGrid *labgrid; @@ -122,6 +139,10 @@ private: void MedgreinfChanged(); void TMmethodChanged(); void complexmethodChanged(); + void denmethodChanged(); + void mixmethodChanged(); + void quamethodChanged(); + void slimethodChanged(); void TilesmethodChanged(); void avoidToggled(); void showmaskToggled (); @@ -183,6 +204,14 @@ private: FlatCurveEditor* opacityShapeRG; CurveEditorGroup* const opacityCurveEditorG; FlatCurveEditor* opacityShapeBY; + CurveEditorGroup* const CurveEditorwavnoise; + FlatCurveEditor* wavdenoise; + CurveEditorGroup* const CurveEditorwavnoiseh; + FlatCurveEditor* wavdenoiseh; + CurveEditorGroup* const CurveEditorwavguid; + FlatCurveEditor* wavguidf; + CurveEditorGroup* const CurveEditorwavhue; + FlatCurveEditor* wavhue; CurveEditorGroup* const opacityCurveEditorW; CurveEditorGroup* const opacityCurveEditorWL; FlatCurveEditor* opacityShape; @@ -261,7 +290,13 @@ private: ThresholdAdjuster* const level1noise; ThresholdAdjuster* const level2noise; ThresholdAdjuster* const level3noise; + ThresholdAdjuster* const leveldenoise; + ThresholdAdjuster* const levelsigm; + Adjuster* const sigm; + Adjuster* const levden; + Adjuster* const thrden; + Adjuster* const limden; Adjuster* const threshold; Adjuster* const threshold2; Adjuster* const edgedetect; @@ -277,6 +312,9 @@ private: Adjuster* const mergeC; Adjuster* const softrad; Adjuster* const softradend; + Adjuster* const strend; + Adjuster* const detend; + Adjuster* const thrend; Adjuster* const chrwav; MyComboBoxText* const Lmethod; @@ -311,6 +349,14 @@ private: sigc::connection MedgreinfConn; MyComboBoxText* const ushamethod; sigc::connection ushamethodconn; + MyComboBoxText* const denmethod; + sigc::connection denmethodconn; + MyComboBoxText* const mixmethod; + sigc::connection mixmethodconn; + MyComboBoxText* const quamethod; + sigc::connection quamethodconn; + MyComboBoxText* const slimethod; + sigc::connection slimethodconn; Gtk::Frame* const chanMixerHLFrame; Gtk::Frame* const chanMixerMidFrame; @@ -323,6 +369,7 @@ private: Gtk::Frame* const fincFrame; Gtk::Frame* const dirFrame; Gtk::Frame* const tonFrame; + Gtk::Frame* const guidFrame; Gtk::Label* const wavLabels; Gtk::Label* const labmC; @@ -343,6 +390,10 @@ private: Gtk::HBox* const neutrHBox; Gtk::HBox* const usharpHBox; Gtk::HBox* const ctboxch; + Gtk::HBox* const quaHBox; + Gtk::HBox* const sliHBox; + Gtk::HBox* const denHBox; + Gtk::HBox* const mixHBox; Gtk::VBox* const ctboxBA;// = Gtk::manage(new Gtk::VBox()); sigc::connection enableChromaConn, enableContrastConn, enableEdgeConn, enabletmConn, enableFinalConn, enableclariConn;