diff --git a/rtdata/languages/default b/rtdata/languages/default index 186f0755c..c2e725036 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -625,6 +625,13 @@ HISTORY_MSG_392;W - Residual - CB Reset HISTORY_MSG_393;Use DCP's look table HISTORY_MSG_394;Use DCP's baseline exposure offset HISTORY_MSG_395;Use DCP's base table +HISTORY_MSG_396;W - Contrast sub-tool +HISTORY_MSG_397;W - Chroma sub-tool +HISTORY_MSG_398;W - ES sub-tool +HISTORY_MSG_399;W - Residual sub-tool +HISTORY_MSG_400;W - Final sub-tool +HISTORY_MSG_401;W - Toning sub-tool +HISTORY_MSG_402;W - Denoise sub-tool HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOTS;Snapshots diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index eb87c0924..2e4d8499f 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -142,6 +142,13 @@ struct cont_params { float bllow; float grlow; bool cbena; + bool contena; + bool chromena; + bool edgeena; + bool resena; + bool finena; + bool toningena; + bool noiseena; }; @@ -192,6 +199,20 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int cp.tmstrength=params->wavelet.tmrs; //cp.tonemap = params->wavelet.tmr; + cp.contena=true; + cp.contena=params->wavelet.expcontrast; + cp.chromena=true; + cp.chromena=params->wavelet.expchroma; + cp.edgeena=true; + cp.edgeena=params->wavelet.expedge; + cp.resena=true; + cp.resena=params->wavelet.expresid; + cp.finena=true; + cp.finena=params->wavelet.expfinal; + cp.toningena=true; + cp.toningena=params->wavelet.exptoning; + cp.noiseena=true; + cp.noiseena=params->wavelet.expnoise; if(params->wavelet.Backmethod=="black") cp.backm= 0; if(params->wavelet.Backmethod=="grey") cp.backm = 1; @@ -620,7 +641,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int int levwavL = levwav; bool ref0=false; - if(cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f) ref0=true; + if((cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f) && cp.noiseena) ref0=true; // printf("LevwavL before: %d\n",levwavL); if(cp.contrast == 0.f && cp.tonemap==false && cp.conres == 0.f && cp.conresH == 0.f && cp.val ==0 && !ref0 && params->wavelet.CLmethod=="all") { // no processing of residual L or edge=> we probably can reduce the number of levels @@ -650,7 +671,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int } int ind=0; bool ref=false; - if(cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f) ref=true; + if((cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f) && cp.noiseena) ref=true; bool contr=false; for(int f=0;f 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f) { + if((cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f) && cp.noiseena) { vari[0] = max(0.0001f,vari[0]); vari[1] = max(0.0001f,vari[1]); vari[2] = max(0.0001f,vari[2]); @@ -864,7 +885,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int L = labco->L[i1][j1]; const float Lin=labco->L[i1][j1]; - if(wavclCurve) {labco->L[i1][j1] =(0.5f*Lin + 1.5f*wavclCurve[Lin])/2.f;}//apply contrast curve + if(wavclCurve && cp.finena) {labco->L[i1][j1] =(0.5f*Lin + 1.5f*wavclCurve[Lin])/2.f;}//apply contrast curve L = labco->L[i1][j1]; float Lprov1=L/327.68f; @@ -904,7 +925,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int L = labco->L[i1][j1]; const float Lin=labco->L[i1][j1]; - if(wavclCurve) {labco->L[i1][j1] = (0.5f*Lin + 1.5f*wavclCurve[Lin])/2.f;}//apply contrast curve + if(wavclCurve && cp.finena) {labco->L[i1][j1] = (0.5f*Lin + 1.5f*wavclCurve[Lin])/2.f;}//apply contrast curve L = labco->L[i1][j1]; a = labco->a[i1][j1]; b = labco->b[i1][j1]; @@ -1346,7 +1367,7 @@ void ImProcFunctions::WaveletcontAllLfinal(LabImage * labco, float ** varhue, fl float max0 = 0.f; float min0 = FLT_MAX; - if(contrast != 0.f || cp.tonemap) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step + if(contrast != 0.f || cp.tonemap && cp.resena) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step #ifdef _RT_NESTED_OPENMP #pragma omp parallel for reduction(+:avedbl) num_threads(wavNestedLevels) if(wavNestedLevels>1) #endif @@ -1383,7 +1404,7 @@ void ImProcFunctions::WaveletcontAllLfinal(LabImage * labco, float ** varhue, fl // printf("MAXmax0=%f MINmin0=%f\n",max0,min0); //tone mapping -if(cp.tonemap && cp.contmet==2) { +if(cp.tonemap && cp.contmet==2 && cp.resena) { //iterate = 5 EPDToneMapResid(WavCoeffs_L0, 5, skip, cp, W_L, H_L, max0, min0); @@ -1421,7 +1442,7 @@ if(cp.tonemap && cp.contmet==2) { #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) #endif { - if(contrast != 0.f) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step + if(contrast != 0.f && cp.resena) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step { #ifdef _RT_NESTED_OPENMP #pragma omp for @@ -1446,7 +1467,7 @@ if(cp.tonemap && cp.contmet==2) { } } -if(cp.tonemap && cp.contmet==1) { +if(cp.tonemap && cp.contmet==1 && cp.resena) { float maxp=max0*256.f; float minp=min0*256.f; #ifdef _RT_NESTED_OPENMP @@ -1458,7 +1479,7 @@ if(cp.tonemap && cp.contmet==1) { #pragma omp barrier #endif - if(cp.conres != 0.f || cp.conresH != 0.f) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step + if((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step #ifdef _RT_NESTED_OPENMP #pragma omp for nowait #endif @@ -1545,9 +1566,10 @@ if(cp.detectedge && lipschitz==true) { //enabled Lipschitz control...more memory // interm /= 1.732f;//interm = pseudo variance koeLi interm *= 0.57736721f; float kampli = 1.f; + float eps=0.0001f; // I think this double ratio (alph, beta) is better than arctg - float alph = koeLi[lvl*3][i*W_L + j] / koeLi[lvl*3 + 1][i*W_L + j];//ratio between horizontal and vertical - float beta = koeLi[lvl*3+2][i*W_L + j] / koeLi[lvl*3 + 1][i*W_L + j];//ratio between diagonal and horizontal + float alph = koeLi[lvl*3][i*W_L + j] / (koeLi[lvl*3 + 1][i*W_L + j]+eps);//ratio between horizontal and vertical + float beta = koeLi[lvl*3+2][i*W_L + j] / (koeLi[lvl*3 + 1][i*W_L + j]+eps);//ratio between diagonal and horizontal float alipinfl=(eddlipampl-1.f)/(1.f-eddlipinfl); float blipinfl=eddlipampl-alipinfl; @@ -1618,7 +1640,7 @@ if(cp.detectedge && lipschitz==true) { //enabled Lipschitz control...more memory void ImProcFunctions::WaveletAandBAllAB(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, struct cont_params cp, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* hhCurve, bool hhutili){ // StopWatch Stop1("WaveletAandBAllAB"); - if (hhutili) { // H=f(H) + if (hhutili && cp.resena) { // H=f(H) int W_L = WaveletCoeffs_a.level_W(0); int H_L = WaveletCoeffs_a.level_H(0); @@ -1690,7 +1712,7 @@ if(cp.detectedge && lipschitz==true) { //enabled Lipschitz control...more memory #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) #endif { - if(cp.chrores != 0.f) { // cp.chrores == 0.f means all will be multiplied by 1.f, so we can skip the processing of residual + if(cp.chrores != 0.f && cp.resena) { // cp.chrores == 0.f means all will be multiplied by 1.f, so we can skip the processing of residual #ifdef _RT_NESTED_OPENMP #pragma omp for nowait @@ -1739,7 +1761,7 @@ if(cp.detectedge && lipschitz==true) { //enabled Lipschitz control...more memory } } - if(cp.cbena) {//if user select Toning and color balance + if(cp.cbena && cp.resena) {//if user select Toning and color balance #ifdef _RT_NESTED_OPENMP #pragma omp for nowait @@ -1974,7 +1996,7 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa bool lipschitz=true; float edge=1.f; bool curvdiag=true; - if(curvdiag) {//curve + if(curvdiag && cp.finena) {//curve float insigma=0.666f;//SD float logmax=log(MaxP[level]);//log Max float rapX=(mean[level]+sigma[level])/MaxP[level];//rapport between sD / max @@ -2115,7 +2137,7 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa bool refi=false; // if(cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f) refi=true; // if(cp.val > 0 || refi) {//edge - if(cp.val > 0) {//edge + if(cp.val > 0 && cp.edgeena) { float * koe; float maxkoe=0.f; if(lipschitz==false) { @@ -2205,7 +2227,7 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa // edge = 1.f + value * exp (expkoef);//estimate edge "pseudo variance" //take into account local contrast float refin= value * exp (expkoef); - if(cp.link==true){//combi + if(cp.link==true && cp.noiseena){//combi { if(level==0) refin *= (1.f + cp.lev0s/50.f);// we can change this sensibility! if(level==1) refin *= (1.f + cp.lev1s/50.f); @@ -2228,32 +2250,36 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa float absciss; float kinterm; float kmul; - for (int i=0; i 10.f) edge=(aedstr*cp.eddet+bedstr)*(edgePrecalc*(1.f+koe[i]))/(1.f+0.9f*maxkoe); - else edge=(edgePrecalc*(1.f+koe[i]))/(1.f+0.9f*maxkoe); + if(cp.eddet > 10.f) edge=(aedstr*cp.eddet+bedstr)*(edgePrecalc*(1.f+koe[k]))/(1.f+0.9f*maxkoe); + else edge=(edgePrecalc*(1.f+koe[k]))/(1.f+0.9f*maxkoe); } if(lipschitz==true) { - if(level < 3) edge = 1.f +(edgePrecalc-1.f)*(koeLi[level*3][i])/(1.f+0.9f*maxkoeLi[level*3+ dir-1]); + if(level < 3) edge = 1.f +(edgePrecalc-1.f)*(koeLi[level*3][k])/(1.f+0.9f*maxkoeLi[level*3+ dir-1]); else edge = edgePrecalc; } } else edge = edgePrecalc; if(cp.edgcurv) { - if(fabs(WavCoeffs_L[dir][i])>= (mean[level]+sigma[level])){//for max - float valcour=log(fabs(WavCoeffs_L[dir][i])); + if(fabs(WavCoeffs_L[dir][k])>= (mean[level]+sigma[level])){//for max + float valcour=log(fabs(WavCoeffs_L[dir][k])); float valc=valcour-logmax; float vald=valc*rap; absciss=exp(vald); } - else if(fabs(WavCoeffs_L[dir][i])>=mean[level] && fabs(WavCoeffs_L[dir][i]) < (mean[level]+sigma[level])){ - absciss=asig*fabs(WavCoeffs_L[dir][i])+bsig; + else if(fabs(WavCoeffs_L[dir][k])>=mean[level] && fabs(WavCoeffs_L[dir][k]) < (mean[level]+sigma[level])){ + absciss=asig*fabs(WavCoeffs_L[dir][k])+bsig; } - else if(fabs(WavCoeffs_L[dir][i]) < mean[level]){ - absciss=amean*fabs(WavCoeffs_L[dir][i]); + else if(fabs(WavCoeffs_L[dir][k]) < mean[level]){ + absciss=amean*fabs(WavCoeffs_L[dir][k]); } // Threshold adjuster settings==> approximative for curve //kmul about average cbrt(3--40 / 10)==>1.5 to 2.5 @@ -2288,7 +2314,8 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa if(edge < 1.f) edge=1.f; } - WavCoeffs_L[dir][i] *= edge; + WavCoeffs_L[dir][k] *= edge; + } } } else if(cp.EDmet==1) {//threshold adjuster @@ -2306,15 +2333,19 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa float edgeMaxFactor = SQR(cp.edg_max/b_r); float edgMaxFsup=(cp.edg_max/b_r);//reduce increase of effect for high values contrast..if slider > b_r - for (int i=0; i 10.f) edge=(aedstr*cp.eddet+bedstr)*(edgePrecalc*(1.f+koe[i]))/(1.f+0.9f*maxkoe); - else edge=(edgePrecalc*(1.f+koe[i]))/(1.f+0.9f*maxkoe); + if(cp.eddet > 10.f) edge=(aedstr*cp.eddet+bedstr)*(edgePrecalc*(1.f+koe[k]))/(1.f+0.9f*maxkoe); + else edge=(edgePrecalc*(1.f+koe[k]))/(1.f+0.9f*maxkoe); } if(lipschitz==true) { - if(level < 3) edge = 1.f +(edgePrecalc-1.f)*(koeLi[level*3][i])/(1.f+0.9f*maxkoeLi[level*3+ dir-1]); + if(level < 3) edge = 1.f +(edgePrecalc-1.f)*(koeLi[level*3][k])/(1.f+0.9f*maxkoeLi[level*3+ dir-1]); else edge = edgePrecalc; } } @@ -2331,46 +2362,47 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa // if we move sliders to the right local contrast is increased // MaxP, MaxN, mean, sigma are calculated if necessary (val > 0) by evaluate2(), eval2(), aver() , sigma() if(b_r < 100.f && cp.edg_max/b_r > 1.f) {//in case of b_r < 100 and slider move to right - if (WavCoeffs_L[dir][i] > MaxPCompare*cp.edg_max/b_r) { + if (WavCoeffs_L[dir][k] > MaxPCompare*cp.edg_max/b_r) { edge *= edgMaxFsup; if(edge < 1.f) edge=1.f; } - else if (WavCoeffs_L[dir][i] < MaxNCompare*cp.edg_max/b_r) { + else if (WavCoeffs_L[dir][k] < MaxNCompare*cp.edg_max/b_r) { edge *= edgMaxFsup; if(edge < 1.f) edge=1.f; } } - if (WavCoeffs_L[dir][i] > MaxPCompare) { + if (WavCoeffs_L[dir][k] > MaxPCompare) { edge *= edgeMaxFactor; if(edge < 1.f) edge=1.f; }//reduce edge if > new max - else if (WavCoeffs_L[dir][i] < MaxNCompare) { + else if (WavCoeffs_L[dir][k] < MaxNCompare) { edge *= edgeMaxFactor; if(edge < 1.f) edge=1.f; } - if (fabs(WavCoeffs_L[dir][i]) >= edgeMeanCompare && fabs(WavCoeffs_L[dir][i]) < edgeSdCompare) { + if (fabs(WavCoeffs_L[dir][k]) >= edgeMeanCompare && fabs(WavCoeffs_L[dir][k]) < edgeSdCompare) { //if (fabs(WavCoeffs_L[dir][i]) > edgeSdCompare) { edge *= edgeSdFactor; if(edge < 1.f) edge=1.f; }//mofify effect if sd change - if (fabs(WavCoeffs_L[dir][i]) < edgeMeanCompare) { + if (fabs(WavCoeffs_L[dir][k]) < edgeMeanCompare) { edge *= edgeMeanFactor; if(edge < 1.f) edge=1.f; } // modify effect if mean change - if (fabs(WavCoeffs_L[dir][i]) < edgeLowCompare) { + if (fabs(WavCoeffs_L[dir][k]) < edgeLowCompare) { edge *= edgeLowFactor; if(edge < 1.f) edge=1.f; } - WavCoeffs_L[dir][i] *= edge; + WavCoeffs_L[dir][k] *= edge; + } } } if(lipschitz==false) { @@ -2379,7 +2411,7 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa } - if(cp.link==false) { //used both with denoise 1 2 3 + if(cp.link==false && cp.noiseena) { //used both with denoise 1 2 3 float refine=0.f; for (int i=0; iwavelet.skinprotect; const float skinprotneg = -skinprot; @@ -2489,7 +2521,7 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa } */ float alpha = (1024.f + 15.f *(float) cpMul*scale*scale2*beta*diagacc)/1024.f ; - if(cp.HSmet){ + if(cp.HSmet && cp.chromena){ float aaal=(1.f-alpha)/((cp.b_lhl-cp.t_lhl)*kH[level]); float bbal=1.f-aaal*cp.b_lhl*kH[level]; float aaar=(alpha-1.f)/(cp.t_rhl-cp.b_rhl)*kH[level]; @@ -2520,7 +2552,7 @@ void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, floa } if(waOpacityCurveW) cp.opaW=true; -if(cp.bam) { +if(cp.bam && cp.finena) { if(cp.opaW && cp.BAmet==2){ int iteration = cp.ite; int itplus=7+iteration; @@ -2605,7 +2637,7 @@ if(cp.BAmet==1){ int W_ab, int H_ab, const bool useChannelA) { float cpMul = cp.mul[level]; - if(cpMul != 0.f && cp.CHmet==2 && cp.chro != 0.f) { // cpMul == 0.f or cp.chro = 0.f means all will be multiplied by 1.f, so we can skip this + if(cpMul != 0.f && cp.CHmet==2 && cp.chro != 0.f && cp.chromena) { // cpMul == 0.f or cp.chro = 0.f means all will be multiplied by 1.f, so we can skip this const float skinprot = params->wavelet.skinprotect; const float skinprotneg = -skinprot; const float factorHard = (1.f - skinprotneg/100.f); @@ -2638,7 +2670,7 @@ if(cp.BAmet==1){ float cpMulC = cp.mulC[level]; // if( (cp.curv || cp.CHSLmet==1) && cp.CHmet!=2 && level < 9 && cpMulC != 0.f) { // cpMulC == 0.f means all will be multiplied by 1.f, so we can skip - if( cp.CHmet!=2 && level < 9 && cpMulC != 0.f) { // cpMulC == 0.f means all will be multiplied by 1.f, so we can skip + if( cp.CHmet!=2 && level < 9 && cpMulC != 0.f && cp.chromena) { // cpMulC == 0.f means all will be multiplied by 1.f, so we can skip float modchro, modhue, kClev; const float skinprot = params->wavelet.skinprotect; const float skinprotneg = -skinprot; @@ -2718,7 +2750,7 @@ if(cp.BAmet==1){ mulOpacity = cp.mulopaBY[level]; } - if(useOpacity && level < 9 && mulOpacity != 0.f) { //toning + if((useOpacity && level < 9 && mulOpacity != 0.f) && cp.toningena) { //toning float beta = (1024.f + 20.f * mulOpacity)/1024.f ; //float beta = (1000.f * mulOpacity); diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 2f926e545..4e6a7f4ec 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -420,6 +420,13 @@ enum ProcEvent { EvDCPApplyLookTable=392, EvDCPApplyBaselineExposureOffset=393, EvDCPApplyHueSatMap=394, + EvWavenacont=395, + EvWavenachrom=396, + EvWavenaedge=397, + EvWavenares=398, + EvWavenafin=399, + EvWavenatoning=400, + EvWavenanoise=401, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index b6fdad148..c975d1c3c 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -554,6 +554,13 @@ void WaveletParams::setDefaults() { hhcurve.push_back(FCT_Linear); Chcurve.clear (); Chcurve.push_back(FCT_Linear); + expcontrast=true; + expchroma=true; + expedge=true; + expresid=true; + expfinal=true; + exptoning=true; + expnoise=true; for(int i = 0; i < 9; i ++) { @@ -1640,6 +1647,13 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol if (!pedited || pedited->wavelet.bluehigh) keyFile.set_integer ("Wavelet", "CBbluehigh", wavelet.bluehigh); if (!pedited || pedited->wavelet.bluemed) keyFile.set_integer ("Wavelet", "CBbluemed", wavelet.bluemed); if (!pedited || pedited->wavelet.bluelow) keyFile.set_integer ("Wavelet", "CBbluelow", wavelet.bluelow); + if (!pedited || pedited->wavelet.expcontrast) keyFile.set_boolean ("Wavelet", "Expcontrast", wavelet.expcontrast); + if (!pedited || pedited->wavelet.expchroma) keyFile.set_boolean ("Wavelet", "Expchroma", wavelet.expchroma); + if (!pedited || pedited->wavelet.expedge) keyFile.set_boolean ("Wavelet", "Expedge", wavelet.expedge); + if (!pedited || pedited->wavelet.expresid) keyFile.set_boolean ("Wavelet", "Expresid", wavelet.expresid); + if (!pedited || pedited->wavelet.expfinal) keyFile.set_boolean ("Wavelet", "Expfinal", wavelet.expfinal); + if (!pedited || pedited->wavelet.exptoning) keyFile.set_boolean ("Wavelet", "Exptoning", wavelet.exptoning); + if (!pedited || pedited->wavelet.expnoise) keyFile.set_boolean ("Wavelet", "Expnoise", wavelet.expnoise); for(int i = 0; i < 9; i++) { @@ -2637,6 +2651,8 @@ if (keyFile.has_group ("Wavelet")) { if(keyFile.has_key ("Wavelet", "Skinprotect")) { wavelet.skinprotect = keyFile.get_double ("Wavelet", "Skinprotect"); if (pedited) pedited->wavelet.skinprotect = true; } + if (keyFile.has_key ("Wavelet", "Expcontrast")) {wavelet.expcontrast = keyFile.get_boolean ("Wavelet", "Expcontrast");if (pedited) pedited->wavelet.expcontrast = true;} + if (keyFile.has_key ("Wavelet", "Expchroma")) {wavelet.expchroma = keyFile.get_boolean ("Wavelet", "Expchroma");if (pedited) pedited->wavelet.expchroma = true;} for(int i = 0; i < 9; i ++) { std::stringstream ss; @@ -2649,6 +2665,12 @@ if (keyFile.has_group ("Wavelet")) { ss << "Chroma" << (i+1); if(keyFile.has_key ("Wavelet", ss.str())) {wavelet.ch[i] = keyFile.get_integer ("Wavelet", ss.str()); if (pedited) pedited->wavelet.ch[i] = true;} } + if (keyFile.has_key ("Wavelet", "Expedge")) {wavelet.expedge = keyFile.get_boolean ("Wavelet", "Expedge");if (pedited) pedited->wavelet.expedge = true;} + if (keyFile.has_key ("Wavelet", "Expresid")) {wavelet.expresid = keyFile.get_boolean ("Wavelet", "Expresid");if (pedited) pedited->wavelet.expresid = true;} + if (keyFile.has_key ("Wavelet", "Expfinal")) {wavelet.expfinal = keyFile.get_boolean ("Wavelet", "Expfinal");if (pedited) pedited->wavelet.expfinal = true;} + if (keyFile.has_key ("Wavelet", "Exptoning")) {wavelet.exptoning = keyFile.get_boolean ("Wavelet", "Exptoning");if (pedited) pedited->wavelet.exptoning = true;} + if (keyFile.has_key ("Wavelet", "Expnoise")) {wavelet.expnoise = keyFile.get_boolean ("Wavelet", "Expnoise");if (pedited) pedited->wavelet.expnoise = true;} + } @@ -3222,6 +3244,13 @@ bool ProcParams::operator== (const ProcParams& other) { && wavelet.tmr == other.wavelet.tmr && wavelet.contrast == other.wavelet.contrast && wavelet.median == other.wavelet.median + && wavelet.expcontrast == other.wavelet.expcontrast + && wavelet.expchroma == other.wavelet.expchroma + && wavelet.expedge == other.wavelet.expedge + && wavelet.expresid == other.wavelet.expresid + && wavelet.expfinal == other.wavelet.expfinal + && wavelet.exptoning == other.wavelet.exptoning + && wavelet.expnoise == other.wavelet.expnoise && wavelet.medianlev == other.wavelet.medianlev && wavelet.linkedg == other.wavelet.linkedg && wavelet.cbenab == other.wavelet.cbenab diff --git a/rtengine/procparams.h b/rtengine/procparams.h index d15f39f14..b7e9fd573 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -889,8 +889,15 @@ class WaveletParams { int strength; int balance; int iter; + bool expcontrast; + bool expchroma; int c[9]; int ch[9]; + bool expedge; + bool expresid; + bool expfinal; + bool exptoning; + bool expnoise; Glib::ustring Lmethod; Glib::ustring CLmethod; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index d2cf58687..7d0dc5603 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -416,7 +416,14 @@ DIRPYREQUALIZER, // EvWavbluelow DIRPYREQUALIZER, // EvWavNeutral RGBCURVE, // EvDCPApplyLookTable, RGBCURVE, // EvDCPApplyBaselineExposureOffset, -ALL // EvDCPApplyHueSatMap +ALL, // EvDCPApplyHueSatMap +DIRPYREQUALIZER, // EvWavenacont +DIRPYREQUALIZER, // EvWavenachrom +DIRPYREQUALIZER, // EvWavenaedge +DIRPYREQUALIZER, // EvWavenares +DIRPYREQUALIZER, // EvWavenafin +DIRPYREQUALIZER, // EvWavenatoning +DIRPYREQUALIZER // EvWavenanoise }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index e198bc89f..c5d99bb97 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -424,6 +424,17 @@ void ParamsEdited::set (bool v) { wavelet.pastlev = v; wavelet.satlev = v; +// wavelet.enacont = v; +// wavelet.enachrom = v; +// wavelet.enaedge = v; +// wavelet.enares = v; + wavelet.expfinal = v; + wavelet.expcontrast = v; + wavelet.expchroma = v; + wavelet.expedge = v; + wavelet.expresid = v; + wavelet.exptoning = v; + wavelet.expnoise = v; for(int i = 0; i < 9; i++) { wavelet.c[i] = v; @@ -857,6 +868,15 @@ void ParamsEdited::initFrom (const std::vector wavelet.hhcurve = wavelet.hhcurve && p.wavelet.hhcurve == other.wavelet.hhcurve; 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; + wavelet.expcontrast = wavelet.expcontrast && p.wavelet.expcontrast == other.wavelet.expcontrast; + wavelet.expchroma = wavelet.expchroma && p.wavelet.expchroma == other.wavelet.expchroma; + wavelet.expedge = wavelet.expedge && p.wavelet.expedge == other.wavelet.expedge; + wavelet.expresid = wavelet.expresid && p.wavelet.expresid == other.wavelet.expresid; + wavelet.expfinal = wavelet.expfinal && p.wavelet.expfinal == other.wavelet.expfinal; + wavelet.exptoning = wavelet.exptoning && p.wavelet.exptoning == other.wavelet.exptoning; + wavelet.expnoise = wavelet.expnoise && p.wavelet.expnoise == other.wavelet.expnoise; + for(int i = 0; i < 9; i++) { wavelet.c[i] = wavelet.c[i] && p.wavelet.c[i] == other.wavelet.c[i]; } @@ -1276,6 +1296,15 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (wavelet.hhcurve) toEdit.wavelet.hhcurve = mods.wavelet.hhcurve; if (wavelet.Chcurve) toEdit.wavelet.Chcurve = mods.wavelet.Chcurve; if (wavelet.wavclCurve) toEdit.wavelet.wavclCurve = mods.wavelet.wavclCurve; + //if (wavelet.enacont) toEdit.wavelet.enacont = mods.wavelet.enacont; + if (wavelet.expcontrast) toEdit.wavelet.expcontrast = mods.wavelet.expcontrast; + if (wavelet.expchroma) toEdit.wavelet.expchroma = mods.wavelet.expchroma; + if (wavelet.expedge) toEdit.wavelet.expedge = mods.wavelet.expedge; + if (wavelet.expresid) toEdit.wavelet.expresid = mods.wavelet.expresid; + if (wavelet.expfinal) toEdit.wavelet.expfinal = mods.wavelet.expfinal; + if (wavelet.exptoning) toEdit.wavelet.exptoning = mods.wavelet.exptoning; + if (wavelet.expnoise) toEdit.wavelet.expnoise = mods.wavelet.expnoise; + for(int i = 0; i < 9; i++) { if(wavelet.c[i]) toEdit.wavelet.c[i] = dontforceSet && options.baBehav[ADDSET_WA] ? toEdit.wavelet.c[i] + mods.wavelet.c[i] : mods.wavelet.c[i]; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 0aaf0cd99..9ce247f74 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -551,6 +551,14 @@ class WaveletParamsEdited { bool bluemed; bool greenhigh; bool bluehigh; + bool enacont; + bool expcontrast; + bool expchroma; + bool expedge; + bool expresid; + bool expfinal; + bool exptoning; + bool expnoise; }; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 9e403386a..73569a63f 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -56,21 +56,21 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), expsettings = new MyExpander (false, M("TP_WAVELET_SETTINGS")); expsettings->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButSettings) ); - expcontrast = new MyExpander (false, M("TP_WAVELET_LEVF")); + expcontrast = new MyExpander (true, M("TP_WAVELET_LEVF")); expcontrast->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButContrast) ); - expchroma = new MyExpander (false, M("TP_WAVELET_LEVCH")); + expchroma = new MyExpander (true, M("TP_WAVELET_LEVCH")); expchroma->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButChroma) ); - exptoning = new MyExpander (false,M("TP_WAVELET_TON")); + exptoning = new MyExpander (true,M("TP_WAVELET_TON")); exptoning->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButToning) ); - expnoise = new MyExpander (false, M("TP_WAVELET_NOISE")); + expnoise = new MyExpander (true, M("TP_WAVELET_NOISE")); expnoise->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButNoise) ); - expedge = new MyExpander (false, M("TP_WAVELET_EDGE")); + expedge = new MyExpander (true, M("TP_WAVELET_EDGE")); expedge->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButEdge) ); expgamut = new MyExpander (false, M("TP_WAVELET_CONTR")); expgamut->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButGamut) ); - expresid = new MyExpander (false, M("TP_WAVELET_RESID")); + expresid = new MyExpander (true, M("TP_WAVELET_RESID")); expresid->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButResid) ); - expfinal = new MyExpander (false, M("TP_WAVELET_FINAL")); + expfinal = new MyExpander (true, M("TP_WAVELET_FINAL")); expfinal->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButFinal) ); // Wavelet Settings @@ -172,6 +172,7 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), levBox->set_border_width(4); levBox->set_spacing(2); + Gtk::HBox * buttonBox = Gtk::manage (new Gtk::HBox(true, 10)); wavLabels = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); levBox->pack_start(*buttonBox, Gtk::PACK_SHRINK, 2); @@ -527,7 +528,7 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), Gtk::VBox * resBox = Gtk::manage (new Gtk::VBox()); resBox->set_border_width(4); resBox->set_spacing(2); - + rescon = Gtk::manage (new Adjuster (M("TP_WAVELET_RESCON"), -100, 100, 1, 0)); rescon->setAdjusterListener (this); resBox->pack_start(*rescon, Gtk::PACK_SHRINK); @@ -694,17 +695,26 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), resBox->pack_start (*neutrHBox); // Final Touchup - ctboxBA = Gtk::manage (new Gtk::HBox ()); - labmBA = Gtk::manage (new Gtk::Label (M("TP_WAVELET_BATYPE")+":")); - ctboxBA->pack_start (*labmBA, Gtk::PACK_SHRINK, 1); + Gtk::VBox * ctboxBA = Gtk::manage (new Gtk::VBox()); + ctboxBA->set_border_width(4); + ctboxBA->set_spacing(2); + + //Gtk::HSeparator *separatorfin = Gtk::manage (new Gtk::HSeparator()); + //ctboxBA->pack_start(*separatorfin, Gtk::PACK_SHRINK, 2); + ctboxFI = Gtk::manage (new Gtk::HBox()); + + labmBA = Gtk::manage (new Gtk::Label (M("TP_WAVELET_BATYPE")+":")); + ctboxFI->pack_start (*labmBA, Gtk::PACK_SHRINK, 1); + BAmethod = Gtk::manage (new MyComboBoxText ()); BAmethod->append_text (M("TP_WAVELET_BANONE")); BAmethod->append_text (M("TP_WAVELET_BASLI")); BAmethod->append_text (M("TP_WAVELET_BACUR")); BAmethodconn = BAmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::BAmethodChanged) ); - ctboxBA->pack_start(*BAmethod); - + ctboxFI->pack_start(*BAmethod); + ctboxBA->pack_start(*ctboxFI); + balance = Gtk::manage (new Adjuster (M("TP_WAVELET_BALANCE"), -30, 100, 1, 0)); balance->setAdjusterListener (this); balance->set_tooltip_text (M("TP_WAVELET_BALANCE_TOOLTIP")); @@ -1036,8 +1046,17 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { if (!pedited->wavelet.Medgreinf) Medgreinf->set_active (2); + + set_inconsistent (multiImage && !pedited->wavelet.enabled); ccshape->setUnChanged (!pedited->wavelet.ccwcurve); + expcontrast->set_inconsistent (!pedited->wavelet.expcontrast); + expchroma->set_inconsistent (!pedited->wavelet.expchroma); + expedge->set_inconsistent (!pedited->wavelet.expedge); + expresid->set_inconsistent (!pedited->wavelet.expresid); + expfinal->set_inconsistent (!pedited->wavelet.expfinal); + exptoning->set_inconsistent (!pedited->wavelet.exptoning); + expnoise->set_inconsistent (!pedited->wavelet.expnoise); opacityShapeRG->setCurve (pp->wavelet.opacityCurveRG); opacityShapeBY->setCurve (pp->wavelet.opacityCurveBY); opacityShape->setCurve (pp->wavelet.opacityCurveW); @@ -1104,6 +1123,8 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { for(int i = 0; i < 9; i++) { correctionch[i]->setEditedState (pedited->wavelet.ch[i] ? Edited : UnEdited); } + + } ccshape->setCurve (pp->wavelet.ccwcurve); opacityShapeRG->setCurve (pp->wavelet.opacityCurveRG); @@ -1113,6 +1134,13 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { hhshape->setCurve (pp->wavelet.hhcurve); Chshape->setCurve (pp->wavelet.Chcurve); clshape->setCurve (pp->wavelet.wavclCurve); + expcontrast->setEnabled (pp->wavelet.expcontrast); + expchroma->setEnabled (pp->wavelet.expchroma); + expedge->setEnabled (pp->wavelet.expedge); + expresid->setEnabled (pp->wavelet.expresid); + expfinal->setEnabled (pp->wavelet.expfinal); + exptoning->setEnabled (pp->wavelet.exptoning); + expnoise->setEnabled (pp->wavelet.expnoise); setEnabled(pp->wavelet.enabled); avoidConn.block (true); @@ -1194,9 +1222,11 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { for (int i = 0; i < 9; i++) { correction[i]->setValue(pp->wavelet.c[i]); } + for (int i = 0; i < 9; i++) { correctionch[i]->setValue(pp->wavelet.ch[i]); } + int y; y=thres->getValue(); int z; @@ -1317,6 +1347,13 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { pp->wavelet.bluemed = bluemed->getValue (); pp->wavelet.greenhigh = greenhigh->getValue (); pp->wavelet.bluehigh = bluehigh->getValue (); + pp->wavelet.expcontrast = expcontrast->getEnabled(); + pp->wavelet.expchroma = expchroma->getEnabled(); + pp->wavelet.expedge = expedge->getEnabled(); + pp->wavelet.expresid = expresid->getEnabled(); + pp->wavelet.expfinal = expfinal->getEnabled(); + pp->wavelet.exptoning = exptoning->getEnabled(); + pp->wavelet.expnoise = expnoise->getEnabled(); pp->wavelet.iter = (int) iter->getValue(); pp->wavelet.wavclCurve = clshape->getCurve (); @@ -1400,6 +1437,13 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { pedited->wavelet.balance = balance->getEditedState (); pedited->wavelet.iter = iter->getEditedState (); pedited->wavelet.wavclCurve = !clshape->isUnChanged (); + pedited->wavelet.expcontrast = !expcontrast->get_inconsistent(); + pedited->wavelet.expchroma = !expchroma->get_inconsistent(); + pedited->wavelet.expedge = !expedge->get_inconsistent(); + pedited->wavelet.expresid = !expresid->get_inconsistent(); + pedited->wavelet.expfinal = !expfinal->get_inconsistent(); + pedited->wavelet.exptoning = !exptoning->get_inconsistent(); + pedited->wavelet.expnoise = !expnoise->get_inconsistent(); for(int i = 0; i < 9; i++) { pedited->wavelet.c[i] = correction[i]->getEditedState(); @@ -1501,6 +1545,7 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { } + void Wavelet::curveChanged (CurveEditor* ce) { if (listener && getEnabled()) { @@ -2229,11 +2274,11 @@ void Wavelet::adjusterChanged (Adjuster* a, double newval) { listener->panelChanged (EvWavbluelow, Glib::ustring::compose("%1", Glib::ustring::format(std::fixed, std::setprecision(0), bluelow->getValue())) - ); + ); } - else if (a == correction[0] || a == correction[1] || a == correction[2] || a == correction[3] || a == correction[4] || a == correction[5] || a == correction[6] || a == correction[7] || a == correction[8] ) { - listener->panelChanged (EvWavelet, + if ((a == correction[0] || a == correction[1] || a == correction[2] || a == correction[3] || a == correction[4] || a == correction[5] || a == correction[6] || a == correction[7] || a == correction[8])) { + listener->panelChanged (EvWavelet, Glib::ustring::compose("%1, %2, %3, %4, %5, %6, %7, %8, %9", Glib::ustring::format(std::fixed, std::setprecision(0), correction[0]->getValue()), Glib::ustring::format(std::fixed, std::setprecision(0), correction[1]->getValue()), @@ -2638,31 +2683,78 @@ void Wavelet::foldAllButSettings (GdkEventButton* event) { void Wavelet::foldAllButContrast (GdkEventButton* event) { if (event->button == 3) { foldAllButOne(expcontrast); + + } + if (listener) { + if (expcontrast->getEnabled ()) + { listener->panelChanged (EvWavenacont, M("GENERAL_ENABLED")); + } + else + { listener->panelChanged (EvWavenacont, M("GENERAL_DISABLED")); + } + } + } void Wavelet::foldAllButChroma (GdkEventButton* event) { if (event->button == 3) { foldAllButOne(expchroma); } + if (listener) { + if (expchroma->getEnabled ()) + { listener->panelChanged (EvWavenachrom, M("GENERAL_ENABLED")); + } + else + { listener->panelChanged (EvWavenachrom, M("GENERAL_DISABLED")); + } + } + } void Wavelet::foldAllButToning (GdkEventButton* event) { if (event->button == 3) { foldAllButOne(exptoning); } + if (listener) { + if (exptoning->getEnabled ()) + { listener->panelChanged (EvWavenatoning, M("GENERAL_ENABLED")); + } + else + { listener->panelChanged (EvWavenatoning, M("GENERAL_DISABLED")); + } + } + } void Wavelet::foldAllButNoise (GdkEventButton* event) { if (event->button == 3) { foldAllButOne(expnoise); } + if (listener) { + if (expnoise->getEnabled ()) + { listener->panelChanged (EvWavenanoise, M("GENERAL_ENABLED")); + } + else + { listener->panelChanged (EvWavenanoise, M("GENERAL_DISABLED")); + } + } + } void Wavelet::foldAllButEdge (GdkEventButton* event) { if (event->button == 3) { foldAllButOne(expedge); } + if (listener) { + if (expedge->getEnabled ()) + { listener->panelChanged (EvWavenaedge, M("GENERAL_ENABLED")); + } + else + { listener->panelChanged (EvWavenaedge, M("GENERAL_DISABLED")); + } + } + } void Wavelet::foldAllButGamut (GdkEventButton* event) { @@ -2675,12 +2767,31 @@ void Wavelet::foldAllButResid (GdkEventButton* event) { if (event->button == 3) { foldAllButOne(expresid); } + if (listener) { + if (expresid->getEnabled ()) + { listener->panelChanged (EvWavenares, M("GENERAL_ENABLED")); + } + else + { listener->panelChanged (EvWavenares, M("GENERAL_DISABLED")); + } + } + + } void Wavelet::foldAllButFinal (GdkEventButton* event) { if (event->button == 3) { foldAllButOne(expfinal); } + if (listener) { + if (expfinal->getEnabled ()) + { listener->panelChanged (EvWavenafin, M("GENERAL_ENABLED")); + } + else + { listener->panelChanged (EvWavenafin, M("GENERAL_DISABLED")); + } + } + } void Wavelet::foldAllButOne (MyExpander * whichOne) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 28f4ef05c..e773ba672 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -75,7 +75,6 @@ protected: Gtk::CheckButton * tmr; Gtk::Button * neutralchButton; - Adjuster* correction[9]; Adjuster* correctionch[9]; Adjuster* rescon; @@ -197,7 +196,7 @@ protected: Gtk::HBox* levdirSubHBox; Gtk::HBox* tilesizeHBox; - Gtk::HBox* ctboxBA; + Gtk::HBox* ctboxFI; Gtk::HBox* ctboxch; Gtk::HBox* edbox; Gtk::HBox* ednoisbox;