From 2e86d15c502b88a9a628978938f6dff02ceb942a Mon Sep 17 00:00:00 2001 From: jdc Date: Sun, 3 Mar 2013 07:37:59 +0100 Subject: [PATCH] Noise Colour Chanels Lab mode see issue1734 --- rtdata/languages/default | 16 +- rtdata/profiles/BW-1.pp3 | 5 +- rtdata/profiles/BW-2.pp3 | 5 +- rtdata/profiles/BW-3.pp3 | 5 +- rtdata/profiles/BW-4.pp3 | 5 +- rtdata/profiles/Default-ISO-High.pp3 | 5 +- rtdata/profiles/Default-ISO-Medium.pp3 | 5 +- rtdata/profiles/Default.pp3 | 5 +- rtdata/profiles/Highkey-1.pp3 | 5 +- rtdata/profiles/Natural-1.pp3 | 5 +- rtdata/profiles/Natural-2.pp3 | 5 +- rtdata/profiles/Neutral.pp3 | 5 +- rtdata/profiles/Punchy-1.pp3 | 5 +- rtdata/profiles/Punchy-2.pp3 | 5 +- rtengine/FTblockDN.cc | 308 +++++++++++++++++++------ rtengine/color.cc | 37 ++- rtengine/color.h | 35 ++- rtengine/improcfun.cc | 14 +- rtengine/improcfun.h | 15 +- rtengine/procevents.h | 7 +- rtengine/procparams.cc | 17 ++ rtengine/procparams.h | 7 +- rtengine/refreshmap.cc | 6 +- rtgui/addsetids.h | 64 ++--- rtgui/batchtoolpanelcoord.cc | 11 +- rtgui/dirpyrdenoise.cc | 136 ++++++++++- rtgui/dirpyrdenoise.h | 12 +- rtgui/options.cc | 6 +- rtgui/paramsedited.cc | 18 +- rtgui/paramsedited.h | 4 + rtgui/preferences.cc | 9 +- 31 files changed, 643 insertions(+), 144 deletions(-) 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"));