diff --git a/rtdata/languages/default b/rtdata/languages/default index 080af5c38..75a62c482 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -435,8 +435,8 @@ HISTORY_MSG_197;CAM02 - Color curve HISTORY_MSG_198;CAM02 - Color curve HISTORY_MSG_199;CAM02 - Show CIECAM02 output histograms in curves HISTORY_MSG_200;CAM02 - Tone mapping using CIECAM02 Q -HISTORY_MSG_201;NR - Delta Chrominance red -HISTORY_MSG_202;NR - Delta Chrominance blue +HISTORY_MSG_201;NR - Delta Chrominance red-green +HISTORY_MSG_202;NR - Delta Chrominance blue-yellow HISTORY_MSG_203;NR - Method HISTORY_MSG_204;LMMSE Enhancement Steps HISTORY_MSG_205;CAM02 hot/bad pixels @@ -483,6 +483,7 @@ HISTORY_MSG_246;"CL" curve HISTORY_MSG_247;"LH" curve HISTORY_MSG_248;"HH" curve HISTORY_MSG_249;Contrast by Detail Levels Threshold +HISTORY_MSG_250;NR enhance HISTORY_NEWSNAPSHOTAS;As... HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s @@ -1144,7 +1145,9 @@ TP_DARKFRAME_LABEL;Dark Frame TP_DEFRINGE_LABEL;Defringe TP_DEFRINGE_RADIUS;Radius TP_DEFRINGE_THRESHOLD;Threshold -TP_DIRPYRDENOISE_BLUE;Delta chrominance Blue +TP_DIRPYRDENOISE_BLUE;Delta chrominance Blue & Yellow +TP_DIRPYRDENOISE_ENH;Enhanced mode +TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases the quality of denoise, but increases processing time approximately 20% TP_DIRPYRDENOISE_CHROMA;Chrominance (Master) TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on gamma of the input color profile. Gamma of sRGB is assumed, thus if input image is in color profile of a different gamma, luminance noise reduction will vary. TP_DIRPYRDENOISE_GAMMA;Gamma @@ -1156,7 +1159,7 @@ TP_DIRPYRDENOISE_LUMA;Luminance TP_DIRPYRDENOISE_METHOD;Method TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be used.\n\nFor non-raw images Lab method will be used, regardless of the selection. TP_DIRPYRDENOISE_PERF;RGB mode (raw images) -TP_DIRPYRDENOISE_RED;Delta chrominance Red +TP_DIRPYRDENOISE_RED;Delta chrominance Red & Green TP_DIRPYRDENOISE_RGB;RGB TP_DIRPYREQUALIZER_LABEL;Contrast by Detail Levels TP_DIRPYREQUALIZER_LUMACOARSEST;Coarsest diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index fef2d047a..7ddb6835a 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -39,10 +39,11 @@ #include "iccmatrices.h" #include "boxblur.h" #include "rt_math.h" +#include "mytime.h" #include "sleef.c" -#ifdef __SSE2__ - #include "sleefsseavx.c" -#endif +#ifdef __SSE2__ + #include "sleefsseavx.c" +#endif #ifdef _OPENMP #include @@ -82,15 +83,21 @@ namespace rtengine { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + extern const Settings* settings; void ImProcFunctions::RGB_denoise(Imagefloat * src, Imagefloat * dst, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const procparams::DefringeParams & defringe, const double expcomp) - { + { +//#ifdef _DEBUG +// MyTime t1e,t2e; +// t1e.set(); +//#endif + static MyMutex FftwMutex; MyMutex::MyLock lock(FftwMutex); - + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*if (plistener) { @@ -158,15 +165,15 @@ namespace rtengine { const float gain = pow (2.0f, float(expcomp)); float incr=1.f; float noisevar_Ldetail = SQR((SQR(100.f-dnparams.Ldetail) + 50.f*(100.f-dnparams.Ldetail)) * TS * 0.5f * incr); + bool enhance_denoise = dnparams.enhance; + noisered=1.f;//chroma red + if(dnparams.redchro<-0.1f) {noisered=0.001f+SQR((100.f + dnparams.redchro)/100.0f);} + else if(dnparams.redchro>0.1f) {noisered=1.f+SQR((dnparams.redchro));} + else if (dnparams.redchro>= -0.1f && dnparams.redchro<=0.1f) noisered=0.f; - noisered=1.f;//chroma red - if(dnparams.redchro<-0.1f) {noisered=0.001f+SQR((100.f + dnparams.redchro)/100.0f);} - else if(dnparams.redchro>0.1f) {noisered=1.f+SQR((dnparams.redchro));} - else if (dnparams.redchro>= -0.1f && dnparams.redchro<=0.1f) noisered=0.f; - - noiseblue=1.f;//chroma blue - if(dnparams.bluechro<-0.1f) {noiseblue=0.001f+SQR((100.f + dnparams.bluechro)/100.0f);} - else if(dnparams.bluechro>0.1f) {noiseblue=1.f+SQR((dnparams.bluechro));} + noiseblue=1.f;//chroma blue + if(dnparams.bluechro<-0.1f) {noiseblue=0.001f+SQR((100.f + dnparams.bluechro)/100.0f);} + else if(dnparams.bluechro>0.1f) {noiseblue=1.f+SQR((dnparams.bluechro));} else if (dnparams.bluechro>= -0.1f && dnparams.bluechro<=0.1f) noiseblue=0.f; array2D tilemask_in(TS,TS); @@ -261,9 +268,9 @@ namespace rtengine { // Calculate number of tiles. If less than omp_get_max_threads(), then limit num_threads to number of tiles int numtiles = numtiles_W * numtiles_H; int numthreads = MIN(numtiles,omp_get_max_threads()); - if(options.rgbDenoiseThreadLimit > 0) numthreads = MIN(numthreads,options.rgbDenoiseThreadLimit); - // Issue 1887, overide setting of 1, if more than one thread is available. This way the inner omp-directives should become inactive - if(numthreads == 1 && omp_get_max_threads() > 1) + if(options.rgbDenoiseThreadLimit > 0) numthreads = MIN(numthreads,options.rgbDenoiseThreadLimit); + // Issue 1887, overide setting of 1, if more than one thread is available. This way the inner omp-directives should become inactive + if(numthreads == 1 && omp_get_max_threads() > 1) numthreads = 2; #pragma omp parallel num_threads(numthreads) #endif @@ -434,23 +441,43 @@ namespace rtengine { //binary 1 or 0 for each level, eg subsampling = 0 means no subsampling, 1 means subsample //the first level only, 7 means subsample the first three levels, etc. float noisevarL = SQR((dnparams.luma/125.0f)*(1+ dnparams.luma/25.0f)); - - float noisevarab = SQR(dnparams.chroma/10.0f); - - + + float interm_med= dnparams.chroma/10.0f; + float intermred, intermblue; + if(dnparams.redchro > 0.f) intermred=0.0014f*SQR(dnparams.redchro); else intermred= dnparams.redchro/7.0f;//increase slower than linear for more sensit + float intermred2=dnparams.redchro/7.0f; + if(dnparams.bluechro > 0.f) intermblue=0.0014f*SQR(dnparams.bluechro); else intermblue= dnparams.bluechro/7.0f;//increase slower than linear + float intermblue2=dnparams.bluechro/7.0f; + //adjust noise ab in function of sliders red and blue + float realred = interm_med + intermred; if (realred < 0.f) realred=0.01f; + float realred2 = interm_med + intermred2; if (realred2 < 0.f) realred2=0.01f; + float noisevarab_r = SQR(realred); + float realblue = interm_med + intermblue; if (realblue < 0.f) realblue=0.01f; + float realblue2 = interm_med + intermblue2; if (realblue2 < 0.f) realblue2=0.01f; + float noisevarab_b = SQR(realblue); + + { // enclosing this code in a block frees about 120 MB before allocating 20 MB after this block (measured with D700 NEF) wavelet_decomposition* Ldecomp; wavelet_decomposition* adecomp; wavelet_decomposition* bdecomp; int levwav=5; - // if(xxxx) levwav=7; + float maxreal = max(realred2, realblue2); + //increase the level of wavelet if user increase much or very much sliders + if( maxreal < 8.f) levwav=5; + else if( maxreal < 10.f)levwav=6; + else if( maxreal < 15.f)levwav=7; + else levwav=8;//maximum ==> I have increase Maxlevel in cplx_wavelet_dec.h from 8 to 9 + + + // if (settings->verbose) printf("levwavelet=%i noisevarA=%f noisevarB=%f \n",levwav, noisevarab_r, noisevarab_b ); Ldecomp = new wavelet_decomposition (labdn->data, labdn->W, labdn->H, levwav/*maxlevels*/, 0/*subsampling*/ ); adecomp = new wavelet_decomposition (labdn->data+datalen, labdn->W, labdn->H,levwav, 1 ); bdecomp = new wavelet_decomposition (labdn->data+2*datalen, labdn->W, labdn->H, levwav, 1 ); - //WaveletDenoiseAll_BiShrink(Ldecomp, adecomp, bdecomp, noisevarL, noisevarab); - WaveletDenoiseAll(*Ldecomp, *adecomp, *bdecomp, noisevarL, noisevarab, labdn);//mod JD + if(enhance_denoise) WaveletDenoiseAll_BiShrink(*Ldecomp, *adecomp, *bdecomp, noisevarL, noisevarab_r, noisevarab_b,labdn);//enhance mode + else; WaveletDenoiseAll(*Ldecomp, *adecomp, *bdecomp, noisevarL, noisevarab_r, noisevarab_b,labdn);// Ldecomp->reconstruct(labdn->data); delete Ldecomp; @@ -744,7 +771,13 @@ namespace rtengine { fftwf_destroy_plan( plan_forward_blox[1] ); fftwf_destroy_plan( plan_backward_blox[1] ); fftwf_cleanup(); - +//#ifdef _DEBUG +// if (settings->verbose) { +// t2e.set(); +// printf("Denoise performed in %d usec:\n", t2e.etime(t1e)); +// } +//#endif + }//end of main RGB_denoise @@ -753,26 +786,26 @@ namespace rtengine { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -#if defined( __SSE2__ ) && defined( WIN32 ) -__attribute__((force_align_arg_pointer)) void ImProcFunctions::RGBtile_denoise (float * fLblox, int vblproc, int hblproc, int numblox_H, int numblox_W, float noisevar_Ldetail ) //for DCT -#else - void ImProcFunctions::RGBtile_denoise (float * fLblox, int vblproc, int hblproc, int numblox_H, int numblox_W, float noisevar_Ldetail ) //for DCT +#if defined( __SSE2__ ) && defined( WIN32 ) +__attribute__((force_align_arg_pointer)) void ImProcFunctions::RGBtile_denoise (float * fLblox, int vblproc, int hblproc, int numblox_H, int numblox_W, float noisevar_Ldetail ) //for DCT +#else + void ImProcFunctions::RGBtile_denoise (float * fLblox, int vblproc, int hblproc, int numblox_H, int numblox_W, float noisevar_Ldetail ) //for DCT #endif { float * nbrwt = new float[TS*TS]; //for DCT int blkstart = hblproc*TS*TS; - boxabsblur(fLblox+blkstart, nbrwt, 3, 3, TS, TS);//blur neighbor weights for more robust estimation //for DCT + boxabsblur(fLblox+blkstart, nbrwt, 3, 3, TS, TS);//blur neighbor weights for more robust estimation //for DCT -#ifdef __SSE2__ - __m128 tempv; - __m128 noisevar_Ldetailv = _mm_set1_ps( noisevar_Ldetail ); - __m128 onev = _mm_set1_ps( 1.0f ); - for (int n=0; n0.01) { + if (noisevar_abr>0.01) { //printf(" dir=%d mad_L=%f mad_a=%f mad_b=%f \n",dir,sqrt(mad_L),sqrt(mad_a),sqrt(mad_b)); @@ -1034,7 +1067,7 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::RGBtile_denoise ( //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void ImProcFunctions::WaveletDenoiseAll(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_a, - wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_ab, LabImage * noi)//mod JD + wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_abr, float noisevar_abb, LabImage * noi)//mod JD { int maxlvl = WaveletCoeffs_L.maxlevel(); @@ -1062,7 +1095,7 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::RGBtile_denoise ( // printf("Hab : %d\n", Hlvl_ab); // printf("Wab : %d\n", Wlvl_ab); ShrinkAll(WavCoeffs_L, WavCoeffs_a, WavCoeffs_b, lvl, Wlvl_L, Hlvl_L, Wlvl_ab, Hlvl_ab, - skip_L, skip_ab, noisevar_L, noisevar_ab, noi); + skip_L, skip_ab, noisevar_L, noisevar_abr, noisevar_abb, noi); } //omp_set_nested(false); @@ -1070,12 +1103,12 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::RGBtile_denoise ( //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -#if defined( __SSE2__ ) && defined( WIN32 ) +#if defined( __SSE2__ ) && defined( WIN32 ) __attribute__((force_align_arg_pointer)) void ImProcFunctions::ShrinkAll(float ** WavCoeffs_L, float ** WavCoeffs_a, float ** WavCoeffs_b, int level, - int W_L, int H_L, int W_ab, int H_ab,int skip_L, int skip_ab, float noisevar_L, float noisevar_ab, LabImage * noi) -#else + int W_L, int H_L, int W_ab, int H_ab,int skip_L, int skip_ab, float noisevar_L, float noisevar_abr, float noisevar_abb, LabImage * noi) +#else void ImProcFunctions::ShrinkAll(float ** WavCoeffs_L, float ** WavCoeffs_a, float ** WavCoeffs_b, int level, - int W_L, int H_L, int W_ab, int H_ab,int skip_L, int skip_ab, float noisevar_L, float noisevar_ab, LabImage * noi) + int W_L, int H_L, int W_ab, int H_ab,int skip_L, int skip_ab, float noisevar_L, float noisevar_abr, float noisevar_abb, LabImage * noi) #endif { @@ -1098,10 +1131,10 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::ShrinkAll(float * // printf(" dir=%d mad_L=%f mad_a=%f mad_b=%f skip_ab=%i \n",dir,sqrt(madL),sqrt(mada),sqrt(madb), skip_ab); float mad_L = madL*noisevar_L*5/(level+1); - float mad_a = mada*noisevar_ab; - float mad_b = madb*noisevar_ab; + float mad_a = mada*noisevar_abr; // noisevar_abr between 0..2.25=default 100=middle value ==> 582=max + float mad_b = madb*noisevar_abb; - if (noisevar_ab>0.01) { + if (noisevar_abr>0.01 || noisevar_abb>0.01) { //OpenMP here #ifdef _OPENMP @@ -1115,25 +1148,28 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::ShrinkAll(float * int coeffloc_ab = i*W_ab+j; int coeffloc_L = ((i*skip_L)/skip_ab)*W_L + ((j*skip_L)/skip_ab); //modification Jacques feb 2013 - + /* float reduc=1.f; float bluuc=1.f; if(noisered!=0. || noiseblue !=0.) { - float hh=xatan2(noi->b[2*i][2*j],noi->a[2*i][2*j]); + // float hh=xatan2(noi->b[2*i][2*j],noi->a[2*i][2*j]); + float hh =xatan2(WavCoeffs_b[dir][coeffloc_ab],WavCoeffs_a[dir][coeffloc_ab]); //one can also use L or c (chromaticity) if necessary - if(hh > -0.4f && hh < 1.6f) reduc=noisered;//red from purple to next yellow - if(hh>-2.45f && hh <=-0.4f) bluuc=noiseblue;//blue + // if(hh > -0.4f && hh < 1.6f) reduc=noisered;//red from purple to next yellow + // if(hh>-2.45f && hh <=-0.4f) bluuc=noiseblue;//blue + if(hh>1.3f && hh <=2.2f) bluuc=noiseblue;//blue } + mad_a*=reduc; mad_a*=bluuc; mad_b*=reduc; mad_b*=bluuc; - + */ float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L ])+eps; float mag_a = SQR(WavCoeffs_a[dir][coeffloc_ab])+eps; float mag_b = SQR(WavCoeffs_b[dir][coeffloc_ab])+eps; - sfavea[coeffloc_ab] = (1-xexpf(-(mag_a/mad_a)-(mag_L/(9*madL)))); - sfaveb[coeffloc_ab] = (1-xexpf(-(mag_b/mad_b)-(mag_L/(9*madL)))); + sfavea[coeffloc_ab] = (1.f-xexpf(-(mag_a/mad_a)-(mag_L/(9.f*madL)))); + sfaveb[coeffloc_ab] = (1.f-xexpf(-(mag_b/mad_b)-(mag_L/(9.f*madL)))); mad_a=m_a; mad_b=m_b; // 'firm' threshold of chroma coefficients @@ -1159,25 +1195,31 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::ShrinkAll(float * int coeffloc_ab = i*W_ab+j; int coeffloc_L = ((i*skip_L)/skip_ab)*W_L + ((j*skip_L)/skip_ab); //modification Jacques feb 2013 - + /* float reduc=1.f; float bluuc=1.f; + if(noisered!=0. || noiseblue !=0.) { - float hh=xatan2(noi->b[2*i][2*j],noi->a[2*i][2*j]); - if(hh > -0.4f && hh < 1.6f) reduc=noisered; - if(hh>-2.45f && hh <=-0.4f) bluuc=noiseblue; + // float hh=xatan2(noi->b[2*i][2*j],noi->a[2*i][2*j]); + float hh =xatan2(WavCoeffs_b[dir][coeffloc_ab],WavCoeffs_a[dir][coeffloc_ab]); + + // if(hh > -0.4f && hh < 1.6f) reduc=noisered; + // if(hh>-2.45f && hh <=-0.4f) bluuc=noiseblue; + if(hh>1.3f && hh <=2.2f) bluuc=noiseblue;//blue + } + mad_a*=reduc; mad_a*=bluuc; mad_b*=reduc; mad_b*=bluuc; - + */ float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L ])+eps; float mag_a = SQR(WavCoeffs_a[dir][coeffloc_ab])+eps; float mag_b = SQR(WavCoeffs_b[dir][coeffloc_ab])+eps; - float sfa = (1-xexpf(-(mag_a/mad_a)-(mag_L/(9*madL)))); - float sfb = (1-xexpf(-(mag_b/mad_b)-(mag_L/(9*madL)))); + float sfa = (1.f-xexpf(-(mag_a/mad_a)-(mag_L/(9.f*madL)))); + float sfb = (1.f-xexpf(-(mag_b/mad_b)-(mag_L/(9.f*madL)))); //use smoothed shrinkage unless local shrinkage is much less WavCoeffs_a[dir][coeffloc_ab] *= (SQR(sfavea[coeffloc_ab])+SQR(sfa))/(sfavea[coeffloc_ab]+sfa+eps); @@ -1189,20 +1231,20 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::ShrinkAll(float * } if (noisevar_L>0.01) { -#ifdef __SSE2__ - __m128 magv; - __m128 mad_Lv = _mm_set1_ps( mad_L ); - __m128 ninev = _mm_set1_ps( 9.0f ); - __m128 epsv = _mm_set1_ps( eps ); +#ifdef __SSE2__ + __m128 magv; + __m128 mad_Lv = _mm_set1_ps( mad_L ); + __m128 ninev = _mm_set1_ps( 9.0f ); + __m128 epsv = _mm_set1_ps( eps ); for (int i=0; i1 && histogram[whiteclip]+clipped <= clippable) { clipped += histogram[whiteclip]; whiteclip--; } - + int clipwh=clipped; //compute clipped black point clipped = 0; int shc = 0; @@ -3786,6 +3787,8 @@ fclose(f);*/ clipped += histogram[shc]; shc++; } + int clipbl=clipped; + //rescale to 65535 max rawmax <<= histcompr; whiteclip <<= histcompr; @@ -3857,7 +3860,8 @@ fclose(f);*/ //diagnostics //printf ("**************** AUTO LEVELS ****************\n"); - /* if (settings->verbose) { +/* if (settings->verbose) { + printf("sum=%i clip=%f clippable=%i clipWh=%i clipBl=%i\n",somm, clip, clippable,clipwh, clipbl); printf ("expcomp1= %f expcomp2= %f gain= %f expcomp=%f\n",expcomp1,expcomp2,gain,expcomp); printf ("expo=%f\n",expo); printf ("median: %i average: %f median/average: %f\n",median,ave, median/ave); diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index f900df52a..e496275e0 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -255,10 +255,10 @@ class ImProcFunctions { // void WaveletDenoiseAll(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_a, // wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_ab, wavelet_decomposition &wch, NoiImage * noi ); void WaveletDenoiseAll(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_a, - wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_ab, LabImage * noi ); + wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_abr, float noisevar_abb, LabImage * noi ); void WaveletDenoiseAll_BiShrink(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_a, - wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_ab ); + wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_abr, float noisevar_abb, LabImage * noi); //void BiShrink(float * ReCoeffs, float * ImCoeffs, float * ReParents, float * ImParents, // int W, int H, int level, int padding, float noisevar); //void Shrink(float ** WavCoeffs, int W, int H, int level, float noisevar); @@ -266,7 +266,7 @@ class ImProcFunctions { // int W_L, int H_L, int W_ab, int H_ab, int W_h, int H_h, int skip_L, int skip_ab, int skip_h, float noisevar_L, float noisevar_ab, float **WavCoeffs_h, LabImage * noi); void ShrinkAll(float ** WavCoeffs_L, float ** WavCoeffs_a, float ** WavCoeffs_b, int level, - int W_L, int H_L, int W_ab, int H_ab, int skip_L, int skip_ab, float noisevar_L, float noisevar_ab, LabImage * noi); + int W_L, int H_L, int W_ab, int H_ab, int skip_L, int skip_ab, float noisevar_L, float noisevar_abr, float noisevar_abb,LabImage * noi); float MadMax(float * HH_Coeffs, int &max, int datalen); diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 3e991cde9..b3a205a14 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -272,8 +272,9 @@ enum ProcEvent { EvLLHCurve=246, EvLHHCurve=247, EvDirPyrEqualizerThreshold=248, + EvDPDNenhance=249, - NUMOFEVENTS=249 + NUMOFEVENTS=250 }; } #endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 1ea58f41c..b80859c1e 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -291,6 +291,7 @@ void ProcParams::setDefaults () { defringe.huecurve.at(24) = 0.35; dirpyrDenoise.enabled = false; + dirpyrDenoise.enhance = false; // dirpyrDenoise.perform = false; dirpyrDenoise.luma = 0; dirpyrDenoise.Ldetail = 50; @@ -870,6 +871,7 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol // save dirpyrDenoise if (!pedited || pedited->dirpyrDenoise.enabled) keyFile.set_boolean ("Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled); + if (!pedited || pedited->dirpyrDenoise.enhance) keyFile.set_boolean ("Directional Pyramid Denoising", "Enhance", dirpyrDenoise.enhance); // if (!pedited || pedited->dirpyrDenoise.perform) keyFile.set_boolean ("Directional Pyramid Denoising", "Perform", dirpyrDenoise.perform); if (!pedited || pedited->dirpyrDenoise.luma) keyFile.set_double ("Directional Pyramid Denoising", "Luma", dirpyrDenoise.luma); if (!pedited || pedited->dirpyrDenoise.Ldetail) keyFile.set_double ("Directional Pyramid Denoising", "Ldetail", dirpyrDenoise.Ldetail); @@ -1455,6 +1457,7 @@ if (keyFile.has_group ("Impulse Denoising")) { // load dirpyrDenoise if (keyFile.has_group ("Directional Pyramid Denoising")) {//TODO: No longer an accurate description for FT denoise if (keyFile.has_key ("Directional Pyramid Denoising", "Enabled")) { dirpyrDenoise.enabled = keyFile.get_boolean ("Directional Pyramid Denoising", "Enabled"); if (pedited) pedited->dirpyrDenoise.enabled = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "Enhance")) { dirpyrDenoise.enhance = keyFile.get_boolean ("Directional Pyramid Denoising", "Enhance"); if (pedited) pedited->dirpyrDenoise.enhance = true; } // if (keyFile.has_key ("Directional Pyramid Denoising", "Perform")) { dirpyrDenoise.perform = keyFile.get_boolean ("Directional Pyramid Denoising", "Perform"); if (pedited) pedited->dirpyrDenoise.perform = true; } if (keyFile.has_key ("Directional Pyramid Denoising", "Luma")) { dirpyrDenoise.luma = keyFile.get_double ("Directional Pyramid Denoising", "Luma"); if (pedited) pedited->dirpyrDenoise.luma = true; } if (keyFile.has_key ("Directional Pyramid Denoising", "Ldetail")) { dirpyrDenoise.Ldetail = keyFile.get_double ("Directional Pyramid Denoising", "Ldetail"); if (pedited) pedited->dirpyrDenoise.Ldetail = true; } @@ -1873,6 +1876,7 @@ bool ProcParams::operator== (const ProcParams& other) { && impulseDenoise.enabled == other.impulseDenoise.enabled && impulseDenoise.thresh == other.impulseDenoise.thresh && dirpyrDenoise.enabled == other.dirpyrDenoise.enabled + && dirpyrDenoise.enhance == other.dirpyrDenoise.enhance // && dirpyrDenoise.perform == other.dirpyrDenoise.perform && dirpyrDenoise.luma == other.dirpyrDenoise.luma && dirpyrDenoise.Ldetail == other.dirpyrDenoise.Ldetail diff --git a/rtengine/procparams.h b/rtengine/procparams.h index c3a2523a5..17c9e5c87 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -470,6 +470,8 @@ class DirPyrDenoiseParams { public: bool enabled; + bool enhance; + bool perform; double luma; double Ldetail; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 4d3390913..767a6cbe9 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -268,7 +268,8 @@ TRANSFORM, // EvVignettingCenter LUMINANCECURVE, // EvLCLCurve LUMINANCECURVE, // EvLLHCurve LUMINANCECURVE, // EvLHHCurve -DIRPYREQUALIZER // EvDirPyrEqualizerThreshold +DIRPYREQUALIZER, // EvDirPyrEqualizerThreshold +ALLNORAW // EvDPDNenhance //LUMINANCECURVE // EvCATsharpcie diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc index d26001ba1..851549dc8 100644 --- a/rtgui/dirpyrdenoise.cc +++ b/rtgui/dirpyrdenoise.cc @@ -84,6 +84,11 @@ DirPyrDenoise::DirPyrDenoise () : Gtk::VBox(), FoldableToolPanel(this) { // perform->show(); gamma->show(); // perform->set_active (true); + + enhance = Gtk::manage (new Gtk::CheckButton (M("TP_DIRPYRDENOISE_ENH"))); + enhance->set_active (false); + enhance->set_tooltip_text (M("TP_DIRPYRDENOISE_ENH_TOOLTIP")); + pack_start (*luma); pack_start (*Ldetail); @@ -92,7 +97,10 @@ DirPyrDenoise::DirPyrDenoise () : Gtk::VBox(), FoldableToolPanel(this) { pack_start (*bluechro); pack_start (*gamma); + pack_start (*enhance); + // pack_start (*perform); + enhanConn = enhance->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrDenoise::enhanceChanged) ); } @@ -119,14 +127,17 @@ void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) { gamma->setEditedState (pedited->dirpyrDenoise.gamma ? Edited : UnEdited); enabled->set_inconsistent (!pedited->dirpyrDenoise.enabled); + enhance->set_inconsistent (!pedited->dirpyrDenoise.enhance); // perform->set_inconsistent (!pedited->dirpyrDenoise.perform); } // perfconn.block (true); enabled->set_active (pp->dirpyrDenoise.enabled); + enhance->set_active (pp->dirpyrDenoise.enhance); // perform->set_active (pp->dirpyrDenoise.perform); // perfconn.block (false); lastEnabled = pp->dirpyrDenoise.enabled; + lastenhance = pp->dirpyrDenoise.enhance; // lastperform = pp->dirpyrDenoise.perform; luma->setValue (pp->dirpyrDenoise.luma); Ldetail->setValue (pp->dirpyrDenoise.Ldetail); @@ -150,6 +161,7 @@ void DirPyrDenoise::write (ProcParams* pp, ParamsEdited* pedited) { pp->dirpyrDenoise.bluechro = bluechro->getValue (); pp->dirpyrDenoise.gamma = gamma->getValue (); pp->dirpyrDenoise.enabled = enabled->get_active(); + pp->dirpyrDenoise.enhance = enhance->get_active(); // pp->dirpyrDenoise.perform = perform->get_active(); if (pedited) { @@ -161,6 +173,7 @@ void DirPyrDenoise::write (ProcParams* pp, ParamsEdited* pedited) { pedited->dirpyrDenoise.bluechro = bluechro->getEditedState (); pedited->dirpyrDenoise.gamma = gamma->getEditedState (); pedited->dirpyrDenoise.enabled = !enabled->get_inconsistent(); + pedited->dirpyrDenoise.enhance = !enhance->get_inconsistent(); // pedited->dirpyrDenoise.perform = !perform->get_inconsistent(); } if (dmethod->get_active_row_number()==0) @@ -248,6 +261,30 @@ void DirPyrDenoise::enabledChanged () { listener->panelChanged (EvDPDNEnabled, M("GENERAL_DISABLED")); } } + +void DirPyrDenoise::enhanceChanged () { + + if (batchMode) { + if (enhance->get_inconsistent()) { + enhance->set_inconsistent (false); + enhanConn.block (true); + enhance->set_active (false); + enhanConn.block (false); + } + else if (lastenhance) + enhance->set_inconsistent (true); + + lastenhance = enhance->get_active (); + } + + if (listener) { + if (enhance->get_active ()) + listener->panelChanged (EvDPDNenhance, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvDPDNenhance, M("GENERAL_DISABLED")); + } +} + /* void DirPyrDenoise::perform_toggled () { diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h index 57362dcdd..c0506d44a 100644 --- a/rtgui/dirpyrdenoise.h +++ b/rtgui/dirpyrdenoise.h @@ -36,6 +36,10 @@ class DirPyrDenoise : public Gtk::VBox, public AdjusterListener, public Foldable Gtk::CheckButton* enabled; bool lastEnabled; sigc::connection enaConn; + Gtk::CheckButton* enhance; + bool lastenhance; + sigc::connection enhanConn; + // Gtk::CheckButton* perform; // bool lastperform; // sigc::connection perfconn; @@ -54,6 +58,7 @@ class DirPyrDenoise : public Gtk::VBox, public AdjusterListener, public Foldable void adjusterChanged (Adjuster* a, double newval); void enabledChanged (); + void enhanceChanged (); // void perform_toggled (); void dmethodChanged (); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index c25527051..f152572a7 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -152,6 +152,7 @@ void ParamsEdited::set (bool v) { impulseDenoise.enabled = v; impulseDenoise.thresh = v; dirpyrDenoise.enabled = v; + dirpyrDenoise.enhance = v; // dirpyrDenoise.perform = v; dirpyrDenoise.luma = v; dirpyrDenoise.Ldetail = v; @@ -433,6 +434,7 @@ void ParamsEdited::initFrom (const std::vector impulseDenoise.thresh = impulseDenoise.thresh && p.impulseDenoise.thresh == other.impulseDenoise.thresh; dirpyrDenoise.enabled = dirpyrDenoise.enabled && p.dirpyrDenoise.enabled == other.dirpyrDenoise.enabled; + dirpyrDenoise.enhance = dirpyrDenoise.enhance && p.dirpyrDenoise.enhance == other.dirpyrDenoise.enhance; // dirpyrDenoise.perform = dirpyrDenoise.perform && p.dirpyrDenoise.perform == other.dirpyrDenoise.perform; dirpyrDenoise.luma = dirpyrDenoise.luma && p.dirpyrDenoise.luma == other.dirpyrDenoise.luma; dirpyrDenoise.Ldetail = dirpyrDenoise.Ldetail && p.dirpyrDenoise.Ldetail == other.dirpyrDenoise.Ldetail; @@ -714,6 +716,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (impulseDenoise.thresh) toEdit.impulseDenoise.thresh = mods.impulseDenoise.thresh; if (dirpyrDenoise.enabled) toEdit.dirpyrDenoise.enabled = mods.dirpyrDenoise.enabled; + if (dirpyrDenoise.enhance) toEdit.dirpyrDenoise.enhance = mods.dirpyrDenoise.enhance; if (dirpyrDenoise.luma) toEdit.dirpyrDenoise.luma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_LUMA] ? toEdit.dirpyrDenoise.luma + mods.dirpyrDenoise.luma : mods.dirpyrDenoise.luma; if (dirpyrDenoise.Ldetail) toEdit.dirpyrDenoise.Ldetail = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_LUMDET] ? toEdit.dirpyrDenoise.Ldetail + mods.dirpyrDenoise.Ldetail : mods.dirpyrDenoise.Ldetail; if (dirpyrDenoise.chroma) toEdit.dirpyrDenoise.chroma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMA] ? toEdit.dirpyrDenoise.chroma + mods.dirpyrDenoise.chroma : mods.dirpyrDenoise.chroma; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 5e11940ac..3ba0bc8bb 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -233,6 +233,7 @@ class DirPyrDenoiseParamsEdited { public: bool enabled; + bool enhance; bool Ldetail; bool luma; bool chroma;