diff --git a/rtdata/languages/default b/rtdata/languages/default index e960fb34a..7f4d1fe05 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -328,6 +328,14 @@ HISTORY_MSG_97;'b' curve HISTORY_MSG_98;Demosaicing method HISTORY_MSG_99;Hot/dead pixel filtering HISTORY_MSG_9;Highlight Compression +HISTORY_MSG_142;Clarity -passes +HISTORY_MSG_143;Clarity -gradient strength +HISTORY_MSG_147;Clarity - luminance only +HISTORY_MSG_144;Microcontrast - strength +HISTORY_MSG_145;Microcontrast - uniformity +HISTORY_MSG_146;Clarity Sharpening - enabled +HISTORY_MSG_148;Clarity Microcontrast - enabled +HISTORY_MSG_149;Clarity Microcontrast matrix HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOTAS;As... HISTORY_NEWSSDIALOGLABEL;Label of the snapshot: @@ -719,6 +727,15 @@ TP_CHMIXER_GREEN;Green TP_CHMIXER_LABEL;Channel Mixer TP_CHMIXER_RED;Red TP_CHROMATABERR_LABEL;Chromatic Aberration +TP_CLARITY_LABEL;Clarity and Sharpening +TP_CLARITY_SHARPEN;Gradient Sharpening (border) +TP_CLARITY_STRENGTH;Gradient strength +TP_CLARITY_PASSES;Gradient passes +TP_CLARITY_MICRO;Microcontrast (texture) +TP_CLARITY_THREE;Luminance only +TP_CLARITY_MATRIX;Matrix 3x3 instead of 5x5 +TP_MLMICRO_STRENGTH;Strength +TP_MLMICRO_UNIFORMITY;Uniformity TP_COARSETRAF_DEGREE;degree: TP_COARSETRAF_TOOLTIP_HFLIP;Flip horizontally TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotate left [ diff --git a/rtdata/profiles/crisp.pp3 b/rtdata/profiles/crisp.pp3 index 3f57ad0be..47da7d1be 100644 --- a/rtdata/profiles/crisp.pp3 +++ b/rtdata/profiles/crisp.pp3 @@ -43,6 +43,16 @@ DeconvAmount=75 DeconvDamping=20 DeconvIterations=30 +[Clarity] +Enabled=false +Clpasses=2 +Clstrength=50 +Clthreechannels=false +Enabledtwo=false +Mlstrength=20 +Uniformity=50 +Matrix=false + [Color Boost] Amount=12 AvoidColorClipping=false diff --git a/rtdata/profiles/default.pp3 b/rtdata/profiles/default.pp3 index f1f43efad..2301df152 100644 --- a/rtdata/profiles/default.pp3 +++ b/rtdata/profiles/default.pp3 @@ -28,7 +28,7 @@ aCurve=0; bCurve=0; [Sharpening] -Enabled=true +Enabled=false Method=usm Radius=0.8 Amount=120 @@ -43,6 +43,16 @@ DeconvAmount=75 DeconvDamping=20 DeconvIterations=30 +[Clarity] +Enabled=false +Clpasses=2 +Clstrength=50 +Clthreechannels=false +Enabledtwo=false +Mlstrength=20 +Uniformity=50 +Matrix=false + [Color Boost] Amount=0 AvoidColorClipping=false diff --git a/rtdata/profiles/neutral.pp3 b/rtdata/profiles/neutral.pp3 index ed64c6273..c6330f246 100644 --- a/rtdata/profiles/neutral.pp3 +++ b/rtdata/profiles/neutral.pp3 @@ -43,6 +43,16 @@ DeconvAmount=75 DeconvDamping=20 DeconvIterations=30 +[Clarity] +Enabled=false +Clpasses=2 +Clstrength=50 +Clthreechannels=false +Enabledtwo=false +Mlstrength=20 +Uniformity=50 +Matrix=false + [Color Boost] Amount=0 AvoidColorClipping=false diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 5d68df353..4d9aff94b 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -172,6 +172,9 @@ void Crop::update (int todo) { //parent->ipf.lumadenoise (labnCrop, cbuffer); //parent->ipf.colordenoise (labnCrop, cbuffer); parent->ipf.dirpyrdenoise (labnCrop); + parent->ipf.MLsharpen (labnCrop); + parent->ipf.MLmicrocontrast (labnCrop); + //parent->ipf.MLmicrocontrast (labnCrop); parent->ipf.sharpening (labnCrop, (float**)cbuffer); parent->ipf.dirpyrequalizer (labnCrop); //parent->ipf.waveletEqualizer(labnCrop, true, true); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index c87a563e6..a235c67cc 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -251,7 +251,14 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { // ipf.colordenoise (nprevl, buffer); progress ("Denoising luma/chroma...",100*readyphase/numofphases); ipf.dirpyrdenoise (nprevl); - + if (params.clarity.enabled) { + progress ("Clarity...",100*readyphase/numofphases); + ipf.MLsharpen (nprevl); + } + if (params.clarity.enabledtwo) { + progress ("Microcontrast...",100*readyphase/numofphases); + ipf.MLmicrocontrast (nprevl); + } if (params.sharpening.enabled) { progress ("Sharpening...",100*readyphase/numofphases); diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index a1f6d3539..446d03976 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -88,6 +88,8 @@ class ImProcFunctions { void deconvsharpening (LabImage* lab, float** buffer); void waveletEqualizer (Imagefloat * image); void waveletEqualizer (LabImage * image, bool luminance, bool chromaticity); + void MLsharpen (LabImage* lab);// Manuel's clarity / sharpening + void MLmicrocontrast(LabImage* lab ); //Manuel's microcontrast void impulsedenoise (LabImage* lab);//Emil's impulse denoise void impulse_nr (LabImage* lab, double thresh); diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc index 2591b7db3..d78c0db79 100644 --- a/rtengine/ipsharpen.cc +++ b/rtengine/ipsharpen.cc @@ -35,6 +35,9 @@ namespace rtengine { #define CLIP(a) ((a)>0?((a)sharpening.method=="rld") { - deconvsharpening (lab, b2); + deconvsharpening (lab, b2); return; } @@ -222,5 +225,339 @@ void ImProcFunctions::sharpenHaloCtrl (LabImage* lab, float** blurmap, float** b } } } +// To the extent possible under law, Manuel Llorens [ + // has waived all copyright and related or neighboring rights to this work. +// This work is published from: Spain. + +//thanks to Manuel for this excellent job.. (Jacques Desmis JDC or frej83) +void ImProcFunctions::MLsharpen (LabImage* lab) { +// JD: this algorithm maximize clarity of images; it does not play on accutance. It can remove (partialy) the effects of the AA filter) +// I think we can use this algorithm alone in most cases, or first to clarify image and if you want a very little USM (unsharp mask sharpening) after... + if (params->clarity.enabled==false) + return; + MyTime t1e,t2e; + t1e.set(); + + int offset,c,i,j,p,width2; + int width = lab->W, height = lab->H; + float *L,lumH,lumV,lumD1,lumD2,v,contrast,med,s; + float difL,difR,difT,difB,difLT,difRB,difLB,difRT,wH,wV,wD1,wD2,chmax[3]; + float f1,f2,f3,f4; + float templab; + int iii,kkk; + width2=2*width; + float strength; + strength=params->clarity.clstrength / 100.0f; + if(strength < 0.00001f) return; + + if (settings->verbose) printf ("Clarity strength %f\n", strength); + + L = new float[width*height]; + + chmax[0]=8.0f; + chmax[1]=3.0f; + chmax[2]=3.0f; + + int channels; + if(params->clarity.clthreechannels) channels=0; else channels=2; + if (settings->verbose) printf ("Clarity channels %d\n", channels); + + int passes=params->clarity.clpasses; + if (settings->verbose) printf ("Clarity passes %d\n", passes); + + for(p=0;pL[ii][kk]/327.68f; // adjust to RT and to 0..100 + else if (c==1) L[offset]=lab->a[ii][kk]/327.68f; + else if (c==2) L[offset]=lab->b[ii][kk]/327.68f; + } + #pragma omp parallel for private(j,i,iii,kkk, templab,offset,wH,wV,wD1,wD2,s,lumH,lumV,lumD1,lumD2,v,contrast,f1,f2,f3,f4,difT,difB,difL,difR,difLT,difLB,difRT,difRB) shared(lab,L,strength) + for(j=2;jL[ii][kk]/327.68f; + else if (c==1) lumH=lumV=lumD1=lumD2=v=lab->a[ii][kk]/327.68f; + else if (c==2) lumH=lumV=lumD1=lumD2=v=lab->b[ii][kk]/327.68f; + + + // contrast detection + contrast=sqrt(fabs(L[offset+1]-L[offset-1])*fabs(L[offset+1]-L[offset-1])+fabs(L[offset+width]-L[offset-width])*fabs(L[offset+width]-L[offset-width]))/chmax[c]; + if(contrast>1.0) contrast=1.0; + + // new possible values + if((L[offset]L[offset+1])||(L[offset]>L[offset-1])&&(L[offset]L[offset+width])||(L[offset]>L[offset-width])&&(L[offset]L[offset+1+width])||(L[offset]>L[offset-1-width])&&(L[offset]L[offset-1+width])||(L[offset]>L[offset+1-width])&&(L[offset]0.05f))||((fabs(wV/wH)<0.45f)&&(fabs(wV/wH)>0.05f))) s=strength/3.0f; + + // final mix + if((wH!=0.0f)&&(wV!=0.0f)&&(wD1!=0.0f)&&(wD2!=0.0f)) { + iii=offset/width; + kkk=offset-iii*width; + templab=v*(1-s)+(lumH*wH+lumV*wV+lumD1*wD1+lumD2*wD2)/(wH+wV+wD1+wD2)*s; + if(c==0) lab->L[iii][kkk]=fabs(327.68f*templab);// fabs because lab->L always >0 + else if (c==1){lab->a[iii][kkk]=327.68f*templab;} + else if (c==2)lab->b[iii][kkk]=327.68f*templab; + } + + } + } + + delete [] L; + + t2e.set(); + if( settings->verbose ) + printf("Clarity gradient %d usec\n", t2e.etime(t1e)); + + } + + // To the extent possible under law, Manuel Llorens + // has waived all copyright and related or neighboring rights to this work. + // This code is licensed under CC0 v1.0, see license information at + // http://creativecommons.org/publicdomain/zero/1.0/ + // addition from JD : pyramid + ponderated contrast with matrix 5x5 + void ImProcFunctions::MLmicrocontrast(LabImage* lab){ + if (params->clarity.enabledtwo==false) + return; + MyTime t1e,t2e; + t1e.set(); + int k; + if(params->clarity.MLmicromatrix == false) k=2; else k=1; + // k=2 matrix 5x5 k=1 matrix 3x3 + + int offset,offset2,c,i,j,col,row,n; + float temp,temp2,temp3,temp4,tempL; + float *LM,v,s,contrast,w; + int signs[25]; + int width = lab->W, height = lab->H; + float uniform=params->clarity.uniformity;//between 0 to 100 + int unif; + unif=(int)(uniform/10.0f); //put unif between 0 to 10 + float strength=params->clarity.mlstrength/1500.0f; //strength 2000.0 quasi no artefacts ==> 1500 = maximum, after artefacts + if(strength < 0.000001f) return; + if(k==1) strength*=2.0f;//25/9, but reality # 2 + if (settings->verbose) printf ("Microcontrast strength %f\n", strength); + if (settings->verbose) printf ("Microcontrast uniformity %i\n",unif); + //modualtion uniformity in function of luminance + float L98[11]={0.0012f,0.0015f,0.002f,0.004f,0.006f,0.008f,0.01f,0.03f,0.05f,0.1f,0.1f}; + float L95[11]={0.0015f,0.0025f,0.005f,0.01f,0.02f,0.05f,0.1f,0.12f,0.15f,0.2f,0.25f}; + float L92[11]={0.01f,0.015f,0.02f,0.06f,0.10f,0.13f,0.17f,0.25f,0.3f,0.32f,0.35f}; + float L90[11]={0.015f,0.02f,0.04f,0.08f,0.12f,0.15f,0.2f,0.3f,0.4f,0.5f,0.6f}; + float L87[11]={0.025f,0.03f,0.05f,0.1f,0.15f,0.25f,0.3f,0.4f,0.5f,0.63f,0.75f}; + float L83[11]={0.055f,0.08f,0.1f,0.15f,0.2f,0.3f,0.4f,0.5f,0.6f,0.75f,0.85f}; + float L80[11]={0.15f,0.2f,0.25f,0.3f,0.35f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f}; + float L75[11]={0.22f,0.25f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.85f,0.9f,0.95f}; + float L70[11]={0.35f,0.4f,0.5f,0.6f,0.7f,0.8f,0.97f,1.0f,1.0f,1.0f,1.0f}; + float L63[11]={0.55f,0.6f,0.7f,0.8f,0.85f,0.9f,1.0f,1.0f,1.0f,1.0f,1.0f}; + float L58[11]={0.75f,0.77f,0.8f,0.9f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f}; + //default 5 + + float chmax=8.0f; + LM = new float[width*height];//allocation for Luminance + c=0; + #pragma omp parallel for private(offset, i,j) shared(LM) + for(j=0;jL[j][i]/327.68f;// adjust to 0.100 and to RT variables + } + + #pragma omp parallel for private(j,i,offset,s,signs,v,n,row,col,offset2,contrast,temp,w,temp2,temp3,tempL,temp4) shared(lab,LM,strength,chmax,unif,k,L98,L95,L92,L90,L87,L83,L80,L75,L70,L63,L58) + for(j=k;jLM[offset2]) signs[n]=1; + n++; + } + if(k==1) contrast=sqrt(fabs(LM[offset+1]-LM[offset-1])*fabs(LM[offset+1]-LM[offset-1])+fabs(LM[offset+width]-LM[offset-width])*fabs(LM[offset+width]-LM[offset-width]))/chmax; //for 3x3 + else if(k==2) contrast=sqrt(fabs(LM[offset+1]-LM[offset-1])*fabs(LM[offset+1]-LM[offset-1])+fabs(LM[offset+width]-LM[offset-width])*fabs(LM[offset+width]-LM[offset-width])\ + +fabs(LM[offset+2]-LM[offset-2])*fabs(LM[offset+2]-LM[offset-2])+fabs(LM[offset+2*width]-LM[offset-2*width])*fabs(LM[offset+2*width]-LM[offset-2*width]))/(2*chmax); //for 5x5 + + if(contrast>1.0f) contrast=1.0f; + //matrix 5x5 + temp=lab->L[j][i]/327.68f; //begin 3x3 + temp +=(v-LM[offset-width-1])*sqrtf(2.0f)*s; + temp +=(v-LM[offset-width])*s; + temp +=(v-LM[offset-width+1])*sqrtf(2.0f)*s; + temp +=(v-LM[offset-1])*s; + temp +=(v-LM[offset+1])*s; + temp +=(v-LM[offset+width-1])*sqrtf(2.0f)*s; + temp +=(v-LM[offset+width])*s; + temp +=(v-LM[offset+width+1])*sqrtf(2.0f)*s;//end 3x3 + + // add JD continue 5x5 + if(k==2) { + temp +=2.0f*(v-LM[offset+2*width])*s; + temp +=2.0f*(v-LM[offset-2*width])*s; + temp +=2.0f*(v-LM[offset-2])*s; + temp +=2.0f*(v-LM[offset+2])*s; + + temp +=2.0f*(v-LM[offset+2*width -1])*s*sqrtf(1.25f);// 1.25 = 1*1 + 0.5*0.5 + temp +=2.0f*(v-LM[offset+2*width -2])*s*sqrtf(2.0f); + temp +=2.0f*(v-LM[offset+2*width+1])*s*sqrtf(1.25f);; + temp +=2.0f*(v-LM[offset+2*width+2])*s*sqrtf(2.0f); + temp +=2.0f*(v-LM[offset+ width+2])*s*sqrtf(1.25f);; + temp +=2.0f*(v-LM[offset+width-2])*s*sqrtf(1.25f);; + temp +=2.0f*(v-LM[offset-2*width -1])*s*sqrtf(1.25f); + temp +=2.0f*(v-LM[offset-2*width -2])*s*sqrtf(2.0f); + temp +=2.0f*(v-LM[offset-2*width+1])*s*sqrtf(1.25f);; + temp +=2.0f*(v-LM[offset-2*width+2])*s*sqrtf(2.0f); + temp +=2.0f*(v-LM[offset- width+2])*s*sqrtf(1.25f);; + temp +=2.0f*(v-LM[offset-width-2])*s*sqrtf(1.25f);; + } + if(temp <0.0f) temp=0.0f; + v=temp; + + n=0; + + for(row=j-k;row<=j+k;row++) + for(col=i-k,offset2=row*width+col;col<=i+k;col++,offset2++){ + if(((v0))||((v>LM[offset2])&&(signs[n]<0))) + { + temp =v*0.75f+LM[offset2]*0.25f;// 0.75 0.25 + n++; + } + } + if(LM[offset]>95.0f || LM[offset]<5.0f) contrast*=0.05f; //+ JD : luminance pyramid to adjust contrast and avoid pseudo halo by evaluation of LM[offset] + else if(LM[offset]>90.0f || LM[offset]<10.0f) contrast*=0.3f; + else if(LM[offset]>80.0f || LM[offset]<20.0f) contrast*=0.5f; + else if(LM[offset]>70.0f || LM[offset]<30.0f) contrast*=0.6f; + else if(LM[offset]>60.0f || LM[offset]<40.0f) contrast*=0.7f; + else contrast*=0.8f; + if(contrast>1.0f) contrast=1.0f; + tempL=327.68f*(temp*(1.0f-contrast)+LM[offset]*contrast); + // JD: modulation of microcontrast in function of original Luminance and modulation of luminance + temp2=tempL/(327.68f*LM[offset]);//for highlights + if(temp2>1.0f) { + if(LM[offset]>98.0f) {temp3=temp2-1.0f;temp=(L98[unif]*temp3)+1.0f;lab->L[j][i]=temp*LM[offset]*327.68f;} + else if(LM[offset]>95.0f) {temp3=temp2-1.0f;temp=(L95[unif]*temp3)+1.0f;lab->L[j][i]=temp*LM[offset]*327.68f;} + else if(LM[offset]>92.0f) {temp3=temp2-1.0f;temp=(L92[unif]*temp3)+1.0f;lab->L[j][i]=temp*LM[offset]*327.68f;} + else if(LM[offset]>90.0f) {temp3=temp2-1.0f;temp=(L90[unif]*temp3)+1.0f;lab->L[j][i]=temp*LM[offset]*327.68f;} + else if(LM[offset]>87.0f) {temp3=temp2-1.0f;temp=(L87[unif]*temp3)+1.0f;lab->L[j][i]=temp*LM[offset]*327.68f;} + else if(LM[offset]>83.0f) {temp3=temp2-1.0f;temp=(L83[unif]*temp3)+1.0f;lab->L[j][i]=temp*LM[offset]*327.68f;} + else if(LM[offset]>80.0f) {temp3=temp2-1.0f;temp=(L80[unif]*temp3)+1.0f;lab->L[j][i]=temp*LM[offset]*327.68f;} + else if(LM[offset]>75.0f) {temp3=temp2-1.0f;temp=(L75[unif]*temp3)+1.0f;lab->L[j][i]=temp*LM[offset]*327.68f;} + else if(LM[offset]>70.0f) {temp3=temp2-1.0f;temp=(L70[unif]*temp3)+1.0f;lab->L[j][i]=temp*LM[offset]*327.68f;} + else if(LM[offset]>63.0f) {temp3=temp2-1.0f;temp=(L63[unif]*temp3)+1.0f;lab->L[j][i]=temp*LM[offset]*327.68f;} + else if(LM[offset]>58.0f) {temp3=temp2-1.0f;temp=(L58[unif]*temp3)+1.0f;lab->L[j][i]=temp*LM[offset]*327.68f;} + + else lab->L[j][i]=tempL;//no modulation for L <58 + } + temp4=(327.68f*LM[offset])/tempL;//for lowlights + if(temp4>1.0f) { + if(LM[offset]<2.0f) {temp3=temp4-1.0f;temp=(L98[unif]*temp3)+1.0f;lab->L[j][i]=(LM[offset]*327.68f)/temp;} + else if(LM[offset]<5.0f) {temp3=temp4-1.0f;temp=(L95[unif]*temp3)+1.0f;lab->L[j][i]=(LM[offset]*327.68f)/temp;} + else if(LM[offset]<8.0f) {temp3=temp4-1.0f;temp=(L92[unif]*temp3)+1.0f;lab->L[j][i]=(LM[offset]*327.68f)/temp;} + else if(LM[offset]<10.0f) {temp3=temp4-1.0f;temp=(L90[unif]*temp3)+1.0f;lab->L[j][i]=(LM[offset]*327.68f)/temp;} + else if(LM[offset]<13.0f) {temp3=temp4-1.0f;temp=(L87[unif]*temp3)+1.0f;lab->L[j][i]=(LM[offset]*327.68f)/temp;} + else if(LM[offset]<17.0f) {temp3=temp4-1.0f;temp=(L83[unif]*temp3)+1.0f;lab->L[j][i]=(LM[offset]*327.68f)/temp;} + else if(LM[offset]<20.0f) {temp3=temp4-1.0f;temp=(L80[unif]*temp3)+1.0f;lab->L[j][i]=(LM[offset]*327.68f)/temp;} + else if(LM[offset]<25.0f) {temp3=temp4-1.0f;temp=(L75[unif]*temp3)+1.0f;lab->L[j][i]=(LM[offset]*327.68f)/temp;} + else if(LM[offset]<30.0f) {temp3=temp4-1.0f;temp=(L70[unif]*temp3)+1.0f;lab->L[j][i]=(LM[offset]*327.68f)/temp;} + else if(LM[offset]<37.0f) {temp3=temp4-1.0f;temp=(L63[unif]*temp3)+1.0f;lab->L[j][i]=(LM[offset]*327.68f)/temp;} + else if(LM[offset]<42.0f) {temp3=temp4-1.0f;temp=(L58[unif]*temp3)+1.0f;lab->L[j][i]=(LM[offset]*327.68f)/temp;} + + else lab->L[j][i]=tempL;//no modulation for L>42 + } + + } + + delete [] LM; + t2e.set(); + if( settings->verbose ) + printf("Microcontrast %d usec\n", t2e.etime(t1e)); + + } } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 984337257..a0e5ef224 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -163,7 +163,15 @@ enum ProcEvent { EvPreProcessExpBlacktwo=138, EvPreProcessExpBlackthree=139, EvPreProcessExptwoGreen=140, - NUMOFEVENTS=141 + EvClaritypasses=141, + EvClaritystrength=142, + EvMLmicrostrength=143, + EvMLuniformity=144, + EvClarityEnabled=145, + EvClaritythreechannels=146, + EvClarityEnabledtwo=147, + EvClaritymatrix=148, + NUMOFEVENTS=149 }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 3d3ae27f8..81e135ae8 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -90,8 +90,17 @@ void ProcParams::setDefaults () { labCurve.acurve.push_back(DCT_Linear); labCurve.bcurve.clear (); labCurve.bcurve.push_back(DCT_Linear); - - sharpening.enabled = true; + + clarity.enabled = false; + clarity.clpasses = 2; + clarity.clstrength = 50.0; + clarity.enabledtwo = false; + clarity.mlstrength = 20.0; + clarity.uniformity = 50.0; + clarity.clthreechannels = false; + clarity.MLmicromatrix = false; + + sharpening.enabled = false; sharpening.radius = 1.0; sharpening.amount = 90; sharpening.threshold = 768; @@ -326,7 +335,17 @@ int ProcParams::save (Glib::ustring fname) const { keyFile.set_integer ("Sharpening", "DeconvAmount", sharpening.deconvamount); keyFile.set_integer ("Sharpening", "DeconvDamping", sharpening.deconvdamping); keyFile.set_integer ("Sharpening", "DeconvIterations", sharpening.deconviter); - + //save clarity + keyFile.set_boolean ("Clarity", "Enabled", clarity.enabled); + keyFile.set_integer ("Clarity", "Clpasses", clarity.clpasses); + keyFile.set_double ("Clarity", "Clstrength", clarity.clstrength); + keyFile.set_boolean ("Clarity", "Clthreechannels", clarity.clthreechannels); + keyFile.set_boolean ("Clarity", "Enabledtwo", clarity.enabledtwo); + keyFile.set_double ("Clarity", "Mlstrength", clarity.mlstrength); + keyFile.set_double ("Clarity", "Uniformity", clarity.uniformity); + keyFile.set_boolean ("Clarity", "Matrix", clarity.MLmicromatrix); + + // save colorBoost keyFile.set_integer ("Color Boost", "Amount", colorBoost.amount); keyFile.set_boolean ("Color Boost", "AvoidColorClipping", colorBoost.avoidclip); @@ -615,7 +634,22 @@ if (keyFile.has_group ("Sharpening")) { if (keyFile.has_key ("Sharpening", "DeconvDamping")) sharpening.deconvdamping = keyFile.get_integer ("Sharpening", "DeconvDamping"); if (keyFile.has_key ("Sharpening", "DeconvIterations")) sharpening.deconviter = keyFile.get_integer ("Sharpening", "DeconvIterations"); } - + + +if (keyFile.has_group ("Clarity")) { + if (keyFile.has_key ("Clarity", "Enabled")) clarity.enabled = keyFile.get_boolean ("Clarity", "Enabled"); + if (keyFile.has_key ("Clarity", "Clpasses")) clarity.clpasses = keyFile.get_integer ("Clarity", "Clpasses"); + if (keyFile.has_key ("Clarity", "Clstrength")) clarity.clstrength = keyFile.get_double ("Clarity", "Clstrength"); + if (keyFile.has_key ("Clarity", "Clthreechannels")) clarity.clthreechannels = keyFile.get_boolean ("Clarity", "Clthreechannels"); + if (keyFile.has_key ("Clarity", "Enabledtwo")) clarity.enabledtwo = keyFile.get_boolean ("Clarity", "Enabledtwo"); + if (keyFile.has_key ("Clarity", "Matrix")) clarity.MLmicromatrix = keyFile.get_boolean ("Clarity", "Matrix"); + + if (keyFile.has_key ("Clarity", "Mlstrength")) clarity.mlstrength = keyFile.get_double ("Clarity", "Mlstrength"); + if (keyFile.has_key ("Clarity", "Uniformity")) clarity.uniformity = keyFile.get_double ("Clarity", "Uniformity"); + + +} + // load colorBoost if (keyFile.has_group ("Color Boost")) { if (keyFile.has_key ("Color Boost", "Amount")) colorBoost.amount = keyFile.get_integer ("Color Boost", "Amount"); @@ -923,7 +957,15 @@ bool ProcParams::operator== (const ProcParams& other) { && labCurve.saturation == other.labCurve.saturation && labCurve.avoidclip == other.labCurve.avoidclip && labCurve.enable_saturationlimiter == other.labCurve.enable_saturationlimiter - && labCurve.saturationlimit == other.labCurve.saturationlimit + && labCurve.saturationlimit == other.labCurve.saturationlimit + && clarity.enabled == other.clarity.enabled + && clarity.clpasses == other.clarity.clpasses + && clarity.clstrength == other.clarity.clstrength + && clarity.enabledtwo == other.clarity.enabledtwo + && clarity.mlstrength == other.clarity.mlstrength + && clarity.uniformity == other.clarity.uniformity + && clarity.MLmicromatrix == other.clarity.MLmicromatrix + && clarity.clthreechannels == other.clarity.clthreechannels && sharpening.enabled == other.sharpening.enabled && sharpening.radius == other.sharpening.radius && sharpening.amount == other.sharpening.amount diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 6a0235c4a..989fcee60 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -83,7 +83,17 @@ class SharpeningParams { int deconviter; int deconvdamping; }; - +class ClarityParams { + public: + bool enabled; + int clpasses; + double clstrength; + bool enabledtwo; + double mlstrength; + bool clthreechannels; + double uniformity; + bool MLmicromatrix; +}; /** * Parameters of the color boost */ @@ -443,6 +453,7 @@ class ProcParams { ToneCurveParams toneCurve; ///< Tone curve parameters LCurveParams labCurve; ///< CIELAB luminance curve parameters SharpeningParams sharpening; ///< Sharpening parameters + ClarityParams clarity; ColorBoostParams colorBoost; ///< Color boost parameters WBParams wb; ///< White balance parameters ColorShiftParams colorShift; ///< Color shift parameters diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 1cf81ad2b..2dc300e55 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -161,7 +161,13 @@ DARKFRAME, // EvPreProcessExpBlackone DARKFRAME, // EvPreProcessExpBlacktwo DARKFRAME, // EvPreProcessExpBlackthree DARKFRAME, //EvPreProcessExptwoGreen - - +SHARPENING, //EvClaritypasses +SHARPENING, //EvClaritystrength +SHARPENING, //EvMLmicrostrength +SHARPENING, //EvMLuniformity +SHARPENING, //EvClarityEnabled +SHARPENING, //EvClaritythreechannels +SHARPENING, //EvClarityEnabledtwo +SHARPENING, //EvClaritymatrix }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index df320e616..ef346cc76 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -178,7 +178,12 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p ipf.defringe (labView); //ipf.lumadenoise (labView, buffer); ipf.dirpyrdenoise (labView); - + if (params.clarity.enabled) { + ipf.MLsharpen(labView); + } + if (params.clarity.enabledtwo) { + ipf.MLmicrocontrast (labView); + } if (params.sharpening.enabled) { float** buffer = new float*[fh]; for (int i=0; isetAdjusterBehavior (false); //lumadenoise->setAdjusterBehavior (false); sharpening->setAdjusterBehavior (false); + clarity->setAdjusterBehavior (false, false, false, false); + chmixer->setAdjusterBehavior (false); shadowshighlights->setAdjusterBehavior (false, false, false); dirpyrequalizer->setAdjusterBehavior (false); @@ -151,6 +153,8 @@ void BatchToolPanelCoordinator::initSession () { //colorboost->setAdjusterBehavior (options.baBehav[ADDSET_CBOOST_AMOUNT]); //lumadenoise->setAdjusterBehavior (options.baBehav[ADDSET_LD_EDGETOLERANCE]); sharpening->setAdjusterBehavior (options.baBehav[ADDSET_SHARP_AMOUNT]); + clarity->setAdjusterBehavior (options.baBehav[ADDSET_CLAR_STREN],options.baBehav[ADDSET_CLAR_MLSTREN],options.baBehav[ADDSET_CLAR_PASS],options.baBehav[ADDSET_CLAR_UNIFORMITY]); + chmixer->setAdjusterBehavior (options.baBehav[ADDSET_CHMIXER]); shadowshighlights->setAdjusterBehavior (options.baBehav[ADDSET_SH_HIGHLIGHTS], options.baBehav[ADDSET_SH_SHADOWS], options.baBehav[ADDSET_SH_LOCALCONTRAST]); dirpyrequalizer->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYREQ]); @@ -176,6 +180,12 @@ void BatchToolPanelCoordinator::initSession () { if (options.baBehav[ADDSET_LC_SATURATION]) pparams.labCurve.saturation = 0; if (options.baBehav[ADDSET_SHARP_AMOUNT]) pparams.sharpening.amount = 0; + if (options.baBehav[ADDSET_CLAR_STREN]) pparams.clarity.clstrength = 0; + if (options.baBehav[ADDSET_CLAR_MLSTREN]) pparams.clarity.mlstrength = 0; + if (options.baBehav[ADDSET_CLAR_PASS]) pparams.clarity.clpasses = 0; + if (options.baBehav[ADDSET_CLAR_UNIFORMITY]) pparams.clarity.uniformity = 0; + + if (options.baBehav[ADDSET_CHMIXER]) for (int i=0; i<3; i++) pparams.chmixer.red[i] = pparams.chmixer.green[i] = pparams.chmixer.blue[i] = 0; if (options.baBehav[ADDSET_LD_EDGETOLERANCE]) pparams.lumaDenoise.edgetolerance = 0; diff --git a/rtgui/clarity.cc b/rtgui/clarity.cc new file mode 100644 index 000000000..743335fa4 --- /dev/null +++ b/rtgui/clarity.cc @@ -0,0 +1,343 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * 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. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include + + + +using namespace rtengine; +using namespace rtengine::procparams; + + + +Clarity::Clarity () : Gtk::VBox(), FoldableToolPanel(this) +{ + + Gtk::HSeparator *hsep66aa = Gtk::manage (new Gtk::HSeparator()); + pack_start(*hsep66aa, Gtk::PACK_SHRINK, 2); + hsep66aa->show (); + Gtk::Label* clsh = Gtk::manage (new Gtk::Label ()); + clsh->set_alignment (0.0, 0.5); + clsh->set_markup (Glib::ustring("") + M("TP_CLARITY_SHARPEN") + ""); + clsh->show (); + pack_start (*clsh); + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (true); + pack_start(*enabled); + enabled->show (); + + Claritypasses = Gtk::manage(new Adjuster (M("TP_CLARITY_PASSES"),1,4,1,1)); + Claritypasses->setAdjusterListener (this); + if (Claritypasses->delay < 1000) Claritypasses->delay = 1000; + Claritypasses->show(); + Claritystrength = Gtk::manage(new Adjuster (M("TP_CLARITY_STRENGTH"),0,100,1,40)); + Claritystrength->setAdjusterListener (this); + if (Claritystrength->delay < 1000) Claritystrength->delay = 1000; + Claritystrength->show(); + + Claritythreechannels = Gtk::manage(new Gtk::CheckButton((M("TP_CLARITY_THREE"))));// L + a + b + Claritythreechannels->set_active (false); + pack_start( *Claritypasses, Gtk::PACK_SHRINK, 4);//passes + pack_start( *Claritystrength, Gtk::PACK_SHRINK, 4);//strength + pack_start( *Claritythreechannels, Gtk::PACK_SHRINK, 4);//one or 3 channels Lab + Claritythreechannels->show(); + Gtk::HSeparator *hsep67aa = Gtk::manage (new Gtk::HSeparator()); + pack_start(*hsep67aa, Gtk::PACK_SHRINK, 2); + hsep67aa->show (); + Gtk::Label* clmc = Gtk::manage (new Gtk::Label ()); + clmc->set_alignment (0.0, 0.5); + clmc->set_markup (Glib::ustring("") + M("TP_CLARITY_MICRO") + ""); + clmc->show (); + pack_start (*clmc); + enabledtwo = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabledtwo->set_active (true); + pack_start(*enabledtwo); + enabledtwo->show (); + + + MLmicrostrength= Gtk::manage(new Adjuster (M("TP_MLMICRO_STRENGTH"),0,100,1,25)); + MLmicrostrength->setAdjusterListener (this); + if (MLmicrostrength->delay < 1000) MLmicrostrength->delay = 1000; + MLmicrostrength->show(); + uniformity= Gtk::manage(new Adjuster (M("TP_MLMICRO_UNIFORMITY"),0,100,10,50)); + + uniformity->setAdjusterListener (this); + if (uniformity->delay < 1000) uniformity->delay = 1000; + uniformity->show(); + MLmicromatrix = Gtk::manage (new Gtk::CheckButton (M("TP_CLARITY_MATRIX"))); + MLmicromatrix->set_active (true); + pack_start(*MLmicromatrix); + MLmicromatrix->show (); + + pack_start( *MLmicrostrength, Gtk::PACK_SHRINK, 4);//microcontraste strength + pack_start( *uniformity, Gtk::PACK_SHRINK, 4);//uniformity + + enaconn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Clarity::enabled_toggled) ); + chanthreeconn = Claritythreechannels->signal_toggled().connect( sigc::mem_fun(*this, &Clarity::chanthree_toggled) ); + enatwoconn = enabledtwo->signal_toggled().connect( sigc::mem_fun(*this, &Clarity::enabledtwo_toggled) ); + matrixconn = MLmicromatrix->signal_toggled().connect( sigc::mem_fun(*this, &Clarity::MLmicromatrix_toggled) ); + +} +Clarity::~Clarity () { + +} + +void Clarity::read(const ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + + if(pedited ){ + Claritypasses->setEditedState (pedited->clarity.clpasses ? Edited : UnEdited); + Claritystrength->setEditedState (pedited->clarity.clstrength ? Edited : UnEdited); + MLmicrostrength->setEditedState (pedited->clarity.mlstrength ? Edited : UnEdited); + uniformity->setEditedState (pedited->clarity.uniformity ? Edited : UnEdited); + enabled->set_inconsistent (!pedited->clarity.enabled); + Claritythreechannels->set_inconsistent (!pedited->clarity.clthreechannels); + enabledtwo->set_inconsistent (!pedited->clarity.enabledtwo); + MLmicromatrix->set_inconsistent (!pedited->clarity.MLmicromatrix); + + } + enaconn.block (true); + enabled->set_active (pp->clarity.enabled); + enaconn.block (false); + lastEnabled = pp->clarity.enabled; + + enatwoconn.block (true); + enabledtwo->set_active (pp->clarity.enabledtwo); + enatwoconn.block (false); + lastEnabledtwo = pp->clarity.enabledtwo; + + chanthreeconn.block (true); + Claritythreechannels->set_active (pp->clarity.clthreechannels); + chanthreeconn.block (false); + lastchanthree = pp->clarity.clthreechannels; + + matrixconn.block (true); + MLmicromatrix->set_active (pp->clarity.MLmicromatrix); + matrixconn.block (false); + lastmatrix = pp->clarity.MLmicromatrix; + + Claritypasses->setValue (pp->clarity.clpasses); + Claritystrength->setValue (pp->clarity.clstrength); + MLmicrostrength->setValue (pp->clarity.mlstrength); + uniformity->setValue (pp->clarity.uniformity); + + enableListener (); +} + +void Clarity::write( ProcParams* pp, ParamsEdited* pedited) +{ + pp->clarity.clpasses = (int)Claritypasses->getValue(); + pp->clarity.enabled = enabled->get_active (); + pp->clarity.clstrength = Claritystrength->getValue (); + pp->clarity.mlstrength = MLmicrostrength->getValue (); + pp->clarity.uniformity = uniformity->getValue (); + pp->clarity.clthreechannels = Claritythreechannels->get_active (); + pp->clarity.enabledtwo = enabledtwo->get_active (); + pp->clarity.MLmicromatrix = MLmicromatrix->get_active (); + + + if (pedited) { + pedited->clarity.clpasses = Claritypasses->getEditedState (); + pedited->clarity.enabled = !enabled->get_inconsistent(); + pedited->clarity.clthreechannels = !Claritythreechannels->get_inconsistent(); + pedited->clarity.clstrength = Claritystrength->getEditedState (); + pedited->clarity.mlstrength = MLmicrostrength->getEditedState (); + pedited->clarity.uniformity = uniformity->getEditedState (); + pedited->clarity.enabledtwo = !enabledtwo->get_inconsistent(); + pedited->clarity.MLmicromatrix = !MLmicromatrix->get_inconsistent(); + + } + +} + +void Clarity::enabled_toggled () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaconn.block (true); + enabled->set_active (false); + enaconn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvClarityEnabled, M("GENERAL_ENABLED")); + // listener->panelChanged (EvMLunifor, M("GENERAL_ENABLED")); + + else + listener->panelChanged (EvClarityEnabled, M("GENERAL_DISABLED")); + } +} +void Clarity::enabledtwo_toggled () { + + if (batchMode) { + if (enabledtwo->get_inconsistent()) { + enabledtwo->set_inconsistent (false); + enatwoconn.block (true); + enabledtwo->set_active (false); + enatwoconn.block (false); + } + else if (lastEnabledtwo) + enabledtwo->set_inconsistent (true); + + lastEnabledtwo = enabledtwo->get_active (); + } + + if (listener) { + if (enabledtwo->get_active ()) + listener->panelChanged (EvClarityEnabledtwo, M("GENERAL_ENABLED")); + + else + listener->panelChanged (EvClarityEnabledtwo, M("GENERAL_DISABLED")); + + } +} + +void Clarity::chanthree_toggled () { + + if (batchMode) { + if (Claritythreechannels->get_inconsistent()) { + Claritythreechannels->set_inconsistent (false); + chanthreeconn.block (true); + Claritythreechannels->set_active (false); + chanthreeconn.block (false); + } + else if (lastchanthree) + Claritythreechannels->set_inconsistent (true); + + lastchanthree = Claritythreechannels->get_active (); + } + + if (listener && enabled->get_active ()) { + if (Claritythreechannels->get_active ()) + listener->panelChanged (EvClaritythreechannels, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvClaritythreechannels, M("GENERAL_DISABLED")); + } +} + +void Clarity::MLmicromatrix_toggled () { + if (batchMode) { + if (MLmicromatrix->get_inconsistent()) { + MLmicromatrix->set_inconsistent (false); + matrixconn.block (true); + MLmicromatrix->set_active (false); + matrixconn.block (false); + } + else if (lastmatrix) + MLmicromatrix->set_inconsistent (true); + + lastmatrix = MLmicromatrix->get_active (); + } + + if (listener && enabledtwo->get_active ()) { + if (MLmicromatrix->get_active ()) + listener->panelChanged (EvClaritymatrix, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvClaritymatrix, M("GENERAL_DISABLED")); + } + +} + + +void Clarity::adjusterChanged (Adjuster* a, double newval) +{ + if (listener && enabled->get_active()) { + Glib::ustring value = a->getTextValue(); + { + + if (a == Claritypasses ) + listener->panelChanged (EvClaritypasses, value ); + else if (a == Claritystrength) + listener->panelChanged (EvClaritystrength, value ); + } + + } + if (listener && enabledtwo->get_active()) { + Glib::ustring value = a->getTextValue(); + { + if (a == MLmicrostrength) + listener->panelChanged (EvMLmicrostrength, value ); + else if (a == uniformity) + listener->panelChanged (EvMLuniformity, value ); + + } + + } + + + +} + +void Clarity::setBatchMode(bool batchMode) +{ + Claritypasses->showEditedCB (); + Claritystrength->showEditedCB (); + MLmicrostrength->showEditedCB (); + uniformity->showEditedCB (); + +} + +void Clarity::setDefaults(const ProcParams* defParams, const ParamsEdited* pedited) +{ + Claritypasses->setDefault (defParams->clarity.clpasses); + Claritystrength->setDefault (defParams->clarity.clstrength); + MLmicrostrength->setDefault (defParams->clarity.mlstrength); + uniformity->setDefault (defParams->clarity.uniformity); + + if (pedited) { + Claritypasses->setDefaultEditedState (pedited->clarity.clpasses ? Edited : UnEdited); + Claritystrength->setDefaultEditedState (pedited->clarity.clstrength ? Edited : UnEdited); + MLmicrostrength->setDefaultEditedState (pedited->clarity.mlstrength ? Edited : UnEdited); + uniformity->setDefaultEditedState (pedited->clarity.uniformity ? Edited : UnEdited); + + } else { + Claritypasses->setDefaultEditedState (Irrelevant); + Claritystrength->setDefaultEditedState (Irrelevant); + MLmicrostrength->setDefaultEditedState (Irrelevant); + uniformity->setDefaultEditedState (Irrelevant); + + } +} + +void Clarity::setAdjusterBehavior (bool strengthadd, bool mlstrentghadd, bool passadd, bool uniformityadd ) { + Claritystrength->setAddMode(strengthadd); + MLmicrostrength->setAddMode(mlstrentghadd); + Claritypasses->setAddMode(passadd); + uniformity->setAddMode(uniformityadd); +} + +void Clarity::trimValues (ProcParams* pp) { + Claritystrength->trimValue(pp->clarity.clstrength); + MLmicrostrength->trimValue(pp->clarity.mlstrength); + Claritypasses->trimValue(pp->clarity.clpasses); + uniformity->trimValue(pp->clarity.uniformity); + +} diff --git a/rtgui/clarity.h b/rtgui/clarity.h new file mode 100644 index 000000000..32e4c2b96 --- /dev/null +++ b/rtgui/clarity.h @@ -0,0 +1,70 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * 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. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _CLARITY_H_ +#define _CLARITY_H_ + +#include +#include +#include + +class Clarity : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* Claritypasses; + Adjuster* Claritystrength; + + Adjuster* MLmicrostrength; + Adjuster* uniformity; + Gtk::CheckButton* enabled; + Gtk::CheckButton* Claritythreechannels; + Gtk::CheckButton* enabledtwo; + Gtk::CheckButton* MLmicromatrix; + + bool lastEnabled; + bool lastEnabledtwo; + sigc::connection enaconn; + sigc::connection enatwoconn; + sigc::connection matrixconn; + + sigc::connection chanthreeconn; + bool lastchanthree; + bool lastmatrix; + + public: + + Clarity (); + virtual ~Clarity (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool strengthadd, bool mlstrentghadd, bool passadd, bool uniformityadd ); + void enabled_toggled(); + void enabledtwo_toggled(); + void MLmicromatrix_toggled(); + + void chanthree_toggled(); + void trimValues (rtengine::procparams::ProcParams* pp); + +}; + +#endif diff --git a/rtgui/options.cc b/rtgui/options.cc index 3bd5caa29..056bb9b63 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -186,7 +186,11 @@ void Options::setDefaults () { 0, // ADDSET_RAWCACORR 1, // ADDSET_RAWEXPOS_LINEAR 1, // ADDSET_RAWEXPOS_PRESER - 1 // ADDSET_RAWEXPOS_BLACKS + 1, // ADDSET_RAWEXPOS_BLACKS + 0, // ADDSET_CLAR_STREN + 0, // ADDSET_CLAR_MLSTREN + 0, // ADDSET_CLAR_PASS + 0 // ADDSET_CLAR_RELAT }; baBehav = std::vector (babehav, babehav+ADDSET_PARAM_NUM); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 9cb444602..c86aeca6e 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -62,6 +62,14 @@ void ParamsEdited::set (bool v) { sharpening.deconvradius = v; sharpening.deconviter = v; sharpening.deconvdamping = v; + clarity.clpasses = v; + clarity.clstrength = v; + clarity.mlstrength = v; + clarity.uniformity = v; + clarity.enabled = v; + clarity.enabledtwo = v; + clarity.clthreechannels = v; + clarity.MLmicromatrix = v; colorBoost.amount = v; colorBoost.avoidclip = v; colorBoost.enable_saturationlimiter = v; @@ -215,6 +223,14 @@ void ParamsEdited::initFrom (const std::vector labCurve.avoidclip = labCurve.avoidclip && p.labCurve.avoidclip == other.labCurve.avoidclip; labCurve.enable_saturationlimiter = labCurve.enable_saturationlimiter && p.labCurve.enable_saturationlimiter == other.labCurve.enable_saturationlimiter; labCurve.saturationlimit = labCurve.saturationlimit && p.labCurve.saturationlimit == other.labCurve.saturationlimit; + clarity.enabled = clarity.enabled && p.clarity.enabled == other.clarity.enabled; + clarity.clpasses = clarity.clpasses && p.clarity.clpasses == other.clarity.clpasses; + clarity.clstrength = clarity.clstrength && p.clarity.clstrength == other.clarity.clstrength; + clarity.enabledtwo = clarity.enabledtwo && p.clarity.enabledtwo == other.clarity.enabledtwo; + clarity.MLmicromatrix = clarity.MLmicromatrix && p.clarity.MLmicromatrix == other.clarity.MLmicromatrix; + clarity.mlstrength = clarity.mlstrength && p.clarity.mlstrength == other.clarity.mlstrength; + clarity.uniformity = clarity.uniformity && p.clarity.uniformity == other.clarity.uniformity; + clarity.clthreechannels = clarity.clthreechannels && p.clarity.clthreechannels == other.clarity.clthreechannels; sharpening.enabled = sharpening.enabled && p.sharpening.enabled == other.sharpening.enabled; sharpening.radius = sharpening.radius && p.sharpening.radius == other.sharpening.radius; sharpening.amount = sharpening.amount && p.sharpening.amount == other.sharpening.amount; @@ -379,6 +395,14 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (labCurve.avoidclip) toEdit.labCurve.avoidclip = mods.labCurve.avoidclip; if (labCurve.enable_saturationlimiter)toEdit.labCurve.enable_saturationlimiter = mods.labCurve.enable_saturationlimiter; if (labCurve.saturationlimit) toEdit.labCurve.saturationlimit = mods.labCurve.saturationlimit; + if (clarity.enabled) toEdit.clarity.enabled = mods.clarity.enabled; + if (clarity.clpasses) toEdit.clarity.clpasses = dontforceSet && options.baBehav[ADDSET_CLAR_PASS] ? toEdit.clarity.clpasses + mods.clarity.clpasses : mods.clarity.clpasses; + if (clarity.clstrength) toEdit.clarity.clstrength = dontforceSet && options.baBehav[ADDSET_CLAR_STREN] ? toEdit.clarity.clstrength + mods.clarity.clstrength : mods.clarity.clstrength; + if (clarity.enabledtwo) toEdit.clarity.enabledtwo = mods.clarity.enabledtwo; + if (clarity.MLmicromatrix) toEdit.clarity.MLmicromatrix = mods.clarity.MLmicromatrix; + if (clarity.mlstrength) toEdit.clarity.mlstrength = dontforceSet && options.baBehav[ADDSET_CLAR_MLSTREN] ? toEdit.clarity.mlstrength + mods.clarity.mlstrength : mods.clarity.mlstrength; + if (clarity.uniformity) toEdit.clarity.uniformity = dontforceSet && options.baBehav[ADDSET_CLAR_UNIFORMITY] ? toEdit.clarity.uniformity + mods.clarity.uniformity : mods.clarity.uniformity; + if (clarity.clthreechannels) toEdit.clarity.clthreechannels = mods.clarity.clthreechannels; if (sharpening.enabled) toEdit.sharpening.enabled = mods.sharpening.enabled; if (sharpening.radius) toEdit.sharpening.radius = mods.sharpening.radius; if (sharpening.amount) toEdit.sharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.amount + mods.sharpening.amount : mods.sharpening.amount; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 662547fb6..58555f97a 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -54,6 +54,19 @@ class LCurveParamsEdited { bool bcurve; }; +class ClarityParamsEdited { + public : + + bool clpasses; + bool clstrength; + bool mlstrength; + bool enabled; + bool enabledtwo; + bool clthreechannels; + bool uniformity; + bool MLmicromatrix; +}; + class SharpeningParamsEdited { public: @@ -327,7 +340,9 @@ class ParamsEdited { public: ToneCurveParamsEdited toneCurve; LCurveParamsEdited labCurve; - SharpeningParamsEdited sharpening; + SharpeningParamsEdited sharpening; + ClarityParamsEdited clarity; + ColorBoostParamsEdited colorBoost; WBParamsEdited wb; ColorShiftParamsEdited colorShift; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 767146ca6..9a8c27076 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -168,6 +168,14 @@ Gtk::Widget* Preferences::getBatchProcPanel () { mi->set_value (behavColumns.label, M("TP_SHARPENING_LABEL")); appendBehavList (mi, M("TP_SHARPENING_AMOUNT"), ADDSET_SHARP_AMOUNT, false); + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_CLARITY_LABEL")); + appendBehavList (mi, M("TP_CLARITY_PASSES"), ADDSET_CLAR_PASS, false); + appendBehavList (mi, M("TP_CLARITY_STRENGTH"), ADDSET_CLAR_STREN, false); + appendBehavList (mi, M("TP_MLMICRO_STRENGTH"), ADDSET_CLAR_MLSTREN, false); + appendBehavList (mi, M("TP_MLMICRO_UNIFORMITY"), ADDSET_CLAR_UNIFORMITY, false); + + //mi = behModel->append (); //mi->set_value (behavColumns.label, M("TP_LUMADENOISE_LABEL")); //appendBehavList (mi, M("TP_LUMADENOISE_EDGETOLERANCE"), ADDSET_LD_EDGETOLERANCE, true); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 96ae6eeaa..3c6c06df7 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -44,6 +44,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { defringe = Gtk::manage (new Defringe ()); dirpyrdenoise = Gtk::manage (new DirPyrDenoise ()); sharpening = Gtk::manage (new Sharpening ()); + clarity = Gtk::manage (new Clarity ()); lcurve = Gtk::manage (new LCurve ()); //colorboost = Gtk::manage (new ColorBoost ()); //colorshift = Gtk::manage (new ColorShift ()); @@ -77,6 +78,8 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { addPanel (colorPanel, chmixer, M("TP_CHMIXER_LABEL")); toolPanels.push_back (chmixer); addPanel (exposurePanel, shadowshighlights, M("TP_SHADOWSHLIGHTS_LABEL")); toolPanels.push_back (shadowshighlights); addPanel (detailsPanel, sharpening, M("TP_SHARPENING_LABEL")); toolPanels.push_back (sharpening); + addPanel (detailsPanel, clarity, M("TP_CLARITY_LABEL")); toolPanels.push_back (clarity); + //addPanel (colorPanel, colorboost, M("TP_COLORBOOST_LABEL")); toolPanels.push_back (colorboost); //addPanel (colorPanel, colorshift, M("TP_COLORSHIFT_LABEL")); toolPanels.push_back (colorshift); addPanel (colorPanel, hsvequalizer, M("TP_HSVEQUALIZER_LABEL")); toolPanels.push_back (hsvequalizer); diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index ea6b66b18..9b4804e2d 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -63,7 +63,7 @@ #include #include #include - +#include class ImageEditorCoordinator; class ToolPanelCoordinator : public ToolPanelListener, @@ -101,6 +101,7 @@ class ToolPanelCoordinator : public ToolPanelListener, ImpulseDenoise* impulsedenoise; DirPyrDenoise* dirpyrdenoise; Sharpening* sharpening; + Clarity* clarity; LCurve* lcurve; //Equalizer * equalizer; DirPyrEqualizer * dirpyrequalizer;