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;