From 5ee2bf9431e2cdbb0cb7ae83564f02554c294fa0 Mon Sep 17 00:00:00 2001 From: jdc Date: Tue, 31 Mar 2015 08:42:41 +0200 Subject: [PATCH] Wavelet levels Improvments - issue2702 --- rtdata/languages/default | 76 +- rtengine/FTblockDN.cc | 167 ++-- rtengine/cplx_wavelet_dec.h | 28 +- rtengine/cplx_wavelet_filter_coeffs.h | 21 +- rtengine/curves.cc | 3 + rtengine/improcfun.h | 21 +- rtengine/ipwavelet.cc | 1278 ++++++++++++++++++++----- rtengine/procevents.h | 22 +- rtengine/procparams.cc | 179 +++- rtengine/procparams.h | 24 +- rtengine/refreshmap.cc | 22 +- rtengine/settings.h | 10 +- rtgui/addsetids.h | 5 +- rtgui/batchtoolpanelcoord.cc | 5 +- rtgui/dirpyrequalizer.cc | 2 +- rtgui/editid.h | 2 + rtgui/options.cc | 34 + rtgui/paramsedited.cc | 68 +- rtgui/paramsedited.h | 22 +- rtgui/preferences.cc | 7 +- rtgui/wavelet.cc | 1125 ++++++++++++++++++---- rtgui/wavelet.h | 68 +- 22 files changed, 2632 insertions(+), 557 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index ff2837c3e..55af5aafd 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -541,7 +541,7 @@ HISTORY_MSG_319;Wavelet Highlight range HISTORY_MSG_320;Wavelet Shadow range HISTORY_MSG_321;Wavelet Shadow levels HISTORY_MSG_322;Wavelet Avoid color shift -HISTORY_MSG_323;Wavelet Chroma level +HISTORY_MSG_323;Wavelet Contrast curve HISTORY_MSG_324;Wavelet Chroma pastel HISTORY_MSG_325;Wavelet Chroma saturated HISTORY_MSG_326;Wavelet Chroma method @@ -559,6 +559,24 @@ HISTORY_MSG_337;Wavelet Hue range HISTORY_MSG_338;Wavelet Edge Radius HISTORY_MSG_339;Wavelet Edge Value HISTORY_MSG_340;Wavelet Strength +HISTORY_MSG_341;Wavelet Daubechies +HISTORY_MSG_342;Wavelet Reinforce first level +HISTORY_MSG_343;Wavelet level chroma +HISTORY_MSG_344;Wavelet Meth chroma sl/cur +HISTORY_MSG_345;Wavelet Local contrast +HISTORY_MSG_346;Wavelet Local contrast Meth +HISTORY_MSG_347;Wavelet Level0 + denoise +HISTORY_MSG_348;Wavelet Level1 + denoise +HISTORY_MSG_349;Wavelet Level2 + denoise +HISTORY_MSG_350;Wavelet edgedetect +HISTORY_MSG_351;Wavelet Curve Hue +HISTORY_MSG_352;Wavelet Background +HISTORY_MSG_353;Wavelet edgedetect value +HISTORY_MSG_354;Wavelet edgedetect enhance +HISTORY_MSG_355;Wavelet edgedetect thresholdLow +HISTORY_MSG_356;Wavelet edgedetect thresholdHi +HISTORY_MSG_357;Wavelet Denoise link +HISTORY_MSG_358;Wavelet Contrast Hue curve HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOTS;Snapshots @@ -1297,7 +1315,7 @@ TP_DIRPYRDENOISE_SOFT;3x3 TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 TP_DIRPYREQUALIZER_ALGO;Skin Color Range TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. -TP_DIRPYREQUALIZER_GAMUT;Reduce artifacts +TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts TP_DIRPYREQUALIZER_HUESKIN;Skin hue TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;This pyramid is for the upper part, so far as the algorithm at its maximum efficiency.\nTo the lower part, the transition zones.\nIf you need to move the area significantly to the left or right - or if there are artifacts: the white balance is incorrect\nYou can slightly reduce the zone to prevent the rest of the image is affected. TP_DIRPYREQUALIZER_LABEL;Contrast by Detail Levels @@ -1618,14 +1636,17 @@ TP_WAVELET_CHRO;Saturated - Pastel TP_WAVELET_CHRO_TOOLTIP;Limit between pastel and saturated\n 1-x level saturated \n x-9 level pastel TP_WAVELET_CHR;Chroma link TP_WAVELET_CHR_TOOLTIP;Adjust chroma in function of:\na-levels contrasts\nb-Chroma link slider strength -TP_WAVELET_CLVCURVE;Chrominance - Levels +TP_WAVELET_CCURVE;Local contrast TP_WAVELET_COLORT;Opacity Red-Green Levels TP_WAVELET_CONTRAST_MINUS;Contrast - TP_WAVELET_CONTRAST_PLUS;Contrast + TP_WAVELET_CONTRA;Contrast TP_WAVELET_CONTRA_TOOLTIP;Change contrast residual image\nFunction of Max Levels TP_WAVELET_CONTR;Gamut - controls -TP_WAVELET_CURVEEDITOR_CLV_TOOLTIP;Give chroma in function of levels (absciss)\nLevels are discrets values +TP_WAVELET_CTYPE;Chrominance control +TP_WAVELET_EDTYPE;Local contrast control +TP_WAVELET_CHTYPE;Chrominance type +TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modify local contral in fonction of original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) TP_WAVELET_DALL;All directions TP_WAVELET_DISPLAYCHRO;Chromaticity and Toning TP_WAVELET_DISPLAYGAM;Gamut and Control @@ -1634,10 +1655,41 @@ TP_WAVELET_DISP;Preview Settings TP_WAVELET_DONE;Vertical TP_WAVELET_DTHR;Diagonal TP_WAVELET_DTWO;Horizontal +TP_WAVELET_DAUB;Edge Quality +TP_WAVELET_daub2;D2 - low +TP_WAVELET_daub4;D4 - standard +TP_WAVELET_daub6;D6 - standard plus +TP_WAVELET_daub10;D10 - medium +TP_WAVELET_daub14;D14 - high +TP_WAVELET_DAUB_TOOLTIP;Change Daubechies coefficients\nD4=standard quality\nD14=best quality, more discriminant, increase slightly time treatment about 10%\nThese factors affect the detection of edges, but also general quality for firsts levels TP_WAVELET_EDGE;Edge Sharpness (Luminance) -TP_WAVELET_EDGTHRESH;Threshold +TP_WAVELET_EDGTHRESH;Detail TP_WAVELET_EDRAD;Radius -TP_WAVELET_EDVAL;Value +TP_WAVELET_EDRAD_TOOLTIP;Radius is very different from others sharpening tools\nIts value is compared to each level, through a complex function\nIn this sense, a zero radius value produce an effect +TP_WAVELET_EDVAL;Strength +TP_WAVELET_MEDGREINF;First level +TP_WAVELET_RE1;Reinforced +TP_WAVELET_RE2;Unchanged +TP_WAVELET_RE3;Reduced +TP_WAVELET_NOISE;Denoise and refine +TP_WAVELET_LEVZERO;Level 1 +TP_WAVELET_LEVONE;Level 2 +TP_WAVELET_LEVTWO;Level 3 +TP_WAVELET_STREN;Strength +TP_WAVELET_NOIS;Denoise +TP_WAVELET_LINKEDG;Link with Edge-sharpness (strength) +TP_WAVELET_MEDILEV;Edge detection +TP_WAVELET_LIPST;Enhanced algorithm +TP_WAVELET_LIPST_TOOLTIP;This algorithme use Lipschitz regularity\nIt increases the processing time and memory requirements, but it is better at detecting edges. +TP_WAVELET_EDGEDETECT;Gradient sensitivity +TP_WAVELET_EDGEDETECTTHR;Threshold Low (noise) +TP_WAVELET_EDGEDETECTTHR2;Threshold High (detection) +TP_WAVELET_EDGEDETECTTHR_TOOLTIP;You can adjust threshold to avoid apply edge sharpness to thin details (noise in sky...) +TP_WAVELET_EDGEDETECT_TOOLTIP;Algorithm detect edge\nMore the slider is moved to the right, more edge gradient with high level are take into account\nThis has an incidence on local contrast, on edge settings and also on noise +TP_WAVELET_EDGCONT;Local contrast +TP_WAVELET_EDGCONT_TOOLTIP;If you move sliders to the left contrast decrease...and to the right..increase +TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others\nThe more threshold is high, the more the action is centred on the first levels\nBe carefull to negatives values, they increase the action of high levels and can bring artifacts +TP_WAVELET_EDGREINF_TOOLTIP;For low radius value, increase/decrease the action of the first level, and decrease/increase the action of second level then the others TP_WAVELET_FINEST;Finest TP_WAVELET_HIGHLIGHT;Highlight luminance range TP_WAVELET_HIGHSHA;Highlight Shadows @@ -1660,13 +1712,25 @@ TP_WAVELET_MAX;max TP_WAVELET_MEDI;Reduce artifacts in blue sky TP_WAVELET_MIN;min TP_WAVELET_NEUTRAL;Neutral +TP_WAVELET_CHSL;Sliders +TP_WAVELET_CHCU;Curve +TP_WAVELET_EDSL;Threshold Sliders +TP_WAVELET_EDCU;Curve TP_WAVELET_ONE;One level TP_WAVELET_OPACITY;Opacity Blue-Yellow Levels TP_WAVELET_PASTEL;Pastel chromacity TP_WAVELET_PREVIEWLEVELS;Preview +TP_WAVELET_PREVIEWBACK;Background +TP_WAVELET_B0;Black +TP_WAVELET_B1;Grey +TP_WAVELET_B2;Residual TP_WAVELET_RESCHRO;Chromaticity TP_WAVELET_RESCONH;Highlights TP_WAVELET_RESCON;Shadows +TP_WAVELET_CURVEEDITOR_CH;Contrast levels /Hue +TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modify each level contrast in function oh hue\nCareful not to overwrite changes made with skin-tone hue (red)\nOnly active for contrast levels +TP_WAVELET_CURVEEDITOR_HH;HH +TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modify Hue in function of Hue, only for residual image TP_WAVELET_RESID;Residual image TP_WAVELET_SAT;Saturated chromacity TP_WAVELET_SETTINGS;Wavelet Settings diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 7037ff66e..551026a1d 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -13,7 +13,7 @@ // (at your option) any later version. // // This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of +// but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // @@ -379,8 +379,8 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //#endif if (dnparams.luma==0 && dnparams.chroma==0 && !dnparams.median && !noiseLCurve && !noiseCCurve) { //nothing to do; copy src to dst or do nothing in case src == dst - if(src != dst) - src->copyData(dst); + if(src != dst) + src->copyData(dst); if(calclum) { delete calclum; calclum = NULL; @@ -419,11 +419,11 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // init luma noisevarL const float noiseluma=(float) dnparams.luma; const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? (float) (SQR(((noiseluma+1.0)/125.0)*(10.+ (noiseluma+1.0)/25.0))) : (float) (SQR((noiseluma/125.0)*(1.0+ noiseluma/25.0))); - const bool denoiseLuminance = (noisevarL > 0.00001f); - + const bool denoiseLuminance = (noisevarL > 0.00001f); + //printf("NL=%f \n",noisevarL); if(useNoiseLCurve || useNoiseCCurve) { int hei=calclum->height; - int wid=calclum->width; + int wid=calclum->width; TMatrix wprofi = iccStore->workingSpaceMatrix (params->icm.working); const float wpi[3][3] = { @@ -479,7 +479,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef } delete calclum; calclum = NULL; - } + } const short int imheight=src->height, imwidth=src->width; @@ -550,7 +550,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef array2D tilemask_in(TS,TS); array2D tilemask_out(TS,TS); if(denoiseLuminance) { - const int border = MAX(2,TS/16); + const int border = MAX(2,TS/16); for (int i=0; iTS/2 ? i-TS+1 : i)); float vmask = (i1leveldnti ==1) { } int numTries = 0; if(ponder) - printf("Tiled denoise processing caused by Automatic Multizone mode\n"); + printf("Tiled denoise processing caused by Automatic Multizone mode\n"); bool memoryAllocationFailed = false; do { @@ -593,16 +593,16 @@ do { if(numtiles == 1) dsttmp = dst; else { - dsttmp = new Imagefloat(imwidth,imheight); -#ifdef _OPENMP -#pragma omp parallel for -#endif - for(int i=0;ir(i,j) = 0.f; - dsttmp->g(i,j) = 0.f; - dsttmp->b(i,j) = 0.f; - } + dsttmp = new Imagefloat(imwidth,imheight); +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i=0;ir(i,j) = 0.f; + dsttmp->g(i,j) = 0.f; + dsttmp->b(i,j) = 0.f; + } } //now we have tile dimensions, overlaps @@ -619,7 +619,7 @@ do { // these are needed only for creation of the plans and will be freed before entering the parallel loop fftwf_plan plan_forward_blox[2]; fftwf_plan plan_backward_blox[2]; - + if(denoiseLuminance) { float *Lbloxtmp = (float*) fftwf_malloc(max_numblox_W*TS*TS*sizeof (float)); float *fLbloxtmp = (float*) fftwf_malloc(max_numblox_W*TS*TS*sizeof (float)); @@ -636,7 +636,7 @@ do { plan_forward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, Lbloxtmp, NULL, 1, TS*TS, fLbloxtmp, NULL, 1, TS*TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); plan_backward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, fLbloxtmp, NULL, 1, TS*TS, Lbloxtmp, NULL, 1, TS*TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); fftwf_free ( Lbloxtmp ); - fftwf_free ( fLbloxtmp ); + fftwf_free ( fLbloxtmp ); } #ifndef _OPENMP @@ -712,7 +712,7 @@ do { int tilebottom = MIN(imheight,tiletop+tileheight); int width = tileright-tileleft; int height = tilebottom-tiletop; - int width2 = (width+1)/2; + int width2 = (width+1)/2; float realred, realblue; float interm_med =(float) dnparams.chroma/10.0; float intermred, intermblue; @@ -725,7 +725,7 @@ do { const float noisevarab_r = SQR(realred); const float noisevarab_b = SQR(realblue); - //input L channel + //input L channel array2D *Lin; //wavelet denoised image LabImage * labdn = new LabImage(width,height); @@ -886,18 +886,18 @@ do { //now perform basic wavelet denoise //arguments 4 and 5 of wavelet decomposition are max number of wavelet decomposition levels; //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 + //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. //actual implementation only works with subsampling set to 1 - float interm_medT = (float) dnparams.chroma/10.0; + float interm_medT = (float) dnparams.chroma/10.0; bool execwavelet = true; if(!denoiseLuminance && interm_medT < 0.05f && dnparams.median && (dnparams.methodmed=="Lab" || dnparams.methodmed=="Lonly")) execwavelet=false;//do not exec wavelet if sliders luminance and chroma are very small and median need - //we considered user don't want wavelet + //we considered user don't want wavelet if(settings->leveldnautsimpl==1 && dnparams.Cmethod!="MAN") execwavelet=true; if(settings->leveldnautsimpl==0 && dnparams.C2method!="MANU") - execwavelet=true; + execwavelet=true; if(execwavelet) {//gain time if user choose only median sliders L <=1 slider chrom master < 1 wavelet_decomposition* Ldecomp; wavelet_decomposition* adecomp; @@ -911,7 +911,7 @@ do { else levwav=8;//maximum ==> I have increase Maxlevel in cplx_wavelet_dec.h from 8 to 9 if(nrQuality == QUALITY_HIGH) levwav += settings->nrwavlevel;//increase level for enhanced mode - if(levwav>8) levwav=8; + if(levwav>8) levwav=8; int minsizetile=min(tilewidth, tileheight); int maxlev2=8; if(minsizetile < 256) maxlev2 = 7; @@ -925,7 +925,7 @@ do { memoryAllocationFailed = true; } float madL[8][3]; - if(!memoryAllocationFailed) { + if(!memoryAllocationFailed) { // precalculate madL, because it's used in adecomp and bdecomp int maxlvl = Ldecomp->maxlevel(); #ifdef _OPENMP @@ -978,7 +978,7 @@ do { adecomp->reconstruct(labdn->a[0]); } delete adecomp; - if(!memoryAllocationFailed) { + if(!memoryAllocationFailed) { wavelet_decomposition* bdecomp = new wavelet_decomposition (labdn->b[0], labdn->W, labdn->H, levwav, 1, 1, max(1,denoiseNestedLevels)); if(bdecomp->memoryAllocationFailed) { memoryAllocationFailed = true; @@ -1007,30 +1007,31 @@ do { bdecomp->reconstruct(labdn->b[0]); } delete bdecomp; - if(!memoryAllocationFailed) { - if(denoiseLuminance) { + if(!memoryAllocationFailed) { + if(denoiseLuminance) { + int edge=0; if(nrQuality==QUALITY_STANDARD) { - if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL))//enhance mode + if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, NULL, edge))//enhance mode memoryAllocationFailed = true; } else /*if(nrQuality==QUALITY_HIGH)*/ { if(!WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL))//enhance mode memoryAllocationFailed = true; if(!memoryAllocationFailed) - if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL)) + if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, NULL, edge)) memoryAllocationFailed = true; - } - if(!memoryAllocationFailed) { - // copy labdn->L to Lin before it gets modified by reconstruction - Lin = new array2D(width,height); + } + if(!memoryAllocationFailed) { + // copy labdn->L to Lin before it gets modified by reconstruction + Lin = new array2D(width,height); #ifdef _OPENMP #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) #endif - for(int i=0;iL[i][j]; - - Ldecomp->reconstruct(labdn->L[0]); - } + for(int i=0;iL[i][j]; + + Ldecomp->reconstruct(labdn->L[0]); + } } } } @@ -1122,7 +1123,7 @@ do { // Main detail recovery algorithm: Block loop //DCT block data storage - if(denoiseLuminance /*&& execwavelet*/) { + if(denoiseLuminance /*&& execwavelet*/) { //residual between input and denoised L channel array2D Ldetail(width,height,ARRAY2D_CLEAR_DATA); //pixel weight @@ -1236,7 +1237,7 @@ do { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% } - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #ifdef _OPENMP #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) @@ -1246,7 +1247,7 @@ do { //may want to include masking threshold for large hipass data to preserve edges/detail labdn->L[i][j] += Ldetail[i][j]/totwt[i][j]; //note that labdn initially stores the denoised hipass data } - } + } } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // transform denoised "Lab" to output RGB @@ -1278,10 +1279,10 @@ do { } //convert back to RGB and write to destination array if (isRAW) { - if(!denoiseMethodRgb) {//Lab mode + if(!denoiseMethodRgb) {//Lab mode realred /= 100.f; realblue /= 100.f; - + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) #endif @@ -1297,7 +1298,7 @@ do { float c_h=SQR(a)+SQR(b); if(c_h>9000000.f){ a *= 1.f + qhighFactor*realred; - b *= 1.f + qhighFactor*realblue; + b *= 1.f + qhighFactor*realblue; } //convert XYZ float X,Y,Z; @@ -1326,7 +1327,7 @@ do { dsttmp->b(i,j) += factor*b_; } } - } + } } else {//RGB mode #ifdef _OPENMP #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) @@ -1407,8 +1408,8 @@ do { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% } - delete labdn; - if(denoiseLuminance) + delete labdn; + if(denoiseLuminance) delete Lin; }//end of tile row @@ -1419,43 +1420,43 @@ do { } } - if(denoiseLuminance) { + if(denoiseLuminance) { for(int i=0;i1) { - if(!memoryAllocationFailed) - dsttmp->copyData(dst); + if(!memoryAllocationFailed) + dsttmp->copyData(dst); else if(dst != src) - src->copyData(dst); + src->copyData(dst); delete dsttmp; } - if (!isRAW && !memoryAllocationFailed) {//restore original image gamma -#ifdef _OPENMP -#pragma omp parallel for -#endif - for(int i=0;iheight;i++) - for(int j=0;jwidth;j++) { - dst->r(i,j) = Color::gammatab_srgb[ dst->r(i,j) ]; - dst->g(i,j) = Color::gammatab_srgb[ dst->g(i,j) ]; - dst->b(i,j) = Color::gammatab_srgb[ dst->b(i,j) ]; - } - } - + if (!isRAW && !memoryAllocationFailed) {//restore original image gamma +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i=0;iheight;i++) + for(int j=0;jwidth;j++) { + dst->r(i,j) = Color::gammatab_srgb[ dst->r(i,j) ]; + dst->g(i,j) = Color::gammatab_srgb[ dst->g(i,j) ]; + dst->b(i,j) = Color::gammatab_srgb[ dst->b(i,j) ]; + } + } + if(denoiseLuminance) { // destroy the plans fftwf_destroy_plan( plan_forward_blox[0] ); fftwf_destroy_plan( plan_backward_blox[0] ); fftwf_destroy_plan( plan_forward_blox[1] ); fftwf_destroy_plan( plan_backward_blox[1] ); - fftwf_cleanup(); + fftwf_cleanup(); } } while(memoryAllocationFailed && numTries < 2 && (options.rgbDenoiseThreadLimit == 0) && !ponder); if(memoryAllocationFailed) @@ -1765,7 +1766,7 @@ SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc, int histo[256] ALIGNED64 = {0}; //calculate histogram of absolute values of wavelet coeffs - for (int i=0; i maxWL) @@ -2081,7 +2085,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi if(WaveletCoeffs_L.level_H(lvl) > maxHL) maxHL = WaveletCoeffs_L.level_H(lvl); } - bool memoryAllocationFailed = false; + bool memoryAllocationFailed = false; #ifdef _OPENMP #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) #endif @@ -2100,7 +2104,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi #endif for (int lvl=0; lvl maxHL) maxHL = WaveletCoeffs_L.level_H(lvl); - } + } bool memoryAllocationFailed = false; #ifdef _OPENMP #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) @@ -2160,7 +2164,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, - float *noisevarlum, float * madL ) + float *noisevarlum, float * madL, float * vari, int edge ) { //simple wavelet shrinkage @@ -2176,7 +2180,12 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(level); float mad_L = madL[dir-1] ; - + if(edge==1) { + noisevarlum = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer + for (int i=0; i. * * 2012 Emil Martinec + * 2014 Jacques Desmis */ @@ -22,12 +23,26 @@ namespace rtengine { const int Daub4_offset=2; -const float Daub4_anal[2][6] ALIGNED16 = {//analysis filter +const float Daub4_anal0[2][4] ALIGNED16 = {//analysis filter 2 Hall + {0.f, 0.f, 0.5f, 0.5f}, + {-0.5f, 0.5f, 0.f, 0.f}}; + +const float Daub4_anal[2][6] ALIGNED16 = {//Daub4 {0.f, 0.f, 0.34150635f, 0.59150635f, 0.15849365f, -0.091506351f}, {-0.091506351f, -0.15849365f, 0.59150635f, -0.34150635f, 0.f, 0.f}}; -const float Daub4_anal8[2][8] ALIGNED16 = {//analysis filter - {0.f,0.f, 0.235233605f, 0.57055846f, 0.3251825f, -0.09546721f, -0.060416105f, 0.02490875f}, +const float Daub4_anal8[2][8] ALIGNED16 = {//Daub6 + {0.f, 0.f, 0.235233605f, 0.57055846f, 0.3251825f, -0.09546721f, -0.060416105f, 0.02490875f}, {-0.02490875f, -0.060416105f, 0.09546721f, 0.3251825f, -0.57055846f , 0.235233605f, 0.f, 0.f}}; + +const float Daub4_anal12[2][12] ALIGNED16 = {//Daub10 + {0.f, 0.f, 0.11320949f, 0.42697177f, 0.51216347f, 0.09788348f, -0.171328355f, -0.022800565f, 0.054851325f, -0.0044134f, -0.008895935f, 0.002358714f}, + {-0.002358714f, -0.008895935f, 0.0044134f, 0.054851325f, 0.022800565f , -0.171328355f, -0.09788348f, 0.51216347f, -0.42697177f, 0.11320949f, 0.f, 0.f}}; + +const float Daub4_anal16[2][16] ALIGNED16 = {//Daub 14 + {0.f, 0.f, 0.055049715f, 0.28039564f, 0.515574245f, 0.33218624f, -0.10175691f, -0.158417505f, 0.05042335f, 0.057001725f, -0.026891225f, -0.01171997f, 0.008874895f, 0.0003037575f, -0.0012739524f, 0.0002501134f}, + {-0.0002501134f, -0.0012739524f, -0.0003037575f, 0.008874895f, 0.01171997f , -0.026891225f, -0.057001725f, 0.05042335f, 0.158417505f, -0.10175691f, -0.33218624f, 0.515574245f, -0.28039564f, 0.055049715f, 0.f, 0.f}}; + +// if necessary ?? we can add D20 !! }; diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 2d518c29b..27fd67738 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -1166,6 +1166,7 @@ void OpacityCurve::Set(const std::vector &curvePoints, bool &opautili) { } } + WavCurve::WavCurve() : sum(0.f) {}; void WavCurve::Reset() { @@ -1198,6 +1199,8 @@ void WavCurve::Set(const std::vector &curvePoints) { Reset(); } } + + WavOpacityCurveRG::WavOpacityCurveRG(){}; void WavOpacityCurveRG::Reset() { diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 9da2e2876..94c1cea7a 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -288,20 +288,23 @@ class ImProcFunctions { void Tile_calc (int tilesize, int overlap, int kall, int imwidth, int imheight, int &numtiles_W, int &numtiles_H, int &tilewidth, int &tileheight, int &tileWskip, int &tileHskip); void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, int skip); void WaveletcontAllL(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_L, - struct cont_params cp, int skip); + struct cont_params cp, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, FlatCurve* ChCurve, bool Chutili); void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_a, struct cont_params cp, const bool useChannelA); - void ContAllL (LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params cp, - int W_L, int H_L, int skip); + void WaveletAandBAllAB(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, + struct cont_params cp, FlatCurve* hhcurve, bool hhutili); + void ContAllL (float **koeLi, float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params cp, + int W_L, int H_L, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, FlatCurve* ChCurve, bool Chutili); void ContAllAB (LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_a, float * WavCoeffs_a0, int level, int dir, struct cont_params cp, int W_ab, int H_ab, const bool useChannelA); - void Evaluate(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_a, - wavelet_decomposition &WaveletCoeffs_b, float *av_LL, float *av_aa, float *av_bb,struct cont_params cp, int ind, float *mean, float *meanN, float *sigma, float *sigmaN); - void Eval (float ** WavCoeffs_L, float ** WavCoeffs_a, float ** WavCoeffs_b, int level,struct cont_params cp, - int W_L, int H_L, int W_ab, int H_ab,int skip_L, int skip_ab, float * av_LL, float * av_aa, float * av_bb, int ind, float *mean, float *meanN, float *sigma, float *sigmaN); + void Evaluate2(wavelet_decomposition &WaveletCoeffs_L, + struct cont_params cp, int ind, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, float madL[8][3]); + void Eval2 (float ** WavCoeffs_L, int level,struct cont_params cp, + int W_L, int H_L, int skip_L, int ind, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, float *madL); void Aver(float * HH_Coeffs, int datalen, float &averagePlus, float &averageNeg, float &max, float &min); void Sigma(float * HH_Coeffs, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg); + void calckoe(float ** WavCoeffs_LL, struct cont_params cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = NULL); @@ -312,7 +315,7 @@ class ImProcFunctions { void RGB_denoise_info(Imagefloat * src, Imagefloat * calclum, bool isRAW, LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &minredaut, float & minblueaut,float &nresi, float &highresi, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel,float &skinc, float &nsknc, bool multiThread = false); void RGBtile_denoise (float * fLblox, int hblproc, float noisevar_L, float * nbrwt, float * blurbuffer ); //for DCT void RGBoutput_tile_row (float *Lbloxrow, float ** Ldetail, float ** tilemask_out, int height, int width, int top ); - bool WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]); + bool WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge); bool WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); void WaveletDenoiseAll_info(int levwav, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, int width, int height, float noisevar_abr, float noisevar_abb, LabImage * noi, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut,float &minredaut, float & minblueaut, int schoice, bool autoch, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel,float &skinc, float &nsknc, @@ -321,7 +324,7 @@ class ImProcFunctions { bool WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]); bool WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); - void ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madaL); + void ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madaL, float * vari, int edge); void ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab = NULL, bool madCalculated = false); void ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, int level, diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 0687c98a7..9edaae481 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -62,6 +62,14 @@ PIX_SORT(pp[3],pp[6]); PIX_SORT(pp[1],pp[4]); PIX_SORT(pp[2],pp[5]); \ PIX_SORT(pp[4],pp[7]); PIX_SORT(pp[4],pp[2]); PIX_SORT(pp[6],pp[4]); \ PIX_SORT(pp[4],pp[2]); median=pp[4];} //pp4 = median + +#define med2(a0,a1,a2,a3,a4,median) { \ +pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; \ +PIX_SORT(pp[0],pp[1]) ; PIX_SORT(pp[3],pp[4]) ; PIX_SORT(pp[0],pp[3]) ;\ +PIX_SORT(pp[1],pp[4]) ; PIX_SORT(pp[1],pp[2]) ; PIX_SORT(pp[2],pp[3]) ;\ +PIX_SORT(pp[1],pp[2]) ; median=pp[2] ;} + + #define epsilon 0.001f/(TS*TS) //tolerance @@ -79,12 +87,14 @@ struct cont_params { float conres; float conresH; float chrores; + float hueres; float sky; float b_l,t_l,b_r,t_r; float b_ly,t_ly,b_ry,t_ry; float b_lsl,t_lsl,b_rsl,t_rsl; float b_lhl,t_lhl,b_rhl,t_rhl; - + float edg_low, edg_mean, edg_sd, edg_max; + float lev0s, lev0n, lev1s, lev1n, lev2s, lev2n; float b_lpast,t_lpast,b_rpast,t_rpast; float b_lsat,t_lsat,b_rsat,t_rsat; int rad; @@ -97,10 +107,23 @@ struct cont_params { bool curv; bool opaBY; bool opaRG; + bool edgcurv; int CHmet; + int CHSLmet; + int EDmet; bool HSmet; bool avoi; float strength; + int reinforce; + bool detectedge; + int backm; + float eddet; + float eddetthr; + bool lips; + float eddetthrHi; + bool link; + bool lip3; + }; int wavNestedLevels = 1; @@ -123,7 +146,17 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int const short int imheight=lab->H, imwidth=lab->W; struct cont_params cp; cp.avoi = params->wavelet.avoid; - + if(params->wavelet.Medgreinf=="more") cp.reinforce = 1; + if(params->wavelet.Medgreinf=="none") cp.reinforce = 2; + if(params->wavelet.Medgreinf=="less") cp.reinforce = 3; + cp.lip3 = params->wavelet.lipst; + if(params->wavelet.Backmethod=="black") cp.backm= 0; + if(params->wavelet.Backmethod=="grey") cp.backm = 1; + if(params->wavelet.Backmethod=="resid") cp.backm = 2; + cp.link=params->wavelet.linkedg; + cp.eddet=(float) params->wavelet.edgedetect; + cp.eddetthr=(float) params->wavelet.edgedetectthr; + cp.eddetthrHi=(float) params->wavelet.edgedetectthr2; int N=imheight*imwidth; int maxmul=params->wavelet.thres; static const float scales[10] = {1.f,2.f,4.f,8.f,16.f,32.f,64.f,128.f,256.f,512.f}; @@ -133,8 +166,23 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int float atten0 = 0.40f; float atten123=0.90f; - int DaubLen = settings->daubech ? 8 : 6; + //int DaubLen = settings->daubech ? 8 : 6; + int DaubLen; + if(params->wavelet.choicemethod=="2_") DaubLen=4; + if(params->wavelet.choicemethod=="4_") DaubLen=6; + if(params->wavelet.choicemethod=="6_") DaubLen=8; + if(params->wavelet.choicemethod=="10_") DaubLen=12; + if(params->wavelet.choicemethod=="14_") DaubLen=16; + + cp.CHSLmet=1; +// if(params->wavelet.CHSLmethod=="SL") cp.CHSLmet=1; +// if(params->wavelet.CHSLmethod=="CU") cp.CHSLmet=2; + cp.EDmet=1; + if(params->wavelet.EDmethod=="SL") cp.EDmet=1; + if(params->wavelet.EDmethod=="CU") cp.EDmet=2; + cp.curv=false; + cp.edgcurv=false; cp.opaRG=false; cp.opaBY=false; cp.CHmet=0; @@ -143,26 +191,31 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int if(params->wavelet.CHmethod=="link") cp.CHmet=2; if(params->wavelet.HSmethod=="with") cp.HSmet=true; - //printf("params->wavelet.strength : %d\n",params->wavelet.strength); cp.strength = min(1.f,max(0.f,((float)params->wavelet.strength / 100.f))); - //printf("cp.strength : %f\n",cp.strength); - if(wavCLVCcurve) cp.curv=true; - - if(cp.curv) {//convert curve in discret values - cp.mulC[0]=200.f*(wavCLVCcurve[0]-0.5f); - cp.mulC[1]=200.f*(wavCLVCcurve[62]-0.5f); - cp.mulC[2]=200.f*(wavCLVCcurve[125]-0.5f); - cp.mulC[3]=200.f*(wavCLVCcurve[187]-0.5f); - cp.mulC[4]=200.f*(wavCLVCcurve[250]-0.5f); - cp.mulC[5]=200.f*(wavCLVCcurve[312]-0.5f); - cp.mulC[6]=200.f*(wavCLVCcurve[375]-0.5f); - cp.mulC[7]=200.f*(wavCLVCcurve[438]-0.5f); - cp.mulC[8]=200.f*(wavCLVCcurve[500]-0.5f); - } - else { - for(int level=0;level<9;level++) - cp.mulC[level] = 0.f; - } + +// if(wavCLVCcurve) cp.curv=true; + /* if(cp.CHSLmet==2) {//curve + if(cp.curv) {//convert curve in discret values + cp.mulC[0]=200.f*(wavCLVCcurve[0]-0.5f); + cp.mulC[1]=200.f*(wavCLVCcurve[62]-0.5f); + cp.mulC[2]=200.f*(wavCLVCcurve[125]-0.5f); + cp.mulC[3]=200.f*(wavCLVCcurve[187]-0.5f); + cp.mulC[4]=200.f*(wavCLVCcurve[250]-0.5f); + cp.mulC[5]=200.f*(wavCLVCcurve[312]-0.5f); + cp.mulC[6]=200.f*(wavCLVCcurve[375]-0.5f); + cp.mulC[7]=200.f*(wavCLVCcurve[438]-0.5f); + cp.mulC[8]=200.f*(wavCLVCcurve[500]-0.5f); + } + else { + for(int level=0;level<9;level++) + cp.mulC[level] = 0.f; + } + } + */ +// else if(cp.CHSLmet==1) {//slider + for(int m=0;m(params->wavelet.hueskin2.value[3]) / 100.0f; cp.numlevH=params->wavelet.threshold; - cp.numlevH=params->wavelet.threshold; //shadows cp.b_lsl = static_cast(params->wavelet.bllev.value[0]); cp.t_lsl = static_cast(params->wavelet.bllev.value[1]); @@ -247,12 +301,13 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int cp.numlevS=params->wavelet.threshold2; int maxlevS=9-cp.numlevH; cp.numlevS = MIN(cp.numlevS,maxlevS); + //printf("levHigh=%d levShad=%d\n",cp.numlevH,cp.numlevS); //highlight cp.b_lhl = static_cast(params->wavelet.hllev.value[0]); cp.t_lhl = static_cast(params->wavelet.hllev.value[1]); cp.b_rhl = static_cast(params->wavelet.hllev.value[2]); cp.t_rhl = static_cast(params->wavelet.hllev.value[3]); - //printf("H=%d S=%d\n",cp.numlevH,cp.numlevS); + //printf("BL=%f TL=%f BR=%f TR=%f\n",cp.b_lhl,cp.t_lhl,cp.b_rhl,cp.t_rhl); //pastel cp.b_lpast = static_cast(params->wavelet.pastlev.value[0]); cp.t_lpast = static_cast(params->wavelet.pastlev.value[1]); @@ -263,8 +318,22 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int cp.t_lsat = static_cast(params->wavelet.satlev.value[1]); cp.b_rsat = static_cast(params->wavelet.satlev.value[2]); cp.t_rsat = static_cast(params->wavelet.satlev.value[3]); - - + //edge local contrast + cp.edg_low = static_cast(params->wavelet.edgcont.value[0]); + cp.edg_mean = static_cast(params->wavelet.edgcont.value[1]); + cp.edg_max = static_cast(params->wavelet.edgcont.value[2]); + cp.edg_sd = static_cast(params->wavelet.edgcont.value[3]); + //level noise + cp.lev0s =static_cast(params->wavelet.level0noise.value[0]); + cp.lev0n =static_cast(params->wavelet.level0noise.value[1]); + cp.lev1s =static_cast(params->wavelet.level1noise.value[0]); + cp.lev1n =static_cast(params->wavelet.level1noise.value[1]); + cp.lev2s =static_cast(params->wavelet.level2noise.value[0]); + cp.lev2n =static_cast(params->wavelet.level2noise.value[1]); + + cp.detectedge = false; + cp.detectedge = params->wavelet.medianlev; + //printf("low=%f mean=%f sd=%f max=%f\n",cp.edg_low,cp.edg_mean,cp.edg_sd,cp.edg_max); int minwin=min(imwidth,imheight); int maxlevelcrop=9; if(cp.mul[9]!=0) @@ -376,7 +445,9 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int float *meanN = new float [9]; float *sigma = new float [9]; float *sigmaN = new float [9]; - + float *MaxP = new float [9]; + float *MaxN = new float [9]; + float** varhue = new float*[tileheight]; for (int i=0; iW * labco->H; int levwavL = levwav; - //printf("LevwavL before: %d\n",levwavL); - if(cp.contrast == 0 && cp.conres == 0.f && cp.conresH == 0.f && cp.val ==0 && params->wavelet.CLmethod=="all") { // no processing of residual L or edge=> we probably can reduce the number of levels + bool ref0=false; + if(cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f) ref0=true; + + printf("LevwavL before: %d\n",levwavL); + if(cp.contrast == 0.f && cp.conres == 0.f && cp.conresH == 0.f && cp.val ==0 && !ref0 && params->wavelet.CLmethod=="all") { // no processing of residual L or edge=> we probably can reduce the number of levels while(levwavL > 0 && cp.mul[levwavL-1] == 0.f) // cp.mul[level] == 0.f means no changes to level levwavL--; } - //printf("LevwavL after: %d\n",levwavL); + printf("LevwavL after: %d\n",levwavL); + if(levwavL < 3) levwavL=3;//to allow edge => I always allocate 3 levels..because if user select wavelet it is to do something !! if(levwavL > 0) { wavelet_decomposition* Ldecomp = new wavelet_decomposition (labco->data, labco->W, labco->H, levwavL, 1, skip, max(1,wavNestedLevels), DaubLen ); if(!Ldecomp->memoryAllocationFailed) { - WaveletcontAllL(labco, varhue, varchro, *Ldecomp, cp, skip); + + float madL[8][3]; + bool memoryAllocationFailed = false; +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic) collapse(2) num_threads(wavNestedLevels) if(wavNestedLevels>1) +#endif + for (int lvl=0; lvl<3; lvl++) { + for (int dir=1; dir<4; dir++) { + int Wlvl_L = Ldecomp->level_W(lvl); + int Hlvl_L = Ldecomp->level_H(lvl); + + float ** WavCoeffs_L = Ldecomp->level_coeffs(lvl); + + madL[lvl][dir-1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L*Hlvl_L)); + } + } + int ind=0; + bool ref=false; + if(cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f) ref=true; + + if(cp.val > 0 || ref) {//edge + Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL); + } + //init for edge and denoise + float vari[3]; + + vari[0]=8.f*SQR((cp.lev0n/125.0)*(1.0+ cp.lev0n/25.0)); + vari[1]=8.f*SQR((cp.lev1n/125.0)*(1.0+ cp.lev1n/25.0)); + vari[2]=8.f*SQR((cp.lev2n/125.0)*(1.0+ cp.lev2n/25.0)); + int edge=1; + if(cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f) { + vari[0] = max(0.0001f,vari[0]); + vari[1] = max(0.0001f,vari[1]); + vari[2] = max(0.0001f,vari[2]); + float* noisevarlum = NULL; // we need a dummy to pass it to WaveletDenoiseAllL + if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge))// + memoryAllocationFailed = true; + } + ind=1; + //Flat curve for Contrast=f(H) in levels + FlatCurve* ChCurve = NULL;//curve C=f(H) + bool Chutili = false; + ChCurve = new FlatCurve(params->wavelet.Chcurve); + if (!ChCurve || ChCurve->isIdentity()) { + if (ChCurve) { + delete ChCurve; + ChCurve = NULL; + } + } else + Chutili = true; + + + WaveletcontAllL(labco, varhue, varchro, *Ldecomp, cp, skip, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavCLVCcurve, ChCurve, Chutili); + if(cp.val > 0 || ref) {//edge + Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL); + } + Ldecomp->reconstruct(labco->data, cp.strength); } delete Ldecomp; } - int levwava = levwav; - //printf("Levwava before: %d\n",levwava); - if(cp.chrores == 0.f && params->wavelet.CLmethod=="all") { // no processing of residual ab => we probably can reduce the number of levels - while(levwava > 0 && (((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwava-1] == 0.f )) || (cp.CHmet!=2 && (levwava == 10 || (!cp.curv || (cp.curv && cp.mulC[levwava-1] == 0.f)))))) && (!cp.opaRG || levwava == 10 || (cp.opaRG && cp.mulopaRG[levwava-1] == 0.f))) { - levwava--; + //Flat curve for H=f(H) in residual image + FlatCurve* hhCurve = NULL;//curve H=f(H) + bool hhutili = false; + hhCurve = new FlatCurve(params->wavelet.hhcurve); + if (!hhCurve || hhCurve->isIdentity()) { + if (hhCurve) { + delete hhCurve; + hhCurve = NULL; } - } - //printf("Levwava after: %d\n",levwava); - if(levwava > 0) { - wavelet_decomposition* adecomp = new wavelet_decomposition (labco->data+datalen, labco->W, labco->H,levwava, 1, skip, max(1,wavNestedLevels), DaubLen ); - if(!adecomp->memoryAllocationFailed) { - WaveletcontAllAB(labco, varhue, varchro, *adecomp, cp, true); - adecomp->reconstruct(labco->data+datalen, cp.strength); + } else + hhutili = true; + + + if(!hhutili) {//always a or b + int levwava = levwav; + // printf("Levwava before: %d\n",levwava); + if(cp.chrores == 0.f && params->wavelet.CLmethod=="all") { // no processing of residual ab => we probably can reduce the number of levels + while(levwava > 0 && (((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwava-1] == 0.f )) || (cp.CHmet!=2 && (levwava == 10 || (!cp.curv || (cp.curv && cp.mulC[levwava-1] == 0.f)))))) && (!cp.opaRG || levwava == 10 || (cp.opaRG && cp.mulopaRG[levwava-1] == 0.f)) && ((levwava == 10 ||(cp.CHSLmet==1 && cp.mulC[levwava-1] == 0.f)))) { + levwava--; + } } - delete adecomp; - } - int levwavb = levwav; - //printf("Levwavb before: %d\n",levwavb); - if(cp.chrores == 0.f && params->wavelet.CLmethod=="all") { // no processing of residual ab => we probably can reduce the number of levels - while(levwavb > 0 && (((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwavb-1] == 0.f )) || (cp.CHmet!=2 && (levwavb == 10 || (!cp.curv || (cp.curv && cp.mulC[levwavb-1] == 0.f)))))) && (!cp.opaBY || levwavb == 10 || (cp.opaBY && cp.mulopaBY[levwavb-1] == 0.f))) { - levwavb--; + //printf("Levwava after: %d\n",levwava); + if(levwava > 0) { + wavelet_decomposition* adecomp = new wavelet_decomposition (labco->data+datalen, labco->W, labco->H,levwava, 1, skip, max(1,wavNestedLevels), DaubLen ); + if(!adecomp->memoryAllocationFailed) { + WaveletcontAllAB(labco, varhue, varchro, *adecomp, cp, true); + adecomp->reconstruct(labco->data+datalen, cp.strength); + } + delete adecomp; } - } - //printf("Levwavb after: %d\n",levwavb); - if(levwavb > 0) { - wavelet_decomposition* bdecomp = new wavelet_decomposition (labco->data+2*datalen, labco->W, labco->H, levwavb, 1, skip, max(1,wavNestedLevels), DaubLen ); - if(!bdecomp->memoryAllocationFailed) { - WaveletcontAllAB(labco, varhue, varchro, *bdecomp, cp, false); - bdecomp->reconstruct(labco->data+2*datalen, cp.strength); + int levwavb = levwav; + //printf("Levwavb before: %d\n",levwavb); + if(cp.chrores == 0.f && params->wavelet.CLmethod=="all") { // no processing of residual ab => we probably can reduce the number of levels + while(levwavb > 0 && (((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwavb-1] == 0.f )) || (cp.CHmet!=2 && (levwavb == 10 || (!cp.curv || (cp.curv && cp.mulC[levwavb-1] == 0.f)))))) && (!cp.opaBY || levwavb == 10 || (cp.opaBY && cp.mulopaBY[levwavb-1] == 0.f)) && ((levwavb == 10 ||(cp.CHSLmet==1 && cp.mulC[levwavb-1] == 0.f)))) { + levwavb--; + } } - delete bdecomp; - } + // printf("Levwavb after: %d\n",levwavb); + if(levwavb > 0) { + wavelet_decomposition* bdecomp = new wavelet_decomposition (labco->data+2*datalen, labco->W, labco->H, levwavb, 1, skip, max(1,wavNestedLevels), DaubLen ); + if(!bdecomp->memoryAllocationFailed) { + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, cp, false); + bdecomp->reconstruct(labco->data+2*datalen, cp.strength); + } + delete bdecomp; + } + } else {// a and b + int levwavab = levwav; + printf("Levwavab before: %d\n",levwavab); + if(cp.chrores == 0.f && !hhutili && params->wavelet.CLmethod=="all") { // no processing of residual ab => we probably can reduce the number of levels + while(levwavab > 0 && (((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwavab-1] == 0.f )) || (cp.CHmet!=2 && (levwavab == 10 || (!cp.curv || (cp.curv && cp.mulC[levwavab-1] == 0.f)))))) && (!cp.opaRG || levwavab == 10 || (cp.opaRG && cp.mulopaRG[levwavab-1] == 0.f)) && ((levwavab == 10 ||(cp.CHSLmet==1 && cp.mulC[levwavab-1] == 0.f)))) { + levwavab--; + } + } + printf("Levwavab after: %d\n",levwavab); + if(levwavab > 0) { + wavelet_decomposition* adecomp = new wavelet_decomposition (labco->data+datalen, labco->W, labco->H,levwavab, 1, skip, max(1,wavNestedLevels), DaubLen ); + wavelet_decomposition* bdecomp = new wavelet_decomposition (labco->data+2*datalen, labco->W, labco->H, levwavab, 1, skip, max(1,wavNestedLevels), DaubLen ); + if(!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { + WaveletcontAllAB(labco, varhue, varchro, *adecomp, cp, true); + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, cp, false); + WaveletAandBAllAB(labco, varhue, varchro, *adecomp, *bdecomp, cp, hhCurve, hhutili ); + + adecomp->reconstruct(labco->data+datalen, cp.strength); + bdecomp->reconstruct(labco->data+2*datalen, cp.strength); + + } + delete adecomp; + delete bdecomp; + } + } + if (hhCurve) + delete hhCurve; if(numtiles > 1 || (numtiles == 1 && cp.avoi)) { //calculate mask for feathering output tile overlaps @@ -733,10 +905,10 @@ omp_set_nested(oldNested); delete dsttmp; } - if (settings->verbose) { +// if (settings->verbose) { t2e.set(); printf("Wavelet performed in %d usec:\n", t2e.etime(t1e)); - } +// } }//end o @@ -749,22 +921,44 @@ omp_set_nested(oldNested); #undef epsilon void ImProcFunctions::Aver( float * RESTRICT DataList, int datalen, float &averagePlus, float &averageNeg, float &max, float &min) { + //find absolute mean - int averaP=0, averaN=0, count=0, countP=0, countN=0; - max=0.f;min=0.f; - averagePlus=0.f;averageNeg=0.f; - while (count= 0.f) {averaP += abs((int)DataList[count]); - if(abs((int)DataList[count])> max) max=abs((int)DataList[count]); - countP++; + int countP = 0, countN = 0; + float averaP = 0.f, averaN = 0.f; + + float thres = 5.f;//different fom zero to take into account only data large enough + +#ifdef _OPENMP +#pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) +#endif +{ + float lmax = 0.f, lmin = 0.f; +#ifdef _OPENMP +#pragma omp for reduction(+:averaP,averaN,countP,countN) nowait +#endif + for(int i=0;i= thres) { + averaP += DataList[i]; + if(DataList[i]> lmax) + lmax = DataList[i]; + countP++; } - if(DataList[count] < 0.f) {averaN += abs((int)DataList[count]); - if(abs((int)DataList[count])> min) min=abs((int)DataList[count]); - countN++; + else if(DataList[i] < -thres) { + averaN += DataList[i]; + if(DataList[i] < lmin) + lmin = DataList[i]; + countN++; } - - count++; - } + } +#ifdef _OPENMP +#pragma omp critical +#endif +{ + max = max > lmax ? max : lmax; + min = min < lmin ? min : lmin; +} +} + averagePlus=averaP/countP; averageNeg=averaN/countN; @@ -772,96 +966,94 @@ omp_set_nested(oldNested); void ImProcFunctions::Sigma( float * RESTRICT DataList, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg) { - int count=0, countP=0, countN=0; - float variP=0.f,variN=0.f; - while (count= 0.f) {variP += SQR(DataList[count] - averagePlus); - countP++; + int countP = 0, countN = 0; + float variP = 0.f, variN = 0.f; + float thres = 5.f;//different fom zero to take into account only data large enough + +#ifdef _OPENMP +#pragma omp parallel for reduction(+:variP,variN,countP,countN) num_threads(wavNestedLevels) if(wavNestedLevels>1) +#endif + for(int i=0;i= thres) { + variP += SQR(DataList[i] - averagePlus); + countP++; } - else if(DataList[count] < 0.f) {variN += SQR(DataList[count] - averageNeg); - countN++; + else if(DataList[i] <= -thres) { + variN += SQR(DataList[i] - averageNeg); + countN++; } - count++; } + sigmaPlus=sqrt(variP/countP); sigmaNeg=sqrt(variN/countN); } - void ImProcFunctions::Evaluate(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_a, - wavelet_decomposition &WaveletCoeffs_b, float *av_LL, float *av_aa, float *av_bb,struct cont_params cp, int ind, float *mean, float *meanN, float *sigma, float *sigmaN){ + void ImProcFunctions::Evaluate2(wavelet_decomposition &WaveletCoeffs_L, + struct cont_params cp, int ind, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, float madL[8][3]){ +StopWatch Stop1("Evaluate2"); int maxlvl = WaveletCoeffs_L.maxlevel(); for (int lvl=0; lvlwavelet.thres; for (int dir=1; dir<4; dir++) { - { - float averagePlus=0.f,averageNeg=0.f, max, min; - // Aver(WavCoeffs_L[dir], W_L*H_L, averagePlus, averageNeg, max, min); - Aver(WavCoeffs_b[dir], W_L*H_L, averagePlus, averageNeg, max, min); - avLP[dir] = fabs(averagePlus); - avLN[dir] = -fabs(averageNeg); - maxL[dir] = max; - minL[dir] = -min; - float sigmaPlus, sigmaNeg; - Sigma(WavCoeffs_b[dir], W_L*H_L, avLP[dir], -avLN[dir], sigmaPlus, sigmaNeg); - sigP[dir]=sigmaPlus; - sigN[dir]=sigmaNeg; - // printf("dir=%d level=%d avLP=%f max=%f avLN=%f min=%f sigP=%f sigN=%f\n",dir,level,avLP[dir] ,maxL[dir], avLN[dir] ,minL[dir], sigP[dir], sigN[dir]); - } - + Aver(WavCoeffs_L[dir], W_L*H_L, avLP[dir], avLN[dir], maxL[dir], minL[dir]); + Sigma(WavCoeffs_L[dir], W_L*H_L, avLP[dir], avLN[dir], sigP[dir], sigN[dir]); + // printf("dir=%d level=%d avLP=%f max=%f avLN=%f min=%f sigP=%f sigN=%f\n",dir,level,avLP[dir] ,maxL[dir], avLN[dir] ,minL[dir], sigP[dir], sigN[dir]); } - AvL=0.f;AvN=0.f;SL=0.f;SN=0.f; + AvL=0.f;AvN=0.f;SL=0.f;SN=0.f;maxLP=0.f;maxLN=0.f;MADL=0.f; for (int dir=1; dir<4; dir++) { AvL +=avLP[dir]; AvN +=avLN[dir]; SL +=sigP[dir]; SN +=sigN[dir]; + maxLP += maxL[dir]; + maxLN += minL[dir]; + MADL += madL[dir]; } AvL/=3; AvN/=3; SL/=3; SN/=3; + maxLP/=3; + maxLN/=3; + MADL/=3; + if(level < 3) MADL=sqrt(MADL);else MADL=0.f; mean[level]=AvL; meanN[level]=AvN; sigma[level]=SL; sigmaN[level]=SN; - - //printf("Ind=%d Level=%d AvL=%f AvN=%f SL=%f SN=%f\n",ind, level,mean[level],meanN[level],sigma[level],sigmaN[level]); - + MaxP[level]=maxLP; + MaxN[level]=maxLN; + if(params->wavelet.CLmethod!="all") {//display only if user choose different from all + printf("Ind=%d Level=%d MadL=%f AvL=%f AvN=%f SL=%f SN=%f maxP=%f maxN=%f\n",ind, level,MADL,mean[level],meanN[level],sigma[level],sigmaN[level],MaxP[level],MaxN[level]); + } } void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_L, - struct cont_params cp, int skip){ - + struct cont_params cp, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, FlatCurve* ChCurve, bool Chutili){ + StopWatch Stop1("WaveletcontAllL"); int maxlvl = WaveletCoeffs_L.maxlevel(); int W_L = WaveletCoeffs_L.level_W(0); int H_L = WaveletCoeffs_L.level_H(0); @@ -872,7 +1064,6 @@ omp_set_nested(oldNested); float contrast=cp.contrast; float multL=(float)contrast*(maxl-1.f)/100.f + 1.f; float multH=(float) contrast*(maxh-1.f)/100.f + 1.f; - double avedbl=0.f; // use double precision for big summations if(contrast != 0.f) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step #ifdef _OPENMP @@ -890,7 +1081,24 @@ omp_set_nested(oldNested); float bl=1.f; float factorx=1.f; - + float *koeLi[9]; + float maxkoeLi[9]; + float *koeLibuffer = NULL; + bool lipschitz =false; + //if(cp.lips)lipschitz=true;//I suppress "logical" normal algorithm, low quality, same time + lipschitz=true; + + if(lipschitz==true) { + for(int y=0;y<9;y++) maxkoeLi[y]=0.f; + koeLibuffer = new float[9*H_L*W_L]; + for (int i=0; i<9; i++) { + koeLi[i] = &koeLibuffer[i*W_L*H_L]; + } + + for(int j=0;j<9;j++) + for (int i=0; i1) #endif @@ -922,9 +1130,10 @@ omp_set_nested(oldNested); #pragma omp for nowait #endif for (int i=0; iL[ii*2][jj*2]; + //int ii = i/W_L; + //int jj = i-ii*W_L; + //float LL = labco->L[ii*2][jj*2]; + float LL=WavCoeffs_L0[i]; float LL100 = LL/327.68f; float tran = 5.f;//transition //shadow @@ -954,6 +1163,105 @@ omp_set_nested(oldNested); } } } + //enabled Lipschitz..replace simple by complex edge detection + // I found this concept on the web (doctoral thesis on medical Imaging) + // I was inspired by the principle of Canny and Lipschitz (continuity and derivability) + // I adapted the principle but have profoundly changed the algorithm + // One can 1) change all parameters and found good parameters; + //one can also chnage in calckoe + float edd=settings->ed_detec; + float eddlow=settings->ed_low; + float eddlipinfl=settings->ed_lipinfl; + float eddlipampl=settings->ed_lipampl; + + + +if(cp.detectedge && lipschitz==true) { //enabled Lipschitz control...more memory..more time... + float *tmCBuffer = new float[H_L*W_L]; + float *tmC[H_L]; + for (int i=0; i 1 for alp >eddlipinfl and alph < 1 + //Liamp < 1 for alp < eddlipinfl and alph > 0 + if(alph > 1.f) {alph = 1.f/ alph;} + if(beta > 1.f) {beta=1.f/beta;} + //take into account diagonal + //if in same value OK + //if not no edge or reduction + float bet=1.f; + //if(cp.lip3) {//enhance algorithm + if(alph > eddlipinfl && beta < 0.85f*eddlipinfl) {//0.85 arbitrary value ==> eliminate from edge if H V D too different + bet=beta; + } + //} + float AmpLip=1.f; + + if(alph > eddlipinfl) {AmpLip=alipinfl*alph+blipinfl;kampli=SQR(bet)*AmpLip*aamp;}//If beta low reduce kampli + else {AmpLip=(1.f/eddlipinfl)*SQR(SQR(alph*bet));kampli=AmpLip/aamp;}//Strong Reduce if beta low + // comparaison betwwen pixel and neighbours to do ==> I think 3 dir above is better + + //koeLi[lvl*3][i*W_L + j] koeLi[lvl*3][(i-1)*W_L + j] koeLi[lvl*3][(i+1)*W_L + j] + // koeLi[lvl*3][i*W_L + j+1] koeLi[lvl*3][i*W_L + j-1]) koeLi[lvl*3][(i-1)*W_L + j-1] + // koeLi[lvl*3][(i-1)*W_L + j+1] koeLi[lvl*3][(i+1)*W_L + j-1] koeLi[lvl*3][(i+1)*W_L + j+1]) + + // apply to each direction Wavelet level : horizontal / vertiacle / diagonal + + interm*=kampli; + if(interm < cp.eddetthr/eddlow) interm = 0.01f;//eliminate too low values + //we can change this part of algo==> not equal but ponderate + koeLi[lvl*3][i*W_L + j]=koeLi[lvl*3 + 1][i*W_L + j]=koeLi[lvl*3 + 2][i*W_L + j]=interm;//new value + //here KoeLi contains values where gradient is high and coef high, and eliminate low values... + } + } + } + // end +} + #ifdef _OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif @@ -965,12 +1273,80 @@ omp_set_nested(oldNested); float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); - ContAllL (labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip); + ContAllL (koeLi, maxkoeLi, lipschitz, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavCLVCcurve, ChCurve, Chutili); } } -} + + +} + //delete edge detection + if(koeLibuffer) { + delete [] koeLibuffer; + } } + void ImProcFunctions::WaveletAandBAllAB(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, + struct cont_params cp, FlatCurve* hhCurve, bool hhutili){ + StopWatch Stop1("WaveletAandBAllAB"); + if (hhutili) { // H=f(H) + int W_L = WaveletCoeffs_a.level_W(0); + int H_L = WaveletCoeffs_a.level_H(0); + + float * WavCoeffs_a0 = WaveletCoeffs_a.coeff0; + float * WavCoeffs_b0 = WaveletCoeffs_b.coeff0; +#ifdef _OPENMP +#pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) +#endif +{ +#ifdef __SSE2__ + float huebuffer[W_L] ALIGNED64; + float chrbuffer[W_L] ALIGNED64; +#endif // __SSE2__ +#ifdef _OPENMP +#pragma omp for schedule(dynamic,16) +#endif + for (int i=0; iv(i,j) = valpar; + } + */ + float valparam = float((hhCurve->getVal(Color::huelab_to_huehsv2(hueR))-0.5f) * 1.7f) +hueR;//get H=f(H) 1.7 optimisation ! + float2 sincosval = xsincosf(valparam); + WavCoeffs_a0[i*W_L+j]=chR*sincosval.y; + WavCoeffs_b0[i*W_L+j]=chR*sincosval.x; + } + } +} + } + +} + void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_ab, struct cont_params cp, const bool useChannelA){ @@ -1054,8 +1430,144 @@ omp_set_nested(oldNested); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - void ImProcFunctions::ContAllL (LabImage * labco, float ** varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params cp, - int W_L, int H_L, int skip) +void ImProcFunctions::calckoe(float ** WavCoeffs_LL, struct cont_params cp, float *koeLi[9], int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC){ + int borderL = 2; + if(cp.eddetthr < 30.f) { + borderL = 1; + // I calculate coefficients with r size matrix 3x3 r=1 ; 5x5 r=2; 7x7 r=3 + /* + float k[2*r][2*r]; + for(int i=1;i<=(2*r+1);i++) { + for(int j=1;j<=(2*r+1);j++) { + k[i][j]=(1.f/6.283*sigma*sigma)*exp(-SQR(i-r-1)+SQR(j-r-1)/2.f*SQR(sigma)); + } + } + //I could also use Gauss.h for 3x3 + // If necessary I can put a 7x7 matrix + */ + for (int i=1; i= 30.f && cp.eddetthr < 50.f) { + borderL = 1; + + for (int i=1; i= 50.f && cp.eddetthr < 75.f) { + borderL = 1; + for (int i=1; i= 75.f) { + for (int i=2; i lees good results==> probably because structure data different and also I compare to original value which have + and - + for(int i = borderL; i < H_L-borderL; i++ ) {//[-1 0 1] x==>j + for(int j = borderL; j < W_L-borderL; j++) { + tmC[i][j]=- WavCoeffs_LL[dir][(i)*W_L + j-1] + WavCoeffs_LL[dir][(i)*W_L + j+1]; + } + } + for(int i = borderL; i < H_L-borderL; i++ ) {//[1 0 -1] y==>i + for(int j = borderL; j < W_L-borderL; j++) { + tmC[i][j]= - WavCoeffs_LL[dir][(i-1)*W_L + j] + WavCoeffs_LL[dir][(i+1)*W_L + j]; + } + } + */ + + float thr=40.f;//avoid artifact eg. noise...to test + float thr2=1.5f*edd;//edd can be modified in option ed_detect + thr2+=cp.eddet/30.f;//to test + float diffFactor = (cp.eddet/100.f); + for(int i = borderL; i < H_L-borderL; i++ ) { + for(int j = borderL; j < W_L-borderL; j++) { + // my own algo : probably a little false, but simpler as Lipschitz ! + // Thr2 = maximum of the function ==> Lipsitch says = probably edge +// float temp = WavCoeffs_LL[dir][i*W_L + j]; +// if(temp>=0.f && temp < thr) temp = thr; +// if(temp < 0.f && temp > -thr) temp = -thr; + float temp = max(fabsf(WavCoeffs_LL[dir][i*W_L + j]), thr ); + koeLi[level*3 + dir-1][i*W_L + j]= min(thr2,fabs(tmC[i][j]/temp));// limit maxi + //it will be more complicated to calculate both Wh and Wv, but we have also Wd==> pseudo Lipschitz + if(koeLi[level*3+ dir-1][i*W_L + j] > maxkoeLi[level*3+ dir-1]) + maxkoeLi[level*3+ dir-1] = koeLi[level*3 + dir-1][i*W_L + j]; + float diff = maxkoeLi[level*3+ dir-1] - koeLi[level*3 + dir-1][i*W_L + j]; + diff *= diffFactor; + koeLi[level*3 + dir-1][i*W_L + j] = maxkoeLi[level*3 + dir-1] - diff; + } + } + +} + + + + void ImProcFunctions::ContAllL (float *koeLi[9], float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * labco, float ** varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params cp, + int W_L, int H_L, int skip, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, FlatCurve* ChCurve, bool Chutili) { static const float scales[10] = {1.f,2.f,4.f,8.f,16.f,32.f,64.f,128.f,256.f,512.f}; @@ -1063,21 +1575,290 @@ omp_set_nested(oldNested); for(int sc=0;sc<10;sc++) scaleskip[sc]=scales[sc]/skip; float atten01234 = 0.80f; + float t_r=settings->top_right; + float t_l=settings->top_left; + float b_r=settings->bot_right; + float b_l=settings->bot_left; + float edd=settings->ed_detec; + float eddlow=settings->ed_low; + float eddstrength=settings->ed_detecStr; + float aedstr=(eddstrength-1.f)/90.f; + float bedstr=1.f-10.f*aedstr; + bool refi=false; + // if(cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f) refi=true; + // if(cp.val > 0 || refi) {//edge if(cp.val > 0) {//edge - float rad = ((float)cp.rad)/60.f;//radius ==> not too high value to avoid artifacts - float value = ((float)cp.val)/8.f;//strength - //value /= skip; - if (scaleskip[1] < 1.f) value *= (atten01234*scaleskip[1]);//for zoom < 100% reduce strength...I choose level 1...but!! - float al0 = 1.f + ((float)cp.til)/50.f; - float al10 =1.0f;//arbitrary value ==> less = take into account high levels - float ak =-(al0-al10)/10.f;//10 = maximum levels - float bk =al0; - float koef = ak*level+bk;//modulate for levels : more levels high, more koef low ==> concentrated action on low levelsn but without forfot high levels - float edge = 1.f + value * exp (-pow(fabs(rad - level),koef));//estimate edge "pseudo variance" - for (int i=0; i=0.f && temp < thr) temp= thr; + if(temp < 0.f && temp > -thr) temp= -thr; + koe[i*W_L + j]= min(thr2,fabs(tmC[i][j]/temp)); + + if(koe[i*W_L + j] > maxkoe) maxkoe=koe[i*W_L + j]; + float diff=maxkoe-koe[i*W_L + j]; + diff *=(cp.eddet/100.f); + float interm=maxkoe-diff; + if(interm < cp.eddetthr/30.f) interm = 0.01f; + + koe[i*W_L + j]=interm; + + } + } + //printf("maxkoe=%f \n",maxkoe); + + for (int i=0; i not too high value to avoid artifacts + float value = ((float)cp.val)/8.f;//strength + if (scaleskip[1] < 1.f) value *= (atten01234*scaleskip[1]);//for zoom < 100% reduce strength...I choose level 1...but!! + float edge=1.f; + float lim0=20.f;//arbitrary limit for low radius and level between 2 or 3 to 30 maxi + float lev = float (level); + float repart=(float)cp.til; + float brepart; + if(cp.reinforce==1) brepart=3.f; + if(cp.reinforce==3) brepart=0.5f; //arbitrary value to increase / decrease repart, between 1 and 0 + float arepart=-(brepart-1.f)/(lim0/60.f); + if (cp.reinforce !=2) {if(rad < lim0/60.f) repart *= (arepart*rad + brepart);}//linear repartition of repart + + float al0 = 1.f + (repart)/50.f; + float al10 =1.0f;//arbitrary value ==> less = take into account high levels + // float ak =-(al0-al10)/10.f;//10 = maximum levels + float ak =-(al0-al10)/10.f;//10 = maximum levels + float bk =al0; + float koef = ak*level+bk;//modulate for levels : more levels high, more koef low ==> concentrated action on low levels, without or near for high levels + float expkoef= -pow(fabs(rad - lev),koef);//reduce effect for high levels + if (cp.reinforce==3) {if(rad < lim0/60.f && level==0) expkoef *= repart;}//reduce effect for low values of rad and level=0==> quasi only level 1 is effective + if (cp.reinforce==1) {if(rad < lim0/60.f && level==1) expkoef /= repart;}//increase effect for low values of rad and level=1==> quasi only level 0 is effective + float coefsd=0.85f;//arbitray value to reduce effect after sigma in all case + float coefmean=0.85f;//arbitray value to reduce effect after sigma in all case +// edge = 1.f + value * exp (expkoef);//estimate edge "pseudo variance" + //take into account local contrast + float refin= value * exp (expkoef); + if(cp.link==true){//combi + { + if(level==0) refin *= (1.f + cp.lev0s/50.f);// we can change this sensibility! + if(level==1) refin *= (1.f + cp.lev1s/50.f); + if(level==2) refin *= (1.f + cp.lev2s/50.f); + } + } + float edgePrecalc = 1.f + refin; //estimate edge "pseudo variance" + + if(cp.EDmet==2) {//curve + float insigma=0.666f;//SD + float logmax=log(MaxP[level]);//log Max + float rapX=(mean[level]+sigma[level])/MaxP[level];//rapport between sD / max + float inx=log(insigma); + float iny=log(rapX); + float rap=inx/iny;//koef + float asig=0.166f/sigma[level]; + float bsig=0.5f-asig*mean[level]; + float amean=0.5f/mean[level]; + float absciss; + float kinterm; + float kmul; + for (int i=0; i 10.f) edge=(aedstr*cp.eddet+bedstr)*(edgePrecalc*(1.f+koe[i]))/(1.f+0.9f*maxkoe); + else edge=(edgePrecalc*(1.f+koe[i]))/(1.f+0.9f*maxkoe); + } + if(lipschitz==true) { + if(level < 3) edge = 1.f +(edgePrecalc-1.f)*(koeLi[level*3][i])/(1.f+0.9f*maxkoeLi[level*3+ dir-1]); + else edge = edgePrecalc; + } + } + else edge = edgePrecalc; + + if(cp.edgcurv) { + if(fabs(WavCoeffs_L[dir][i])>= (mean[level]+sigma[level])){//for max + float valcour=log(fabs(WavCoeffs_L[dir][i])); + float valc=valcour-logmax; + float vald=valc*rap; + absciss=exp(vald); + + } + else if(fabs(WavCoeffs_L[dir][i])>=mean[level] && fabs(WavCoeffs_L[dir][i]) < (mean[level]+sigma[level])){ + absciss=asig*fabs(WavCoeffs_L[dir][i])+bsig; + } + else if(fabs(WavCoeffs_L[dir][i]) < mean[level]){ + absciss=amean*fabs(WavCoeffs_L[dir][i]); + } + // Threshold adjuster settings==> approximative for curve + //kmul about average cbrt(3--40 / 10)==>1.5 to 2.5 + //kmul about SD 10--60 / 35 ==> 2 + // kmul about low cbrt((5.f+cp.edg_low)/5.f);==> 1.5 + // kmul about max ==> 9 + // we can change these values + // result is different not best or bad than threshold slider...but similar + float abssd=4.f;//amplification reference + float bbssd=2.f;//mini ampli + float maxamp=2.5f;//maxi ampli at end + float maxampd=10.f;//maxi ampli at end + float a_abssd=(maxamp - abssd)/0.333f; + float b_abssd=maxamp-a_abssd; + float da_abssd=(maxampd - abssd)/0.333f; + float db_abssd=maxampd-da_abssd; + float am=(abssd-bbssd)/0.666f; + float kmuld=0.f; + if(absciss>0.666f && absciss < 1.f) {kmul=a_abssd*absciss + b_abssd;kmuld=da_abssd*absciss + db_abssd;}//about max ==> kinterm + else kmul = kmuld = absciss*am+bbssd; + kinterm=1.f; + float kc= kmul*(wavCLVCcurve[absciss*500.f]-0.5f); + float kcd= kmuld*(wavCLVCcurve[absciss*500.f]-0.5f); + float reduceeffect=0.6f; + if(kc >=0.f) + kinterm = 1.f + reduceeffect*kmul*(wavCLVCcurve[absciss*500.f]-0.5f);//about 1 to 3 general and big amplification for max (under 0) + else + kinterm = 1.f - (SQR(kcd))/10.f; + + if(kinterm<0.f) kinterm=0.01f; + edge *= kinterm; + if(edge < 1.f) + edge=1.f; + } + WavCoeffs_L[dir][i] *= edge; + } + } + else if(cp.EDmet==1) {//threshold adjuster + float MaxPCompare = MaxP[level]*SQR(cp.edg_max/100.f);//100 instead of b_r...case if b_r < 100 + float MaxNCompare = MaxN[level]*SQR(cp.edg_max/100.f);//always rduce a little edge for near max values + float edgeSdCompare = (mean[level]+1.5f*sigma[level])*SQR(cp.edg_sd/t_r);// 1.5 standard deviation #80% range between mean 50% and 80% + float edgeMeanCompare = mean[level]*SQR(cp.edg_mean/t_l); + float edgeLowCompare = (5.f+SQR(cp.edg_low)); + float edgeMeanFactor = cbrt(cp.edg_mean/t_l); + float interm; + if(cp.edg_low < 10.f) interm= cbrt((5.f+cp.edg_low)/5.f); + else interm=1.437f;//cbrt(3); + float edgeLowFactor = interm; + float edgeSdFactor = cp.edg_sd/t_r; + float edgeMaxFactor = SQR(cp.edg_max/b_r); + float edgMaxFsup=(cp.edg_max/b_r);//reduce increase of effect for high values contrast..if slider > b_r + + for (int i=0; i 10.f) edge=(aedstr*cp.eddet+bedstr)*(edgePrecalc*(1.f+koe[i]))/(1.f+0.9f*maxkoe); + else edge=(edgePrecalc*(1.f+koe[i]))/(1.f+0.9f*maxkoe); + } + if(lipschitz==true) { + if(level < 3) edge = 1.f +(edgePrecalc-1.f)*(koeLi[level*3][i])/(1.f+0.9f*maxkoeLi[level*3+ dir-1]); + else edge = edgePrecalc; + } + } + else edge = edgePrecalc; + + //algorithm that take into account local contrast + // I use a thresholdadjuster with + // Bottom left ==> minimal low value for local contrast (not 0, but 5...we can change) + // 0 10*10 35*35 100*100 substantially correspond to the true distribution of low value, mean, standard-deviation and max (ed 5, 50, 400, 4000 + // Top left ==> mean reference value (for each level), we can change cbrt(cp.edg_mean/10.f) + // Top Right==> standard deviation (for each level) we can change (cp.edg_sd/35.f) + // bottom right ==> Max for positif and negatif contrast we can change cp.edg_max/100.f + // If we move sliders to the left, local contrast is reduced + // if we move sliders to the right local contrast is increased + // MaxP, MaxN, mean, sigma are calculated if necessary (val > 0) by evaluate2(), eval2(), aver() , sigma() + if(b_r < 100.f && cp.edg_max/b_r > 1.f) {//in case of b_r < 100 and slider move to right + if (WavCoeffs_L[dir][i] > MaxPCompare*cp.edg_max/b_r) { + edge *= edgMaxFsup; + if(edge < 1.f) + edge=1.f; + } + else if (WavCoeffs_L[dir][i] < MaxNCompare*cp.edg_max/b_r) { + edge *= edgMaxFsup; + if(edge < 1.f) + edge=1.f; + } + } + + if (WavCoeffs_L[dir][i] > MaxPCompare) { + edge *= edgeMaxFactor; + if(edge < 1.f) + edge=1.f; + }//reduce edge if > new max + else if (WavCoeffs_L[dir][i] < MaxNCompare) { + edge *= edgeMaxFactor; + if(edge < 1.f) + edge=1.f; + } + + if (fabs(WavCoeffs_L[dir][i]) >= edgeMeanCompare && fabs(WavCoeffs_L[dir][i]) < edgeSdCompare) { + //if (fabs(WavCoeffs_L[dir][i]) > edgeSdCompare) { + edge *= edgeSdFactor; + if(edge < 1.f) + edge=1.f; + }//mofify effect if sd change + if (fabs(WavCoeffs_L[dir][i]) < edgeMeanCompare) { + edge *= edgeMeanFactor; + if(edge < 1.f) + edge=1.f; + } // modify effect if mean change + if (fabs(WavCoeffs_L[dir][i]) < edgeLowCompare) { + edge *= edgeLowFactor; + if(edge < 1.f) + edge=1.f; + } + WavCoeffs_L[dir][i] *= edge; + } + } + if(lipschitz==false) { + delete [] koe; + } + } + + + if(cp.link==false) { //used both with denoise 1 2 3 + float refine=0.f; + for (int i=0; iL[ii*2][jj*2]; - LL100=LL/327.68f; + LL100=LL100init=LL/327.68f; + LL100res=WavCoeffs_L0[i]/327.68f; + float delta=fabs(LL100init-LL100res)/(maxlvl/2); + for(int ml=0;mlgetVal(lr=Color::huelab_to_huehsv2(modhue2))-0.5f));//get valparam=f(H) + + if(valparam > 0.f) scale2=1.f + 3.f* valparam;//arbitrary value + else scale2 = 1.f + 1.9f*valparam;//near 0 but not zero if curve # 0 + + //curve Contrast / hue + + } + // //linear transition HL - float alpha = (1024.f + 15.f *(float) cpMul*scale*beta)/1024.f ; + float alpha = (1024.f + 15.f *(float) cpMul*scale*scale2*beta)/1024.f ; if(cp.HSmet){ - float aaal=(1.f-alpha)/(cp.b_lhl-cp.t_lhl); - float bbal=1.f-aaal*cp.b_lhl; - float aaar=(alpha-1.f)/(cp.t_rhl-cp.b_rhl); - float bbbr=1.f-cp.b_rhl*aaar; + float aaal=(1.f-alpha)/((cp.b_lhl-cp.t_lhl)*kH[level]); + float bbal=1.f-aaal*cp.b_lhl*kH[level]; + float aaar=(alpha-1.f)/(cp.t_rhl-cp.b_rhl)*kH[level]; + float bbbr=1.f-cp.b_rhl*aaar*kH[level]; //linear transition Shadows float aaalS=(1.f-alpha)/(cp.b_lsl-cp.t_lsl); float bbalS=1.f-aaalS*cp.b_lsl; float aaarS=(alpha-1.f)/(cp.t_rsl-cp.b_rsl); float bbbrS=1.f-cp.b_rsl*aaarS; if(level <=cp.numlevH) {//in function of levels - if((LL100 > cp.t_lhl && LL100 < cp.t_rhl)) kLlev=alpha; - else if((LL100 > cp.b_lhl && LL100 <= cp.t_lhl)) kLlev=aaal*LL100+bbal; - else if((LL100 > cp.t_rhl && LL100 <= cp.b_rhl)) kLlev=aaar*LL100+bbbr; + if((LL100 > cp.t_lhl*kH[level] && LL100 < cp.t_rhl*kH[level])) {kLlev=alpha;} + else if((LL100 > cp.b_lhl*kH[level] && LL100 <= cp.t_lhl*kH[level])) kLlev=aaal*LL100+bbal; + else if((LL100 > cp.t_rhl*kH[level] && LL100 <= cp.b_rhl*kH[level])) kLlev=aaar*LL100+bbbr; else kLlev=1.f; } if(level >=(9-cp.numlevS)) { @@ -1176,8 +1980,8 @@ omp_set_nested(oldNested); else if((LL100 > cp.b_lsl && LL100 <= cp.t_lsl)) kLlev=aaalS*LL100+bbalS; else if((LL100 > cp.t_rsl && LL100 <= cp.b_rsl)) kLlev=aaarS*LL100+bbbrS; else kLlev=1.f; - } else - kLlev=alpha; + } + } else kLlev=alpha; WavCoeffs_L[dir][i]*=(kLlev); @@ -1210,72 +2014,63 @@ omp_set_nested(oldNested); else if(params->wavelet.Dirmethod=="thr") choiceDir=3; else if(params->wavelet.Dirmethod=="all") choiceDir=0; - // printf("LUm lev=%d clev=%d dir=%d\n",choicelevel,choiceClevel,choiceDir); - if(choiceClevel==0) { - if(choiceDir==0) { - if(level == 0) - for (int i=0; i= choicelevel) { - for (int dir=1; dir<4; dir++) { - for (int i=0; i= choicelevel) { - for (int i=0; i= choicelevel) { + for (int dir=1; dir<4; dir++) { + for (int i=0; i= choicelevel + if(level >= choicelevel) { + for (int i=0; i= choicelevel + if(level <= choicelevel) { + for (int i=0; iwavelet.skinprotect; const float skinprotneg = -skinprot; @@ -1427,55 +2224,48 @@ omp_set_nested(oldNested); else if(params->wavelet.Dirmethod=="thr") choiceDir=3; else if(params->wavelet.Dirmethod=="all") choiceDir=0; - // printf("LUm lev=%d clev=%d dir=%d\n",choicelevel,choiceClevel,choiceDir); - if(choiceClevel==0) { - if(choiceDir==0) { - if(level == 0) + int dir1 = (choiceDir == 2) ? 1 : 2; + int dir2 = (choiceDir == 3) ? 1 : 3; + if(choiceClevel<3) { // not all levels visible, paint residual + if(level == 0) { + if(cp.backm!=2) { // nothing to change when residual is used as background + float backGroundChroma = (cp.backm==1) ? 0.f : 0.f;//we can change first to colorized... for (int i=0; i= choicelevel) { for (int dir=1; dir<4; dir++) { for (int i=0; i= choicelevel) { - for (int dir=1; dir<4; dir++) { - for (int i=0; i= choicelevel if(level >= choicelevel) { for (int i=0; i= choicelevel if(level <= choicelevel) { for (int i=0; i &curve) { } -void WaveletParams::getDefaultCLVCurve(std::vector &curve) { - double v[8]= { 0.0, 0.50,0.35,0.35, - 1.00, 0.50,0.35,0.35}; - curve.resize(9); +void WaveletParams::getDefaultCCWCurve(std::vector &curve) { + double v[12]= { 0.0, 0.25, 0.35, 0.35, + 0.50, 0.75, 0.35, 0.35, 0.90, 0.0, 0.35, 0.35}; + + curve.resize(13); curve.at(0 ) = double(FCT_MinMaxCPoints); for (size_t i=1; i GCurve; - // GCurve = this->colorCurve; - cCurve.Set(this->clvcurve); + cCurve.Set(this->ccwcurve); opacityCurveLUTRG.Set(this->opacityCurveRG); - // colorCurveLUT.SetXYZ(GCurve, xyz_rgb, rgb_xyz, satur, lumin); - opacityCurveLUTBY.Set(this->opacityCurveBY); } void WaveletParams::setDefaults() { - getDefaultCLVCurve(clvcurve); + getDefaultCCWCurve(ccwcurve); getDefaultOpacityCurveRG(opacityCurveRG); getDefaultOpacityCurveBY(opacityCurveBY); enabled = false; median = false; + medianlev = false; + linkedg = true; + lipst = false; + Medgreinf = "none"; avoid = false; strength = 100; Lmethod = "4_"; CHmethod = "without"; + CHSLmethod = "SL"; + EDmethod = "CU"; HSmethod = "with"; CLmethod = "all"; + Backmethod = "grey"; Dirmethod = "all"; Tilesmethod = "full"; + choicemethod = "4_"; rescon = 0; resconH = 0; reschro = 0; @@ -484,22 +495,37 @@ void WaveletParams::setDefaults() { edgrad =15; edgval = 0; edgthresh = 10; - thr = 30; - thrH = 70; + thr = 35; + thrH = 65; skinprotect = 0.; hueskin.setValues(-5, 25, 170, 120); hueskin2.setValues(-260, -250, -130, -140); threshold=5; threshold2=4; + edgedetect=80; + edgedetectthr=20; + edgedetectthr2=0; hllev.setValues(50, 75, 100, 98); bllev.setValues(0, 2, 50, 25); pastlev.setValues(0, 2, 30, 20); satlev.setValues(30, 45, 130, 100); + edgcont.setValues(bl, tl, br, tr); + level0noise.setValues(0, 0); + level1noise.setValues(0, 0); + level2noise.setValues(0, 0); + hhcurve.clear (); + hhcurve.push_back(FCT_Linear); + Chcurve.clear (); + Chcurve.push_back(FCT_Linear); for(int i = 0; i < 9; i ++) { c[i] = 0; } + for(int i = 0; i < 9; i ++) + { + ch[i] = 0; + } } @@ -1516,7 +1542,9 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol if (!pedited || pedited->wavelet.strength) keyFile.set_integer ("Wavelet", "Strength", wavelet.strength); if (!pedited || pedited->wavelet.thres) keyFile.set_integer ("Wavelet", "MaxLev", wavelet.thres); if (!pedited || pedited->wavelet.Tilesmethod) keyFile.set_string ("Wavelet", "TilesMethod", wavelet.Tilesmethod); + if (!pedited || pedited->wavelet.choicemethod) keyFile.set_string ("Wavelet", "DaubMethod", wavelet.choicemethod); if (!pedited || pedited->wavelet.CLmethod) keyFile.set_string ("Wavelet", "ChoiceLevMethod", wavelet.CLmethod); + if (!pedited || pedited->wavelet.Backmethod) keyFile.set_string ("Wavelet", "BackMethod", wavelet.Backmethod); if (!pedited || pedited->wavelet.Lmethod) keyFile.set_string ("Wavelet", "LevMethod", wavelet.Lmethod); if (!pedited || pedited->wavelet.Dirmethod) keyFile.set_string ("Wavelet", "DirMethod", wavelet.Dirmethod); for(int i = 0; i < 9; i++) @@ -1525,6 +1553,13 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol ss << "Contrast" << (i+1); if (!pedited || pedited->wavelet.c[i]) keyFile.set_integer("Wavelet", ss.str(), wavelet.c[i]); } + for(int i = 0; i < 9; i++) + { + std::stringstream ss; + ss << "Chroma" << (i+1); + if (!pedited || pedited->wavelet.ch[i]) keyFile.set_integer("Wavelet", ss.str(), wavelet.ch[i]); + } + if (!pedited || pedited->wavelet.sup) keyFile.set_integer ("Wavelet", "ContExtra", wavelet.sup); if (!pedited || pedited->wavelet.HSmethod) keyFile.set_string ("Wavelet", "HSMethod", wavelet.HSmethod); if (!pedited || pedited->wavelet.hllev) { @@ -1535,14 +1570,37 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol Glib::ArrayHandle thresh (wavelet.bllev.value, 4, Glib::OWNERSHIP_NONE); keyFile.set_integer_list("Wavelet", "SHRange", thresh); } + if (!pedited || pedited->wavelet.edgcont) { + Glib::ArrayHandle thresh (wavelet.edgcont.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "Edgcont", thresh); + } + if (!pedited || pedited->wavelet.level0noise) { + Glib::ArrayHandle thresh (wavelet.level0noise.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "Level0noise", thresh); + } + if (!pedited || pedited->wavelet.level0noise) { + Glib::ArrayHandle thresh (wavelet.level1noise.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "Level1noise", thresh); + } + if (!pedited || pedited->wavelet.level2noise) { + Glib::ArrayHandle thresh (wavelet.level0noise.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "Level2noise", thresh); + } + if (!pedited || pedited->wavelet.threshold) keyFile.set_integer ("Wavelet", "ThresholdHighlight", wavelet.threshold); if (!pedited || pedited->wavelet.threshold2) keyFile.set_integer ("Wavelet", "ThresholdShadow", wavelet.threshold2); + if (!pedited || pedited->wavelet.edgedetect) keyFile.set_integer ("Wavelet", "Edgedetect", wavelet.edgedetect); + if (!pedited || pedited->wavelet.edgedetectthr) keyFile.set_integer ("Wavelet", "Edgedetectthr", wavelet.edgedetectthr); + if (!pedited || pedited->wavelet.edgedetectthr2) keyFile.set_integer ("Wavelet", "EdgedetectthrHi", wavelet.edgedetectthr2); if (!pedited || pedited->wavelet.chroma) keyFile.set_integer ("Wavelet", "ThresholdChroma", wavelet.chroma); if (!pedited || pedited->wavelet.CHmethod) keyFile.set_string ("Wavelet", "CHromaMethod", wavelet.CHmethod); + if (!pedited || pedited->wavelet.Medgreinf) keyFile.set_string ("Wavelet", "Medgreinf", wavelet.Medgreinf); + if (!pedited || pedited->wavelet.CHSLmethod) keyFile.set_string ("Wavelet", "CHSLromaMethod", wavelet.CHSLmethod); + if (!pedited || pedited->wavelet.EDmethod) keyFile.set_string ("Wavelet", "EDMethod", wavelet.EDmethod); if (!pedited || pedited->wavelet.chro) keyFile.set_integer ("Wavelet", "ChromaLink", wavelet.chro); - if (!pedited || pedited->wavelet.clvcurve) { - Glib::ArrayHandle clvcurve = wavelet.clvcurve; - keyFile.set_double_list("Wavelet", "ChromaCurve", clvcurve); + if (!pedited || pedited->wavelet.ccwcurve) { + Glib::ArrayHandle ccwcurve = wavelet.ccwcurve; + keyFile.set_double_list("Wavelet", "ContrastCurve", ccwcurve); } if (!pedited || pedited->wavelet.pastlev) { Glib::ArrayHandle thresh (wavelet.pastlev.value, 4, Glib::OWNERSHIP_NONE); @@ -1561,9 +1619,21 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol Glib::ArrayHandle curve = wavelet.opacityCurveBY; keyFile.set_double_list("Wavelet", "OpacityCurveBY", curve); } + if (!pedited || pedited->wavelet.hhcurve) { + Glib::ArrayHandle curve = wavelet.hhcurve; + keyFile.set_double_list("Wavelet", "HHcurve", curve); + } + if (!pedited || pedited->wavelet.Chcurve) { + Glib::ArrayHandle curve = wavelet.Chcurve; + keyFile.set_double_list("Wavelet", "CHcurve", curve); + } if (!pedited || pedited->wavelet.median) keyFile.set_boolean ("Wavelet", "Median", wavelet.median); + if (!pedited || pedited->wavelet.medianlev) keyFile.set_boolean ("Wavelet", "Medianlev", wavelet.medianlev); + if (!pedited || pedited->wavelet.linkedg) keyFile.set_boolean ("Wavelet", "Linkedg", wavelet.linkedg); + if (!pedited || pedited->wavelet.lipst) keyFile.set_boolean ("Wavelet", "Lipst", wavelet.lipst); + // if (!pedited || pedited->wavelet.edgreinf) keyFile.set_boolean ("Wavelet", "Edgreinf", wavelet.edgreinf); if (!pedited || pedited->wavelet.skinprotect) keyFile.set_double ("Wavelet", "Skinprotect", wavelet.skinprotect); if (!pedited || pedited->wavelet.hueskin) { Glib::ArrayHandle thresh (wavelet.hueskin.value, 4, Glib::OWNERSHIP_NONE); @@ -2307,11 +2377,20 @@ if (keyFile.has_group ("Wavelet")) { if (keyFile.has_key ("Wavelet", "Enabled")) { wavelet.enabled = keyFile.get_boolean ("Wavelet", "Enabled"); if (pedited) pedited->wavelet.enabled = true; } if (keyFile.has_key ("Wavelet", "Strength")) { wavelet.strength = keyFile.get_integer ("Wavelet", "Strength"); if (pedited) pedited->wavelet.strength = true; } if (keyFile.has_key ("Wavelet", "Median")) {wavelet.median = keyFile.get_boolean ("Wavelet", "Median");if (pedited) pedited->wavelet.median = true;} + if (keyFile.has_key ("Wavelet", "Medianlev")) {wavelet.medianlev = keyFile.get_boolean ("Wavelet", "Medianlev");if (pedited) pedited->wavelet.medianlev = true;} + if (keyFile.has_key ("Wavelet", "Linkedg")) {wavelet.linkedg = keyFile.get_boolean ("Wavelet", "Linkedg");if (pedited) pedited->wavelet.linkedg = true;} + // if (keyFile.has_key ("Wavelet", "Edgreinf")) {wavelet.edgreinf = keyFile.get_boolean ("Wavelet", "Edgreinf");if (pedited) pedited->wavelet.edgreinf = true;} + if (keyFile.has_key ("Wavelet", "Lipst")) {wavelet.lipst = keyFile.get_boolean ("Wavelet", "Lipst");if (pedited) pedited->wavelet.lipst = true;} if (keyFile.has_key ("Wavelet", "AvoidColorShift")) {wavelet.avoid = keyFile.get_boolean ("Wavelet", "AvoidColorShift");if (pedited) pedited->wavelet.avoid = true;} if (keyFile.has_key ("Wavelet", "LevMethod")) {wavelet.Lmethod = keyFile.get_string ("Wavelet", "LevMethod"); if (pedited) pedited->wavelet.Lmethod = true; } if (keyFile.has_key ("Wavelet", "ChoiceLevMethod")) {wavelet.CLmethod = keyFile.get_string ("Wavelet", "ChoiceLevMethod"); if (pedited) pedited->wavelet.CLmethod = true; } + if (keyFile.has_key ("Wavelet", "BackMethod")) {wavelet.Backmethod = keyFile.get_string ("Wavelet", "BackMethod"); if (pedited) pedited->wavelet.Backmethod = true; } if (keyFile.has_key ("Wavelet", "TilesMethod")) {wavelet.Tilesmethod = keyFile.get_string ("Wavelet", "TilesMethod"); if (pedited) pedited->wavelet.Tilesmethod = true; } + if (keyFile.has_key ("Wavelet", "DaubMethod")) {wavelet.choicemethod = keyFile.get_string ("Wavelet", "DaubMethod"); if (pedited) pedited->wavelet.choicemethod = true; } if (keyFile.has_key ("Wavelet", "CHromaMethod")) {wavelet.CHmethod = keyFile.get_string ("Wavelet", "CHromaMethod"); if (pedited) pedited->wavelet.CHmethod = true; } + if (keyFile.has_key ("Wavelet", "Medgreinf")) {wavelet.Medgreinf = keyFile.get_string ("Wavelet", "Medgreinf"); if (pedited) pedited->wavelet.Medgreinf = true; } + if (keyFile.has_key ("Wavelet", "CHSLromaMethod")) {wavelet.CHSLmethod = keyFile.get_string ("Wavelet", "CHSLromaMethod"); if (pedited) pedited->wavelet.CHSLmethod = true; } + if (keyFile.has_key ("Wavelet", "EDMethod")) {wavelet.EDmethod = keyFile.get_string ("Wavelet", "EDMethod"); if (pedited) pedited->wavelet.EDmethod = true; } if (keyFile.has_key ("Wavelet", "HSMethod")) {wavelet.HSmethod = keyFile.get_string ("Wavelet", "HSMethod"); if (pedited) pedited->wavelet.HSmethod = true; } if (keyFile.has_key ("Wavelet", "DirMethod")) {wavelet.Dirmethod = keyFile.get_string ("Wavelet", "DirMethod"); if (pedited) pedited->wavelet.Dirmethod = true; } if (keyFile.has_key ("Wavelet", "ResidualcontShadow")) {wavelet.rescon = keyFile.get_integer ("Wavelet", "ResidualcontShadow"); if (pedited) pedited->wavelet.rescon = true; } @@ -2322,6 +2401,9 @@ if (keyFile.has_group ("Wavelet")) { if (keyFile.has_key ("Wavelet", "MaxLev")) {wavelet.thres = keyFile.get_integer ("Wavelet", "MaxLev"); if (pedited) pedited->wavelet.thres = true; } if (keyFile.has_key ("Wavelet", "ThresholdHighLight")) {wavelet.threshold = keyFile.get_integer ("Wavelet", "ThresholdHighLight"); if (pedited) pedited->wavelet.threshold = true; } if (keyFile.has_key ("Wavelet", "ThresholdShadow")) {wavelet.threshold2 = keyFile.get_integer ("Wavelet", "ThresholdShadow"); if (pedited) pedited->wavelet.threshold2 = true; } + if (keyFile.has_key ("Wavelet", "Edgedetect")) {wavelet.edgedetect = keyFile.get_integer ("Wavelet", "Edgedetect"); if (pedited) pedited->wavelet.edgedetect = true; } + if (keyFile.has_key ("Wavelet", "Edgedetectthr")) {wavelet.edgedetectthr = keyFile.get_integer ("Wavelet", "Edgedetectthr"); if (pedited) pedited->wavelet.edgedetectthr = true; } + if (keyFile.has_key ("Wavelet", "EdgedetectthrHi")) {wavelet.edgedetectthr2 = keyFile.get_integer ("Wavelet", "EdgedetectthrHi"); if (pedited) pedited->wavelet.edgedetectthr2 = true; } if (keyFile.has_key ("Wavelet", "ThresholdChroma")) {wavelet.chroma = keyFile.get_integer ("Wavelet", "ThresholdChroma"); if (pedited) pedited->wavelet.chroma = true; } if (keyFile.has_key ("Wavelet", "ChromaLink")) {wavelet.chro = keyFile.get_integer ("Wavelet", "ChromaLink"); if (pedited) pedited->wavelet.chro = true; } if (keyFile.has_key ("Wavelet", "Contrast")) {wavelet.contrast = keyFile.get_integer ("Wavelet", "Contrast"); if (pedited) pedited->wavelet.contrast = true; } @@ -2330,9 +2412,11 @@ if (keyFile.has_group ("Wavelet")) { if (keyFile.has_key ("Wavelet", "ThrEdg")) {wavelet.edgthresh = keyFile.get_integer ("Wavelet", "ThrEdg"); if (pedited) pedited->wavelet.edgthresh = true; } if (keyFile.has_key ("Wavelet", "ThresholdResidShadow")) {wavelet.thr = keyFile.get_integer ("Wavelet", "ThresholdResidShadow"); if (pedited) pedited->wavelet.thr = true; } if (keyFile.has_key ("Wavelet", "ThresholdResidHighLight")) {wavelet.thrH = keyFile.get_integer ("Wavelet", "ThresholdResidHighLight"); if (pedited) pedited->wavelet.thrH = true; } - if (keyFile.has_key ("Wavelet", "ChromaCurve")) {wavelet.clvcurve = keyFile.get_double_list ("Wavelet", "ChromaCurve"); if (pedited) pedited->wavelet.clvcurve = true; } + if (keyFile.has_key ("Wavelet", "ContrastCurve")) {wavelet.ccwcurve = keyFile.get_double_list ("Wavelet", "ContrastCurve"); if (pedited) pedited->wavelet.ccwcurve = true; } if (keyFile.has_key ("Wavelet", "OpacityCurveRG")) { wavelet.opacityCurveRG = keyFile.get_double_list ("Wavelet", "OpacityCurveRG"); if (pedited) pedited->wavelet.opacityCurveRG = true; } if (keyFile.has_key ("Wavelet", "OpacityCurveBY")) { wavelet.opacityCurveBY = keyFile.get_double_list ("Wavelet", "OpacityCurveBY"); if (pedited) pedited->wavelet.opacityCurveBY = true; } + if (keyFile.has_key ("Wavelet", "HHcurve")) { wavelet.hhcurve = keyFile.get_double_list ("Wavelet", "HHcurve"); if (pedited) pedited->wavelet.hhcurve = true; } + if (keyFile.has_key ("Wavelet", "CHcurve")) { wavelet.Chcurve = keyFile.get_double_list ("Wavelet", "CHcurve"); if (pedited) pedited->wavelet.Chcurve = true; } if (keyFile.has_key ("Wavelet", "Hueskin")) { Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "Hueskin"); wavelet.hueskin.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); @@ -2354,6 +2438,27 @@ if (keyFile.has_group ("Wavelet")) { wavelet.bllev.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); if (pedited) pedited->wavelet.bllev = true; } + if (keyFile.has_key ("Wavelet", "Edgcont")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "Edgcont"); + wavelet.edgcont.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); + if (pedited) pedited->wavelet.edgcont = true; + } + if (keyFile.has_key ("Wavelet", "Level0noise")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "Level0noise"); + wavelet.level0noise.setValues(thresh.data()[0], thresh.data()[1]); + if (pedited) pedited->wavelet.level0noise = true; + } + if (keyFile.has_key ("Wavelet", "Level1noise")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "Level1noise"); + wavelet.level1noise.setValues(thresh.data()[0], thresh.data()[1]); + if (pedited) pedited->wavelet.level1noise = true; + } + if (keyFile.has_key ("Wavelet", "Level2noise")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "Level2noise"); + wavelet.level2noise.setValues(thresh.data()[0], thresh.data()[1]); + if (pedited) pedited->wavelet.level2noise = true; + } + if (keyFile.has_key ("Wavelet", "Pastlev")) { Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "Pastlev"); wavelet.pastlev.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); @@ -2373,6 +2478,13 @@ if (keyFile.has_group ("Wavelet")) { ss << "Contrast" << (i+1); if(keyFile.has_key ("Wavelet", ss.str())) {wavelet.c[i] = keyFile.get_integer ("Wavelet", ss.str()); if (pedited) pedited->wavelet.c[i] = true;} } + for(int i = 0; i < 9; i ++) + { + std::stringstream ss; + ss << "Chroma" << (i+1); + if(keyFile.has_key ("Wavelet", ss.str())) {wavelet.ch[i] = keyFile.get_integer ("Wavelet", ss.str()); if (pedited) pedited->wavelet.ch[i] = true;} + } + } // load directional pyramid equalizer parameters @@ -2613,6 +2725,11 @@ bool operator==(const WaveletParams & a, const WaveletParams & b) { if(a.c[i] != b.c[i]) return false; } + for(int i = 0; i < 9; i++) { + if(a.ch[i] != b.ch[i]) + return false; + } + return true; } @@ -2898,8 +3015,12 @@ bool ProcParams::operator== (const ProcParams& other) { && wavelet == other.wavelet && wavelet.Lmethod == other.wavelet.Lmethod && wavelet.CLmethod == other.wavelet.CLmethod + && wavelet.Backmethod == other.wavelet.Backmethod && wavelet.Tilesmethod == other.wavelet.Tilesmethod + && wavelet.choicemethod == other.wavelet.choicemethod && wavelet.CHmethod == other.wavelet.CHmethod + && wavelet.CHSLmethod == other.wavelet.CHSLmethod + && wavelet.EDmethod == other.wavelet.EDmethod && wavelet.HSmethod == other.wavelet.HSmethod && wavelet.Dirmethod == other.wavelet.Dirmethod && wavelet.rescon == other.wavelet.rescon @@ -2912,6 +3033,11 @@ bool ProcParams::operator== (const ProcParams& other) { && wavelet.chroma == other.wavelet.chroma && wavelet.chro == other.wavelet.chro && wavelet.contrast == other.wavelet.contrast + && wavelet.median == other.wavelet.median + && wavelet.medianlev == other.wavelet.medianlev + && wavelet.linkedg == other.wavelet.linkedg + && wavelet.lipst == other.wavelet.lipst + && wavelet.Medgreinf == other.wavelet.Medgreinf && wavelet.edgrad == other.wavelet.edgrad && wavelet.edgval == other.wavelet.edgval && wavelet.edgthresh == other.wavelet.edgthresh @@ -2919,15 +3045,24 @@ bool ProcParams::operator== (const ProcParams& other) { && wavelet.thrH == other.wavelet.thrH && wavelet.threshold == other.wavelet.threshold && wavelet.threshold2 == other.wavelet.threshold2 + && wavelet.edgedetect == other.wavelet.edgedetect + && wavelet.edgedetectthr == other.wavelet.edgedetectthr + && wavelet.edgedetectthr2 == other.wavelet.edgedetectthr2 && wavelet.hueskin == other.wavelet.hueskin && wavelet.hueskin2 == other.wavelet.hueskin2 && wavelet.hllev == other.wavelet.hllev && wavelet.bllev == other.wavelet.bllev + && wavelet.edgcont == other.wavelet.edgcont + && wavelet.level0noise == other.wavelet.level0noise + && wavelet.level1noise == other.wavelet.level1noise + && wavelet.level2noise == other.wavelet.level2noise && wavelet.pastlev == other.wavelet.pastlev && wavelet.satlev == other.wavelet.satlev && wavelet.opacityCurveRG == other.wavelet.opacityCurveRG && wavelet.opacityCurveBY == other.wavelet.opacityCurveBY - && wavelet.clvcurve == other.wavelet.clvcurve + && wavelet.hhcurve == other.wavelet.hhcurve + && wavelet.Chcurve == other.wavelet.Chcurve + && wavelet.ccwcurve == other.wavelet.ccwcurve && wavelet.skinprotect == other.wavelet.skinprotect && wavelet.strength == other.wavelet.strength && dirpyrequalizer == other.dirpyrequalizer diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 41f9fdae7..caddc3ac6 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -856,18 +856,31 @@ typedef std::map > IPTCPairs; class WaveletParams { public: - std::vector clvcurve; + std::vector ccwcurve; std::vector opacityCurveRG; std::vector opacityCurveBY; + std::vector hhcurve; + std::vector Chcurve; bool enabled; bool median; + bool medianlev; + bool linkedg; + bool lipst; + // bool edgreinf; bool avoid; int strength; int c[9]; + int ch[9]; + Glib::ustring Lmethod; Glib::ustring CLmethod; + Glib::ustring Backmethod; Glib::ustring Tilesmethod; + Glib::ustring choicemethod; Glib::ustring CHmethod; + Glib::ustring Medgreinf; + Glib::ustring CHSLmethod; + Glib::ustring EDmethod; Glib::ustring Dirmethod; Glib::ustring HSmethod; int rescon; @@ -880,6 +893,9 @@ class WaveletParams { int chro; int threshold; int threshold2; + int edgedetect; + int edgedetectthr; + int edgedetectthr2; int contrast; int edgrad; int edgval; @@ -893,12 +909,16 @@ class WaveletParams { Threshold bllev; Threshold pastlev; Threshold satlev; + Threshold edgcont; + Threshold level0noise; + Threshold level1noise; + Threshold level2noise; WaveletParams (); void setDefaults(); void getCurves(WavCurve &cCurve,WavOpacityCurveRG &opacityCurveLUTRG , WavOpacityCurveBY &opacityCurveLUTBY) const; - static void getDefaultCLVCurve(std::vector &curve); + static void getDefaultCCWCurve(std::vector &curve); static void getDefaultOpacityCurveRG(std::vector &curve); static void getDefaultOpacityCurveBY(std::vector &curve); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 075e229aa..8d2870d3a 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -344,7 +344,7 @@ DIRPYREQUALIZER, // EvWavlhl DIRPYREQUALIZER, // EvWavbhl DIRPYREQUALIZER, // EvWavThresHold2 DIRPYREQUALIZER, // EvWavavoid -DIRPYREQUALIZER, // EvWavCLVCurve +DIRPYREQUALIZER, // EvWavCCCurve DIRPYREQUALIZER, // EvWavpast DIRPYREQUALIZER, // EvWavsat DIRPYREQUALIZER, // EvWavCHmet @@ -361,7 +361,25 @@ DIRPYREQUALIZER, // EvWavthrH DIRPYREQUALIZER, // EvWavHueskin2 DIRPYREQUALIZER, // EvWavedgrad DIRPYREQUALIZER, // EvWavedgval -DIRPYREQUALIZER // EvWavStrngth +DIRPYREQUALIZER, // EvWavStrngth +DIRPYREQUALIZER, // EvWavchoicemet +DIRPYREQUALIZER, // EvWavedgreinf +DIRPYREQUALIZER, // EvWaveletch +DIRPYREQUALIZER, //EvWavCHSLmet +DIRPYREQUALIZER, //EvWavedgcont +DIRPYREQUALIZER, //EvWavEDmet +DIRPYREQUALIZER, //EvWavlev0nois +DIRPYREQUALIZER, //EvWavlev1nois +DIRPYREQUALIZER, //EvWavlev2nois +DIRPYREQUALIZER, //EvWavmedianlev +DIRPYREQUALIZER, //EvWavHHCurve +DIRPYREQUALIZER, //EvWavBackmet +DIRPYREQUALIZER, //EvWavedgedetect +DIRPYREQUALIZER, //EvWavlipst +DIRPYREQUALIZER, //EvWavedgedetectthr +DIRPYREQUALIZER, //EvWavedgedetectthr2 +DIRPYREQUALIZER, //EvWavlinkedg +DIRPYREQUALIZER //EvWavCHCurve }; diff --git a/rtengine/settings.h b/rtengine/settings.h index 0c65d8494..8da2df91a 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -74,7 +74,15 @@ namespace rtengine { double artifact_cbdl; double level0_cbdl; double level123_cbdl; - + double bot_left; + double top_left; + double top_right; + double bot_right; + double ed_detec; + double ed_detecStr; + double ed_low; + double ed_lipinfl; + double ed_lipampl; /** Creates a new instance of Settings. * @return a pointer to the new Settings instance. */ static Settings* create (); diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index da7d8ccbd..b851e620e 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -102,8 +102,11 @@ #define ADDSET_WA_EDGRAD 94 #define ADDSET_WA_EDGVAL 95 #define ADDSET_WA_STRENGTH 96 +#define ADDSET_WA_EDGEDETECT 97 +#define ADDSET_WA_EDGEDETECTTHR 98 +#define ADDSET_WA_EDGEDETECTTHR2 99 // When adding items, make sure to update ADDSET_PARAM_NUM -#define ADDSET_PARAM_NUM 97 // THIS IS USED AS A DELIMITER!! +#define ADDSET_PARAM_NUM 100 // THIS IS USED AS A DELIMITER!! #endif diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index a227b8c24..4cbea64b1 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -148,7 +148,7 @@ void BatchToolPanelCoordinator::initSession () { shadowshighlights->setAdjusterBehavior (false, false, false); dirpyrequalizer->setAdjusterBehavior (false, false, false); - wavelet->setAdjusterBehavior (false, false, false,false,false,false,false,false,false,false,false,false,false,false,false,false,false); + wavelet->setAdjusterBehavior (false, false, false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false, false, false); dirpyrdenoise->setAdjusterBehavior (false, false,false,false,false,false, false); bayerpreprocess->setAdjusterBehavior (false, false); rawcacorrection->setAdjusterBehavior (false); @@ -186,7 +186,7 @@ void BatchToolPanelCoordinator::initSession () { blackwhite->setAdjusterBehavior (options.baBehav[ADDSET_BLACKWHITE_HUES],options.baBehav[ADDSET_BLACKWHITE_GAMMA]); shadowshighlights->setAdjusterBehavior (options.baBehav[ADDSET_SH_HIGHLIGHTS], options.baBehav[ADDSET_SH_SHADOWS], options.baBehav[ADDSET_SH_LOCALCONTRAST]); dirpyrequalizer->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYREQ], options.baBehav[ADDSET_DIRPYREQ_THRESHOLD], options.baBehav[ADDSET_DIRPYREQ_SKINPROTECT]); - wavelet->setAdjusterBehavior (options.baBehav[ADDSET_WA], options.baBehav[ADDSET_WA_THRESHOLD], options.baBehav[ADDSET_WA_THRESHOLD2],options.baBehav[ADDSET_WA_THRES],options.baBehav[ADDSET_WA_CHRO],options.baBehav[ADDSET_WA_CHROMA],options.baBehav[ADDSET_WA_CONTRAST],options.baBehav[ADDSET_WA_SKINPROTECT],options.baBehav[ADDSET_WA_RESCHRO],options.baBehav[ADDSET_WA_RESCON],options.baBehav[ADDSET_WA_RESCONH],options.baBehav[ADDSET_WA_THRR],options.baBehav[ADDSET_WA_THRRH],options.baBehav[ADDSET_WA_SKYPROTECT], options.baBehav[ADDSET_WA_EDGRAD],options.baBehav[ADDSET_WA_EDGVAL],options.baBehav[ADDSET_WA_STRENGTH]); + wavelet->setAdjusterBehavior (options.baBehav[ADDSET_WA], options.baBehav[ADDSET_WA_THRESHOLD], options.baBehav[ADDSET_WA_THRESHOLD2],options.baBehav[ADDSET_WA_THRES],options.baBehav[ADDSET_WA_CHRO],options.baBehav[ADDSET_WA_CHROMA],options.baBehav[ADDSET_WA_CONTRAST],options.baBehav[ADDSET_WA_SKINPROTECT],options.baBehav[ADDSET_WA_RESCHRO],options.baBehav[ADDSET_WA_RESCON],options.baBehav[ADDSET_WA_RESCONH],options.baBehav[ADDSET_WA_THRR],options.baBehav[ADDSET_WA_THRRH],options.baBehav[ADDSET_WA_SKYPROTECT], options.baBehav[ADDSET_WA_EDGRAD],options.baBehav[ADDSET_WA_EDGVAL],options.baBehav[ADDSET_WA_STRENGTH],options.baBehav[ADDSET_WA_EDGEDETECT], options.baBehav[ADDSET_WA_EDGEDETECTTHR], options.baBehav[ADDSET_WA_EDGEDETECTTHR2]); 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], options.baBehav[ADDSET_DIRPYRDN_PASSES]); bayerpreprocess->setAdjusterBehavior (options.baBehav[ADDSET_PREPROCESS_LINEDENOISE], options.baBehav[ADDSET_PREPROCESS_GREENEQUIL]); rawcacorrection->setAdjusterBehavior (options.baBehav[ADDSET_RAWCACORR]); @@ -304,6 +304,7 @@ void BatchToolPanelCoordinator::initSession () { if (options.baBehav[ADDSET_WA_EDGRAD]) pparams.wavelet.edgrad = 0; if (options.baBehav[ADDSET_WA_EDGVAL]) pparams.wavelet.edgval = 0; if (options.baBehav[ADDSET_WA_STRENGTH]) pparams.wavelet.strength = 0; + if (options.baBehav[ADDSET_WA_EDGEDETECT]) pparams.wavelet.edgedetect = 0; if (options.baBehav[ADDSET_DIRPYRDN_LUMA]) pparams.dirpyrDenoise.luma = 0; diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc index b360a2b84..0e8bdb10d 100644 --- a/rtgui/dirpyrequalizer.cc +++ b/rtgui/dirpyrequalizer.cc @@ -109,7 +109,7 @@ DirPyrEqualizer::DirPyrEqualizer () : FoldableToolPanel(this, "dirpyrequalizer", hueskin->setBgGradient(milestones); pack_start(*hueskin); - gamutlab = Gtk::manage (new Gtk::CheckButton (M("TP_DIRPYREQUALIZER_GAMUT"))); + gamutlab = Gtk::manage (new Gtk::CheckButton (M("TP_DIRPYREQUALIZER_ARTIF"))); gamutlab->set_active (true); pack_start(*gamutlab); gamutlabConn = gamutlab->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrEqualizer::gamutlabToggled) ); diff --git a/rtgui/editid.h b/rtgui/editid.h index a1c43201a..35308f5fa 100644 --- a/rtgui/editid.h +++ b/rtgui/editid.h @@ -44,6 +44,8 @@ enum EditUniqueID { EUID_BlackWhiteLuminance, EUID_BlackWhiteBeforeCurve, EUID_BlackWhiteAfterCurve, + EUID_WW_HHCurve, + }; /// @brief Editing mechanisms diff --git a/rtgui/options.cc b/rtgui/options.cc index 375a282d6..0f677bf1a 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -535,6 +535,9 @@ void Options::setDefaults () { 0, //ADDSET_WA_EDGRAD 0, //ADDSET_WA_EDGVAL 0, //ADDSET_WA_STRENGTH + 0, //ADDSET_WA_EDGEDETECT + 0, //ADDSET_WA_EDGEDETECTTHR + 0, //ADDSET_WA_EDGEDETECTTHR2 }; baBehav = std::vector (babehav, babehav+ADDSET_PARAM_NUM); @@ -580,6 +583,16 @@ void Options::setDefaults () { rtSettings.artifact_cbdl = 4.; rtSettings.level0_cbdl = 0; rtSettings.level123_cbdl = 30; + rtSettings.bot_left=0; + rtSettings.top_left=10; + rtSettings.top_right=40; + rtSettings.bot_right=75; + rtSettings.ed_detec=3;//between 2 and 10 + rtSettings.ed_detecStr=1.3;//not use + rtSettings.ed_low=15.;//between 5 to 40 + rtSettings.ed_lipinfl=0.8;//between 0.5 to 0.9 + rtSettings.ed_lipampl=1.1;//between 1 and 2 + rtSettings.ciecamfloat = true; rtSettings.protectred = 60; @@ -670,6 +683,17 @@ if (keyFile.has_group ("General")) { if( keyFile.has_key ("General", "DarkFramesPath")) rtSettings.darkFramesPath = keyFile.get_string("General", "DarkFramesPath"); if( keyFile.has_key ("General", "FlatFieldsPath")) rtSettings.flatFieldsPath = keyFile.get_string("General", "FlatFieldsPath"); if( keyFile.has_key ("General", "Verbose")) rtSettings.verbose = keyFile.get_boolean ( "General", "Verbose"); + if (keyFile.has_key ("General", "BotLeft")) rtSettings.bot_left = keyFile.get_double("General", "BotLeft"); + if (keyFile.has_key ("General", "TopLeft")) rtSettings.top_left = keyFile.get_double("General", "TopLeft"); + if (keyFile.has_key ("General", "TopRight")) rtSettings.top_right = keyFile.get_double("General", "TopRight"); + if (keyFile.has_key ("General", "BotRight")) rtSettings.bot_right = keyFile.get_double("General", "BotRight"); + if (keyFile.has_key ("General", "EDdetec")) rtSettings.ed_detec = keyFile.get_double("General", "EDdetec"); + if (keyFile.has_key ("General", "EDdetecStr")) rtSettings.ed_detecStr = keyFile.get_double("General", "EDdetecStr"); + if (keyFile.has_key ("General", "EDLow")) rtSettings.ed_low = keyFile.get_double("General", "EDLow"); + if (keyFile.has_key ("General", "EDLipinfl")) rtSettings.ed_lipinfl = keyFile.get_double("General", "EDLipinfl"); + if (keyFile.has_key ("General", "EDLipampl")) rtSettings.ed_lipampl = keyFile.get_double("General", "EDLipampl"); + + } if (keyFile.has_group ("External Editor")) { @@ -1009,7 +1033,17 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_string ("General", "DarkFramesPath", rtSettings.darkFramesPath); keyFile.set_string ("General", "FlatFieldsPath", rtSettings.flatFieldsPath); keyFile.set_boolean ("General", "Verbose", rtSettings.verbose); + keyFile.set_double ("General", "BotLeft", rtSettings.bot_left); + keyFile.set_double ("General", "TopLeft", rtSettings.top_left); + keyFile.set_double ("General", "TopRight", rtSettings.top_right); + keyFile.set_double ("General", "BotRight", rtSettings.bot_right); + keyFile.set_double ("General", "EDdetec", rtSettings.ed_detec); + keyFile.set_double ("General", "EDdetecStr", rtSettings.ed_detecStr); + keyFile.set_double ("General", "EDLow", rtSettings.ed_low); + keyFile.set_double ("General", "EDLipinfl", rtSettings.ed_lipinfl); + keyFile.set_double ("General", "EDLipampl", rtSettings.ed_lipampl); + keyFile.set_integer ("External Editor", "EditorKind", editorToSendTo); keyFile.set_string ("External Editor", "GimpDir", gimpDir); keyFile.set_string ("External Editor", "PhotoshopDir", psDir); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 4f7618cca..f47a78819 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -338,11 +338,19 @@ void ParamsEdited::set (bool v) { wavelet.enabled = v; wavelet.strength = v; wavelet.median = v; + wavelet.medianlev = v; + wavelet.linkedg = v; + wavelet.lipst = v; + wavelet.Medgreinf = v; wavelet.avoid = v; wavelet.Lmethod = v; wavelet.CLmethod = v; + wavelet.Backmethod = v; wavelet.Tilesmethod = v; + wavelet.choicemethod = v; wavelet.CHmethod = v; + wavelet.CHSLmethod = v; + wavelet.EDmethod = v; wavelet.HSmethod = v; wavelet.Dirmethod = v; wavelet.rescon = v; @@ -353,6 +361,9 @@ void ParamsEdited::set (bool v) { wavelet.thres = v; wavelet.threshold = v; wavelet.threshold2 = v; + wavelet.edgedetect = v; + wavelet.edgedetectthr = v; + wavelet.edgedetectthr2 = v; wavelet.chroma = v; wavelet.chro = v; wavelet.contrast = v; @@ -366,15 +377,24 @@ void ParamsEdited::set (bool v) { wavelet.hueskin2 = v; wavelet.hllev = v; wavelet.bllev = v; - wavelet.clvcurve = v; + wavelet.edgcont = v; + wavelet.level0noise = v; + wavelet.level1noise = v; + wavelet.level2noise = v; + wavelet.ccwcurve = v; wavelet.opacityCurveRG = v; wavelet.opacityCurveBY = v; + wavelet.hhcurve = v; + wavelet.Chcurve = v; wavelet.pastlev = v; wavelet.satlev = v; for(int i = 0; i < 9; i++) { wavelet.c[i] = v; } + for(int i = 0; i < 9; i++) { + wavelet.ch[i] = v; + } dirpyrequalizer.enabled = v; dirpyrequalizer.gamutlab = v; @@ -716,11 +736,19 @@ void ParamsEdited::initFrom (const std::vector wavelet.enabled = wavelet.enabled && p.wavelet.enabled == other.wavelet.enabled; wavelet.strength = wavelet.strength && p.wavelet.strength == other.wavelet.strength; wavelet.median = wavelet.median && p.wavelet.median == other.wavelet.median; + wavelet.medianlev = wavelet.medianlev && p.wavelet.medianlev == other.wavelet.medianlev; + wavelet.linkedg = wavelet.linkedg && p.wavelet.linkedg == other.wavelet.linkedg; + wavelet.lipst = wavelet.lipst && p.wavelet.lipst == other.wavelet.lipst; + wavelet.Medgreinf = wavelet.Medgreinf && p.wavelet.Medgreinf == other.wavelet.Medgreinf; wavelet.avoid = wavelet.avoid && p.wavelet.avoid == other.wavelet.avoid; wavelet.Lmethod = wavelet.Lmethod && p.wavelet.Lmethod == other.wavelet.Lmethod; wavelet.CLmethod = wavelet.CLmethod && p.wavelet.CLmethod == other.wavelet.CLmethod; + wavelet.Backmethod = wavelet.Backmethod && p.wavelet.Backmethod == other.wavelet.Backmethod; wavelet.Tilesmethod = wavelet.Tilesmethod && p.wavelet.Tilesmethod == other.wavelet.Tilesmethod; + wavelet.choicemethod = wavelet.choicemethod && p.wavelet.choicemethod == other.wavelet.choicemethod; wavelet.CHmethod = wavelet.CHmethod && p.wavelet.CHmethod == other.wavelet.CHmethod; + wavelet.CHSLmethod = wavelet.CHSLmethod && p.wavelet.CHSLmethod == other.wavelet.CHSLmethod; + wavelet.EDmethod = wavelet.EDmethod && p.wavelet.EDmethod == other.wavelet.EDmethod; wavelet.HSmethod = wavelet.HSmethod && p.wavelet.HSmethod == other.wavelet.HSmethod; wavelet.Dirmethod = wavelet.Dirmethod && p.wavelet.Dirmethod == other.wavelet.Dirmethod; wavelet.rescon = wavelet.rescon && p.wavelet.rescon == other.wavelet.rescon; @@ -730,6 +758,9 @@ void ParamsEdited::initFrom (const std::vector wavelet.sky = wavelet.sky && p.wavelet.sky == other.wavelet.sky; wavelet.threshold = wavelet.threshold && p.wavelet.threshold == other.wavelet.threshold; wavelet.threshold2 = wavelet.threshold2 && p.wavelet.threshold2 == other.wavelet.threshold2; + wavelet.edgedetect = wavelet.edgedetect && p.wavelet.edgedetect == other.wavelet.edgedetect; + wavelet.edgedetectthr = wavelet.edgedetectthr && p.wavelet.edgedetectthr == other.wavelet.edgedetectthr; + wavelet.edgedetectthr2 = wavelet.edgedetectthr2 && p.wavelet.edgedetectthr2 == other.wavelet.edgedetectthr2; wavelet.thres = wavelet.thres && p.wavelet.thres == other.wavelet.thres; wavelet.chroma = wavelet.chroma && p.wavelet.chroma == other.wavelet.chroma; wavelet.chro = wavelet.chro && p.wavelet.chro == other.wavelet.chro; @@ -743,15 +774,24 @@ void ParamsEdited::initFrom (const std::vector wavelet.hueskin2 = wavelet.hueskin2 && p.wavelet.hueskin2 == other.wavelet.hueskin2; wavelet.hllev = wavelet.hllev && p.wavelet.hllev == other.wavelet.hllev; wavelet.bllev = wavelet.bllev && p.wavelet.bllev == other.wavelet.bllev; + wavelet.edgcont = wavelet.edgcont && p.wavelet.edgcont == other.wavelet.edgcont; + wavelet.level0noise = wavelet.level0noise && p.wavelet.level0noise == other.wavelet.level0noise; + wavelet.level1noise = wavelet.level1noise && p.wavelet.level1noise == other.wavelet.level1noise; + wavelet.level2noise = wavelet.level2noise && p.wavelet.level2noise == other.wavelet.level2noise; wavelet.pastlev = wavelet.pastlev && p.wavelet.pastlev == other.wavelet.pastlev; wavelet.satlev = wavelet.satlev && p.wavelet.satlev == other.wavelet.satlev; - wavelet.clvcurve = wavelet.clvcurve && p.wavelet.clvcurve == other.wavelet.clvcurve; + wavelet.ccwcurve = wavelet.ccwcurve && p.wavelet.ccwcurve == other.wavelet.ccwcurve; wavelet.opacityCurveRG = wavelet.opacityCurveRG && p.wavelet.opacityCurveRG == other.wavelet.opacityCurveRG; wavelet.opacityCurveBY = wavelet.opacityCurveBY && p.wavelet.opacityCurveBY == other.wavelet.opacityCurveBY; - wavelet.skinprotect = wavelet.skinprotect && p.wavelet.skinprotect == other.wavelet.skinprotect; + wavelet.hhcurve = wavelet.hhcurve && p.wavelet.hhcurve == other.wavelet.hhcurve; + wavelet.Chcurve = wavelet.Chcurve && p.wavelet.Chcurve == other.wavelet.Chcurve; + wavelet.skinprotect = wavelet.skinprotect && p.wavelet.skinprotect == other.wavelet.skinprotect; for(int i = 0; i < 9; i++) { wavelet.c[i] = wavelet.c[i] && p.wavelet.c[i] == other.wavelet.c[i]; } + for(int i = 0; i < 9; i++) { + wavelet.ch[i] = wavelet.ch[i] && p.wavelet.ch[i] == other.wavelet.ch[i]; + } dirpyrequalizer.enabled = dirpyrequalizer.enabled && p.dirpyrequalizer.enabled == other.dirpyrequalizer.enabled; dirpyrequalizer.gamutlab = dirpyrequalizer.gamutlab && p.dirpyrequalizer.gamutlab == other.dirpyrequalizer.gamutlab; @@ -1099,11 +1139,19 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (wavelet.enabled) toEdit.wavelet.enabled = mods.wavelet.enabled; if (wavelet.strength) toEdit.wavelet.strength = mods.wavelet.strength; if (wavelet.median) toEdit.wavelet.median = mods.wavelet.median; + if (wavelet.medianlev) toEdit.wavelet.medianlev = mods.wavelet.medianlev; + if (wavelet.linkedg) toEdit.wavelet.linkedg = mods.wavelet.linkedg; + if (wavelet.lipst) toEdit.wavelet.lipst = mods.wavelet.lipst; + if (wavelet.Medgreinf) toEdit.wavelet.Medgreinf = mods.wavelet.Medgreinf; if (wavelet.avoid) toEdit.wavelet.avoid = mods.wavelet.avoid; if (wavelet.Lmethod) toEdit.wavelet.Lmethod = mods.wavelet.Lmethod; if (wavelet.CLmethod) toEdit.wavelet.CLmethod = mods.wavelet.CLmethod; + if (wavelet.Backmethod) toEdit.wavelet.Backmethod = mods.wavelet.Backmethod; if (wavelet.Tilesmethod) toEdit.wavelet.Tilesmethod = mods.wavelet.Tilesmethod; + if (wavelet.choicemethod) toEdit.wavelet.choicemethod = mods.wavelet.choicemethod; if (wavelet.CHmethod) toEdit.wavelet.CHmethod = mods.wavelet.CHmethod; + if (wavelet.CHSLmethod) toEdit.wavelet.CHSLmethod = mods.wavelet.CHSLmethod; + if (wavelet.EDmethod) toEdit.wavelet.EDmethod = mods.wavelet.EDmethod; if (wavelet.HSmethod) toEdit.wavelet.HSmethod = mods.wavelet.HSmethod; if (wavelet.Dirmethod) toEdit.wavelet.Dirmethod = mods.wavelet.Dirmethod; if (wavelet.edgthresh) toEdit.wavelet.edgthresh = mods.wavelet.edgthresh; @@ -1113,14 +1161,23 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (wavelet.sup) toEdit.wavelet.sup = mods.wavelet.sup; if (wavelet.hllev) toEdit.wavelet.hllev = mods.wavelet.hllev; if (wavelet.bllev) toEdit.wavelet.bllev = mods.wavelet.bllev; + if (wavelet.edgcont) toEdit.wavelet.edgcont = mods.wavelet.edgcont; + if (wavelet.level0noise) toEdit.wavelet.level0noise = mods.wavelet.level0noise; + if (wavelet.level1noise) toEdit.wavelet.level1noise = mods.wavelet.level1noise; + if (wavelet.level2noise) toEdit.wavelet.level2noise = mods.wavelet.level2noise; if (wavelet.pastlev) toEdit.wavelet.pastlev = mods.wavelet.pastlev; if (wavelet.satlev) toEdit.wavelet.satlev = mods.wavelet.satlev; - if (wavelet.clvcurve) toEdit.wavelet.clvcurve = mods.wavelet.clvcurve; + if (wavelet.ccwcurve) toEdit.wavelet.ccwcurve = mods.wavelet.ccwcurve; if (wavelet.opacityCurveRG) toEdit.wavelet.opacityCurveRG = mods.wavelet.opacityCurveRG; if (wavelet.opacityCurveBY) toEdit.wavelet.opacityCurveBY = mods.wavelet.opacityCurveBY; + if (wavelet.hhcurve) toEdit.wavelet.hhcurve = mods.wavelet.hhcurve; + if (wavelet.Chcurve) toEdit.wavelet.Chcurve = mods.wavelet.Chcurve; for(int i = 0; i < 9; i++) { if(wavelet.c[i]) toEdit.wavelet.c[i] = dontforceSet && options.baBehav[ADDSET_WA] ? toEdit.wavelet.c[i] + mods.wavelet.c[i] : mods.wavelet.c[i]; } + for(int i = 0; i < 9; i++) { + if(wavelet.ch[i]) toEdit.wavelet.ch[i] = dontforceSet && options.baBehav[ADDSET_WA] ? toEdit.wavelet.ch[i] + mods.wavelet.ch[i] : mods.wavelet.ch[i]; + } if (wavelet.skinprotect)toEdit.wavelet.skinprotect= dontforceSet && options.baBehav[ADDSET_WA_SKINPROTECT] ? toEdit.wavelet.skinprotect + mods.wavelet.skinprotect : mods.wavelet.skinprotect; if (wavelet.hueskin) toEdit.wavelet.hueskin = mods.wavelet.hueskin; if (wavelet.hueskin2) toEdit.wavelet.hueskin2 = mods.wavelet.hueskin2; @@ -1130,6 +1187,9 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (wavelet.thres)toEdit.wavelet.thres= dontforceSet && options.baBehav[ADDSET_WA_THRES] ? toEdit.wavelet.thres + mods.wavelet.thres : mods.wavelet.thres; if (wavelet.threshold)toEdit.wavelet.threshold= dontforceSet && options.baBehav[ADDSET_WA_THRESHOLD] ? toEdit.wavelet.threshold + mods.wavelet.threshold : mods.wavelet.threshold; if (wavelet.threshold2)toEdit.wavelet.threshold2= dontforceSet && options.baBehav[ADDSET_WA_THRESHOLD2] ? toEdit.wavelet.threshold2 + mods.wavelet.threshold2 : mods.wavelet.threshold2; + if (wavelet.edgedetect)toEdit.wavelet.edgedetect= dontforceSet && options.baBehav[ADDSET_WA_EDGEDETECT] ? toEdit.wavelet.edgedetect + mods.wavelet.edgedetect : mods.wavelet.edgedetect; + if (wavelet.edgedetectthr)toEdit.wavelet.edgedetectthr= dontforceSet && options.baBehav[ADDSET_WA_EDGEDETECTTHR] ? toEdit.wavelet.edgedetectthr + mods.wavelet.edgedetectthr : mods.wavelet.edgedetectthr; + if (wavelet.edgedetectthr2)toEdit.wavelet.edgedetectthr2= dontforceSet && options.baBehav[ADDSET_WA_EDGEDETECTTHR2] ? toEdit.wavelet.edgedetectthr2 + mods.wavelet.edgedetectthr2 : mods.wavelet.edgedetectthr2; if (wavelet.chro)toEdit.wavelet.chro= dontforceSet && options.baBehav[ADDSET_WA_CHRO] ? toEdit.wavelet.chro + mods.wavelet.chro : mods.wavelet.chro; if (wavelet.chroma)toEdit.wavelet.chroma= dontforceSet && options.baBehav[ADDSET_WA_CHROMA] ? toEdit.wavelet.chroma + mods.wavelet.chroma : mods.wavelet.chroma; if (wavelet.contrast)toEdit.wavelet.contrast= dontforceSet && options.baBehav[ADDSET_WA_CONTRAST] ? toEdit.wavelet.contrast + mods.wavelet.contrast : mods.wavelet.contrast; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 3d8fc3121..8b1b9dbc5 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -478,13 +478,22 @@ class WaveletParamsEdited { bool enabled; bool strength; bool median; + bool medianlev; + bool linkedg; + bool lipst; + bool Medgreinf; bool avoid; bool c[9]; + bool ch[9]; bool Lmethod; bool CHmethod; + bool CHSLmethod; + bool EDmethod; bool HSmethod; bool CLmethod; + bool Backmethod; bool Tilesmethod; + bool choicemethod; bool Dirmethod; bool rescon; bool resconH; @@ -494,8 +503,11 @@ class WaveletParamsEdited { bool thres; bool threshold; bool threshold2; - bool chroma; + bool edgedetect; + bool edgedetectthr; + bool edgedetectthr2; bool chro; + bool chroma; bool contrast; bool edgrad; bool edgval; @@ -507,9 +519,15 @@ class WaveletParamsEdited { bool hueskin2; bool hllev; bool bllev; - bool clvcurve; + bool edgcont; + bool level0noise; + bool level1noise; + bool level2noise; + bool ccwcurve; bool opacityCurveBY; bool opacityCurveRG; + bool hhcurve; + bool Chcurve; bool pastlev; bool satlev; }; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 4a55c3759..e44efd588 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -301,7 +301,7 @@ Gtk::Widget* Preferences::getBatchProcPanel () { mi = behModel->append (); mi->set_value (behavColumns.label, M("TP_WAVELET_LABEL")); - appendBehavList (mi, M("TP_WAVELET_THRES"), ADDSET_WA_THRES, true); + appendBehavList (mi, M("TP_WAVELET_LEVELS"), ADDSET_WA_THRES, true); // appendBehavList (mi, M("TP_WAVELET_CONTRAST"), ADDSET_WA, true); appendBehavList (mi, M("TP_WAVELET_THRESHOLD"), ADDSET_WA_THRESHOLD, true); appendBehavList (mi, M("TP_WAVELET_THRESHOLD2"), ADDSET_WA_THRESHOLD2, true); @@ -318,6 +318,9 @@ Gtk::Widget* Preferences::getBatchProcPanel () { appendBehavList (mi, M("TP_WAVELET_SKY"), ADDSET_WA_SKYPROTECT, true); appendBehavList (mi, M("TP_WAVELET_CONTRA"), ADDSET_WA_CONTRAST, true); appendBehavList (mi, M("TP_WAVELET_STRENGTH"), ADDSET_WA_STRENGTH, true); + appendBehavList (mi, M("TP_WAVELET_EDGEDETECT"), ADDSET_WA_EDGEDETECT, true); + appendBehavList (mi, M("TP_WAVELET_EDGEDETECTTHR"), ADDSET_WA_EDGEDETECTTHR, true); + appendBehavList (mi, M("TP_WAVELET_EDGEDETECTTHR2"), ADDSET_WA_EDGEDETECTTHR2, true); mi = behModel->append (); mi->set_value (behavColumns.label, M("TP_PREPROCESS_LABEL")); @@ -649,7 +652,7 @@ Gtk::Widget* Preferences::getPerformancePanel () { // <--- To be hard-coded and removed once tested cbdaubech = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_DAUB_LABEL"), Gtk::ALIGN_LEFT)); cbdaubech->set_tooltip_markup (M("PREFERENCES_DAUB_TOOLTIP")); - vbdenoise->pack_start (*cbdaubech, Gtk::PACK_SHRINK); + // vbdenoise->pack_start (*cbdaubech, Gtk::PACK_SHRINK); // ---> fdenoise->add (*vbdenoise); mainContainer->pack_start (*fdenoise, Gtk::PACK_SHRINK, 4); diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 1f8a82e07..4f90eb5d0 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -54,7 +54,7 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), milestones2.push_back( GradientMilestone(1.0, 1.0, 1.0, 1.0) ); std::vector defaultCurve; - + // frame and expand dispFrame = Gtk::manage (new Gtk::Frame () ); expdisplay = Gtk::manage (new Gtk::Expander (M("TP_WAVELET_DISP"))); @@ -92,6 +92,13 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), hbtoning->pack_start(*tbtoning); tbtoning->signal_toggled().connect( sigc::mem_fun(this, &Wavelet::exptoningTog)); + noiseFrame = Gtk::manage (new Gtk::Frame () ); + expnoise = Gtk::manage (new Gtk::Expander (M("TP_WAVELET_NOISE"))); + Gtk::HBox* hbnoise = Gtk::manage( new Gtk::HBox()); + tbnoise = Gtk::manage( new Gtk::ToggleButton()); + noiseFrame->add(*expnoise); + hbnoise->set_spacing(8); + hbnoise->pack_start(*tbnoise); edgeFrame = Gtk::manage (new Gtk::Frame () ); expedge = Gtk::manage (new Gtk::Expander (M("TP_WAVELET_EDGE"))); @@ -140,10 +147,11 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), strength = Gtk::manage (new Adjuster (M("TP_WAVELET_STRENGTH"), 0, 100, 1, 100)); strength->setAdjusterListener (this); - thres = Gtk::manage (new Adjuster (M("TP_WAVELET_LEVELS"), 4, 9, 1, 7)); + thres = Gtk::manage (new Adjuster (M("TP_WAVELET_LEVELS"), 3, 9, 1, 7)); thres->set_tooltip_text (M("TP_WAVELET_LEVELS_TOOLTIP")); thres->setAdjusterListener (this); + tilesizeHBox = Gtk::manage (new Gtk::HBox()); tilesizeLabel = Gtk::manage (new Gtk::Label (M("TP_WAVELET_TILESIZE") + ":")); Tilesmethod = Gtk::manage (new MyComboBoxText ()); @@ -155,9 +163,25 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), tilesizeHBox->pack_start(*tilesizeLabel, Gtk::PACK_SHRINK, 4); tilesizeHBox->pack_start(*Tilesmethod); + choiceHBox = Gtk::manage (new Gtk::HBox()); + choiceLabel = Gtk::manage (new Gtk::Label (M("TP_WAVELET_DAUB") + ":")); + choicemethod = Gtk::manage (new MyComboBoxText ()); + choicemethod->set_sensitive(true); + choicemethod->append_text (M("TP_WAVELET_daub2")); + choicemethod->append_text (M("TP_WAVELET_daub4")); + choicemethod->append_text (M("TP_WAVELET_daub6")); + choicemethod->append_text (M("TP_WAVELET_daub10")); + choicemethod->append_text (M("TP_WAVELET_daub14")); + choicemethodconn = choicemethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::choicemethodChanged) ); + choicemethod->set_tooltip_text (M("TP_WAVELET_DAUB_TOOLTIP")); + choiceHBox->pack_start(*choiceLabel, Gtk::PACK_SHRINK, 4); + choiceHBox->pack_start(*choicemethod); + + settingsVBox->pack_start(*strength); settingsVBox->pack_start(*thres); settingsVBox->pack_start(*tilesizeHBox); + settingsVBox->pack_start(*choiceHBox); settingsFrame->add(*settingsVBox); pack_start (*settingsFrame, Gtk::PACK_EXPAND_WIDGET, 4); @@ -165,6 +189,17 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), Gtk::VBox * diBox = Gtk::manage (new Gtk::VBox()); diBox->set_border_width(4); diBox->set_spacing(2); + + previewBackHBox = Gtk::manage (new Gtk::HBox()); + previewBackLabel = Gtk::manage (new Gtk::Label (M("TP_WAVELET_PREVIEWBACK") + ":")); + previewBackHBox->pack_start(*previewBackLabel, Gtk::PACK_SHRINK, 4); + Backmethod = Gtk::manage (new MyComboBoxText ()); + Backmethod->append_text (M("TP_WAVELET_B0")); + Backmethod->append_text (M("TP_WAVELET_B1")); + Backmethod->append_text (M("TP_WAVELET_B2")); + Backmethodconn = Backmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::BackmethodChanged) ); + previewBackHBox->pack_start(*Backmethod); + previewLevelsHBox = Gtk::manage (new Gtk::HBox()); previewLevelsLabel = Gtk::manage (new Gtk::Label (M("TP_WAVELET_PREVIEWLEVELS") + ":")); @@ -180,6 +215,7 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), previewLDirHBox = Gtk::manage (new Gtk::HBox()); Lmethod = Gtk::manage (new MyComboBoxText ()); + Lmethod->set_sensitive(false); Lmethod->set_sensitive(false); Lmethod->append_text (M("TP_WAVELET_1")); Lmethod->append_text (M("TP_WAVELET_2")); @@ -207,62 +243,8 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), previewLDirHBox->pack_start(*Dirmethod); diBox->pack_start (*previewLDirHBox, Gtk::PACK_EXPAND_WIDGET, 0); + diBox->pack_start (*previewBackHBox); - // residual image - Gtk::VBox * resBox = Gtk::manage (new Gtk::VBox()); - resBox->set_border_width(4); - resBox->set_spacing(2); - - rescon = Gtk::manage (new Adjuster (M("TP_WAVELET_RESCON"), -100, 100, 1, 0)); - resBox->pack_start(*rescon, Gtk::PACK_SHRINK); - rescon->setAdjusterListener (this); - - thr = Gtk::manage (new Adjuster (M("TP_WAVELET_THR"), 0, 100, 1, 30)); - resBox->pack_start(*thr); - - thr->setAdjusterListener (this); - - resconH = Gtk::manage (new Adjuster (M("TP_WAVELET_RESCONH"), -100, 100, 1, 0)); - resBox->pack_start(*resconH, Gtk::PACK_SHRINK); - - resconH->setAdjusterListener (this); - - thrH = Gtk::manage (new Adjuster (M("TP_WAVELET_THRH"), 0, 100, 1, 70)); - resBox->pack_start(*thrH,Gtk::PACK_SHRINK); - - thrH->setAdjusterListener (this); - - - contrast = Gtk::manage (new Adjuster (M("TP_WAVELET_CONTRA"), -100, 100, 1, 0)); - contrast->set_tooltip_text (M("TP_WAVELET_CONTRA_TOOLTIP")); - - resBox->pack_start(*contrast); //keep the possibility to reinstall - contrast->setAdjusterListener (this); - - reschro = Gtk::manage (new Adjuster (M("TP_WAVELET_RESCHRO"), -100, 100, 1, 0)); - - resBox->pack_start(*reschro); - reschro->setAdjusterListener (this); - - - hueskin2 = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_HUESKY"), -314., 314., -260., -250, -130., -140., 0, false)); - hueskin2->set_tooltip_markup (M("TP_WAVELET_HUESKY_TOOLTIP")); - - hueskin2->setBgGradient(milestones); - resBox->pack_start(*hueskin2); - - hueskin2->setAdjusterListener (this); - - sky = Gtk::manage (new Adjuster (M("TP_WAVELET_SKY"), -100., 100.0, 1., 0.)); - sky->set_tooltip_text (M("TP_WAVELET_SKY_TOOLTIP")); - sky->setAdjusterListener (this); - - resBox->pack_start(*sky); - //*************************************************** - - // Gtk::HSeparator *separator1 = Gtk::manage (new Gtk::HSeparator()); - //pack_start(*separator1, Gtk::PACK_SHRINK, 2); - //levels contrast******************************** Gtk::VBox * levBox = Gtk::manage (new Gtk::VBox()); @@ -292,10 +274,6 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), Gtk::HSeparator *separator2 = Gtk::manage (new Gtk::HSeparator()); levBox->pack_start(*separator2, Gtk::PACK_SHRINK, 2); - - - // Gtk::HSeparator *separatorU = Gtk::manage (new Gtk::HSeparator()); -// levBox->pack_start(*separatorU, Gtk::PACK_SHRINK, 2); for(int i = 0; i < 9; i++) { @@ -362,13 +340,33 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), Gtk::VBox * chBox = Gtk::manage (new Gtk::VBox()); chBox->set_border_width(4); chBox->set_spacing(2); + + ctboxch = Gtk::manage (new Gtk::HBox ()); + labmch = Gtk::manage (new Gtk::Label (M("TP_WAVELET_CHTYPE")+":")); + ctboxch->pack_start (*labmch, Gtk::PACK_SHRINK, 1); CHmethod = Gtk::manage (new MyComboBoxText ()); CHmethod->append_text (M("TP_WAVELET_CH1")); CHmethod->append_text (M("TP_WAVELET_CH2")); CHmethod->append_text (M("TP_WAVELET_CH3")); CHmethodconn = CHmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::CHmethodChanged) ); - chBox->pack_start(*CHmethod); + ctboxch->pack_start(*CHmethod); + chBox->pack_start(*ctboxch); + + ctboxCH = Gtk::manage (new Gtk::HBox ()); + labmC = Gtk::manage (new Gtk::Label (M("TP_WAVELET_CTYPE")+":")); + ctboxCH->pack_start (*labmC, Gtk::PACK_SHRINK, 1); + + CHSLmethod = Gtk::manage (new MyComboBoxText ()); + CHSLmethod->append_text (M("TP_WAVELET_CHSL")); + CHSLmethod->append_text (M("TP_WAVELET_CHCU")); + CHSLmethodconn = CHSLmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::CHSLmethodChanged) ); + ctboxCH->pack_start(*CHSLmethod); + +// chBox->pack_start (*ctboxCH); + + Gtk::HSeparator *separator22 = Gtk::manage (new Gtk::HSeparator()); + chBox->pack_start(*separator22, Gtk::PACK_SHRINK, 2); chroma = Gtk::manage (new Adjuster (M("TP_WAVELET_CHRO"), 1, 9, 1, 5)); chroma->set_tooltip_text (M("TP_WAVELET_CHRO_TOOLTIP")); @@ -390,20 +388,42 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), chBox->pack_start(*chro); chro->setAdjusterListener (this); - //Chroma curve levels******************************** - CLVcurveEditorG = new CurveEditorGroup (options.lastWaveletCurvesDir, M("TP_WAVELET_CLVCURVE")); - CLVcurveEditorG->setCurveListener (this); - rtengine::WaveletParams::getDefaultCLVCurve(defaultCurve); - ccshape = static_cast(CLVcurveEditorG->addCurve(CT_Flat, "", NULL, false)); - ccshape->setIdentityValue(0.); - ccshape->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); - ccshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CLV_TOOLTIP")); -// ccshape->setBottomBarColorProvider(this, 2); + //Chroma curve and sliders levels******************************** + + + Gtk::HBox * buttonchBox = Gtk::manage (new Gtk::HBox()); + wavLabelsch = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); + + chBox->pack_start(*buttonchBox, Gtk::PACK_SHRINK, 2); - CLVcurveEditorG->curveListComplete(); - chBox->pack_start(*CLVcurveEditorG, Gtk::PACK_SHRINK, 4); + neutralchButton = Gtk::manage (new Gtk::Button(M("TP_WAVELET_NEUTRAL"))); + buttonchBox->pack_start(*neutralchButton, Gtk::PACK_SHRINK, 2); + neutralchPressedConn = neutralchButton->signal_pressed().connect( sigc::mem_fun(*this, &Wavelet::neutralchPressed)); + + buttonchBox->show_all_children(); + separator3 = Gtk::manage (new Gtk::HSeparator()); + chBox->pack_start(*separator3, Gtk::PACK_SHRINK, 2); + for(int i = 0; i < 9; i++) + { + Glib::ustring ss; + switch( i ){ + case 0: + ss =Glib::ustring::compose( "%1 (%2)",(i+1), M("TP_WAVELET_FINEST"));break; + case 8: + ss =Glib::ustring::compose( "%1 (%2)",(i+1), M("TP_WAVELET_LARGEST"));break; + default: + ss =Glib::ustring::compose( "%1",(i+1)); + } + + correctionch[i] = Gtk::manage ( new Adjuster (ss, -100, 100, 1, 0) ); + correctionch[i]->setAdjusterListener(this); + chBox->pack_start(*correctionch[i]); + } + + + //----------- Color Opacity curve RG ------------------------------ Gtk::VBox * tonBox = Gtk::manage (new Gtk::VBox()); tonBox->set_border_width(4); @@ -411,14 +431,12 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), opaCurveEditorG = new CurveEditorGroup (options.lastWaveletCurvesDir, M("TP_WAVELET_COLORT")); opaCurveEditorG->setCurveListener (this); - std::vector defaultCCurve; - rtengine::WaveletParams::getDefaultOpacityCurveRG(defaultCCurve); + rtengine::WaveletParams::getDefaultOpacityCurveRG(defaultCurve); opacityShapeRG = static_cast(opaCurveEditorG->addCurve(CT_Flat, "", NULL, false)); opacityShapeRG->setIdentityValue(0.); - opacityShapeRG->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCCurve); + opacityShapeRG->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); - // This will add the reset button at the end of the curveType buttons opaCurveEditorG->curveListComplete(); opaCurveEditorG->show(); @@ -429,42 +447,169 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), opacityCurveEditorG = new CurveEditorGroup (options.lastWaveletCurvesDir, M("TP_WAVELET_OPACITY")); opacityCurveEditorG->setCurveListener (this); - std::vector defaultCCBurve; - rtengine::WaveletParams::getDefaultOpacityCurveBY(defaultCCBurve); + rtengine::WaveletParams::getDefaultOpacityCurveBY(defaultCurve); opacityShapeBY = static_cast(opacityCurveEditorG->addCurve(CT_Flat, "", NULL, false)); opacityShapeBY->setIdentityValue(0.); - opacityShapeBY->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCCBurve); -// opacityShape->setBottomBarBgGradient(milestones); -// milestones.push_back( GradientMilestone(1., 1., 1., 0.) ); -// milestones.push_back( GradientMilestone(0., 0., 0., 1.) ); -// opacityShapeBY->setLeftBarBgGradient(milestones); + opacityShapeBY->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); - // This will add the reset button at the end of the curveType buttons opacityCurveEditorG->curveListComplete(); opacityCurveEditorG->show(); tonBox->pack_start( *opacityCurveEditorG, Gtk::PACK_SHRINK, 2); + + //----------------Noise + Gtk::VBox * noiseBox = Gtk::manage (new Gtk::VBox()); + noiseBox->set_border_width(4); + noiseBox->set_spacing(2); + linkedg = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_LINKEDG"))); + linkedg->set_active (true); + linkedgConn = linkedg->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::linkedgToggled) ); + noiseBox->pack_start(*linkedg); + + + /*ednoisbox = Gtk::manage (new Gtk::HBox ()); + labmednois = Gtk::manage (new Gtk::Label (M("TP_WAVELET_NOISE")+":")); + ednoisbox->pack_start (*labmednois, Gtk::PACK_SHRINK, 1); + */ + level0noise = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_LEVZERO"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., NULL, false)); + level0noise->setAdjusterListener (this); + level0noise->setUpdatePolicy(RTUP_DYNAMIC); + + level1noise = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_LEVONE"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., NULL, false)); + level1noise->setAdjusterListener (this); + level1noise->setUpdatePolicy(RTUP_DYNAMIC); + + level2noise = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_LEVTWO"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., NULL, false)); + level2noise->setAdjusterListener (this); + level2noise->setUpdatePolicy(RTUP_DYNAMIC); + + // Gtk::HSeparator *separatored = Gtk::manage (new Gtk::HSeparator()); + // noiseBox->pack_start(*separatored, Gtk::PACK_SHRINK, 2); + + //noiseBox->pack_start (*ednoisbox); + noiseBox->pack_start( *level0noise, Gtk::PACK_SHRINK, 0); + + noiseBox->pack_start( *level1noise, Gtk::PACK_SHRINK, 0); + + noiseBox->pack_start( *level2noise, Gtk::PACK_SHRINK, 0); + //----------- Edge------------------------------ Gtk::VBox * edgBox = Gtk::manage (new Gtk::VBox()); edgBox->set_border_width(4); edgBox->set_spacing(2); - - edgrad = Gtk::manage ( new Adjuster (M("TP_WAVELET_EDRAD"), 0, 100, 1, 15) ); - edgrad->setAdjusterListener(this); - edgBox->pack_start(*edgrad); - //->set_tooltip_markup (M("TP_WAVELET_SKIN_TOOLTIP")); + edgval = Gtk::manage ( new Adjuster (M("TP_WAVELET_EDVAL"), 0, 100, 1, 0) ); edgval->setAdjusterListener(this); edgBox->pack_start(*edgval); - //not use - edgthresh = Gtk::manage (new Adjuster (M("TP_WAVELET_EDGTHRESH"), 0, 100, 1, 10 )); - edgthresh->setAdjusterListener (this); + edgrad = Gtk::manage ( new Adjuster (M("TP_WAVELET_EDRAD"), 0, 100, 1, 15) ); + edgrad->setAdjusterListener(this); + edgBox->pack_start(*edgrad); + edgrad->set_tooltip_markup (M("TP_WAVELET_EDRAD_TOOLTIP")); + + // + edgthresh = Gtk::manage (new Adjuster (M("TP_WAVELET_EDGTHRESH"), -50, 100, 1, 10 )); + edgthresh->setAdjusterListener (this); + edgthresh->set_tooltip_markup (M("TP_WAVELET_EDGTHRESH_TOOLTIP")); edgBox->pack_start (*edgthresh); + edbox = Gtk::manage (new Gtk::HBox ()); + labmedgr = Gtk::manage (new Gtk::Label (M("TP_WAVELET_MEDGREINF")+":")); + edbox->pack_start (*labmedgr, Gtk::PACK_SHRINK, 1); + + Medgreinf = Gtk::manage (new MyComboBoxText ()); + Medgreinf->append_text (M("TP_WAVELET_RE1")); + Medgreinf->append_text (M("TP_WAVELET_RE2")); + Medgreinf->append_text (M("TP_WAVELET_RE3")); + MedgreinfConn = Medgreinf->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::MedgreinfChanged) ); + Medgreinf->set_tooltip_markup (M("TP_WAVELET_EDGREINF_TOOLTIP")); + edbox->pack_start(*Medgreinf); + edgBox->pack_start(*edbox); + + Gtk::HSeparator *separatorlc = Gtk::manage (new Gtk::HSeparator()); + edgBox->pack_start(*separatorlc, Gtk::PACK_SHRINK, 2); + + ctboxED = Gtk::manage (new Gtk::HBox ()); + labmED = Gtk::manage (new Gtk::Label (M("TP_WAVELET_EDTYPE")+":")); + ctboxED->pack_start (*labmED, Gtk::PACK_SHRINK, 1); + + EDmethod = Gtk::manage (new MyComboBoxText ()); + EDmethod->append_text (M("TP_WAVELET_EDSL")); + EDmethod->append_text (M("TP_WAVELET_EDCU")); + EDmethodconn = EDmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::EDmethodChanged) ); + ctboxED->pack_start(*EDmethod); + edgBox->pack_start (*ctboxED); +// edgcont = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_EDGCONT"), 0., 100., 0., 20., 100., 75., 0, false)); + double tr=options.rtSettings.top_right; + double br=options.rtSettings.bot_right; + double tl=options.rtSettings.top_left; + double bl=options.rtSettings.bot_left; + + edgcont = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_EDGCONT"), 0., 100., bl, tl, br, tr, 0., false)); + edgcont->setAdjusterListener (this); + edgcont->setBgGradient(milestones2); + edgcont->set_tooltip_markup (M("TP_WAVELET_EDGCONT_TOOLTIP")); + + + + + //-------------------Curve for Edge + CCWcurveEditorG = new CurveEditorGroup (options.lastWaveletCurvesDir, M("TP_WAVELET_CCURVE")); + CCWcurveEditorG->setCurveListener (this); + + rtengine::WaveletParams::getDefaultCCWCurve(defaultCurve); + ccshape = static_cast(CCWcurveEditorG->addCurve(CT_Flat, "", NULL, false)); + + ccshape->setIdentityValue(0.); + ccshape->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); + ccshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CC_TOOLTIP")); + + CCWcurveEditorG->curveListComplete(); + CCWcurveEditorG->show(); + //---------------- + + edgBox->pack_start (*edgcont); + edgBox->pack_start(*CCWcurveEditorG, Gtk::PACK_SHRINK, 4); + + medianlev = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_MEDILEV"))); + medianlev->set_active (true); + medianlevConn = medianlev->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::medianlevToggled) ); + + Gtk::HSeparator *separatored1 = Gtk::manage (new Gtk::HSeparator()); + edgBox->pack_start(*separatored1, Gtk::PACK_SHRINK, 2); + + eddebox = Gtk::manage (new Gtk::HBox ()); + + edgBox->pack_start (*eddebox); + + edgBox->pack_start(*medianlev); + + edgedetect = Gtk::manage (new Adjuster (M("TP_WAVELET_EDGEDETECT"), 0, 100, 1, 80)); + edgedetect->setAdjusterListener (this); + edgedetect->set_tooltip_text (M("TP_WAVELET_EDGEDETECT_TOOLTIP")); + edgBox->pack_start(*edgedetect); + + edgedetectthr = Gtk::manage (new Adjuster (M("TP_WAVELET_EDGEDETECTTHR"), 0, 100, 1, 20)); + edgedetectthr->setAdjusterListener (this); + edgedetectthr->set_tooltip_text (M("TP_WAVELET_EDGEDETECTTHR_TOOLTIP")); + edgBox->pack_start(*edgedetectthr); + + + edgedetectthr2 = Gtk::manage (new Adjuster (M("TP_WAVELET_EDGEDETECTTHR2"), -10, 100, 1, 0)); + edgedetectthr2->setAdjusterListener (this); + //edgedetectthr2->set_tooltip_text (M("TP_WAVELET_EDGEDETECTTHR2_TOOLTIP")); + edgBox->pack_start(*edgedetectthr2); + + + lipst = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_LIPST"))); + lipst->set_active (true); + lipstConn = lipst->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::lipstToggled) ); + lipst->set_tooltip_text (M("TP_WAVELET_LIPST_TOOLTIP")); + //edgBox->pack_start(*lipst); + // gamut control------------------------------------------------- Gtk::VBox * conBox = Gtk::manage (new Gtk::VBox()); conBox->set_border_width(4); @@ -486,12 +631,92 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), hueskin->setBgGradient(milestones); conBox->pack_start(*hueskin); hueskin->setAdjusterListener (this); + + curveEditorGAM = new CurveEditorGroup (options.lastWaveletCurvesDir); + curveEditorGAM->setCurveListener (this); + + Chshape = static_cast(curveEditorGAM->addCurve(CT_Flat, M("TP_WAVELET_CURVEEDITOR_CH"))); + Chshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CH_TOOLTIP")); + Chshape->setCurveColorProvider(this, 5); + curveEditorGAM->curveListComplete(); + Chshape->setBottomBarBgGradient(milestones); + + conBox->pack_start (*curveEditorGAM, Gtk::PACK_SHRINK, 4); + avoid = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_AVOID"))); avoid->set_active (true); avoidConn = avoid->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::avoidToggled) ); conBox->pack_start(*avoid); //************************** + + // residual image + Gtk::VBox * resBox = Gtk::manage (new Gtk::VBox()); + resBox->set_border_width(4); + resBox->set_spacing(2); + + rescon = Gtk::manage (new Adjuster (M("TP_WAVELET_RESCON"), -100, 100, 1, 0)); + rescon->setAdjusterListener (this); + resBox->pack_start(*rescon, Gtk::PACK_SHRINK); + + thr = Gtk::manage (new Adjuster (M("TP_WAVELET_THR"), 0, 100, 1, 35)); + resBox->pack_start(*thr); + + thr->setAdjusterListener (this); + + resconH = Gtk::manage (new Adjuster (M("TP_WAVELET_RESCONH"), -100, 100, 1, 0)); + resconH->setAdjusterListener (this); + resBox->pack_start(*resconH, Gtk::PACK_SHRINK); + + + thrH = Gtk::manage (new Adjuster (M("TP_WAVELET_THRH"), 0, 100, 1, 65)); + thrH->setAdjusterListener (this); + resBox->pack_start(*thrH,Gtk::PACK_SHRINK); + + contrast = Gtk::manage (new Adjuster (M("TP_WAVELET_CONTRA"), -100, 100, 1, 0)); + contrast->set_tooltip_text (M("TP_WAVELET_CONTRA_TOOLTIP")); + contrast->setAdjusterListener (this); + resBox->pack_start(*contrast); //keep the possibility to reinstall + + reschro = Gtk::manage (new Adjuster (M("TP_WAVELET_RESCHRO"), -100, 100, 1, 0)); + reschro->setAdjusterListener (this); + resBox->pack_start(*reschro); + + + hueskin2 = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_HUESKY"), -314., 314., -260., -250, -130., -140., 0, false)); + hueskin2->set_tooltip_markup (M("TP_WAVELET_HUESKY_TOOLTIP")); + hueskin2->setBgGradient(milestones); + resBox->pack_start(*hueskin2); + hueskin2->setAdjusterListener (this); + + sky = Gtk::manage (new Adjuster (M("TP_WAVELET_SKY"), -100., 100.0, 1., 0.)); + sky->set_tooltip_text (M("TP_WAVELET_SKY_TOOLTIP")); + sky->setAdjusterListener (this); + + resBox->pack_start(*sky); + + // whole hue range + milestones.clear(); + for (int i=0; i<7; i++) { + float R, G, B; + float x = float(i)*(1.0f/6.0); + Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); + milestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); + } + + + curveEditorRES = new CurveEditorGroup (options.lastWaveletCurvesDir); + curveEditorRES->setCurveListener (this); + + hhshape = static_cast(curveEditorRES->addCurve(CT_Flat, M("TP_WAVELET_CURVEEDITOR_HH"))); + hhshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_HH_TOOLTIP")); + hhshape->setCurveColorProvider(this, 5); + curveEditorRES->curveListComplete(); + hhshape->setBottomBarBgGradient(milestones); + + resBox->pack_start (*curveEditorRES, Gtk::PACK_SHRINK, 4); + +//-------------------------------------- expdisplay->add(*diBox); pack_start (*dispFrame, Gtk::PACK_EXPAND_WIDGET, 4); @@ -504,6 +729,9 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), exptoning->add(*tonBox); pack_start (*toningFrame, Gtk::PACK_EXPAND_WIDGET, 4); + expnoise->add(*noiseBox); + pack_start (*noiseFrame, Gtk::PACK_EXPAND_WIDGET, 4); + expedge->add(*edgBox); pack_start (*edgeFrame, Gtk::PACK_EXPAND_WIDGET, 4); @@ -517,9 +745,12 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), } Wavelet::~Wavelet () { - delete CLVcurveEditorG; delete opaCurveEditorG; delete opacityCurveEditorG; + delete CCWcurveEditorG; + delete curveEditorRES; + delete curveEditorGAM; + } int wavChangedUI (void* data) { GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected @@ -546,8 +777,7 @@ void Wavelet::updatewavLabel () { { wavLabels->set_text( Glib::ustring::compose(M("TP_WAVELET_LEVLABEL"), - Glib::ustring::format(std::fixed, std::setprecision(0), lv)) - + Glib::ustring::format(std::fixed, std::setprecision(0), lv)) ); } } @@ -558,11 +788,17 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { disableListener (); Lmethodconn.block(true); CLmethodconn.block(true); + Backmethodconn.block(true); Tilesmethodconn.block(true); + choicemethodconn.block(true); Dirmethodconn.block(true); CHmethodconn.block(true); + CHSLmethodconn.block(true); + EDmethodconn.block(true); HSmethodconn.block(true); + MedgreinfConn.block(true); HSmethod->set_active (1); + if (pp->wavelet.HSmethod=="without") HSmethod->set_active (0); else if (pp->wavelet.HSmethod=="with") @@ -577,6 +813,41 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { else if (pp->wavelet.CHmethod=="link") CHmethod->set_active (2); CHmethodChanged(); + + Medgreinf->set_active (1); + if (pp->wavelet.Medgreinf=="more") + Medgreinf->set_active (0); + else if (pp->wavelet.Medgreinf=="none") + Medgreinf->set_active (1); + else if (pp->wavelet.Medgreinf=="less") + Medgreinf->set_active (2); + MedgreinfChanged(); + + CHSLmethod->set_active (1); + if (pp->wavelet.CHSLmethod=="SL") + CHSLmethod->set_active (0); + else if (pp->wavelet.CHSLmethod=="CU") + CHSLmethod->set_active (1); + CHSLmethodChanged(); + + EDmethod->set_active (1); + if (pp->wavelet.EDmethod=="SL") + EDmethod->set_active (0); + else if (pp->wavelet.EDmethod=="CU") + EDmethod->set_active (1); + EDmethodChanged(); + + Backmethod->set_active (3); + if (pp->wavelet.Backmethod=="black") { + Backmethod->set_active (0); + } + else if (pp->wavelet.Backmethod=="grey") { + Backmethod->set_active (1); + } + else if (pp->wavelet.Backmethod=="resid") { + Backmethod->set_active (2); + } + BackmethodChanged(); CLmethod->set_active (3); if (pp->wavelet.CLmethod=="one") { @@ -601,6 +872,19 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { else if (pp->wavelet.Tilesmethod=="lit") Tilesmethod->set_active (2); TilesmethodChanged(); + + choicemethod->set_active (4); + if (pp->wavelet.choicemethod=="2_") + choicemethod->set_active (0); + else if (pp->wavelet.choicemethod=="4_") + choicemethod->set_active (1); + else if (pp->wavelet.choicemethod=="6_") + choicemethod->set_active (2); + else if (pp->wavelet.choicemethod=="10_") + choicemethod->set_active (3); + else if (pp->wavelet.choicemethod=="14_") + choicemethod->set_active (4); + choicemethodChanged(); Dirmethod->set_active (3); if (pp->wavelet.Dirmethod=="one") @@ -617,25 +901,36 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { Lmethod->set_active (selectedLevel == -1 ? 4 :selectedLevel); LmethodChanged(); - if (pedited) { if (!pedited->wavelet.Lmethod) Lmethod->set_active (8); if (!pedited->wavelet.CLmethod) CLmethod->set_active (3); + if (!pedited->wavelet.Backmethod) + Backmethod->set_active (2); if (!pedited->wavelet.Tilesmethod) - Tilesmethod->set_active (2); + Tilesmethod->set_active (2); + if (!pedited->wavelet.choicemethod) + choicemethod->set_active (4); if (!pedited->wavelet.Dirmethod) - Dirmethod->set_active (3); + Dirmethod->set_active (3); if (!pedited->wavelet.CHmethod) - CHmethod->set_active (1); + CHmethod->set_active (1); + if (!pedited->wavelet.CHSLmethod) + CHSLmethod->set_active (1); + if (!pedited->wavelet.EDmethod) + EDmethod->set_active (1); if (!pedited->wavelet.HSmethod) - HSmethod->set_active (1); + HSmethod->set_active (1); + if (!pedited->wavelet.Medgreinf) + Medgreinf->set_active (2); set_inconsistent (multiImage && !pedited->wavelet.enabled); - ccshape->setUnChanged (!pedited->wavelet.clvcurve); + ccshape->setUnChanged (!pedited->wavelet.ccwcurve); opacityShapeRG->setCurve (pp->wavelet.opacityCurveRG); opacityShapeBY->setCurve (pp->wavelet.opacityCurveBY); + hhshape->setUnChanged (!pedited->wavelet.hhcurve); + Chshape->setUnChanged (!pedited->wavelet.Chcurve); avoid->set_inconsistent (!pedited->wavelet.avoid); edgthresh->setEditedState (pedited->wavelet.edgthresh ? Edited : UnEdited); rescon->setEditedState (pedited->wavelet.rescon ? Edited : UnEdited); @@ -646,9 +941,16 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { thres->setEditedState (pedited->wavelet.thres ? Edited : UnEdited); threshold->setEditedState (pedited->wavelet.threshold ? Edited : UnEdited); threshold2->setEditedState (pedited->wavelet.threshold2 ? Edited : UnEdited); + edgedetect->setEditedState (pedited->wavelet.edgedetect ? Edited : UnEdited); + edgedetectthr->setEditedState (pedited->wavelet.edgedetectthr ? Edited : UnEdited); + edgedetectthr2->setEditedState (pedited->wavelet.edgedetectthr2 ? Edited : UnEdited); chroma->setEditedState (pedited->wavelet.chroma ? Edited : UnEdited); chro->setEditedState (pedited->wavelet.chro ? Edited : UnEdited); median->set_inconsistent (!pedited->wavelet.median); + medianlev->set_inconsistent (!pedited->wavelet.medianlev); + linkedg->set_inconsistent (!pedited->wavelet.linkedg); + // edgreinf->set_inconsistent (!pedited->wavelet.edgreinf); + lipst->set_inconsistent (!pedited->wavelet.lipst); contrast->setEditedState (pedited->wavelet.contrast ? Edited : UnEdited); edgrad->setEditedState (pedited->wavelet.edgrad ? Edited : UnEdited); edgval->setEditedState (pedited->wavelet.edgval ? Edited : UnEdited); @@ -661,15 +963,24 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { bllev->setEditedState (pedited->wavelet.bllev ? Edited : UnEdited); pastlev->setEditedState (pedited->wavelet.pastlev ? Edited : UnEdited); satlev->setEditedState (pedited->wavelet.satlev ? Edited : UnEdited); + strength->setEditedState(pedited->wavelet.strength ? Edited : UnEdited); + edgcont->setEditedState (pedited->wavelet.edgcont ? Edited : UnEdited); + level0noise->setEditedState (pedited->wavelet.level0noise ? Edited : UnEdited); + level1noise->setEditedState (pedited->wavelet.level1noise ? Edited : UnEdited); + level2noise->setEditedState (pedited->wavelet.level2noise ? Edited : UnEdited); for(int i = 0; i < 9; i++) { correction[i]->setEditedState (pedited->wavelet.c[i] ? Edited : UnEdited); } - strength->setEditedState(pedited->wavelet.strength ? Edited : UnEdited); + for(int i = 0; i < 9; i++) { + correctionch[i]->setEditedState (pedited->wavelet.ch[i] ? Edited : UnEdited); + } } - ccshape->setCurve (pp->wavelet.clvcurve); + ccshape->setCurve (pp->wavelet.ccwcurve); opacityShapeRG->setCurve (pp->wavelet.opacityCurveRG); opacityShapeBY->setCurve (pp->wavelet.opacityCurveBY); + hhshape->setCurve (pp->wavelet.hhcurve); + Chshape->setCurve (pp->wavelet.Chcurve); setEnabled(pp->wavelet.enabled); avoidConn.block (true); @@ -678,7 +989,24 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { medianConn.block (true); median->set_active (pp->wavelet.median); medianConn.block (false); + medianlevConn.block (true); + medianlev->set_active (pp->wavelet.medianlev); + medianlevConn.block (false); + linkedgConn.block (true); + linkedg->set_active (pp->wavelet.linkedg); + linkedgConn.block (false); + + lipstConn.block (true); + lipst->set_active (pp->wavelet.lipst); + lipstConn.block (false); + //edgreinfConn.block (true); + //edgreinf->set_active (pp->wavelet.edgreinf); + //edgreinfConn.block (false); + //lastedgreinf = pp->wavelet.edgreinf; lastmedian = pp->wavelet.median; + lastmedianlev = pp->wavelet.medianlev; + lastlinkedg = pp->wavelet.linkedg; + lastlipst = pp->wavelet.lipst; lastavoid = pp->wavelet.avoid; rescon->setValue (pp->wavelet.rescon); resconH->setValue (pp->wavelet.resconH); @@ -699,34 +1027,65 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { hueskin2->setValue(pp->wavelet.hueskin2); threshold->setValue(pp->wavelet.threshold); threshold2->setValue(pp->wavelet.threshold2); + edgedetect->setValue(pp->wavelet.edgedetect); + edgedetectthr->setValue(pp->wavelet.edgedetectthr); + edgedetectthr2->setValue(pp->wavelet.edgedetectthr2); hllev->setValue(pp->wavelet.hllev); bllev->setValue(pp->wavelet.bllev); pastlev->setValue(pp->wavelet.pastlev); satlev->setValue(pp->wavelet.satlev); + edgcont->setValue(pp->wavelet.edgcont); + level0noise->setValue(pp->wavelet.level0noise); + level1noise->setValue(pp->wavelet.level1noise); + level2noise->setValue(pp->wavelet.level2noise); + strength->setValue(pp->wavelet.strength); for (int i = 0; i < 9; i++) { correction[i]->setValue(pp->wavelet.c[i]); } - strength->setValue(pp->wavelet.strength); + for (int i = 0; i < 9; i++) { + correctionch[i]->setValue(pp->wavelet.ch[i]); + } int y; y=thres->getValue(); int z; -// for(z=y;z<9;z++) correction[z]->set_sensitive (false); -// for(z=0;zset_sensitive (true); for(z=y;z<9;z++) correction[z]->hide(); for(z=0;zshow(); + if (pp->wavelet.CHSLmethod=="SL") { + for(z=y;z<9;z++) correctionch[z]->hide(); + for(z=0;zshow(); + } + CHmethodChanged(); + CHSLmethodChanged(); + EDmethodChanged(); + MedgreinfChanged(); if(z==9) sup->show(); else sup->hide(); Lmethodconn.block(false); CLmethodconn.block(false); + Backmethodconn.block(false); Tilesmethodconn.block(false); + choicemethodconn.block(false); CHmethodconn.block(false); + CHSLmethodconn.block(false); + EDmethodconn.block(false); HSmethodconn.block(false); Dirmethodconn.block(false); + MedgreinfConn.block(false); + medianlevToggled () ; + linkedgToggled () ; + lipstToggled () ; + enableListener (); } + void Wavelet::setEditProvider (EditDataProvider *provider) { ccshape->setEditProvider(provider); + opacityShapeRG->setEditProvider(provider); + opacityShapeBY->setEditProvider(provider); + hhshape->setEditProvider(provider); + Chshape->setEditProvider(provider); } + void Wavelet::autoOpenCurve () { ccshape->openIfNonlinear(); //opacityShapeRG->openIfNonlinear(); @@ -746,6 +1105,10 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { pp->wavelet.chroma = chroma->getValue(); pp->wavelet.chro = chro->getValue(); pp->wavelet.median = median->get_active (); + pp->wavelet.medianlev = medianlev->get_active (); + pp->wavelet.linkedg = linkedg->get_active (); + //pp->wavelet.edgreinf = edgreinf->get_active (); + pp->wavelet.lipst = lipst->get_active (); pp->wavelet.contrast = contrast->getValue(); pp->wavelet.edgrad = edgrad->getValue(); pp->wavelet.edgval = edgval->getValue(); @@ -757,26 +1120,47 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { pp->wavelet.skinprotect = skinprotect->getValue(); pp->wavelet.threshold = threshold->getValue(); pp->wavelet.threshold2 = threshold2->getValue(); + pp->wavelet.edgedetect = edgedetect->getValue(); + pp->wavelet.edgedetectthr = edgedetectthr->getValue(); + pp->wavelet.edgedetectthr2 = edgedetectthr2->getValue(); pp->wavelet.hllev = hllev->getValue (); pp->wavelet.bllev = bllev->getValue (); - pp->wavelet.clvcurve = ccshape->getCurve (); + pp->wavelet.edgcont = edgcont->getValue (); + pp->wavelet.level0noise = level0noise->getValue (); + pp->wavelet.level1noise = level1noise->getValue (); + pp->wavelet.level2noise = level2noise->getValue (); + pp->wavelet.ccwcurve = ccshape->getCurve (); pp->wavelet.opacityCurveRG = opacityShapeRG->getCurve (); pp->wavelet.opacityCurveBY = opacityShapeBY->getCurve (); + pp->wavelet.hhcurve = hhshape->getCurve (); + pp->wavelet.Chcurve = Chshape->getCurve (); pp->wavelet.pastlev = pastlev->getValue (); pp->wavelet.satlev = satlev->getValue (); + pp->wavelet.strength = (int) strength->getValue(); for (int i = 0; i < 9; i++) { pp->wavelet.c[i] = (int) correction[i]->getValue(); } - pp->wavelet.strength = (int) strength->getValue(); + for (int i = 0; i < 9; i++) { + pp->wavelet.ch[i] = (int) correctionch[i]->getValue(); + } + if (pedited) { pedited->wavelet.enabled = !get_inconsistent(); pedited->wavelet.avoid = !avoid->get_inconsistent(); pedited->wavelet.median = !median->get_inconsistent(); + pedited->wavelet.medianlev = !medianlev->get_inconsistent(); + pedited->wavelet.linkedg = !linkedg->get_inconsistent(); + pedited->wavelet.lipst = !lipst->get_inconsistent(); + pedited->wavelet.Medgreinf = Medgreinf->get_active_row_number() != 2; pedited->wavelet.Lmethod = Lmethod->get_active_row_number() != 8; pedited->wavelet.CLmethod = CLmethod->get_active_row_number() != 3; + pedited->wavelet.Backmethod = Backmethod->get_active_row_number() != 2; pedited->wavelet.Tilesmethod = Tilesmethod->get_active_row_number() != 2; + pedited->wavelet.choicemethod = choicemethod->get_active_row_number() != 4; pedited->wavelet.CHmethod = CHmethod->get_active_row_number() != 2; + pedited->wavelet.CHSLmethod = CHSLmethod->get_active_row_number() != 1; + pedited->wavelet.EDmethod = EDmethod->get_active_row_number() != 1; pedited->wavelet.HSmethod = HSmethod->get_active_row_number() != 1; pedited->wavelet.Dirmethod = Dirmethod->get_active_row_number() != 3; pedited->wavelet.edgthresh = edgthresh->getEditedState(); @@ -788,6 +1172,9 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { pedited->wavelet.thres = thres->getEditedState(); pedited->wavelet.threshold = threshold->getEditedState(); pedited->wavelet.threshold2 = threshold2->getEditedState(); + pedited->wavelet.edgedetect = edgedetect->getEditedState(); + pedited->wavelet.edgedetectthr = edgedetectthr->getEditedState(); + pedited->wavelet.edgedetectthr2 = edgedetectthr2->getEditedState(); pedited->wavelet.chroma = chroma->getEditedState(); pedited->wavelet.chro = chro->getEditedState(); pedited->wavelet.contrast = contrast->getEditedState(); @@ -799,17 +1186,27 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { pedited->wavelet.hueskin2 = hueskin2->getEditedState (); pedited->wavelet.skinprotect = skinprotect->getEditedState(); pedited->wavelet.hllev = hllev->getEditedState (); - pedited->wavelet.clvcurve = !ccshape->isUnChanged (); + pedited->wavelet.ccwcurve = !ccshape->isUnChanged (); + pedited->wavelet.edgcont = edgcont->getEditedState (); + pedited->wavelet.level0noise = level0noise->getEditedState (); + pedited->wavelet.level1noise = level1noise->getEditedState (); + pedited->wavelet.level2noise = level2noise->getEditedState (); pedited->wavelet.opacityCurveRG = !opacityShapeRG->isUnChanged (); pedited->wavelet.opacityCurveBY = !opacityShapeBY->isUnChanged (); + pedited->wavelet.hhcurve = !hhshape->isUnChanged (); + pedited->wavelet.Chcurve = !Chshape->isUnChanged (); pedited->wavelet.bllev = bllev->getEditedState (); pedited->wavelet.pastlev = pastlev->getEditedState (); pedited->wavelet.satlev = satlev->getEditedState (); + pedited->wavelet.strength = strength->getEditedState (); for(int i = 0; i < 9; i++) { pedited->wavelet.c[i] = correction[i]->getEditedState(); } - pedited->wavelet.strength = strength->getEditedState (); + for(int i = 0; i < 9; i++) { + pedited->wavelet.ch[i] = correctionch[i]->getEditedState(); + } + } if (CHmethod->get_active_row_number()==0) pp->wavelet.CHmethod = "without"; @@ -817,6 +1214,23 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { pp->wavelet.CHmethod = "with"; else if (CHmethod->get_active_row_number()==2) pp->wavelet.CHmethod = "link"; + + if (Medgreinf->get_active_row_number()==0) + pp->wavelet.Medgreinf = "more"; + else if (Medgreinf->get_active_row_number()==1) + pp->wavelet.Medgreinf = "none"; + else if (Medgreinf->get_active_row_number()==2) + pp->wavelet.Medgreinf = "less"; + + if (CHSLmethod->get_active_row_number()==0) + pp->wavelet.CHSLmethod = "SL"; + else if (CHSLmethod->get_active_row_number()==1) + pp->wavelet.CHSLmethod = "CU"; + + if (EDmethod->get_active_row_number()==0) + pp->wavelet.EDmethod = "SL"; + else if (EDmethod->get_active_row_number()==1) + pp->wavelet.EDmethod = "CU"; if (HSmethod->get_active_row_number()==0) pp->wavelet.HSmethod = "without"; @@ -832,12 +1246,30 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { else if (CLmethod->get_active_row_number()==3) pp->wavelet.CLmethod = "all"; + if (Backmethod->get_active_row_number()==0) + pp->wavelet.Backmethod = "black"; + else if (Backmethod->get_active_row_number()==1) + pp->wavelet.Backmethod = "grey"; + else if (Backmethod->get_active_row_number()==2) + pp->wavelet.Backmethod = "resid"; + if (Tilesmethod->get_active_row_number()==0) pp->wavelet.Tilesmethod = "full"; else if (Tilesmethod->get_active_row_number()==1) pp->wavelet.Tilesmethod = "big"; else if (Tilesmethod->get_active_row_number()==2) pp->wavelet.Tilesmethod = "lit"; + + if (choicemethod->get_active_row_number()==0) + pp->wavelet.choicemethod = "2_"; + else if (choicemethod->get_active_row_number()==1) + pp->wavelet.choicemethod = "4_"; + else if (choicemethod->get_active_row_number()==2) + pp->wavelet.choicemethod = "6_"; + else if (choicemethod->get_active_row_number()==3) + pp->wavelet.choicemethod = "10_"; + else if (choicemethod->get_active_row_number()==4) + pp->wavelet.choicemethod = "14_"; if (Dirmethod->get_active_row_number()==0) pp->wavelet.Dirmethod = "one"; @@ -851,26 +1283,6 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { char lMethod[3]; // one additional char to avoid buffer overrun if someone increases number of levels > 9 sprintf(lMethod, "%d", Lmethod->get_active_row_number()+1); pp->wavelet.Lmethod = lMethod; -/* - if (Lmethod->get_active_row_number()==0) - pp->wavelet.Lmethod = "1_"; - else if (Lmethod->get_active_row_number()==1) - pp->wavelet.Lmethod = "2_"; - else if (Lmethod->get_active_row_number()==2) - pp->wavelet.Lmethod = "3_"; - else if (Lmethod->get_active_row_number()==3) - pp->wavelet.Lmethod = "4_"; - else if (Lmethod->get_active_row_number()==4) - pp->wavelet.Lmethod = "5_"; - else if (Lmethod->get_active_row_number()==5) - pp->wavelet.Lmethod = "6_"; - else if (Lmethod->get_active_row_number()==6) - pp->wavelet.Lmethod = "7_"; - else if (Lmethod->get_active_row_number()==7) - pp->wavelet.Lmethod = "8_"; - else if (Lmethod->get_active_row_number()==8) - pp->wavelet.Lmethod = "9_"; -*/ } @@ -878,11 +1290,16 @@ void Wavelet::curveChanged (CurveEditor* ce) { if (listener && getEnabled()) { if (ce == ccshape) - listener->panelChanged (EvWavCLVCurve, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged (EvWavCCCurve, M("HISTORY_CUSTOMCURVE")); else if (ce == opacityShapeRG) listener->panelChanged (EvWavColor, M("HISTORY_CUSTOMCURVE")); else if (ce == opacityShapeBY) listener->panelChanged (EvWavOpac, M("HISTORY_CUSTOMCURVE")); + else if (ce == hhshape) + listener->panelChanged (EvWavHHCurve, M("HISTORY_CUSTOMCURVE")); + else if (ce == Chshape) + listener->panelChanged (EvWavCHCurve, M("HISTORY_CUSTOMCURVE")); + } } @@ -891,6 +1308,9 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi for (int i = 0; i < 9; i++) { correction[i]->setDefault(defParams->wavelet.c[i]); } + for (int i = 0; i < 9; i++) { + correctionch[i]->setDefault(defParams->wavelet.ch[i]); + } strength->setDefault(defParams->wavelet.strength ); rescon->setDefault (defParams->wavelet.rescon); resconH->setDefault (defParams->wavelet.resconH); @@ -900,6 +1320,9 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi thres->setDefault (defParams->wavelet.thres); threshold->setDefault (defParams->wavelet.threshold); threshold2->setDefault (defParams->wavelet.threshold2); + edgedetect->setDefault (defParams->wavelet.edgedetect); + edgedetectthr->setDefault (defParams->wavelet.edgedetectthr); + edgedetectthr2->setDefault (defParams->wavelet.edgedetectthr2); chroma->setDefault (defParams->wavelet.chroma); chro->setDefault (defParams->wavelet.chro); contrast->setDefault (defParams->wavelet.contrast); @@ -914,6 +1337,10 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi bllev->setDefault (defParams->wavelet.bllev); pastlev->setDefault (defParams->wavelet.pastlev); satlev->setDefault (defParams->wavelet.satlev); + edgcont->setDefault (defParams->wavelet.edgcont); + level0noise->setDefault (defParams->wavelet.level0noise); + level1noise->setDefault (defParams->wavelet.level1noise); + level2noise->setDefault (defParams->wavelet.level2noise); if (pedited) { rescon->setDefault (defParams->wavelet.rescon); @@ -924,6 +1351,9 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi thres->setDefaultEditedState(pedited->wavelet.thres ? Edited : UnEdited); threshold->setDefaultEditedState(pedited->wavelet.threshold ? Edited : UnEdited); threshold2->setDefaultEditedState(pedited->wavelet.threshold2 ? Edited : UnEdited); + edgedetect->setDefaultEditedState(pedited->wavelet.edgedetect ? Edited : UnEdited); + edgedetectthr->setDefaultEditedState(pedited->wavelet.edgedetectthr ? Edited : UnEdited); + edgedetectthr2->setDefaultEditedState(pedited->wavelet.edgedetectthr2 ? Edited : UnEdited); chroma->setDefaultEditedState(pedited->wavelet.chroma ? Edited : UnEdited); chro->setDefaultEditedState(pedited->wavelet.chro ? Edited : UnEdited); contrast->setDefaultEditedState(pedited->wavelet.contrast ? Edited : UnEdited); @@ -939,11 +1369,18 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi bllev->setDefaultEditedState (pedited->wavelet.bllev ? Edited : UnEdited); pastlev->setDefaultEditedState (pedited->wavelet.pastlev ? Edited : UnEdited); satlev->setDefaultEditedState (pedited->wavelet.satlev ? Edited : UnEdited); + edgcont->setDefaultEditedState (pedited->wavelet.edgcont ? Edited : UnEdited); + strength->setDefaultEditedState (pedited->wavelet.strength ? Edited : UnEdited); + level0noise->setDefaultEditedState (pedited->wavelet.level0noise ? Edited : UnEdited); + level1noise->setDefaultEditedState (pedited->wavelet.level1noise ? Edited : UnEdited); + level2noise->setDefaultEditedState (pedited->wavelet.level2noise ? Edited : UnEdited); for (int i = 0; i < 9; i++) { correction[i]->setDefaultEditedState(pedited->wavelet.c[i] ? Edited : UnEdited); } - strength->setDefaultEditedState (pedited->wavelet.strength ? Edited : UnEdited); + for (int i = 0; i < 9; i++) { + correctionch[i]->setDefaultEditedState(pedited->wavelet.ch[i] ? Edited : UnEdited); + } } else { rescon->setDefaultEditedState(Irrelevant); @@ -954,7 +1391,10 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi thres->setDefaultEditedState(Irrelevant); threshold->setDefaultEditedState(Irrelevant); threshold2->setDefaultEditedState(Irrelevant); - chroma->setDefaultEditedState(Irrelevant); + edgedetect->setDefaultEditedState(Irrelevant); + edgedetectthr->setDefaultEditedState(Irrelevant); + edgedetectthr2->setDefaultEditedState(Irrelevant); + chroma->setDefaultEditedState(Irrelevant); chro->setDefaultEditedState(Irrelevant); contrast->setDefaultEditedState(Irrelevant); edgrad->setDefaultEditedState(Irrelevant); @@ -967,16 +1407,40 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi hueskin2->setDefaultEditedState (Irrelevant); hllev->setDefaultEditedState (Irrelevant); bllev->setDefaultEditedState (Irrelevant); + edgcont->setDefaultEditedState (Irrelevant); + level0noise->setDefaultEditedState (Irrelevant); + level1noise->setDefaultEditedState (Irrelevant); + level2noise->setDefaultEditedState (Irrelevant); pastlev->setDefaultEditedState (Irrelevant); satlev->setDefaultEditedState (Irrelevant); + strength->setDefaultEditedState (Irrelevant); - for (int i = 0; i < 9; i++) { - correction[i]->setDefaultEditedState(Irrelevant); - } - strength->setDefaultEditedState (Irrelevant); + for (int i = 0; i < 9; i++) { + correction[i]->setDefaultEditedState(Irrelevant); + } + for (int i = 0; i < 9; i++) { + correctionch[i]->setDefaultEditedState(Irrelevant); + } } } +void Wavelet::adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop) { + if (listener && getEnabled()) { + if(a==level0noise) { + listener->panelChanged (EvWavlev0nois, + Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS")+": %1"+"\n"+M("TP_WAVELET_STREN")+": %2"), int(newTop), int(newBottom))); + } + else if(a==level1noise) { + listener->panelChanged (EvWavlev1nois, + Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS")+": %1"+"\n"+M("TP_WAVELET_STREN")+": %2"), int(newTop), int(newBottom))); + } + else if(a==level2noise) { + listener->panelChanged (EvWavlev2nois, + Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS")+": %1"+"\n"+M("TP_WAVELET_STREN")+": %2"), int(newTop), int(newBottom))); + } + + } +} void Wavelet::adjusterChanged2 (ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) { @@ -999,6 +1463,9 @@ void Wavelet::adjusterChanged2 (ThresholdAdjuster* a, int newBottomL, int newTop else if(a==satlev) { listener->panelChanged (EvWavsat,satlev->getHistoryString()); } + else if(a==edgcont) { + listener->panelChanged (EvWavedgcont,edgcont->getHistoryString()); + } } } @@ -1026,26 +1493,84 @@ void Wavelet::HSmethodChanged() { void Wavelet::CHmethodChanged() { if (!batchMode) { if(CHmethod->get_active_row_number()==0) {//without - pastlev->hide(); - satlev->hide(); - chroma->hide(); - chro->hide(); - CLVcurveEditorG->show(); + /* if(CHSLmethod->get_active_row_number()==1) {//CU + CHSLmethod->show(); + pastlev->hide(); + satlev->hide(); + chroma->hide(); + chro->hide(); + //CLVcurveEditorG->show(); + separator3->show(); + labmC->show(); + neutralchButton->hide(); + for (int i = 0; i < 9; i++) { + correctionch[i]->hide(); + } + } + */ + // else if(CHSLmethod->get_active_row_number()==0) {//SL + CHSLmethod->show(); + pastlev->hide(); + satlev->hide(); + chroma->hide(); + chro->hide(); + labmC->show(); + neutralchButton->show(); + int y=thres->getValue(); + int z; + for(z=y;z<9;z++) correctionch[z]->hide(); + for(z=0;zshow(); + // } + } else if(CHmethod->get_active_row_number()==1) {//with - pastlev->show(); - satlev->show(); - chroma->show(); - chro->hide(); - CLVcurveEditorG->show(); + /* if(CHSLmethod->get_active_row_number()==1) {//CU + CHSLmethod->show(); + pastlev->show(); + satlev->show(); + chroma->show(); + chro->hide(); + //CLVcurveEditorG->show(); + separator3->show(); + + labmC->show(); + neutralchButton->hide(); + for (int i = 0; i < 9; i++) { + correctionch[i]->hide(); + } + } + */ + // else if(CHSLmethod->get_active_row_number()==0) {//SL + CHSLmethod->show(); + pastlev->show(); + satlev->show(); + chroma->show(); + chro->hide(); + labmC->show(); + //CLVcurveEditorG->hide(); + neutralchButton->show(); + int y=thres->getValue(); + int z; + for(z=y;z<9;z++) correctionch[z]->hide(); + for(z=0;zshow(); + // } } else {//link chro->show(); pastlev->hide(); satlev->hide(); chroma->hide(); - CLVcurveEditorG->hide(); - } + //CLVcurveEditorG->hide(); + separator3->hide(); + + CHSLmethod->hide(); + labmC->hide(); + neutralchButton->hide(); + for (int i = 0; i < 9; i++) { + correctionch[i]->hide(); + } + } + } if (listener && (multiImage||getEnabled()) ) { @@ -1053,6 +1578,58 @@ void Wavelet::CHmethodChanged() { } } +void Wavelet::CHSLmethodChanged() { + /* + if (!batchMode) { + if(CHSLmethod->get_active_row_number()==0 && CHmethod->get_active_row_number() != 2) {//SL + //CLVcurveEditorG->hide(); + neutralchButton->show(); + int y=thres->getValue(); + int z; + for(z=y;z<9;z++) correctionch[z]->hide(); + for(z=0;zshow(); + } + else if(CHSLmethod->get_active_row_number()==1) {//CU + //CLVcurveEditorG->show(); + neutralchButton->hide(); + for (int i = 0; i < 9; i++) { + correctionch[i]->hide(); + } + } + } + + if (listener && (multiImage||enabled->get_active()) ) { + listener->panelChanged (EvWavCHSLmet, CHSLmethod->get_active_text ()); + } + */ +} + +void Wavelet::EDmethodChanged() { + if (!batchMode) { + if(EDmethod->get_active_row_number()==0 ) {//SL + CCWcurveEditorG->hide(); + edgcont->show(); + } + else if(EDmethod->get_active_row_number()==1) {//CU + CCWcurveEditorG->show(); + edgcont->hide(); + } + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavEDmet, EDmethod->get_active_text ()); + } +} + +void Wavelet::BackmethodChanged() { + if (!batchMode) { + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavBackmet, Backmethod->get_active_text ()); + } +} + + + void Wavelet::CLmethodChanged() { if (!batchMode) { } @@ -1065,17 +1642,17 @@ void Wavelet::CLmethodChanged() { Dirmethod->set_sensitive(true); } else if (CLmethod->get_active_row_number()==1) { - CLmethod->set_active (1); + CLmethod->set_active (1); Lmethod->set_sensitive(true); Dirmethod->set_sensitive(true); } else if (CLmethod->get_active_row_number()==2) { - CLmethod->set_active (2); + CLmethod->set_active (2); Lmethod->set_sensitive(true); Dirmethod->set_sensitive(true); } else if (CLmethod->get_active_row_number()==3) { - CLmethod->set_active (3); + CLmethod->set_active (3); Lmethod->set_sensitive(false); Dirmethod->set_sensitive(false); } @@ -1089,6 +1666,22 @@ void Wavelet::TilesmethodChanged() { } } +void Wavelet::choicemethodChanged() { + if (!batchMode) { + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavchoicemet, choicemethod->get_active_text ()); + } +} + +void Wavelet::MedgreinfChanged() { + if (!batchMode) { + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavedgreinf, Medgreinf->get_active_text ()); + } +} + void Wavelet::DirmethodChanged() { if (!batchMode) { } @@ -1108,13 +1701,20 @@ void Wavelet::LmethodChanged() { void Wavelet::setBatchMode (bool batchMode) { Lmethod->append_text (M("GENERAL_UNCHANGED")); CLmethod->append_text (M("GENERAL_UNCHANGED")); + Backmethod->append_text (M("GENERAL_UNCHANGED")); Tilesmethod->append_text (M("GENERAL_UNCHANGED")); + choicemethod->append_text (M("GENERAL_UNCHANGED")); CHmethod->append_text (M("GENERAL_UNCHANGED")); + Medgreinf->append_text (M("GENERAL_UNCHANGED")); + CHSLmethod->append_text (M("GENERAL_UNCHANGED")); + EDmethod->append_text (M("GENERAL_UNCHANGED")); HSmethod->append_text (M("GENERAL_UNCHANGED")); Dirmethod->append_text (M("GENERAL_UNCHANGED")); - CLVcurveEditorG->setBatchMode (batchMode); + CCWcurveEditorG->setBatchMode (batchMode); opaCurveEditorG->setBatchMode (batchMode); opacityCurveEditorG->setBatchMode (batchMode); + curveEditorRES->setBatchMode (batchMode); + curveEditorGAM->setBatchMode (batchMode); rescon->showEditedCB (); resconH->showEditedCB (); reschro->showEditedCB (); @@ -1123,6 +1723,9 @@ void Wavelet::setBatchMode (bool batchMode) { thres->showEditedCB (); threshold->showEditedCB (); threshold2->showEditedCB (); + edgedetect->showEditedCB (); + edgedetectthr->showEditedCB (); + edgedetectthr2->showEditedCB (); chroma->showEditedCB (); chro->showEditedCB (); contrast->showEditedCB (); @@ -1138,12 +1741,20 @@ void Wavelet::setBatchMode (bool batchMode) { bllev->showEditedCB (); pastlev->showEditedCB (); satlev->showEditedCB (); + edgcont->showEditedCB (); + strength->showEditedCB (); + level0noise->showEditedCB (); + level1noise->showEditedCB (); + level2noise->showEditedCB (); + ToolPanel::setBatchMode (batchMode); for (int i = 0; i < 9; i++) { correction[i]->showEditedCB(); } - strength->showEditedCB (); + for (int i = 0; i < 9; i++) { + correctionch[i]->showEditedCB(); + } } void Wavelet::adjusterChanged (Adjuster* a, double newval) { @@ -1229,6 +1840,25 @@ void Wavelet::adjusterChanged (Adjuster* a, double newval) { Glib::ustring::format(std::fixed, std::setprecision(0), threshold2->getValue())) ); } + else if (a == edgedetect ) { + listener->panelChanged (EvWavedgedetect, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), edgedetect->getValue())) + ); + } + else if (a == edgedetectthr ) { + listener->panelChanged (EvWavedgedetectthr, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), edgedetectthr->getValue())) + ); + } + else if (a == edgedetectthr2 ) { + listener->panelChanged (EvWavedgedetectthr2, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), edgedetectthr2->getValue())) + ); + } + else if (a == edgrad ) { listener->panelChanged (EvWavedgrad, Glib::ustring::compose("%1", @@ -1246,10 +1876,10 @@ void Wavelet::adjusterChanged (Adjuster* a, double newval) { int y; y=thres->getValue(); int z; - // for(z=y;z<9;z++) correction[z]->set_sensitive (false);; - // for(z=0;zset_sensitive (true);; for(z=y;z<9;z++) correction[z]->hide(); for(z=0;zshow(); + for(z=y;z<9;z++) correctionch[z]->hide(); + for(z=0;zshow(); if(z==9) sup->show(); else sup->hide(); listener->panelChanged (EvWavthres, @@ -1272,7 +1902,7 @@ void Wavelet::adjusterChanged (Adjuster* a, double newval) { } - else { + else if (a == correction[0] || a == correction[1] || a == correction[2] || a == correction[3] || a == correction[4] || a == correction[5] || a == correction[6] || a == correction[7] || a == correction[8] ) { listener->panelChanged (EvWavelet, Glib::ustring::compose("%1, %2, %3, %4, %5, %6, %7, %8, %9", Glib::ustring::format(std::fixed, std::setprecision(0), correction[0]->getValue()), @@ -1286,6 +1916,20 @@ void Wavelet::adjusterChanged (Adjuster* a, double newval) { Glib::ustring::format(std::fixed, std::setprecision(0), correction[8]->getValue())) ); } + else if (a == correctionch[0] || a == correctionch[1] || a == correctionch[2] || a == correctionch[3] || a == correctionch[4] || a == correctionch[5] || a == correctionch[6] || a == correctionch[7] || a == correctionch[8] ) { + listener->panelChanged (EvWaveletch, + Glib::ustring::compose("%1, %2, %3, %4, %5, %6, %7, %8, %9", + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[0]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[1]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[2]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[3]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[4]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[5]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[6]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[7]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[8]->getValue())) + ); + } } } @@ -1383,14 +2027,148 @@ void Wavelet::medianToggled () { lastmedian = median->get_active (); } - if (listener) { - if (getEnabled ()) - listener->panelChanged (EvWavmedian, M("GENERAL_ENABLED")); - else + if (listener && getEnabled()) { + if (median->get_active ()) + {listener->panelChanged (EvWavmedian, M("GENERAL_ENABLED")); + + } + else { listener->panelChanged (EvWavmedian, M("GENERAL_DISABLED")); + + } } } +void Wavelet::medianlevToggled () { + + if (batchMode) { + if (medianlev->get_inconsistent()) { + medianlev->set_inconsistent (false); + medianlevConn.block (true); + medianlev->set_active (false); + medianlevConn.block (false); + } + else if (lastmedianlev) + medianlev->set_inconsistent (true); + + lastmedianlev = medianlev->get_active (); + } + if (medianlev->get_active ()){ + edgedetect->show(); + //lipst->show(); + edgedetectthr->show(); + edgedetectthr2->show(); + // if (lipst->get_active ()) edgedetectthr2->show(); + // else edgedetectthr2->hide(); + } + else { + edgedetect->hide(); + //lipst->hide(); + edgedetectthr->hide(); + edgedetectthr2->hide(); + } + + + if (listener && getEnabled()) { + if (medianlev->get_active () ){ + + listener->panelChanged (EvWavmedianlev, M("GENERAL_ENABLED")); + } + else { + + listener->panelChanged (EvWavmedianlev, M("GENERAL_DISABLED")); + } + } +} + +void Wavelet::linkedgToggled () { + + if (batchMode) { + if (linkedg->get_inconsistent()) { + linkedg->set_inconsistent (false); + linkedgConn.block (true); + linkedg->set_active (false); + linkedgConn.block (false); + } + else if (lastlinkedg) + linkedg->set_inconsistent (true); + + lastlinkedg = linkedg->get_active (); + } + + + if (listener && getEnabled()) { + if (linkedg->get_active () ){ + + listener->panelChanged (EvWavlinkedg, M("GENERAL_ENABLED")); + } + else { + + listener->panelChanged (EvWavlinkedg, M("GENERAL_DISABLED")); + } + } +} + + + +void Wavelet::lipstToggled () { + + if (batchMode) { + if (lipst->get_inconsistent()) { + lipst->set_inconsistent (false); + lipstConn.block (true); + lipst->set_active (false); + lipstConn.block (false); + } + else if (lastlipst) + lipst->set_inconsistent (true); + + lastlipst = lipst->get_active (); + } +/* + if (lipst->get_active ()){ + edgedetectthr2->show(); + } + else { + edgedetectthr2->hide(); + } +*/ + if (listener && getEnabled()) { + if (lipst->get_active ()){ + + listener->panelChanged (EvWavlipst, M("GENERAL_ENABLED")); + } + else { + + listener->panelChanged (EvWavlipst, M("GENERAL_DISABLED")); + } + } +} + +/* +void Wavelet::edgreinfToggled () { + + if (batchMode) { + if (edgreinf->get_inconsistent()) { + edgreinf->set_inconsistent (false); + edgreinfConn.block (true); + edgreinf->set_active (false); + edgreinfConn.block (false); + } + else if (lastedgreinf) + edgreinf->set_inconsistent (true); + + lastedgreinf = edgreinf->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvWavedgreinf, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvWavedgreinf, M("GENERAL_DISABLED")); + } +} +*/ void Wavelet::avoidToggled () { if (batchMode) { @@ -1405,8 +2183,8 @@ void Wavelet::avoidToggled () { lastavoid = avoid->get_active (); } - if (listener) { - if (getEnabled ()) + if (listener && getEnabled ()) { + if (avoid->get_active ()) listener->panelChanged (EvWavavoid, M("GENERAL_ENABLED")); else listener->panelChanged (EvWavavoid, M("GENERAL_DISABLED")); @@ -1449,7 +2227,7 @@ void Wavelet::colorForValue (double valX, double valY, enum ColorCaller::ElemTyp caller->ccGreen = double(G); caller->ccBlue = double(B); } -void Wavelet::setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd,bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd ) { +void Wavelet::setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd,bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool edgedetectadd, bool edgedetectthradd ,bool edgedetectthr2add) { for (int i=0; i<9; i++) correction[i]->setAddMode(multiplieradd); @@ -1468,9 +2246,10 @@ void Wavelet::setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool t sky->setAddMode(skyadd); edgrad->setAddMode(edgradadd); edgval->setAddMode(edgvaladd); - strength->setAddMode(strengthadd); - - + strength->setAddMode(strengthadd); + edgedetect->setAddMode(edgedetectadd); + edgedetectthr->setAddMode(edgedetectthradd); + edgedetectthr2->setAddMode(edgedetectthr2add); } @@ -1478,7 +2257,15 @@ void Wavelet::neutralPressed () { for (int i = 0; i < 9; i++) { correction[i]->setValue(0); - adjusterChanged(correction[i], 0); + adjusterChanged(correction[i], 0); + } +} + +void Wavelet::neutralchPressed () { + + for (int i = 0; i < 9; i++) { + correctionch[i]->setValue(0); + adjusterChanged(correctionch[i], 0); } } diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 19013e138..cf6620205 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -38,12 +38,17 @@ protected: Glib::RefPtr bgPixbuf; Glib::RefPtr srPixbuf; - CurveEditorGroup* CLVcurveEditorG; + CurveEditorGroup* CCWcurveEditorG; + CurveEditorGroup* curveEditorRES; + CurveEditorGroup* curveEditorGAM; Gtk::HSeparator* colorSep; + Gtk::HSeparator* separator3; CurveEditorGroup* opaCurveEditorG; FlatCurveEditor* opacityShapeRG; CurveEditorGroup* opacityCurveEditorG; FlatCurveEditor* opacityShapeBY; + FlatCurveEditor* hhshape; + FlatCurveEditor* Chshape; FlatCurveEditor* ccshape; Gtk::CheckButton * display; @@ -52,18 +57,25 @@ protected: Gtk::CheckButton * displaygam; Gtk::CheckButton * displayres; Gtk::CheckButton * median; + Gtk::CheckButton * medianlev; + Gtk::CheckButton * linkedg; +// Gtk::CheckButton * edgreinf; + Gtk::CheckButton * lipst; Gtk::CheckButton * avoid; Gtk::ToggleButton * tbresid; Gtk::ToggleButton * tbcontrast; Gtk::ToggleButton * tbgamut; Gtk::ToggleButton * tbchroma; Gtk::ToggleButton * tbtoning; + Gtk::ToggleButton * tbnoise; Gtk::ToggleButton * tbdisplay; Gtk::ToggleButton * tbedge; Gtk::CheckButton * cbresid; Gtk::Image* igRes; + Gtk::Button * neutralchButton; Adjuster* correction[9]; + Adjuster* correctionch[9]; Adjuster* rescon; Adjuster* resconH; Adjuster* reschro; @@ -87,20 +99,38 @@ protected: ThresholdAdjuster* bllev; ThresholdAdjuster* pastlev; ThresholdAdjuster* satlev; + ThresholdAdjuster* edgcont; + ThresholdAdjuster* level0noise; + ThresholdAdjuster* level1noise; + ThresholdAdjuster* level2noise; + Adjuster* threshold; Adjuster* threshold2; + Adjuster* edgedetect; + Adjuster* edgedetectthr; + Adjuster* edgedetectthr2; MyComboBoxText* Lmethod; sigc::connection Lmethodconn; MyComboBoxText* CHmethod; sigc::connection CHmethodconn; + MyComboBoxText* CHSLmethod; + sigc::connection CHSLmethodconn; + MyComboBoxText* EDmethod; + sigc::connection EDmethodconn; MyComboBoxText* HSmethod; sigc::connection HSmethodconn; MyComboBoxText* CLmethod; sigc::connection CLmethodconn; + MyComboBoxText* Backmethod; + sigc::connection Backmethodconn; MyComboBoxText* Tilesmethod; sigc::connection Tilesmethodconn; + MyComboBoxText* choicemethod; + sigc::connection choicemethodconn; MyComboBoxText* Dirmethod; sigc::connection Dirmethodconn; + MyComboBoxText* Medgreinf; + sigc::connection MedgreinfConn; Gtk::Frame* settingsFrame; Gtk::Frame* toningFrame; Gtk::Frame* residualFrame; @@ -109,34 +139,53 @@ protected: Gtk::Frame* chromaFrame; Gtk::Frame* controlFrame; Gtk::Frame* edgeFrame; + Gtk::Frame* noiseFrame; Gtk::Frame* contrastSHFrame; Gtk::Label* colLabel; Gtk::Label* interLabel; Gtk::Label* wavLabels; + Gtk::Label* wavLabelsch; Gtk::Label* hsmethodLabel; + Gtk::Label* choiceLabel; + Gtk::Label* labmC; + Gtk::Label* labmch; + Gtk::Label* labmED; + Gtk::Label* labmedgr; + Gtk::Label* labmednois; Gtk::Expander* expcontrast; Gtk::Expander* expresid; Gtk::Expander* expgamut; Gtk::Expander* expchroma; Gtk::Expander* exptoning; Gtk::Expander* expdisplay; + Gtk::Expander* expnoise; Gtk::Expander* expedge; Gtk::HBox* hbresid; Gtk::HBox* tilesizeHBox; Gtk::HBox* previewLevelsHBox; + Gtk::HBox* previewBackHBox; Gtk::HBox* previewLDirHBox; Gtk::HBox* hsmethodHBox; + Gtk::HBox* choiceHBox; + Gtk::HBox* ctboxCH; + Gtk::HBox* ctboxED; + Gtk::HBox* ctboxch; + Gtk::HBox* edbox; + Gtk::HBox* ednoisbox; + Gtk::HBox* eddebox; Gtk::VBox* settingsVBox; Gtk::VBox* contrastSHVBox; Gtk::Label* tilesizeLabel; Gtk::Label* previewLevelsLabel; + Gtk::Label* previewBackLabel; - sigc::connection expConn, medianConn, avoidConn; + sigc::connection expConn, medianConn, avoidConn, medianlevConn, linkedgConn, lipstConn; sigc::connection neutralPressedConn; sigc::connection contrastPlusPressedConn; sigc::connection contrastMinusPressedConn; + sigc::connection neutralchPressedConn; - bool lastdisplay, lastdisplaygam,lastdisplayres,lastdisplaychro, lastdisplaylevel,lastmedian, lastavoid; + bool lastdisplay, lastdisplaygam,lastdisplayres,lastdisplaychro, lastdisplaylevel,lastmedian, lastmedianlev, lastlinkedg, lastavoid, lastlipst; int nextnlevel; public: @@ -162,11 +211,16 @@ public: void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); void setBatchMode (bool batchMode); void adjusterChanged2 (ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR); - void setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd,bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd); + void setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd,bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool edgedetectadd, bool edgedetectthradd, bool edgedetectthr2add); void adjusterChanged (Adjuster* a, double newval); + void adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop); + void enabledChanged (); void medianToggled (); + void medianlevToggled (); + void linkedgToggled (); + void lipstToggled (); void expcontrastTog (); void expresidTog (); void expdisplayTog (); @@ -175,12 +229,18 @@ public: void exptoningTog (); void avoidToggled (); void neutralPressed (); + void neutralchPressed (); void contrastPlusPressed (); void contrastMinusPressed (); void LmethodChanged (); + void choicemethodChanged (); void CHmethodChanged (); + void MedgreinfChanged (); + void CHSLmethodChanged (); + void EDmethodChanged (); void HSmethodChanged (); void CLmethodChanged (); + void BackmethodChanged (); void TilesmethodChanged (); void DirmethodChanged (); virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller);