diff --git a/rtdata/languages/default b/rtdata/languages/default
index ae3d369a9..25096658b 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -426,6 +426,9 @@ 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;CAMO2 - Tone mapping using CIECAM02 Q
+HISTORY_MSG_201;NR - Delta Chrominance red
+HISTORY_MSG_202;NR - Delta Chrominance blue
+HISTORY_MSG_203;NR - RGB <> Lab
HISTORY_NEWSNAPSHOTAS;As...
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
@@ -992,9 +995,18 @@ TP_DARKFRAME_LABEL;Dark Frame
TP_DEFRINGE_LABEL;Defringe (Lab/CIECAM02)
TP_DEFRINGE_RADIUS;Radius
TP_DEFRINGE_THRESHOLD;Threshold
-TP_DIRPYRDENOISE_CHROMA;Chrominance
+TP_DIRPYRDENOISE_METHOD;Method
+TP_DIRPYRDENOISE_RGB;RGB
+TP_DIRPYRDENOISE_LAB;Lab
+TP_DIRPYRDENOISE_CHROMA;Chrominance (Master)
+TP_DIRPYRDENOISE_RED;Delta chrominance Red
+TP_DIRPYRDENOISE_BLUE;Delta chrominance Blue
+TP_DIRPYRDENOISE_PERF;RGB mode (raw images)
+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_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_GAMMA;Gamma
-TP_DIRPYRDENOISE_LABEL;Noise Reduction (raw images only)
+TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones.
+TP_DIRPYRDENOISE_LABEL;Noise Reduction
TP_DIRPYRDENOISE_LDETAIL;Luminance Detail
TP_DIRPYRDENOISE_LUMA;Luminance
TP_DIRPYREQUALIZER_LABEL;Contrast by Detail Levels (Lab/CIECAM02)
diff --git a/rtdata/profiles/BW-1.pp3 b/rtdata/profiles/BW-1.pp3
index 5cef081f4..f86f24f8e 100644
--- a/rtdata/profiles/BW-1.pp3
+++ b/rtdata/profiles/BW-1.pp3
@@ -125,9 +125,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=false
+Method=RGB
Luma=0
-Ldetail=80
+Ldetail=50
Chroma=15
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtdata/profiles/BW-2.pp3 b/rtdata/profiles/BW-2.pp3
index fbf50f751..9cdcd8736 100644
--- a/rtdata/profiles/BW-2.pp3
+++ b/rtdata/profiles/BW-2.pp3
@@ -125,9 +125,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=false
+Method=RGB
Luma=0
-Ldetail=80
+Ldetail=50
Chroma=15
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtdata/profiles/BW-3.pp3 b/rtdata/profiles/BW-3.pp3
index 154c6c24e..cf90b918a 100644
--- a/rtdata/profiles/BW-3.pp3
+++ b/rtdata/profiles/BW-3.pp3
@@ -125,9 +125,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=false
+Method=RGB
Luma=0
-Ldetail=80
+Ldetail=50
Chroma=15
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtdata/profiles/BW-4.pp3 b/rtdata/profiles/BW-4.pp3
index 69ee7b63e..b4b2cbdc2 100644
--- a/rtdata/profiles/BW-4.pp3
+++ b/rtdata/profiles/BW-4.pp3
@@ -126,9 +126,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=false
+Method=RGB
Luma=0
-Ldetail=80
+Ldetail=50
Chroma=15
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtdata/profiles/Default-ISO-High.pp3 b/rtdata/profiles/Default-ISO-High.pp3
index 8cc4b2024..c87759d70 100644
--- a/rtdata/profiles/Default-ISO-High.pp3
+++ b/rtdata/profiles/Default-ISO-High.pp3
@@ -125,9 +125,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=true
+Method=RGB
Luma=50
-Ldetail=80
+Ldetail=50
Chroma=50
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtdata/profiles/Default-ISO-Medium.pp3 b/rtdata/profiles/Default-ISO-Medium.pp3
index cac669ff2..abbdf193b 100644
--- a/rtdata/profiles/Default-ISO-Medium.pp3
+++ b/rtdata/profiles/Default-ISO-Medium.pp3
@@ -125,9 +125,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=true
+Method=RGB
Luma=20
-Ldetail=80
+Ldetail=50
Chroma=30
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtdata/profiles/Default.pp3 b/rtdata/profiles/Default.pp3
index d1c4594f3..f96b6254e 100644
--- a/rtdata/profiles/Default.pp3
+++ b/rtdata/profiles/Default.pp3
@@ -126,9 +126,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=false
+Method=RGB
Luma=0
-Ldetail=80
+Ldetail=50
Chroma=15
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtdata/profiles/Highkey-1.pp3 b/rtdata/profiles/Highkey-1.pp3
index 4afa7b764..83f1be489 100644
--- a/rtdata/profiles/Highkey-1.pp3
+++ b/rtdata/profiles/Highkey-1.pp3
@@ -125,9 +125,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=false
+Method=RGB
Luma=0
-Ldetail=80
+Ldetail=50
Chroma=15
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtdata/profiles/Natural-1.pp3 b/rtdata/profiles/Natural-1.pp3
index 8f2dc2abf..989f33d58 100644
--- a/rtdata/profiles/Natural-1.pp3
+++ b/rtdata/profiles/Natural-1.pp3
@@ -125,9 +125,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=false
+Method=RGB
Luma=0
-Ldetail=80
+Ldetail=50
Chroma=15
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtdata/profiles/Natural-2.pp3 b/rtdata/profiles/Natural-2.pp3
index f929be739..53f49bec7 100644
--- a/rtdata/profiles/Natural-2.pp3
+++ b/rtdata/profiles/Natural-2.pp3
@@ -125,9 +125,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=false
+Method=RGB
Luma=0
-Ldetail=80
+Ldetail=50
Chroma=15
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtdata/profiles/Neutral.pp3 b/rtdata/profiles/Neutral.pp3
index 63fc9d05f..94b229d32 100644
--- a/rtdata/profiles/Neutral.pp3
+++ b/rtdata/profiles/Neutral.pp3
@@ -125,9 +125,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=false
+Method=RGB
Luma=0
-Ldetail=80
+Ldetail=50
Chroma=15
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtdata/profiles/Punchy-1.pp3 b/rtdata/profiles/Punchy-1.pp3
index cc40db5de..4d23f7769 100644
--- a/rtdata/profiles/Punchy-1.pp3
+++ b/rtdata/profiles/Punchy-1.pp3
@@ -125,9 +125,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=false
+Method=RGB
Luma=0
-Ldetail=80
+Ldetail=50
Chroma=15
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtdata/profiles/Punchy-2.pp3 b/rtdata/profiles/Punchy-2.pp3
index 3e7f3c033..094654ae5 100644
--- a/rtdata/profiles/Punchy-2.pp3
+++ b/rtdata/profiles/Punchy-2.pp3
@@ -125,9 +125,12 @@ Threshold=25
[Directional Pyramid Denoising]
Enabled=false
+Method=RGB
Luma=0
-Ldetail=80
+Ldetail=50
Chroma=15
+Redchro=0
+Bluechro=0
Gamma=1.7
[EPD]
diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc
index f74cfaad6..4de5a1082 100644
--- a/rtengine/FTblockDN.cc
+++ b/rtengine/FTblockDN.cc
@@ -102,39 +102,64 @@ namespace rtengine {
memcpy(dst->data,src->data,dst->width*dst->height*3*sizeof(float));
return;
}
-
+ perf=false;
+ if(dnparams.dmethod=="RGB") perf=true;//RGB mode
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// gamma transform for input data
float gam = dnparams.gamma;
- float gamthresh = 0.001;
+ float gamthresh = 0.001f;
+ if(!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG
+ if(gam <1.9f) gam=1.f - (1.9f-gam)/3.f;//minimum gamma 0.7
+ else if (gam >= 1.9f && gam <= 3.f) gam=(1.4f/1.1f)*gam - 1.41818f;
+ }
float gamslope = exp(log((double)gamthresh)/gam)/gamthresh;
LUTf gamcurve(65536,0);
-
+ if(perf) {
for (int i=0; i<65536; i++) {
gamcurve[i] = (Color::gamma((double)i/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) * 32768.0f;
}
+ }
+ else {
+ for (int i=0; i<65536; i++) {
+ gamcurve[i] = (Color::gamman((double)i/65535.0,gam)) * 32768.0f;
+ }
+ }
// inverse gamma transform for output data
- float igam = 1/gam;
+ float igam = 1.f/gam;
float igamthresh = gamthresh*gamslope;
- float igamslope = 1/gamslope;
+ float igamslope = 1.f/gamslope;
LUTf igamcurve(65536,0);
-
+ if(perf) {
for (int i=0; i<65536; i++) {
igamcurve[i] = (Color::gamma((float)i/32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f);
+ }
+ }
+ else {
+ for (int i=0; i<65536; i++) {
+ igamcurve[i] = (Color::gamman((float)i/32768.0f,igam) * 65535.0f);
+ }
+
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//srand((unsigned)time(0));//test with random data
- const float gain = pow (2.0, dnparams.expcomp);
-
- float noisevar_Ldetail = SQR((SQR(100-dnparams.Ldetail) + 50*(100-dnparams.Ldetail)) * TS * 0.5f);
-
+ const float gain = pow (2.0f, dnparams.expcomp);
+ float incr=1.f;
+ float noisevar_Ldetail = SQR((SQR(100.f-dnparams.Ldetail) + 50.f*(100.f-dnparams.Ldetail)) * TS * 0.5f * incr);
+
+ noisered=1.f;//chroma red
+ if(dnparams.redchro<0.1f) {noisered=0.001f+SQR((100.f + dnparams.redchro)/100.0f);}
+ if(dnparams.redchro>0.1f) {noisered=1.f+SQR((dnparams.redchro));}
+ noiseblue=1.f;//chroma blue
+ if(dnparams.bluechro<0.1f) {noiseblue=0.001f+SQR((100.f + dnparams.bluechro)/100.0f);}
+ if(dnparams.bluechro>0.1f) {noiseblue=1.f+SQR((dnparams.bluechro));}
+
array2D tilemask_in(TS,TS);
array2D tilemask_out(TS,TS);
@@ -234,6 +259,24 @@ namespace rtengine {
//DCT block data storage
float * Lblox;
float * fLblox;
+ TMatrix wprof = iccStore->workingSpaceMatrix (params->icm.working);
+
+ double wp[3][3] = {
+ {wprof[0][0],wprof[0][1],wprof[0][2]},
+ {wprof[1][0],wprof[1][1],wprof[1][2]},
+ {wprof[2][0],wprof[2][1],wprof[2][2]}
+ };
+
+ TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working);
+ //inverse matrix user select
+ double wip[3][3] = {
+ {wiprof[0][0],wiprof[0][1],wiprof[0][2]},
+ {wiprof[1][0],wiprof[1][1],wiprof[1][2]},
+ {wiprof[2][0],wiprof[2][1],wiprof[2][2]}
+ };
+
+
+
#ifdef _OPENMP
#pragma omp critical
#endif
@@ -251,16 +294,17 @@ namespace rtengine {
int tilebottom = MIN(imheight,tiletop+tileheight);
int width = tileright-tileleft;
int height = tilebottom-tiletop;
-
//input L channel
array2D Lin(width,height);
//wavelet denoised image
LabImage * labdn = new LabImage(width,height);
+
//residual between input and denoised L channel
array2D Ldetail(width,height,ARRAY2D_CLEAR_DATA);
//pixel weight
array2D totwt(width,height,ARRAY2D_CLEAR_DATA);//weight for combining DCT blocks
-//
+
+ //
//#ifdef _OPENMP
//#pragma omp parallel for
@@ -268,6 +312,42 @@ namespace rtengine {
//TODO: implement using AlignedBufferMP
//fill tile from image; convert RGB to "luma/chroma"
if (isRAW) {//image is raw; use channel differences for chroma channels
+ if(!perf){//lab mode
+ for (int i=tiletop/*, i1=0*/; ir(i,j);
+ float G_ = gain*src->g(i,j);
+ float B_ = gain*src->b(i,j);
+ //modify arbitrary data for Lab..I have test : nothing, gamma standard, gamma SRGB and GammaBT709...
+ //we can put other as gamma g=2.6 slope=11, etc.
+ // Gamma sRGB is a good compromise, but noting to do with real gamma !!!: it's only for data Lab # data RGB
+ //finally I opted fot gamma_26_11
+ R_ = Color::igammatab_26_11[R_];
+ G_ = Color::igammatab_26_11[G_];
+ B_ = Color::igammatab_26_11[B_];
+ //apply gamma noise standard (slider)
+ R_ = R_<65535.0f ? gamcurve[R_] : (Color::gamman((double)R_/65535.0, gam)*32768.0f);
+ G_ = G_<65535.0f ? gamcurve[G_] : (Color::gamman((double)G_/65535.0, gam)*32768.0f);
+ B_ = B_<65535.0f ? gamcurve[B_] : (Color::gamman((double)B_/65535.0, gam)*32768.0f);
+ //true conversion xyz=>Lab
+ float L,a,b;
+ float X,Y,Z;
+ Color::rgbxyz(R_,G_,B_,X,Y,Z,wp);
+
+ //convert to Lab
+ Color::XYZ2Lab(X, Y, Z, L, a, b);
+ labdn->L[i1][j1] = L;
+ labdn->a[i1][j1] = a;
+ labdn->b[i1][j1] = b;
+ Lin[i1][j1] = L;
+// totwt[i1][j1] = 0;
+ }
+ }
+ }
+ else {//RGB mode
for (int i=tiletop/*, i1=0*/; i save TIF with gamma sRGB and re open
float rtmp = Color::igammatab_srgb[ src->r(i,j) ];
float gtmp = Color::igammatab_srgb[ src->g(i,j) ];
- float btmp = Color::igammatab_srgb[ src->b(i,j) ];
-
- //perhaps use LCH or YCrCb ???
- float X = xyz_sRGB[0][0]*rtmp + xyz_sRGB[0][1]*gtmp + xyz_sRGB[0][2]*btmp;
- float Y = xyz_sRGB[1][0]*rtmp + xyz_sRGB[1][1]*gtmp + xyz_sRGB[1][2]*btmp;
- float Z = xyz_sRGB[2][0]*rtmp + xyz_sRGB[2][1]*gtmp + xyz_sRGB[2][2]*btmp;
-
- X = X<65535.0f ? gamcurve[X] : (Color::gamma((double)X/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)*32768.0f);
- Y = Y<65535.0f ? gamcurve[Y] : (Color::gamma((double)Y/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)*32768.0f);
- Z = Z<65535.0f ? gamcurve[Z] : (Color::gamma((double)Z/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)*32768.0f);
-
- labdn->L[i1][j1] = Y;
- labdn->a[i1][j1] = (X-Y);
- labdn->b[i1][j1] = (Y-Z);
+ float btmp = Color::igammatab_srgb[ src->b(i,j) ];
+ //modification Jacques feb 2013
+ // gamma slider different from raw
+ rtmp = rtmp<65535.0f ? gamcurve[rtmp] : (Color::gamman((double)rtmp/65535.0, gam)*32768.0f);
+ gtmp = gtmp<65535.0f ? gamcurve[gtmp] : (Color::gamman((double)gtmp/65535.0, gam)*32768.0f);
+ btmp = btmp<65535.0f ? gamcurve[btmp] : (Color::gamman((double)btmp/65535.0, gam)*32768.0f);
+
+
+ float X,Y,Z;
+ Color::rgbxyz(rtmp,gtmp,btmp,X,Y,Z,wp);
+
+ //convert Lab
+ Color::XYZ2Lab(X, Y, Z, L, a, b);
+ labdn->L[i1][j1] = L;
+ labdn->a[i1][j1] = a;
+ labdn->b[i1][j1] = b;
// Ldetail[i1][j1] = 0;
- Lin[i1][j1] = Y;
+ Lin[i1][j1] = L;
+
// totwt[i1][j1] = 0;
}
}
@@ -334,21 +421,24 @@ namespace rtengine {
//and whether to subsample the image after wavelet filtering. Subsampling is coded as
//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);
+
+
{ // 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;
-
- Ldecomp = new wavelet_decomposition (labdn->data, labdn->W, labdn->H, 5/*maxlevels*/, 0/*subsampling*/ );
- adecomp = new wavelet_decomposition (labdn->data+datalen, labdn->W, labdn->H, 5, 1 );
- bdecomp = new wavelet_decomposition (labdn->data+2*datalen, labdn->W, labdn->H, 5, 1 );
+
+ int levwav=5;
+ // if(xxxx) levwav=7;
+ 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);
+ WaveletDenoiseAll(*Ldecomp, *adecomp, *bdecomp, noisevarL, noisevarab, labdn);//mod JD
Ldecomp->reconstruct(labdn->data);
delete Ldecomp;
@@ -511,9 +601,45 @@ namespace rtengine {
//convert back to RGB and write to destination array
if (isRAW) {
+ if(!perf) {//Lab mode
#ifdef _OPENMP
//#pragma omp parallel for
#endif
+ for (int i=tiletop; ixyz
+ L = labdn->L[i1][j1];
+ a = labdn->a[i1][j1];
+ b = labdn->b[i1][j1];
+ //convert XYZ
+ Color::Lab2XYZ(L, a, b, X, Y, Z);
+ //apply inverse gamma noise
+ float r_,g_,b_;
+ Color::xyz2rgb(X,Y,Z,r_,g_,b_,wip);
+ //inverse gamma standard (slider)
+ r_ = r_<32768.0f ? igamcurve[r_] : (Color::gamman((float)r_/32768.0f, igam) * 65535.0f);
+ g_ = g_<32768.0f ? igamcurve[g_] : (Color::gamman((float)g_/32768.0f, igam) * 65535.0f);
+ b_ = b_<32768.0f ? igamcurve[b_] : (Color::gamman((float)b_/32768.0f, igam) * 65535.0f);
+ //readapt arbitrary gamma (inverse from beginning)
+ r_ = Color::gammatab_26_11[r_];
+ g_ = Color::gammatab_26_11[g_];
+ b_ = Color::gammatab_26_11[b_];
+
+ float factor = Vmask[i1]*Hmask[j1]/gain;
+
+ dsttmp->r(i,j) += factor*r_;
+ dsttmp->g(i,j) += factor*g_;
+ dsttmp->b(i,j) += factor*b_;
+
+ }
+ }
+ }
+ else {//RGB mode
for (int i=tiletop; iL[i1][j1];
- X = (labdn->a[i1][j1]) + Y;
- Z = Y - (labdn->b[i1][j1]);
-
- X = X<32768.0f ? igamcurve[X] : (Color::gamma((float)X/32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f);
- Y = Y<32768.0f ? igamcurve[Y] : (Color::gamma((float)Y/32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f);
- Z = Z<32768.0f ? igamcurve[Z] : (Color::gamma((float)Z/32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f);
+ //modification Jacques feb 2013
+ L = labdn->L[i1][j1];
+ a = labdn->a[i1][j1];
+ b = labdn->b[i1][j1];
+ Color::Lab2XYZ(L, a, b, X, Y, Z);
float factor = Vmask[i1]*Hmask[j1];
-
- float rtmp = sRGB_xyz[0][0]*X + sRGB_xyz[0][1]*Y + sRGB_xyz[0][2]*Z;
- float gtmp = sRGB_xyz[1][0]*X + sRGB_xyz[1][1]*Y + sRGB_xyz[1][2]*Z;
- float btmp = sRGB_xyz[2][0]*X + sRGB_xyz[2][1]*Y + sRGB_xyz[2][2]*Z;
-
- dsttmp->r(i,j) += factor*rtmp;
- dsttmp->g(i,j) += factor*gtmp;
- dsttmp->b(i,j) += factor*btmp;
+ float r_,g_,b_;
+ Color::xyz2rgb(X,Y,Z,r_,g_,b_,wip);
+ //gamma slider is different from Raw
+ r_ = r_<32768.0f ? igamcurve[r_] : (Color::gamman((float)r_/32768.0f, igam) * 65535.0f);
+ g_ = g_<32768.0f ? igamcurve[g_] : (Color::gamman((float)g_/32768.0f, igam) * 65535.0f);
+ b_ = b_<32768.0f ? igamcurve[b_] : (Color::gamman((float)b_/32768.0f, igam) * 65535.0f);
+
+ dsttmp->r(i,j) += factor*r_;
+ dsttmp->g(i,j) += factor*g_;
+ dsttmp->b(i,j) += factor*b_;
}
}
@@ -571,8 +698,12 @@ namespace rtengine {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
delete labdn;
+ // delete noiseh;
+
delete[] Vmask;
delete[] Hmask;
+
+
}//end of tile row
}//end of tile loop
@@ -758,14 +889,17 @@ namespace rtengine {
float skip_L = WaveletCoeffs_L.level_stride(lvl);
float skip_ab = WaveletCoeffs_a.level_stride(lvl);
-
+ float skip_h;
float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl);
float ** WavCoeffs_a = WaveletCoeffs_a.level_coeffs(lvl);
float ** WavCoeffs_b = WaveletCoeffs_b.level_coeffs(lvl);
if (lvl==maxlvl-1) {
+ // ShrinkAll(WavCoeffs_L, WavCoeffs_a, WavCoeffs_b, lvl, Wlvl_L, Hlvl_L, Wlvl_ab, Hlvl_ab,10,10,
+ // skip_L, skip_ab, skip_h, noisevar_L, noisevar_ab, NULL, NULL);//TODO: this implies redundant evaluation of MAD
ShrinkAll(WavCoeffs_L, WavCoeffs_a, WavCoeffs_b, lvl, Wlvl_L, Hlvl_L, Wlvl_ab, Hlvl_ab,
- skip_L, skip_ab, noisevar_L, noisevar_ab);//TODO: this implies redundant evaluation of MAD
+ skip_L, skip_ab, noisevar_L, noisevar_ab, NULL);//TODO: this implies redundant evaluation of MAD
+
} else {
float ** WavPars_L = WaveletCoeffs_L.level_coeffs(lvl+1);
@@ -882,10 +1016,11 @@ namespace rtengine {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void ImProcFunctions::WaveletDenoiseAll(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_ab, LabImage * noi)//mod JD
+
{
int maxlvl = WaveletCoeffs_L.maxlevel();
-// printf("maxlevel = %d\n",maxlvl);
+// printf("maxlevel = %d\n",maxlvl);
//omp_set_nested(true);
#ifdef _OPENMP
#pragma omp parallel for
@@ -898,16 +1033,19 @@ namespace rtengine {
int Wlvl_ab = WaveletCoeffs_a.level_W(lvl);
int Hlvl_ab = WaveletCoeffs_a.level_H(lvl);
+
float skip_L = WaveletCoeffs_L.level_stride(lvl);
float skip_ab = WaveletCoeffs_a.level_stride(lvl);
float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl);
float ** WavCoeffs_a = WaveletCoeffs_a.level_coeffs(lvl);
float ** WavCoeffs_b = WaveletCoeffs_b.level_coeffs(lvl);
-// printf("Hab : %d\n", Hlvl_ab);
-// printf("Wab : %d\n", Wlvl_ab);
+
+ // 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);
+ skip_L, skip_ab, noisevar_L, noisevar_ab, noi);
+
}
//omp_set_nested(false);
}
@@ -916,8 +1054,10 @@ namespace rtengine {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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)
- {
+ 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)
+
+
+ {
//simple wavelet shrinkage
const float eps = 0.01f;
float * sfave = new float[W_L*H_L];
@@ -934,7 +1074,7 @@ namespace rtengine {
float madb = SQR(MadMax(WavCoeffs_b[dir], max, W_ab*H_ab));
- //printf(" dir=%d mad_L=%f mad_a=%f mad_b=%f \n",dir,sqrt(madL),sqrt(mada),sqrt(madb));
+ // 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;
@@ -948,17 +1088,33 @@ namespace rtengine {
#endif
for (int i=0; ib[2*i][2*j],noi->a[2*i][2*j]);
+ //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
+ }
+ 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-exp(-(mag_a/mad_a)-(mag_L/(9*madL))));
sfaveb[coeffloc_ab] = (1-exp(-(mag_b/mad_b)-(mag_L/(9*madL))));
-
+ mad_a=m_a;
+ mad_b=m_b;
// 'firm' threshold of chroma coefficients
//WavCoeffs_a[dir][coeffloc_ab] *= (1-exp(-(mag_a/mad_a)-(mag_L/(9*madL))));//(coeff_a>2*thresh_a ? 1 : (coeff_a2*thresh_b ? 1 : (coeff_bb[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;
+ }
+ 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;
@@ -989,6 +1161,8 @@ namespace rtengine {
//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);
WavCoeffs_b[dir][coeffloc_ab] *= (SQR(sfaveb[coeffloc_ab])+SQR(sfb))/(sfaveb[coeffloc_ab]+sfb+eps);
+ mad_a=m_a;
+ mad_b=m_b;
}//now chrominance coefficients are denoised
}
diff --git a/rtengine/color.cc b/rtengine/color.cc
index 96c9bb19b..9d30ae878 100644
--- a/rtengine/color.cc
+++ b/rtengine/color.cc
@@ -34,6 +34,10 @@ namespace rtengine {
LUTf Color::gammatab;
LUTf Color::igammatab_srgb;
LUTf Color::gammatab_srgb;
+ // LUTf Color::igammatab_709;
+ // LUTf Color::gammatab_709;
+ LUTf Color::igammatab_26_11;
+ LUTf Color::gammatab_26_11;
// Wikipedia sRGB: Unlike most other RGB color spaces, the sRGB gamma cannot be expressed as a single numerical value.
// The overall gamma is approximately 2.2, consisting of a linear (gamma 1.0) section near black, and a non-linear section elsewhere involving a 2.4 exponent
@@ -131,6 +135,10 @@ namespace rtengine {
gammatab(65536,0);
igammatab_srgb(65536,0);
gammatab_srgb(65536,0);
+ // igammatab_709(65536,0);
+ // gammatab_709(65536,0);
+ igammatab_26_11(65536,0);
+ gammatab_26_11(65536,0);
for (int i=0; i<65536; i++)
gammatab_srgb[i] = (65535.0 * gamma2 (i/65535.0));
@@ -138,7 +146,17 @@ namespace rtengine {
igammatab_srgb[i] = (65535.0 * igamma2 (i/65535.0));
for (int i=0; i<65536; i++)
gammatab[i] = (65535.0 * pow (i/65535.0, 0.454545));
-
+/*
+ for (int i=0; i<65536; i++)
+ gammatab_709[i] = (65535.0 * gamma709 (i/65535.0));
+ for (int i=0; i<65536; i++)
+ igammatab_709[i] = (65535.0 * igamma709 (i/65535.0));
+*/
+ for (int i=0; i<65536; i++)
+ gammatab_26_11[i] = (65535.0 * gamma26_11 (i/65535.0));
+ for (int i=0; i<65536; i++)
+ igammatab_26_11[i] = (65535.0 * igamma26_11 (i/65535.0));
+
/*FILE* f = fopen ("c.txt", "wt");
for (int i=0; i<256; i++)
fprintf (f, "%g %g\n", i/255.0, clower (i/255.0, 2.0, 1.0));
@@ -339,7 +357,24 @@ namespace rtengine {
b = ((sRGB_xyz[2][0]*x + sRGB_xyz[2][1]*y + sRGB_xyz[2][2]*z)) ;
}
+ void Color::xyz2Prophoto (float x, float y, float z, float &r, float &g, float &b) {
+ r = ((prophoto_xyz[0][0]*x + prophoto_xyz[0][1]*y + prophoto_xyz[0][2]*z)) ;
+ g = ((prophoto_xyz[1][0]*x + prophoto_xyz[1][1]*y + prophoto_xyz[1][2]*z)) ;
+ b = ((prophoto_xyz[2][0]*x + prophoto_xyz[2][1]*y + prophoto_xyz[2][2]*z)) ;
+ }
+ void Color::Prophotoxyz (float r, float g, float b, float &x, float &y, float &z) {
+ x = ((xyz_prophoto[0][0]*r + xyz_prophoto[0][1]*g + xyz_prophoto[0][2]*b)) ;
+ y = ((xyz_prophoto[1][0]*r + xyz_prophoto[1][1]*g + xyz_prophoto[1][2]*b)) ;
+ z = ((xyz_prophoto[2][0]*r + xyz_prophoto[2][1]*g + xyz_prophoto[2][2]*b)) ;
+ }
+ void Color::rgbxyz (float r, float g, float b, float &x, float &y, float &z, double xyz_rgb[3][3]) {
+ x = ((xyz_rgb[0][0]*r + xyz_rgb[0][1]*g + xyz_rgb[0][2]*b)) ;
+ y = ((xyz_rgb[1][0]*r + xyz_rgb[1][1]*g + xyz_rgb[1][2]*b)) ;
+ z = ((xyz_rgb[2][0]*r + xyz_rgb[2][1]*g + xyz_rgb[2][2]*b)) ;
+ }
+
+
void Color::xyz2rgb (float x, float y, float z, float &r, float &g, float &b, double rgb_xyz[3][3]) {
//Transform to output color. Standard sRGB is D65, but internal representation is D50
//Note that it is only at this point that we should have need of clipping color data
diff --git a/rtengine/color.h b/rtengine/color.h
index 0dc94f335..48d764ed0 100644
--- a/rtengine/color.h
+++ b/rtengine/color.h
@@ -100,6 +100,11 @@ public:
// look-up tables for the standard srgb gamma and its inverse (filled by init())
static LUTf igammatab_srgb;
static LUTf gammatab_srgb;
+// static LUTf igammatab_709;
+// static LUTf gammatab_709;
+ static LUTf igammatab_26_11;
+ static LUTf gammatab_26_11;
+
// look-up tables for the simple exponential gamma
static LUTf gammatab;
@@ -116,8 +121,12 @@ public:
static void hsv2rgb (float h, float s, float v, int &r, int &g, int &b);
static void hsv2rgb01 (float h, float s, float v, float &r, float &g, float &b);
static void xyz2srgb (float x, float y, float z, float &r, float &g, float &b);
+ static void xyz2Prophoto (float x, float y, float z, float &r, float &g, float &b);
+ static void Prophotoxyz (float r, float g, float b, float &x, float &y, float &z);
static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, double rgb_xyz[3][3]);
static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, float rgb_xyz[3][3]);
+ static void rgbxyz (float r, float g, float b, float &x, float &y, float &z, double xyz_rgb[3][3]);
+
static void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z);
static void XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b);
static void Lab2Yuv(float L, float a, float b, float &Y, float &u, float &v);
@@ -126,12 +135,26 @@ public:
static void calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4,double &gamma5);
// standard srgb gamma and its inverse
- static inline double gamma2 (double x) {
+ static inline double gamma2 (double x) {
return x <= 0.00304 ? x*12.92 : 1.055*exp(log(x)/sRGBGammaCurve)-0.055;
}
- static inline double igamma2 (double x) {
- return x <= 0.03928 ? x/12.92 : exp(log((x+0.055)/1.055)*sRGBGammaCurve);
+ static inline double igamma2 (double x) {
+ return x <= 0.03928 ? x/12.92 : exp(log((x+0.055)/1.055)*sRGBGammaCurve);
+ }
+/* static inline double gamma709 (double x) {
+ return x <= 0.0176 ? x*4.5 : 1.0954*exp(log(x)/2.2)-0.0954;
}
+ static inline double igamma709 (double x) {
+ return x <= 0.0795 ? x/4.5 : exp(log((x+0.0954)/1.0954)*2.2);
+ }
+*/
+ static inline double gamma26_11 (double x) {
+ return x <= 0.004921 ? x*11.0 : 1.086603*exp(log(x)/2.6)-0.086603;
+ }
+ static inline double igamma26_11 (double x) {
+ return x <= 0.054127 ? x/11.0 : exp(log((x+0.086603)/1.086603)*2.6);
+ }
+
// gamma function with adjustable parameters
static inline double gamma (double x, double gamma, double start, double slope, double mul, double add){
return (x <= start ? x*slope : exp(log(x)/gamma)*mul-add);
@@ -139,6 +162,12 @@ public:
static inline double igamma (double x, double gamma, double start, double slope, double mul, double add){
return (x <= start*slope ? x/slope : exp(log((x+add)/mul)*gamma) );
}
+ static inline double gamman (double x, double gamma){//gamma standard without slope...
+ return (x =exp(log(x)/gamma));
+ }
+ static inline double igamman (double x, double gamma){//inverse gamma standard without slope...
+ return (x = exp(log(x)*gamma) );
+ }
// gamma functions on [0,65535] based on look-up tables
static inline float gamma_srgb (char x) { return gammatab_srgb[x]; }
diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc
index 8b0adc054..885f5252f 100644
--- a/rtengine/improcfun.cc
+++ b/rtengine/improcfun.cc
@@ -2432,6 +2432,8 @@ void ImProcFunctions::chromiLuminanceCurve (int pW, LabImage* lold, LabImage* ln
else if(Lprov1<75.0f) dred = -3.0f*Lprov1 +265.0f;
else dred = 40.0f;
// end pyramid
+ if(params->dirpyrDenoise.enabled && chromaticity ==0) chromaticity = 0.5f;
+
if(chromaticity!=0 && !bwToning){
float chromahist;
float factorskin, factorsat, factor, factorskinext, interm;
@@ -2460,9 +2462,17 @@ void ImProcFunctions::chromiLuminanceCurve (int pW, LabImage* lold, LabImage* ln
}
factorsat=chromapro;
+ //increase saturation after denoise : ...approximation
+ float factnoise=1.f;
+ if(params->dirpyrDenoise.enabled) {
+ factnoise=(1.f+params->dirpyrDenoise.chroma/500.f);//levels=5
+
+
+ // if(yyyy) factnoise=(1.f+params->dirpyrDenoise.chroma/100.f);//levels=7
+ }
+ factorsat*=factnoise;
+
factor=factorsat;
-
- factor = factorsat;
// Test if chroma is in the normal range first
Color::transitred ( HH, Chprov1, dred, factorskin, protect_red, factorskinext, deltaHH, factorsat, factor);
atmp *= factor;
diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h
index 060091117..9512aba78 100644
--- a/rtengine/improcfun.h
+++ b/rtengine/improcfun.h
@@ -34,6 +34,7 @@
#include
#include "cplx_wavelet_dec.h"
+
namespace rtengine {
using namespace procparams;
@@ -74,6 +75,9 @@ class ImProcFunctions {
double g;
static LUTf cachef;
+ float noisered;
+ float noiseblue;
+ bool perf;
double lumimul[3];
@@ -138,15 +142,22 @@ class ImProcFunctions {
void RGBoutput_tile_row (float *Lbloxrow, float ** Ldetail, float ** tilemask_out, int height, int width, int top );
//void WaveletDenoise(cplx_wavelet_decomposition &DualTreeCoeffs, float noisevar );
//void WaveletDenoise(wavelet_decomposition &WaveletCoeffs, float noisevar );
+ // 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 );
+ wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_ab, LabImage * noi );
+
void WaveletDenoiseAll_BiShrink(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_a,
wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_ab );
//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);
+ // 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 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);
+ 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);
+
float MadMax(float * HH_Coeffs, int &max, int datalen);
// pyramid equalizer
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index 7e99d2940..301afc7e3 100644
--- a/rtengine/procevents.h
+++ b/rtengine/procevents.h
@@ -222,9 +222,12 @@ enum ProcEvent {
EvCATCurveMode3=197,
EvCATdatacie=198,
EvCATtonecie=199,
-// EvCATsharpcie=200,
+ EvDPDNredchro=200,
+ EvDPDNbluechro=201,
+ EvDPDNmet=202,
+// EvDPDNperform=201,
- NUMOFEVENTS=200
+ NUMOFEVENTS=203
};
}
#endif
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index f81e9fde3..e77ea923f 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -252,11 +252,15 @@ void ProcParams::setDefaults () {
defringe.threshold = 25;
dirpyrDenoise.enabled = false;
+ // dirpyrDenoise.perform = false;
dirpyrDenoise.luma = 30;
dirpyrDenoise.Ldetail = 50;
dirpyrDenoise.chroma = 30;
+ dirpyrDenoise.redchro = 0;
+ dirpyrDenoise.bluechro = 0;
dirpyrDenoise.gamma = 1.7;
dirpyrDenoise.expcomp = 0.0;
+ dirpyrDenoise.dmethod = "RGB";
edgePreservingDecompositionUI.enabled = false;
edgePreservingDecompositionUI.Strength = 0.25;
@@ -665,9 +669,13 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, ParamsEdited* p
// save dirpyrDenoise
if (!pedited || pedited->dirpyrDenoise.enabled) keyFile.set_boolean ("Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled);
+ // 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);
if (!pedited || pedited->dirpyrDenoise.chroma) keyFile.set_double ("Directional Pyramid Denoising", "Chroma", dirpyrDenoise.chroma);
+ if (!pedited || pedited->dirpyrDenoise.dmethod) keyFile.set_string ("Directional Pyramid Denoising", "Method", dirpyrDenoise.dmethod);
+ if (!pedited || pedited->dirpyrDenoise.redchro) keyFile.set_double ("Directional Pyramid Denoising", "Redchro", dirpyrDenoise.redchro);
+ if (!pedited || pedited->dirpyrDenoise.bluechro)keyFile.set_double ("Directional Pyramid Denoising", "Bluechro", dirpyrDenoise.bluechro);
if (!pedited || pedited->dirpyrDenoise.gamma) keyFile.set_double ("Directional Pyramid Denoising", "Gamma", dirpyrDenoise.gamma);
//Save edgePreservingDecompositionUI.
@@ -1164,9 +1172,14 @@ 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", "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; }
if (keyFile.has_key ("Directional Pyramid Denoising", "Chroma")) { dirpyrDenoise.chroma = keyFile.get_double ("Directional Pyramid Denoising", "Chroma"); if (pedited) pedited->dirpyrDenoise.chroma = true; }
+ if (keyFile.has_key ("Directional Pyramid Denoising", "Method")) {dirpyrDenoise.dmethod = keyFile.get_string ("Directional Pyramid Denoising", "Method"); if (pedited) pedited->dirpyrDenoise.dmethod = true; }
+
+ if (keyFile.has_key ("Directional Pyramid Denoising", "Redchro")) { dirpyrDenoise.redchro = keyFile.get_double ("Directional Pyramid Denoising", "Redchro"); if (pedited) pedited->dirpyrDenoise.redchro = true; }
+ if (keyFile.has_key ("Directional Pyramid Denoising", "Bluechro")) { dirpyrDenoise.bluechro = keyFile.get_double ("Directional Pyramid Denoising", "Bluechro"); if (pedited) pedited->dirpyrDenoise.bluechro = true; }
if (keyFile.has_key ("Directional Pyramid Denoising", "Gamma")) { dirpyrDenoise.gamma = keyFile.get_double ("Directional Pyramid Denoising", "Gamma"); if (pedited) pedited->dirpyrDenoise.gamma = true; }
}
@@ -1539,9 +1552,13 @@ bool ProcParams::operator== (const ProcParams& other) {
&& impulseDenoise.enabled == other.impulseDenoise.enabled
&& impulseDenoise.thresh == other.impulseDenoise.thresh
&& dirpyrDenoise.enabled == other.dirpyrDenoise.enabled
+// && dirpyrDenoise.perform == other.dirpyrDenoise.perform
&& dirpyrDenoise.luma == other.dirpyrDenoise.luma
&& dirpyrDenoise.Ldetail == other.dirpyrDenoise.Ldetail
&& dirpyrDenoise.chroma == other.dirpyrDenoise.chroma
+ && dirpyrDenoise.dmethod == other.dirpyrDenoise.dmethod
+ && dirpyrDenoise.redchro == other.dirpyrDenoise.redchro
+ && dirpyrDenoise.bluechro == other.dirpyrDenoise.bluechro
&& dirpyrDenoise.gamma == other.dirpyrDenoise.gamma
&& edgePreservingDecompositionUI.enabled == other.edgePreservingDecompositionUI.enabled
&& edgePreservingDecompositionUI.Strength == other.edgePreservingDecompositionUI.Strength
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 476b2c7b7..29dc503eb 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -457,11 +457,16 @@ class WBParams {
public:
bool enabled;
- double luma;
+ bool perform;
+ double luma;
double Ldetail;
double chroma;
+ double redchro;
+ double bluechro;
double gamma;
double expcomp;
+ Glib::ustring dmethod;
+
};
//EPD related parameters.
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index 4be692890..cae922f8a 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -219,7 +219,11 @@ LUMINANCECURVE, // EvCATcurvemode2
LUMINANCECURVE, // EvCATcurve3
LUMINANCECURVE, // EvCATcurvemode3
LUMINANCECURVE, // EvCATdatacie
-LUMINANCECURVE // EvCATtonecie
+LUMINANCECURVE, // EvCATtonecie
+ALLNORAW, // EvDPDNbluechro
+ALLNORAW, // EvDPDNperform
+ALLNORAW //EvDPDNmet
+
//LUMINANCECURVE // EvCATsharpcie
diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h
index 903733b6b..118b74980 100644
--- a/rtgui/addsetids.h
+++ b/rtgui/addsetids.h
@@ -31,36 +31,40 @@
#define ADDSET_TC_HLCOMPTHRESH 23
#define ADDSET_TC_SHCOMP 24
#define ADDSET_DIRPYREQ 25
-#define ADDSET_DIRPYRDN_CHLUM 26
-#define ADDSET_DIRPYRDN_GAMMA 27
-#define ADDSET_CHMIXER 28
-#define ADDSET_PREPROCESS_GREENEQUIL 29
-#define ADDSET_PREPROCESS_LINEDENOISE 30
-#define ADDSET_RAWCACORR 31
-#define ADDSET_RAWEXPOS_LINEAR 32
-#define ADDSET_RAWEXPOS_PRESER 33
-#define ADDSET_RAWEXPOS_BLACKS 34
-#define ADDSET_SHARPENEDGE_AMOUNT 35
-#define ADDSET_SHARPENMICRO_AMOUNT 36
-#define ADDSET_SHARPENEDGE_PASS 37
-#define ADDSET_SHARPENMICRO_UNIFORMITY 38
-#define ADDSET_VIBRANCE_PASTELS 39
-#define ADDSET_VIBRANCE_SATURATED 40
-#define ADDSET_FREE_OUPUT_GAMMA 41
-#define ADDSET_FREE_OUTPUT_SLOPE 42
-#define ADDSET_CAT_DEGREE 43
-#define ADDSET_CAT_ADAPTSCENE 44
-#define ADDSET_CAT_ADAPTVIEWING 45
-#define ADDSET_CAT_LIGHT 46
-#define ADDSET_CAT_CHROMA 47
-#define ADDSET_CAT_CONTRAST 48
-#define ADDSET_CAT_RSTPRO 49
-#define ADDSET_CAT_BRIGHT 50
-#define ADDSET_CAT_CONTRAST_Q 51
-#define ADDSET_CAT_CHROMA_S 52
-#define ADDSET_CAT_CHROMA_M 53
-#define ADDSET_CAT_HUE 54
+#define ADDSET_DIRPYRDN_LUMA 26
+#define ADDSET_DIRPYRDN_LUMDET 27
+#define ADDSET_DIRPYRDN_CHROMA 28
+#define ADDSET_DIRPYRDN_CHROMARED 29
+#define ADDSET_DIRPYRDN_CHROMABLUE 30
+#define ADDSET_DIRPYRDN_GAMMA 31
+#define ADDSET_CHMIXER 32
+#define ADDSET_PREPROCESS_GREENEQUIL 33
+#define ADDSET_PREPROCESS_LINEDENOISE 34
+#define ADDSET_RAWCACORR 35
+#define ADDSET_RAWEXPOS_LINEAR 36
+#define ADDSET_RAWEXPOS_PRESER 37
+#define ADDSET_RAWEXPOS_BLACKS 38
+#define ADDSET_SHARPENEDGE_AMOUNT 39
+#define ADDSET_SHARPENMICRO_AMOUNT 40
+#define ADDSET_SHARPENEDGE_PASS 41
+#define ADDSET_SHARPENMICRO_UNIFORMITY 42
+#define ADDSET_VIBRANCE_PASTELS 43
+#define ADDSET_VIBRANCE_SATURATED 44
+#define ADDSET_FREE_OUPUT_GAMMA 45
+#define ADDSET_FREE_OUTPUT_SLOPE 46
+#define ADDSET_CAT_DEGREE 47
+#define ADDSET_CAT_ADAPTSCENE 48
+#define ADDSET_CAT_ADAPTVIEWING 49
+#define ADDSET_CAT_LIGHT 50
+#define ADDSET_CAT_CHROMA 51
+#define ADDSET_CAT_CONTRAST 52
+#define ADDSET_CAT_RSTPRO 53
+#define ADDSET_CAT_BRIGHT 54
+#define ADDSET_CAT_CONTRAST_Q 55
+#define ADDSET_CAT_CHROMA_S 56
+#define ADDSET_CAT_CHROMA_M 57
+#define ADDSET_CAT_HUE 58
// When adding items, make sure to update ADDSET_PARAM_NUM
-#define ADDSET_PARAM_NUM 55 // THIS IS USED AS A DELIMITER!!
+#define ADDSET_PARAM_NUM 59 // THIS IS USED AS A DELIMITER!!
#endif
diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc
index c40b4cde3..55ac21a68 100644
--- a/rtgui/batchtoolpanelcoord.cc
+++ b/rtgui/batchtoolpanelcoord.cc
@@ -141,7 +141,7 @@ void BatchToolPanelCoordinator::initSession () {
chmixer->setAdjusterBehavior (false);
shadowshighlights->setAdjusterBehavior (false, false, false);
dirpyrequalizer->setAdjusterBehavior (false);
- dirpyrdenoise->setAdjusterBehavior (false, false);
+ dirpyrdenoise->setAdjusterBehavior (false, false,false,false,false,false);
preprocess->setAdjusterBehavior (false, false);
rawcacorrection->setAdjusterBehavior (false);
rawexposure->setAdjusterBehavior (false, false, false);
@@ -168,7 +168,7 @@ void BatchToolPanelCoordinator::initSession () {
chmixer->setAdjusterBehavior (options.baBehav[ADDSET_CHMIXER]);
shadowshighlights->setAdjusterBehavior (options.baBehav[ADDSET_SH_HIGHLIGHTS], options.baBehav[ADDSET_SH_SHADOWS], options.baBehav[ADDSET_SH_LOCALCONTRAST]);
dirpyrequalizer->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYREQ]);
- dirpyrdenoise->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYRDN_CHLUM], options.baBehav[ADDSET_DIRPYRDN_GAMMA]);
+ dirpyrdenoise->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYRDN_LUMA],options.baBehav[ADDSET_DIRPYRDN_LUMDET],options.baBehav[ADDSET_DIRPYRDN_CHROMA],options.baBehav[ADDSET_DIRPYRDN_CHROMARED],options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE], options.baBehav[ADDSET_DIRPYRDN_GAMMA]);
preprocess->setAdjusterBehavior (options.baBehav[ADDSET_PREPROCESS_LINEDENOISE], options.baBehav[ADDSET_PREPROCESS_GREENEQUIL]);
rawcacorrection->setAdjusterBehavior (options.baBehav[ADDSET_RAWCACORR]);
rawexposure->setAdjusterBehavior (options.baBehav[ADDSET_RAWEXPOS_LINEAR], options.baBehav[ADDSET_RAWEXPOS_PRESER], options.baBehav[ADDSET_RAWEXPOS_BLACKS]);
@@ -237,7 +237,12 @@ void BatchToolPanelCoordinator::initSession () {
if (options.baBehav[ADDSET_VIGN_CENTER]) pparams.vignetting.centerY = 0;
if (options.baBehav[ADDSET_DIRPYREQ]) for (int i=0; i<5; i++) pparams.dirpyrequalizer.mult[i] = 0;
- if (options.baBehav[ADDSET_DIRPYRDN_CHLUM]) pparams.dirpyrDenoise.Ldetail = pparams.dirpyrDenoise.luma = pparams.dirpyrDenoise.chroma = 0;
+ if (options.baBehav[ADDSET_DIRPYRDN_LUMA]) pparams.dirpyrDenoise.luma = 0;
+
+ if (options.baBehav[ADDSET_DIRPYRDN_CHROMA]) pparams.dirpyrDenoise.chroma = 0;
+ if (options.baBehav[ADDSET_DIRPYRDN_CHROMARED]) pparams.dirpyrDenoise.redchro = 0;
+ if (options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE]) pparams.dirpyrDenoise.bluechro = 0;
+// pparams.dirpyrDenoise.Ldetail = pparams.dirpyrDenoise.luma = pparams.dirpyrDenoise.chroma = 0;
if (options.baBehav[ADDSET_DIRPYRDN_GAMMA]) pparams.dirpyrDenoise.gamma = 0;
if (options.baBehav[ADDSET_PREPROCESS_GREENEQUIL]) pparams.raw.greenthresh = 0;
diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc
index e484a2c90..974c73a45 100644
--- a/rtgui/dirpyrdenoise.cc
+++ b/rtgui/dirpyrdenoise.cc
@@ -28,6 +28,8 @@ DirPyrDenoise::DirPyrDenoise () : Gtk::VBox(), FoldableToolPanel(this) {
set_border_width(4);
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
+ enabled->set_tooltip_text (M("TP_DIRPYRDENOISE_ENABLED_TOOLTIP"));
+
enabled->set_active (false);
enabled->show ();
pack_start (*enabled);
@@ -40,25 +42,57 @@ DirPyrDenoise::DirPyrDenoise () : Gtk::VBox(), FoldableToolPanel(this) {
luma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_LUMA"), 0, 100, 0.01, 0));
- Ldetail = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_LDETAIL"), 0, 100, 0.01, 80));
+ Ldetail = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_LDETAIL"), 0, 100, 0.01, 50));
chroma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_CHROMA"), 0, 100, 0.01, 15));
+ redchro = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_RED"), -100, 100, 0.1, 0));
+ bluechro = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_BLUE"), -100, 100, 0.1, 0));
+
gamma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_GAMMA"), 1.0, 3.0, 0.01, 1.7));
+ gamma->set_tooltip_text (M("TP_DIRPYRDENOISE_GAMMA_TOOLTIP"));
+
+ Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ());
+ hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_DIRPYRDENOISE_METHOD") +": ")),Gtk::PACK_SHRINK, 4);
+ hb1->set_tooltip_markup (M("TP_DIRPYRDENOISE_METHOD_TOOLTIP"));
+
+ dmethod = Gtk::manage (new MyComboBoxText ());
+ dmethod->append_text (M("TP_DIRPYRDENOISE_RGB"));
+ dmethod->append_text (M("TP_DIRPYRDENOISE_LAB"));
+ dmethod->set_active(0);
+ hb1->pack_end (*dmethod, Gtk::PACK_EXPAND_WIDGET, 4);
+ pack_start( *hb1, Gtk::PACK_SHRINK, 4);
+
+
+// perform = Gtk::manage (new Gtk::CheckButton (M("TP_DIRPYRDENOISE_PERF")));
+// perform->set_tooltip_text (M("TP_DIRPYRDENOISE_PERF_TOOLTIP"));
+// perfconn = perform->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrDenoise::perform_toggled) );
+ dmethodconn = dmethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::dmethodChanged) );
luma->setAdjusterListener (this);
Ldetail->setAdjusterListener (this);
chroma->setAdjusterListener (this);
+ redchro->setAdjusterListener (this);
+ bluechro->setAdjusterListener (this);
+
gamma->setAdjusterListener (this);
luma->show();
Ldetail->show();
chroma->show();
+ redchro->show();
+ bluechro->show();
+// perform->show();
gamma->show();
+// perform->set_active (true);
pack_start (*luma);
pack_start (*Ldetail);
pack_start (*chroma);
+ pack_start (*redchro);
+ pack_start (*bluechro);
+
pack_start (*gamma);
+// pack_start (*perform);
}
@@ -70,19 +104,39 @@ void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) {
luma->setEditedState (pedited->dirpyrDenoise.luma ? Edited : UnEdited);
Ldetail->setEditedState (pedited->dirpyrDenoise.Ldetail ? Edited : UnEdited);
chroma->setEditedState (pedited->dirpyrDenoise.chroma ? Edited : UnEdited);
+ redchro->setEditedState (pedited->dirpyrDenoise.redchro ? Edited : UnEdited);
+ bluechro->setEditedState (pedited->dirpyrDenoise.bluechro ? Edited : UnEdited);
+
gamma->setEditedState (pedited->dirpyrDenoise.gamma ? Edited : UnEdited);
enabled->set_inconsistent (!pedited->dirpyrDenoise.enabled);
+ // perform->set_inconsistent (!pedited->dirpyrDenoise.perform);
+
}
-
+// perfconn.block (true);
enaConn.block (true);
enabled->set_active (pp->dirpyrDenoise.enabled);
- enaConn.block (false);
-
- lastEnabled = pp->dirpyrDenoise.enabled;
+ // perform->set_active (pp->dirpyrDenoise.perform);
+ enaConn.block (false);
+ // perfconn.block (false);
+ lastEnabled = pp->dirpyrDenoise.enabled;
+// lastperform = pp->dirpyrDenoise.perform;
luma->setValue (pp->dirpyrDenoise.luma);
Ldetail->setValue (pp->dirpyrDenoise.Ldetail);
chroma->setValue (pp->dirpyrDenoise.chroma);
+ redchro->setValue (pp->dirpyrDenoise.redchro);
+ bluechro->setValue (pp->dirpyrDenoise.bluechro);
+ dmethodconn.block(true);
+ if (pedited && !pedited->dirpyrDenoise.dmethod)
+ dmethod->set_active (2);
+ else if (pp->dirpyrDenoise.dmethod=="RGB")
+ dmethod->set_active (0);
+ else if (pp->dirpyrDenoise.dmethod=="Lab")
+ dmethod->set_active (1);
+ dmethodconn.block(false);
+ // Have to be manually called to handle initial state update
+ dmethodChanged();
+
gamma->setValue (pp->dirpyrDenoise.gamma);
enableListener ();
@@ -93,35 +147,61 @@ void DirPyrDenoise::write (ProcParams* pp, ParamsEdited* pedited) {
pp->dirpyrDenoise.luma = luma->getValue ();
pp->dirpyrDenoise.Ldetail = Ldetail->getValue ();
pp->dirpyrDenoise.chroma = chroma->getValue ();
+ pp->dirpyrDenoise.redchro = redchro->getValue ();
+ pp->dirpyrDenoise.bluechro = bluechro->getValue ();
pp->dirpyrDenoise.gamma = gamma->getValue ();
pp->dirpyrDenoise.enabled = enabled->get_active();
+// pp->dirpyrDenoise.perform = perform->get_active();
if (pedited) {
pedited->dirpyrDenoise.luma = luma->getEditedState ();
pedited->dirpyrDenoise.Ldetail = Ldetail->getEditedState ();
pedited->dirpyrDenoise.chroma = chroma->getEditedState ();
+ pedited->dirpyrDenoise.redchro = redchro->getEditedState ();
+ pedited->dirpyrDenoise.bluechro = bluechro->getEditedState ();
pedited->dirpyrDenoise.gamma = gamma->getEditedState ();
pedited->dirpyrDenoise.enabled = !enabled->get_inconsistent();
- }
+ // pedited->dirpyrDenoise.perform = !perform->get_inconsistent();
+ }
+ if (dmethod->get_active_row_number()==0)
+ pp->dirpyrDenoise.dmethod = "RGB";
+ else if (dmethod->get_active_row_number()==1)
+ pp->dirpyrDenoise.dmethod = "Lab";
+
+
}
+void DirPyrDenoise::dmethodChanged () {
+
+ if (listener && (multiImage||enabled->get_active()) ) {
+ listener->panelChanged (EvDPDNmet, dmethod->get_active_text ());
+ }
+}
+
+
void DirPyrDenoise::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
luma->setDefault (defParams->dirpyrDenoise.luma);
Ldetail->setDefault (defParams->dirpyrDenoise.Ldetail);
chroma->setDefault (defParams->dirpyrDenoise.chroma);
+ redchro->setDefault (defParams->dirpyrDenoise.redchro);
+ bluechro->setDefault (defParams->dirpyrDenoise.bluechro);
gamma->setDefault (defParams->dirpyrDenoise.gamma);
if (pedited) {
luma->setDefaultEditedState (pedited->dirpyrDenoise.luma ? Edited : UnEdited);
Ldetail->setDefaultEditedState (pedited->dirpyrDenoise.Ldetail ? Edited : UnEdited);
chroma->setDefaultEditedState (pedited->dirpyrDenoise.chroma ? Edited : UnEdited);
+ redchro->setDefaultEditedState (pedited->dirpyrDenoise.redchro ? Edited : UnEdited);
+ bluechro->setDefaultEditedState (pedited->dirpyrDenoise.bluechro ? Edited : UnEdited);
gamma->setDefaultEditedState (pedited->dirpyrDenoise.gamma ? Edited : UnEdited);
}
else {
luma->setDefaultEditedState (Irrelevant);
Ldetail->setDefaultEditedState (Irrelevant);
chroma->setDefaultEditedState (Irrelevant);
+ redchro->setDefaultEditedState (Irrelevant);
+ bluechro->setDefaultEditedState (Irrelevant);
gamma->setDefaultEditedState (Irrelevant);
}
}
@@ -138,6 +218,10 @@ void DirPyrDenoise::adjusterChanged (Adjuster* a, double newval) {
listener->panelChanged (EvDPDNLuma, costr);
else if (a==chroma)
listener->panelChanged (EvDPDNChroma, costr);
+ else if (a==redchro)
+ listener->panelChanged (EvDPDNredchro, costr);
+ else if (a==bluechro)
+ listener->panelChanged (EvDPDNbluechro, costr);
else if (a==gamma)
listener->panelChanged (EvDPDNGamma, costr);
}
@@ -165,6 +249,30 @@ void DirPyrDenoise::enabledChanged () {
listener->panelChanged (EvDPDNEnabled, M("GENERAL_DISABLED"));
}
}
+/*
+void DirPyrDenoise::perform_toggled () {
+
+ if (batchMode) {
+ if (perform->get_inconsistent()) {
+ perform->set_inconsistent (false);
+ perfconn.block (true);
+ perform->set_active (false);
+ perfconn.block (false);
+ }
+ else if (lastperform)
+ perform->set_inconsistent (true);
+
+ lastperform = perform->get_active ();
+ }
+
+ if (listener) {
+ if (perform->get_active ())
+ listener->panelChanged (EvDPDNperform, M("GENERAL_ENABLED"));
+ else
+ listener->panelChanged (EvDPDNperform, M("GENERAL_DISABLED"));
+ }
+}
+*/
void DirPyrDenoise::setBatchMode (bool batchMode) {
@@ -172,14 +280,20 @@ void DirPyrDenoise::setBatchMode (bool batchMode) {
luma->showEditedCB ();
Ldetail->showEditedCB ();
chroma->showEditedCB ();
+ redchro->showEditedCB ();
+ bluechro->showEditedCB ();
gamma->showEditedCB ();
+ dmethod->append_text (M("GENERAL_UNCHANGED"));
+
}
-void DirPyrDenoise::setAdjusterBehavior (bool chrolumaadd, bool gammaadd) {
+void DirPyrDenoise::setAdjusterBehavior (bool lumaadd, bool lumdetadd, bool chromaadd, bool chromaredadd, bool chromablueadd, bool gammaadd) {
- luma->setAddMode(chrolumaadd);
- Ldetail->setAddMode(chrolumaadd);
- chroma->setAddMode(chrolumaadd);
+ luma->setAddMode(lumaadd);
+ Ldetail->setAddMode(lumdetadd);
+ chroma->setAddMode(chromaadd);
+ redchro->setAddMode(chromaredadd);
+ bluechro->setAddMode(chromablueadd);
gamma->setAddMode(gammaadd);
}
@@ -188,5 +302,7 @@ void DirPyrDenoise::trimValues (rtengine::procparams::ProcParams* pp) {
luma->trimValue(pp->dirpyrDenoise.luma);
Ldetail->trimValue(pp->dirpyrDenoise.Ldetail);
chroma->trimValue(pp->dirpyrDenoise.chroma);
+ redchro->trimValue(pp->dirpyrDenoise.redchro);
+ bluechro->trimValue(pp->dirpyrDenoise.bluechro);
gamma->trimValue(pp->dirpyrDenoise.gamma);
}
diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h
index 0aad76286..57362dcdd 100644
--- a/rtgui/dirpyrdenoise.h
+++ b/rtgui/dirpyrdenoise.h
@@ -29,11 +29,19 @@ class DirPyrDenoise : public Gtk::VBox, public AdjusterListener, public Foldable
Adjuster* luma;
Adjuster* Ldetail;
Adjuster* chroma;
+ Adjuster* redchro;
+ Adjuster* bluechro;
Adjuster* gamma;
Gtk::CheckButton* enabled;
bool lastEnabled;
sigc::connection enaConn;
+// Gtk::CheckButton* perform;
+// bool lastperform;
+// sigc::connection perfconn;
+ MyComboBoxText* dmethod;
+ sigc::connection dmethodconn;
+
public:
@@ -46,8 +54,10 @@ class DirPyrDenoise : public Gtk::VBox, public AdjusterListener, public Foldable
void adjusterChanged (Adjuster* a, double newval);
void enabledChanged ();
+// void perform_toggled ();
+ void dmethodChanged ();
- void setAdjusterBehavior (bool chrolumaadd, bool gammaadd);
+ void setAdjusterBehavior (bool lumaadd, bool lumdetadd, bool chromaadd, bool chromaredadd, bool chromablueadd, bool gammaadd);
void trimValues (rtengine::procparams::ProcParams* pp);
};
diff --git a/rtgui/options.cc b/rtgui/options.cc
index abdf88c29..44ed8d1ed 100644
--- a/rtgui/options.cc
+++ b/rtgui/options.cc
@@ -387,7 +387,11 @@ void Options::setDefaults () {
0, // ADDSET_TC_HLCOMPTHRESH
0, // ADDSET_TC_SHCOMP
0, // ADDSET_DIRPYREQ
- 0, // ADDSET_DIRPYRDN_CHLUM
+ 0, // ADDSET_DIRPYRDN_LUMA
+ 0, // ADDSET_DIRPYRDN_LUDET
+ 0, // ADDSET_DIRPYRDN_CHROMA
+ 0, // ADDSET_DIRPYRDN_CHROMARED
+ 0, // ADDSET_DIRPYRDN_CHROMABLUE
0, // ADDSET_DIRPYRDN_GAMMA
0, // ADDSET_CHMIXER
0, // ADDSET_PREPROCESS_GREENEQUIL
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index bac73d126..de199b4d8 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -143,10 +143,14 @@ void ParamsEdited::set (bool v) {
impulseDenoise.enabled = v;
impulseDenoise.thresh = v;
dirpyrDenoise.enabled = v;
+// dirpyrDenoise.perform = v;
dirpyrDenoise.luma = v;
dirpyrDenoise.Ldetail = v;
dirpyrDenoise.chroma = v;
+ dirpyrDenoise.redchro = v;
+ dirpyrDenoise.bluechro = v;
dirpyrDenoise.gamma = v;
+ dirpyrDenoise.dmethod = v;
edgePreservingDecompositionUI.enabled = v;
edgePreservingDecompositionUI.Strength = v;
edgePreservingDecompositionUI.EdgeStopping = v;
@@ -378,10 +382,14 @@ 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.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;
dirpyrDenoise.chroma = dirpyrDenoise.chroma && p.dirpyrDenoise.chroma == other.dirpyrDenoise.chroma;
+ dirpyrDenoise.redchro = dirpyrDenoise.redchro && p.dirpyrDenoise.redchro == other.dirpyrDenoise.redchro;
+ dirpyrDenoise.bluechro = dirpyrDenoise.bluechro && p.dirpyrDenoise.bluechro == other.dirpyrDenoise.bluechro;
dirpyrDenoise.gamma = dirpyrDenoise.gamma && p.dirpyrDenoise.gamma == other.dirpyrDenoise.gamma;
+ dirpyrDenoise.dmethod = dirpyrDenoise.dmethod && p.dirpyrDenoise.dmethod == other.dirpyrDenoise.dmethod;
edgePreservingDecompositionUI.enabled = edgePreservingDecompositionUI.enabled && p.edgePreservingDecompositionUI.enabled == other.edgePreservingDecompositionUI.enabled;
edgePreservingDecompositionUI.Strength = edgePreservingDecompositionUI.Strength && p.edgePreservingDecompositionUI.Strength == other.edgePreservingDecompositionUI.Strength;
@@ -622,10 +630,14 @@ 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.luma) toEdit.dirpyrDenoise.luma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHLUM] ? toEdit.dirpyrDenoise.luma + mods.dirpyrDenoise.luma : mods.dirpyrDenoise.luma;
- if (dirpyrDenoise.Ldetail) toEdit.dirpyrDenoise.Ldetail = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHLUM] ? toEdit.dirpyrDenoise.Ldetail + mods.dirpyrDenoise.Ldetail : mods.dirpyrDenoise.Ldetail;
- if (dirpyrDenoise.chroma) toEdit.dirpyrDenoise.chroma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHLUM] ? toEdit.dirpyrDenoise.chroma + mods.dirpyrDenoise.chroma : mods.dirpyrDenoise.chroma;
+ 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;
+ if (dirpyrDenoise.redchro) toEdit.dirpyrDenoise.redchro = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMARED] ? toEdit.dirpyrDenoise.redchro + mods.dirpyrDenoise.redchro : mods.dirpyrDenoise.redchro;
+ if (dirpyrDenoise.bluechro) toEdit.dirpyrDenoise.bluechro = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE] ? toEdit.dirpyrDenoise.bluechro + mods.dirpyrDenoise.bluechro : mods.dirpyrDenoise.bluechro;
if (dirpyrDenoise.gamma) toEdit.dirpyrDenoise.gamma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_GAMMA] ? toEdit.dirpyrDenoise.gamma + mods.dirpyrDenoise.gamma : mods.dirpyrDenoise.gamma;
+// if (dirpyrDenoise.perform) toEdit.dirpyrDenoise.perform = mods.dirpyrDenoise.perform;
+ if (dirpyrDenoise.dmethod) toEdit.dirpyrDenoise.dmethod = mods.dirpyrDenoise.dmethod;
if (edgePreservingDecompositionUI.enabled) toEdit.edgePreservingDecompositionUI.enabled = mods.edgePreservingDecompositionUI.enabled;
if (edgePreservingDecompositionUI.Strength) toEdit.edgePreservingDecompositionUI.Strength = mods.edgePreservingDecompositionUI.Strength;
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index 7e75f02b5..44e410bd4 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -224,7 +224,11 @@ public:
bool Ldetail;
bool luma;
bool chroma;
+ bool redchro;
+ bool bluechro;
bool gamma;
+// bool perform;
+ bool dmethod;
};
class EPDParamsEdited{
diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc
index bfb35416f..d7a108585 100644
--- a/rtgui/preferences.cc
+++ b/rtgui/preferences.cc
@@ -187,8 +187,13 @@ Gtk::Widget* Preferences::getBatchProcPanel () {
mi = behModel->append ();
mi->set_value (behavColumns.label, M("TP_DIRPYRDENOISE_LABEL"));
- appendBehavList (mi, M("TP_DIRPYRDENOISE_LUMA")+", "+M("TP_DIRPYRDENOISE_CHROMA"), ADDSET_DIRPYRDN_CHLUM, true);
- appendBehavList (mi, M("TP_DIRPYRDENOISE_GAMMA"), ADDSET_DIRPYRDN_GAMMA, true);
+ // appendBehavList (mi, M("TP_DIRPYRDENOISE_LUMA")+", "+M("TP_DIRPYRDENOISE_CHROMA"), ADDSET_DIRPYRDN_CHLUM, true);
+ appendBehavList (mi, M("TP_DIRPYRDENOISE_LUMA"),ADDSET_DIRPYRDN_LUMA, true);
+ appendBehavList (mi, M("TP_DIRPYRDENOISE_LDETAIL"),ADDSET_DIRPYRDN_LUMDET, true);
+ appendBehavList (mi, M("TP_DIRPYRDENOISE_CHROMA"), ADDSET_DIRPYRDN_CHROMA, true);
+ appendBehavList (mi, M("TP_DIRPYRDENOISE_RED"), ADDSET_DIRPYRDN_CHROMARED, true);
+ appendBehavList (mi, M("TP_DIRPYRDENOISE_BLUE"), ADDSET_DIRPYRDN_CHROMABLUE, true);
+ appendBehavList (mi, M("TP_DIRPYRDENOISE_GAMMA"), ADDSET_DIRPYRDN_GAMMA, true);
mi = behModel->append ();
mi->set_value (behavColumns.label, M("TP_WBALANCE_LABEL"));