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;