Wavelet levels improvements issue2702

This commit is contained in:
jdc
2015-07-05 06:42:35 +02:00
parent af3bb68bf9
commit 4d5081909f
10 changed files with 444 additions and 27 deletions

View File

@@ -535,9 +535,9 @@ HISTORY_MSG_302;NR - Chroma method
HISTORY_MSG_303;NR - Chroma method
HISTORY_MSG_304;W - Contrast levels
HISTORY_MSG_305;Wavelet Levels
HISTORY_MSG_306;W - Preview
HISTORY_MSG_307;W - Preview
HISTORY_MSG_308;W - Preview direction
HISTORY_MSG_306;W - Process
HISTORY_MSG_307;W - Process
HISTORY_MSG_308;W - Process direction
HISTORY_MSG_309;W - ES - Detail
HISTORY_MSG_310;W - Residual - Sky tar/prot
HISTORY_MSG_311;W - Wavelet levels
@@ -614,6 +614,14 @@ HISTORY_MSG_381;PRS RLD - Radius
HISTORY_MSG_382;PRS RLD - Amount
HISTORY_MSG_383;PRS RLD - Damping
HISTORY_MSG_384;PRS RLD - Iterations
HISTORY_MSG_385;W - Residual - Color Balance
HISTORY_MSG_386;W - Residual - CB green high
HISTORY_MSG_387;W - Residual - CB blue high
HISTORY_MSG_388;W - Residual - CB green mid
HISTORY_MSG_389;W - Residual - CB blue mid
HISTORY_MSG_390;W - Residual - CB green low
HISTORY_MSG_391;W - Residual - CB blue low
HISTORY_MSG_392;W - Residual - CB Reset
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b>
HISTORY_SNAPSHOTS;Snapshots
@@ -1708,10 +1716,10 @@ TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a functio
TP_WAVELET_DALL;All directions
TP_WAVELET_DAUB;Edge performance
TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses.
TP_WAVELET_DISP;Preview Settings
TP_WAVELET_DONE;Vertical
TP_WAVELET_DTHR;Diagonal
TP_WAVELET_DTWO;Horizontal
TP_WAVELET_DISP;Wavelet settings
TP_WAVELET_EDCU;Curve
TP_WAVELET_EDGCONT;Local contrast
TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima
@@ -1769,7 +1777,7 @@ TP_WAVELET_OPACITYW;Contrast balance d/v-h curve
TP_WAVELET_OPACITY;Opacity Blue-Yellow
TP_WAVELET_PASTEL;Pastel chromaticity
TP_WAVELET_PREVIEWBACK;Background
TP_WAVELET_PREVIEWLEVELS;Preview
TP_WAVELET_PREVIEWLEVELS;Process
TP_WAVELET_RE1;Reinforced
TP_WAVELET_RE2;Unchanged
TP_WAVELET_RE3;Reduced
@@ -1811,6 +1819,9 @@ TP_WAVELET_daub4;D4 - standard
TP_WAVELET_daub6;D6 - standard plus
TP_WAVELET_daub10;D10 - medium
TP_WAVELET_daub14;D14 - high
TP_WAVELET_CBTYPE;Toning and Color Balance
TP_WAVELET_CBENAB;Toning and Color Balance
TP_WAVELET_CB_TOOLTIP;For strong values product color-toning by combining it or not with levels decomposition 'toning'\nFor low values you can change the white balance of the background (sky, ...) without changing that of the front plane, generally more contrasted
TP_WBALANCE_AUTO;Auto
TP_WBALANCE_CAMERA;Camera
TP_WBALANCE_CLOUDY;Cloudy

View File

@@ -135,6 +135,14 @@ struct cont_params {
bool opaW;
int BAmet;
bool bam;
float blhigh;
float grhigh;
float blmed;
float grmed;
float bllow;
float grlow;
bool cbena;
};
int wavNestedLevels = 1;
@@ -215,7 +223,15 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int
cp.EDmet=1;
if(params->wavelet.EDmethod=="SL") cp.EDmet=1;
if(params->wavelet.EDmethod=="CU") cp.EDmet=2;
cp.cbena= params->wavelet.cbenab;
cp.blhigh=(float)params->wavelet.bluehigh;
cp.grhigh=(float)params->wavelet.greenhigh;
cp.blmed=(float)params->wavelet.bluemed;
cp.grmed=(float)params->wavelet.greenmed;
cp.bllow=(float)params->wavelet.bluelow;
cp.grlow=(float)params->wavelet.greenlow;
printf("blmed=%f grmed=%f\n",cp.blmed,cp.grmed);
cp.curv=false;
cp.edgcurv=false;
cp.diagcurv=false;
@@ -438,7 +454,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int
numthreads = MIN(numtiles,omp_get_max_threads());
if(maxnumberofthreadsforwavelet > 0)
numthreads = MIN(numthreads,maxnumberofthreadsforwavelet);
numthreads = MIN(numthreads,maxnumberofthreadsforwavelet);
#ifdef _RT_NESTED_OPENMP
wavNestedLevels = omp_get_max_threads() / numthreads;
bool oldNested = omp_get_nested();
@@ -448,7 +464,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int
omp_set_nested(true);
if(maxnumberofthreadsforwavelet > 0)
while(wavNestedLevels*numthreads > maxnumberofthreadsforwavelet)
wavNestedLevels--;
wavNestedLevels--;
#endif
if(settings->verbose)
printf("Ip Wavelet uses %d main thread(s) and up to %d nested thread(s) for each main thread\n",numthreads,wavNestedLevels);
@@ -699,7 +715,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int
if(!hhutili) {//always a or b
int levwava = levwav;
// printf("Levwava before: %d\n",levwava);
if(cp.chrores == 0.f && params->wavelet.CLmethod=="all") { // no processing of residual ab => we probably can reduce the number of levels
if(cp.chrores == 0.f && params->wavelet.CLmethod=="all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels
while(levwava > 0 && !cp.diag &&(((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwava-1] == 0.f )) || (cp.CHmet!=2 && (levwava == 10 || (!cp.curv || (cp.curv && cp.mulC[levwava-1] == 0.f)))))) && (!cp.opaRG || levwava == 10 || (cp.opaRG && cp.mulopaRG[levwava-1] == 0.f)) && ((levwava == 10 ||(cp.CHSLmet==1 && cp.mulC[levwava-1] == 0.f)))) {
levwava--;
}
@@ -715,7 +731,7 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int
}
int levwavb = levwav;
//printf("Levwavb before: %d\n",levwavb);
if(cp.chrores == 0.f && params->wavelet.CLmethod=="all") { // no processing of residual ab => we probably can reduce the number of levels
if(cp.chrores == 0.f && params->wavelet.CLmethod=="all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels
while(levwavb > 0 && !cp.diag && (((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwavb-1] == 0.f )) || (cp.CHmet!=2 && (levwavb == 10 || (!cp.curv || (cp.curv && cp.mulC[levwavb-1] == 0.f)))))) && (!cp.opaBY || levwavb == 10 || (cp.opaBY && cp.mulopaBY[levwavb-1] == 0.f)) && ((levwavb == 10 ||(cp.CHSLmet==1 && cp.mulC[levwavb-1] == 0.f)))) {
levwavb--;
}
@@ -1080,9 +1096,9 @@ omp_set_nested(oldNested);
sigmaN[level]=SN;
MaxP[level]=maxLP;
MaxN[level]=maxLN;
if(params->wavelet.CLmethod!="all") {//display only if user choose different from all
printf("Ind=%d Level=%d MadL=%f AvL=%f AvN=%f SL=%f SN=%f maxP=%f maxN=%f\n",ind, level,MADL,mean[level],meanN[level],sigma[level],sigmaN[level],MaxP[level],MaxN[level]);
}
// if(params->wavelet.CLmethod!="all") {//display only if user choose different from all
// printf("Ind=%d Level=%d MadL=%f AvL=%f AvN=%f SL=%f SN=%f maxP=%f maxN=%f\n",ind, level,MADL,mean[level],meanN[level],sigma[level],sigmaN[level],MaxP[level],MaxN[level]);
// }
}
float *ImProcFunctions::ContrastDR(float *Source, int skip, struct cont_params cp, int W_L, int H_L, float Compression,float DetailBoost,float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Contrast){
@@ -1222,7 +1238,7 @@ void ImProcFunctions::ContrastResid(float * WavCoeffs_L0, unsigned int Iterates
else if (cp.TMmeth ==2) {min0 = 0.0f;}
#ifdef _RT_NESTED_OPENMP
#pragma omp parallel for
#endif
#endif
for(int i = 0; i < W_L*H_L; i++)
{ WavCoeffs_L0[i]= (WavCoeffs_L0[i] - min0)/max0;
WavCoeffs_L0[i]*=gamm;
@@ -1261,7 +1277,7 @@ void ImProcFunctions::ContrastResid(float * WavCoeffs_L0, unsigned int Iterates
// max0=32768.f;
#ifdef _RT_NESTED_OPENMP
#pragma omp parallel for
#endif
#endif
for(int i = 0; i < W_L*H_L; i++)
{ WavCoeffs_L0[i]= (WavCoeffs_L0[i] - min0)/max0;
WavCoeffs_L0[i]*=gamm;
@@ -1341,14 +1357,14 @@ void ImProcFunctions::WaveletcontAllLfinal(LabImage * labco, float ** varhue, fl
#ifdef _RT_NESTED_OPENMP
#pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1)
#endif
#endif
{
float lminL = FLT_MAX;
float lmaxL = 0.f;
#ifdef _RT_NESTED_OPENMP
#pragma omp for
#endif
#endif
for(int i = 0; i < W_L*H_L; i++) {
if(WavCoeffs_L0[i] < lminL) lminL = WavCoeffs_L0[i];
if(WavCoeffs_L0[i] > lmaxL) lmaxL = WavCoeffs_L0[i];
@@ -1356,7 +1372,7 @@ void ImProcFunctions::WaveletcontAllLfinal(LabImage * labco, float ** varhue, fl
}
#ifdef _RT_NESTED_OPENMP
#pragma omp critical
#endif
#endif
{ if(lminL < min0) min0 = lminL;
if(lmaxL > max0) max0 = lmaxL;
}
@@ -1436,7 +1452,7 @@ if(cp.tonemap && cp.contmet==1) {
float minp=min0*256.f;
#ifdef _RT_NESTED_OPENMP
#pragma omp single
#endif
#endif
ContrastResid(WavCoeffs_L0, 5, skip, cp, W_L, H_L, maxp, minp, ave, ah, bh, al, bl, factorx );
}
#ifdef _RT_NESTED_OPENMP
@@ -1720,9 +1736,68 @@ if(cp.detectedge && lipschitz==true) { //enabled Lipschitz control...more memory
*/
}
WavCoeffs_ab0[i]*=(1.f+cp.chrores*(scale)/100.f);
}
}
if(cp.cbena) {//if user select Toning and color balance
#ifdef _RT_NESTED_OPENMP
#pragma omp for nowait
#endif
for (int i=0; i<W_L*H_L; i++) {
int ii = i/W_L;
int jj = i-ii*W_L;
float LL = (labco->L[ii*2][jj*2])/327.68f;//I use labco but I can use also WavCoeffs_L0 (more exact but more memory)
float sca=1.f;//amplifer - reducter...about 1, but perhaps 0.6 or 1.3
if(useChannelA) {//green red (little magenta)
//transition to avoid artifacts with 6 between 30 to 36 and 63 to 69
float aa=(cp.grmed-cp.grlow)/6.f;
float bb= cp.grlow-30.f*aa;
float aaa=(cp.grhigh-cp.grmed)/6.f;
float bbb= cp.grmed-63.f*aaa;
if(LL < 30.f)//shadows
WavCoeffs_ab0[i]+=cp.grlow*(sca)*300.f;
else if(LL >= 30.f && LL < 36.f) {//transition
float tr=aa*LL+bb;
WavCoeffs_ab0[i]+= tr*(sca)*300.f;
}
else if(LL >= 36.f && LL < 63.f)//midtones
WavCoeffs_ab0[i]+=cp.grmed*(sca)*300.f;
else if(LL >= 63.f && LL < 69.f) {//transition
float trh=aaa*LL+bbb;
WavCoeffs_ab0[i]+=trh*(sca)*300.f;
}
else if(LL >= 69.f)//highlights
WavCoeffs_ab0[i]+=cp.grhigh*(sca)*300.f;
}
else {//blue yellow
//transition with 6 between 30 to 36 and 63 to 69
float aa1=(cp.blmed-cp.bllow)/6.f;
float bb1= cp.bllow-30.f*aa1;
float aaa1=(cp.blhigh-cp.blmed)/6.f;
float bbb1= cp.blmed-63.f*aaa1;
if(LL < 30.f)
WavCoeffs_ab0[i]+=cp.bllow*(sca)*300.f;
else if(LL >= 30.f && LL < 36.f) {
float tr1=aa1*LL+bb1;
WavCoeffs_ab0[i]+=tr1*(sca)*300.f;
}
else if(LL >= 36.f && LL < 63.f)
WavCoeffs_ab0[i]+=cp.blmed*(sca)*300.f;
else if(LL >= 63.f && LL < 69.f) {
float trh1=aaa1*LL+bbb1;
WavCoeffs_ab0[i]+=trh1*(sca)*300.f;
}
else if(LL >= 69.f)
WavCoeffs_ab0[i]+=cp.blhigh*(sca)*300.f;
}
}
}
#ifdef _RT_NESTED_OPENMP
#pragma omp for schedule(dynamic) collapse(2)
#endif
@@ -2645,9 +2720,12 @@ if(cp.BAmet==1){
}
if(useOpacity && level < 9 && mulOpacity != 0.f) { //toning
float beta = (1024.f + 20.f * mulOpacity)/1024.f ;
//float beta = (1000.f * mulOpacity);
for (int i=0; i<W_ab*H_ab; i++)
WavCoeffs_ab[dir][i] *= beta;
// WavCoeffs_ab[dir][i] += beta;
}
if(waOpacityCurveW) cp.opaW=true;

View File

@@ -409,8 +409,16 @@ enum ProcEvent {
EvPrShrDAmount=381,
EvPrShrDDamping=382,
EvPrShrDIterations=383,
NUMOFEVENTS
EvWavcbenab=384,
EvWavgreenhigh=385,
EvWavbluehigh=386,
EvWavgreenmed=387,
EvWavbluemed=388,
EvWavgreenlow=389,
EvWavbluelow=390,
EvWavNeutral=391,
NUMOFEVENTS
};
}
#endif

View File

@@ -494,6 +494,7 @@ void WaveletParams::setDefaults() {
median = false;
medianlev = false;
linkedg = true;
cbenab = false;
lipst = false;
Medgreinf = "less"; //"none";
avoid = false;
@@ -1627,6 +1628,13 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
if (!pedited || pedited->wavelet.Backmethod) keyFile.set_string ("Wavelet", "BackMethod", wavelet.Backmethod);
if (!pedited || pedited->wavelet.Lmethod) keyFile.set_string ("Wavelet", "LevMethod", wavelet.Lmethod);
if (!pedited || pedited->wavelet.Dirmethod) keyFile.set_string ("Wavelet", "DirMethod", wavelet.Dirmethod);
if (!pedited || pedited->wavelet.greenhigh) keyFile.set_integer ("Wavelet", "CBgreenhigh", wavelet.greenhigh);
if (!pedited || pedited->wavelet.greenmed) keyFile.set_integer ("Wavelet", "CBgreenmed", wavelet.greenmed);
if (!pedited || pedited->wavelet.greenlow) keyFile.set_integer ("Wavelet", "CBgreenlow", wavelet.greenlow);
if (!pedited || pedited->wavelet.bluehigh) keyFile.set_integer ("Wavelet", "CBbluehigh", wavelet.bluehigh);
if (!pedited || pedited->wavelet.bluemed) keyFile.set_integer ("Wavelet", "CBbluemed", wavelet.bluemed);
if (!pedited || pedited->wavelet.bluelow) keyFile.set_integer ("Wavelet", "CBbluelow", wavelet.bluelow);
for(int i = 0; i < 9; i++)
{
std::stringstream ss;
@@ -1727,6 +1735,7 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
if (!pedited || pedited->wavelet.median) keyFile.set_boolean ("Wavelet", "Median", wavelet.median);
if (!pedited || pedited->wavelet.medianlev) keyFile.set_boolean ("Wavelet", "Medianlev", wavelet.medianlev);
if (!pedited || pedited->wavelet.linkedg) keyFile.set_boolean ("Wavelet", "Linkedg", wavelet.linkedg);
if (!pedited || pedited->wavelet.cbenab) keyFile.set_boolean ("Wavelet", "CBenab", wavelet.cbenab);
if (!pedited || pedited->wavelet.lipst) keyFile.set_boolean ("Wavelet", "Lipst", wavelet.lipst);
// if (!pedited || pedited->wavelet.edgreinf) keyFile.set_boolean ("Wavelet", "Edgreinf", wavelet.edgreinf);
if (!pedited || pedited->wavelet.skinprotect) keyFile.set_double ("Wavelet", "Skinprotect", wavelet.skinprotect);
@@ -2511,6 +2520,13 @@ if (keyFile.has_group ("Wavelet")) {
if (keyFile.has_key ("Wavelet", "Median")) {wavelet.median = keyFile.get_boolean ("Wavelet", "Median");if (pedited) pedited->wavelet.median = true;}
if (keyFile.has_key ("Wavelet", "Medianlev")) {wavelet.medianlev = keyFile.get_boolean ("Wavelet", "Medianlev");if (pedited) pedited->wavelet.medianlev = true;}
if (keyFile.has_key ("Wavelet", "Linkedg")) {wavelet.linkedg = keyFile.get_boolean ("Wavelet", "Linkedg");if (pedited) pedited->wavelet.linkedg = true;}
if (keyFile.has_key ("Wavelet", "CBenab")) {wavelet.cbenab = keyFile.get_boolean ("Wavelet", "CBenab");if (pedited) pedited->wavelet.cbenab = true;}
if (keyFile.has_key ("Wavelet", "CBgreenhigh")) { wavelet.greenhigh = keyFile.get_integer ("Wavelet", "CBgreenhigh"); if (pedited) pedited->wavelet.greenhigh = true; }
if (keyFile.has_key ("Wavelet", "CBgreenmed")) { wavelet.greenmed = keyFile.get_integer ("Wavelet", "CBgreenmed"); if (pedited) pedited->wavelet.greenmed = true; }
if (keyFile.has_key ("Wavelet", "CBgreenlow")) { wavelet.greenlow = keyFile.get_integer ("Wavelet", "CBgreenlow"); if (pedited) pedited->wavelet.greenlow = true; }
if (keyFile.has_key ("Wavelet", "CBbluehigh")) { wavelet.bluehigh = keyFile.get_integer ("Wavelet", "CBbluehigh"); if (pedited) pedited->wavelet.bluehigh = true; }
if (keyFile.has_key ("Wavelet", "CBbluemed")) { wavelet.bluemed = keyFile.get_integer ("Wavelet", "CBbluemed"); if (pedited) pedited->wavelet.bluemed = true; }
if (keyFile.has_key ("Wavelet", "CBbluelow")) { wavelet.bluelow = keyFile.get_integer ("Wavelet", "CBbluelow"); if (pedited) pedited->wavelet.bluelow = true; }
// if (keyFile.has_key ("Wavelet", "Edgreinf")) {wavelet.edgreinf = keyFile.get_boolean ("Wavelet", "Edgreinf");if (pedited) pedited->wavelet.edgreinf = true;}
if (keyFile.has_key ("Wavelet", "Lipst")) {wavelet.lipst = keyFile.get_boolean ("Wavelet", "Lipst");if (pedited) pedited->wavelet.lipst = true;}
if (keyFile.has_key ("Wavelet", "AvoidColorShift")) {wavelet.avoid = keyFile.get_boolean ("Wavelet", "AvoidColorShift");if (pedited) pedited->wavelet.avoid = true;}
@@ -3196,6 +3212,7 @@ bool ProcParams::operator== (const ProcParams& other) {
&& wavelet.median == other.wavelet.median
&& wavelet.medianlev == other.wavelet.medianlev
&& wavelet.linkedg == other.wavelet.linkedg
&& wavelet.cbenab == other.wavelet.cbenab
&& wavelet.lipst == other.wavelet.lipst
&& wavelet.Medgreinf == other.wavelet.Medgreinf
&& wavelet.edgrad == other.wavelet.edgrad
@@ -3229,6 +3246,12 @@ bool ProcParams::operator== (const ProcParams& other) {
&& wavelet.skinprotect == other.wavelet.skinprotect
&& wavelet.strength == other.wavelet.strength
&& wavelet.balance == other.wavelet.balance
&& wavelet.greenhigh == other.wavelet.greenhigh
&& wavelet.greenmed == other.wavelet.greenmed
&& wavelet.greenlow == other.wavelet.greenlow
&& wavelet.bluehigh == other.wavelet.bluehigh
&& wavelet.bluemed == other.wavelet.bluemed
&& wavelet.bluelow == other.wavelet.bluelow
&& wavelet.iter == other.wavelet.iter
&& dirpyrequalizer == other.dirpyrequalizer
// && dirpyrequalizer.algo == other.dirpyrequalizer.algo

View File

@@ -871,6 +871,14 @@ class WaveletParams {
bool median;
bool medianlev;
bool linkedg;
bool cbenab;
double greenlow;
double bluelow;
double greenmed;
double bluemed;
double greenhigh;
double bluehigh;
bool lipst;
// bool edgreinf;
bool avoid;

View File

@@ -405,7 +405,15 @@ RESIZE, // EvPrShrMethod=379,
RESIZE, // EvPrShrDRadius=380,
RESIZE, // EvPrShrDAmount=381,
RESIZE, // EvPrShrDDamping=382,
RESIZE // EvPrShrDIterations=383,
RESIZE, // EvPrShrDIterations=383,
DIRPYREQUALIZER, // EvWavcbenab
DIRPYREQUALIZER, // EvWavgreenhigh
DIRPYREQUALIZER, // EvWavbluehigh
DIRPYREQUALIZER, // EvWavgreenmed
DIRPYREQUALIZER, // EvWavbluemed
DIRPYREQUALIZER, // EvWavgreenlow
DIRPYREQUALIZER, // EvWavbluelow
DIRPYREQUALIZER // EvWavNeutral
};

View File

@@ -357,6 +357,13 @@ void ParamsEdited::set (bool v) {
wavelet.median = v;
wavelet.medianlev = v;
wavelet.linkedg = v;
wavelet.cbenab = v;
wavelet.greenhigh = v;
wavelet.greenmed = v;
wavelet.greenlow = v;
wavelet.bluehigh = v;
wavelet.bluemed = v;
wavelet.bluelow = v;
wavelet.lipst = v;
wavelet.Medgreinf = v;
wavelet.avoid = v;
@@ -781,6 +788,13 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
wavelet.median = wavelet.median && p.wavelet.median == other.wavelet.median;
wavelet.medianlev = wavelet.medianlev && p.wavelet.medianlev == other.wavelet.medianlev;
wavelet.linkedg = wavelet.linkedg && p.wavelet.linkedg == other.wavelet.linkedg;
wavelet.cbenab = wavelet.cbenab && p.wavelet.cbenab == other.wavelet.cbenab;
wavelet.greenmed = wavelet.greenmed && p.wavelet.greenmed == other.wavelet.greenmed;
wavelet.bluemed = wavelet.bluemed && p.wavelet.bluemed == other.wavelet.bluemed;
wavelet.greenhigh = wavelet.greenhigh && p.wavelet.greenhigh == other.wavelet.greenhigh;
wavelet.bluehigh = wavelet.bluehigh && p.wavelet.bluehigh == other.wavelet.bluehigh;
wavelet.greenlow = wavelet.greenlow && p.wavelet.greenlow == other.wavelet.greenlow;
wavelet.bluelow = wavelet.bluelow && p.wavelet.bluelow == other.wavelet.bluelow;
wavelet.lipst = wavelet.lipst && p.wavelet.lipst == other.wavelet.lipst;
wavelet.Medgreinf = wavelet.Medgreinf && p.wavelet.Medgreinf == other.wavelet.Medgreinf;
wavelet.avoid = wavelet.avoid && p.wavelet.avoid == other.wavelet.avoid;
@@ -1209,6 +1223,13 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (wavelet.median) toEdit.wavelet.median = mods.wavelet.median;
if (wavelet.medianlev) toEdit.wavelet.medianlev = mods.wavelet.medianlev;
if (wavelet.linkedg) toEdit.wavelet.linkedg = mods.wavelet.linkedg;
if (wavelet.cbenab) toEdit.wavelet.cbenab = mods.wavelet.cbenab;
if (wavelet.greenhigh) toEdit.wavelet.greenhigh = mods.wavelet.greenhigh;
if (wavelet.bluehigh) toEdit.wavelet.bluehigh = mods.wavelet.bluehigh;
if (wavelet.greenmed) toEdit.wavelet.greenmed = mods.wavelet.greenmed;
if (wavelet.bluemed) toEdit.wavelet.bluemed = mods.wavelet.bluemed;
if (wavelet.greenlow) toEdit.wavelet.greenlow = mods.wavelet.greenlow;
if (wavelet.bluelow) toEdit.wavelet.bluelow = mods.wavelet.bluelow;
if (wavelet.lipst) toEdit.wavelet.lipst = mods.wavelet.lipst;
if (wavelet.Medgreinf) toEdit.wavelet.Medgreinf = mods.wavelet.Medgreinf;
if (wavelet.avoid) toEdit.wavelet.avoid = mods.wavelet.avoid;

View File

@@ -483,6 +483,7 @@ class WaveletParamsEdited {
bool median;
bool medianlev;
bool linkedg;
bool cbenab;
bool lipst;
bool Medgreinf;
bool avoid;
@@ -541,6 +542,13 @@ class WaveletParamsEdited {
bool pastlev;
bool satlev;
bool wavclCurve;
bool greenlow;
bool bluelow;
bool greenmed;
bool bluemed;
bool greenhigh;
bool bluehigh;
};
class DirPyrEqualizerParamsEdited {

View File

@@ -729,6 +729,93 @@ Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"),
resBox->pack_start (*curveEditorRES, Gtk::PACK_SHRINK, 4);
//color balance
Gtk::HSeparator *separatorCB = Gtk::manage (new Gtk::HSeparator());
Gtk::VBox *chanMixerHLBox = Gtk::manage (new Gtk::VBox());
Gtk::VBox *chanMixerMidBox = Gtk::manage (new Gtk::VBox());
Gtk::VBox *chanMixerShadowsBox = Gtk::manage (new Gtk::VBox());
cbenab = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_CBENAB")));
cbenab->set_active (true);
cbenabConn = cbenab->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::cbenabToggled) );
cbenab->set_tooltip_text (M("TP_WAVELET_CB_TOOLTIP"));
Gtk::Image* iblueR = Gtk::manage (new RTImage ("ajd-wb-temp1.png"));
Gtk::Image* iyelL = Gtk::manage (new RTImage ("ajd-wb-temp2.png"));
Gtk::Image* imagL = Gtk::manage (new RTImage ("ajd-wb-green1.png"));
Gtk::Image* igreenR = Gtk::manage (new RTImage ("ajd-wb-green2.png"));
Gtk::Image* iblueRm = Gtk::manage (new RTImage ("ajd-wb-temp1.png"));
Gtk::Image* iyelLm = Gtk::manage (new RTImage ("ajd-wb-temp2.png"));
Gtk::Image* imagLm = Gtk::manage (new RTImage ("ajd-wb-green1.png"));
Gtk::Image* igreenRm = Gtk::manage (new RTImage ("ajd-wb-green2.png"));
Gtk::Image* iblueRh = Gtk::manage (new RTImage ("ajd-wb-temp1.png"));
Gtk::Image* iyelLh = Gtk::manage (new RTImage ("ajd-wb-temp2.png"));
Gtk::Image* imagLh = Gtk::manage (new RTImage ("ajd-wb-green1.png"));
Gtk::Image* igreenRh = Gtk::manage (new RTImage ("ajd-wb-green2.png"));
greenhigh = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., igreenRh, imagLh));
bluehigh = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., iblueRh, iyelLh));
greenmed = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., igreenRm, imagLm));
bluemed = Gtk::manage (new Adjuster ("", -100., 100., 1., 0. , iblueRm , iyelLm));
greenlow = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., igreenR, imagL));
bluelow = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., iblueR , iyelL));
chanMixerHLBox->pack_start (*greenhigh);
chanMixerHLBox->pack_start (*bluehigh);
chanMixerMidBox->pack_start (*greenmed);
chanMixerMidBox->pack_start (*bluemed);
chanMixerShadowsBox->pack_start (*greenlow);
chanMixerShadowsBox->pack_start (*bluelow);
greenlow->setAdjusterListener (this);
bluelow->setAdjusterListener (this);
greenmed->setAdjusterListener (this);
bluemed->setAdjusterListener (this);
greenhigh->setAdjusterListener (this);
bluehigh->setAdjusterListener (this);
resBox->pack_start(*separatorCB, Gtk::PACK_SHRINK);
chanMixerHLFrame = Gtk::manage (new Gtk::Frame(M("TP_COLORTONING_HIGHLIGHT")));
chanMixerMidFrame = Gtk::manage (new Gtk::Frame(M("TP_COLORTONING_MIDTONES")));
chanMixerShadowsFrame = Gtk::manage (new Gtk::Frame(M("TP_COLORTONING_SHADOWS")));
chanMixerHLFrame->add(*chanMixerHLBox);
chanMixerMidFrame->add(*chanMixerMidBox);
chanMixerShadowsFrame->add(*chanMixerShadowsBox);
resBox->pack_start(*cbenab);
resBox->pack_start(*chanMixerHLFrame, Gtk::PACK_SHRINK);
resBox->pack_start(*chanMixerMidFrame, Gtk::PACK_SHRINK);
resBox->pack_start(*chanMixerShadowsFrame, Gtk::PACK_SHRINK);
//--------------------- Reset sliders ---------------------------
neutrHBox = Gtk::manage (new Gtk::HBox ());
neutrHBox->set_border_width (2);
neutral = Gtk::manage (new Gtk::Button (M("TP_COLORTONING_NEUTRAL")));
RTImage *resetImg = Gtk::manage (new RTImage ("gtk-undo-ltr-small.png", "gtk-undo-rtl-small.png"));
neutral->set_image(*resetImg);
neutral->set_tooltip_text (M("TP_COLORTONING_NEUTRAL_TIP"));
neutralconn = neutral->signal_pressed().connect( sigc::mem_fun(*this, &Wavelet::neutral_pressed) );
neutral->show();
neutrHBox->pack_start (*neutral);
resBox->pack_start (*neutrHBox);
//--------------------------------------
//final touchup
ctboxBA = Gtk::manage (new Gtk::HBox ());
@@ -901,6 +988,20 @@ void Wavelet::updatewavLabel () {
}
}
}
// Will only reset the chanel mixer
void Wavelet::neutral_pressed () {
disableListener();
greenlow->resetValue(false);
bluelow->resetValue(false);
greenmed->resetValue(false);
bluemed->resetValue(false);
greenhigh->resetValue(false);
bluehigh->resetValue(false);
enableListener();
if (listener && getEnabled())
listener->panelChanged (EvWavNeutral, M("ADJUSTER_RESET_TO_DEFAULT"));
}
void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) {
@@ -918,6 +1019,7 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) {
TMmethodconn.block(true);
HSmethodconn.block(true);
MedgreinfConn.block(true);
cbenabConn.block(true);
HSmethod->set_active (1);
if (pp->wavelet.HSmethod=="without")
@@ -1099,11 +1201,21 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) {
edgedetectthr2->setEditedState (pedited->wavelet.edgedetectthr2 ? Edited : UnEdited);
chroma->setEditedState (pedited->wavelet.chroma ? Edited : UnEdited);
chro->setEditedState (pedited->wavelet.chro ? Edited : UnEdited);
greenlow->setEditedState (pedited->wavelet.greenlow ? Edited : UnEdited);
bluelow->setEditedState (pedited->wavelet.bluelow ? Edited : UnEdited);
greenmed->setEditedState (pedited->wavelet.greenmed ? Edited : UnEdited);
bluemed->setEditedState (pedited->wavelet.bluemed ? Edited : UnEdited);
greenhigh->setEditedState (pedited->wavelet.greenhigh ? Edited : UnEdited);
bluehigh->setEditedState (pedited->wavelet.bluehigh ? Edited : UnEdited);
median->set_inconsistent (!pedited->wavelet.median);
medianlev->set_inconsistent (!pedited->wavelet.medianlev);
linkedg->set_inconsistent (!pedited->wavelet.linkedg);
// edgreinf->set_inconsistent (!pedited->wavelet.edgreinf);
lipst->set_inconsistent (!pedited->wavelet.lipst);
cbenab->set_inconsistent (!pedited->wavelet.cbenab);
lipst->set_inconsistent (!pedited->wavelet.lipst);
contrast->setEditedState (pedited->wavelet.contrast ? Edited : UnEdited);
edgrad->setEditedState (pedited->wavelet.edgrad ? Edited : UnEdited);
edgval->setEditedState (pedited->wavelet.edgval ? Edited : UnEdited);
@@ -1154,6 +1266,9 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) {
linkedgConn.block (true);
linkedg->set_active (pp->wavelet.linkedg);
linkedgConn.block (false);
cbenabConn.block (true);
cbenab->set_active (pp->wavelet.cbenab);
cbenabConn.block (false);
lipstConn.block (true);
lipst->set_active (pp->wavelet.lipst);
@@ -1165,6 +1280,7 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) {
lastmedian = pp->wavelet.median;
lastmedianlev = pp->wavelet.medianlev;
lastlinkedg = pp->wavelet.linkedg;
lastcbenab = pp->wavelet.cbenab;
lastlipst = pp->wavelet.lipst;
lastavoid = pp->wavelet.avoid;
lasttmr = pp->wavelet.tmr;
@@ -1197,6 +1313,14 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) {
pastlev->setValue<int>(pp->wavelet.pastlev);
satlev->setValue<int>(pp->wavelet.satlev);
edgcont->setValue<int>(pp->wavelet.edgcont);
greenlow->setValue (pp->wavelet.greenlow);
bluelow->setValue (pp->wavelet.bluelow);
greenmed->setValue (pp->wavelet.greenmed);
bluemed->setValue (pp->wavelet.bluemed);
greenhigh->setValue (pp->wavelet.greenhigh);
bluehigh->setValue (pp->wavelet.bluehigh);
level0noise->setValue<double>(pp->wavelet.level0noise);
level1noise->setValue<double>(pp->wavelet.level1noise);
level2noise->setValue<double>(pp->wavelet.level2noise);
@@ -1247,6 +1371,7 @@ void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) {
medianlevToggled () ;
linkedgToggled () ;
lipstToggled () ;
cbenabToggled () ;
enableListener ();
}
@@ -1288,6 +1413,7 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) {
pp->wavelet.medianlev = medianlev->get_active ();
pp->wavelet.linkedg = linkedg->get_active ();
//pp->wavelet.edgreinf = edgreinf->get_active ();
pp->wavelet.cbenab = cbenab->get_active ();
pp->wavelet.lipst = lipst->get_active ();
pp->wavelet.contrast = contrast->getValue();
pp->wavelet.edgrad = edgrad->getValue();
@@ -1320,6 +1446,14 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) {
pp->wavelet.satlev = satlev->getValue<int> ();
pp->wavelet.strength = (int) strength->getValue();
pp->wavelet.balance = (int) balance->getValue();
pp->wavelet.greenlow = greenlow->getValue ();
pp->wavelet.bluelow = bluelow->getValue ();
pp->wavelet.greenmed = greenmed->getValue ();
pp->wavelet.bluemed = bluemed->getValue ();
pp->wavelet.greenhigh = greenhigh->getValue ();
pp->wavelet.bluehigh = bluehigh->getValue ();
pp->wavelet.iter = (int) iter->getValue();
pp->wavelet.wavclCurve = clshape->getCurve ();
@@ -1337,6 +1471,7 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) {
pedited->wavelet.median = !median->get_inconsistent();
pedited->wavelet.medianlev = !medianlev->get_inconsistent();
pedited->wavelet.linkedg = !linkedg->get_inconsistent();
pedited->wavelet.cbenab = !cbenab->get_inconsistent();
pedited->wavelet.lipst = !lipst->get_inconsistent();
pedited->wavelet.Medgreinf = Medgreinf->get_active_row_number() != 2;
pedited->wavelet.Lmethod = Lmethod->get_active_row_number() != 8;
@@ -1391,6 +1526,13 @@ void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) {
pedited->wavelet.pastlev = pastlev->getEditedState ();
pedited->wavelet.satlev = satlev->getEditedState ();
pedited->wavelet.strength = strength->getEditedState ();
pedited->wavelet.greenlow = greenlow->getEditedState ();
pedited->wavelet.bluelow = bluelow->getEditedState ();
pedited->wavelet.greenmed = greenmed->getEditedState ();
pedited->wavelet.bluemed = bluemed->getEditedState ();
pedited->wavelet.greenhigh = greenhigh->getEditedState ();
pedited->wavelet.bluehigh = bluehigh->getEditedState ();
pedited->wavelet.balance = balance->getEditedState ();
pedited->wavelet.iter = iter->getEditedState ();
pedited->wavelet.wavclCurve = !clshape->isUnChanged ();
@@ -1560,8 +1702,22 @@ void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi
level0noise->setDefault<double> (defParams->wavelet.level0noise);
level1noise->setDefault<double> (defParams->wavelet.level1noise);
level2noise->setDefault<double> (defParams->wavelet.level2noise);
greenlow->setDefault (defParams->wavelet.greenlow);
bluelow->setDefault (defParams->wavelet.bluelow);
greenmed->setDefault (defParams->wavelet.greenmed);
bluemed->setDefault (defParams->wavelet.bluemed);
greenhigh->setDefault (defParams->wavelet.greenhigh);
bluehigh->setDefault (defParams->wavelet.bluehigh);
if (pedited) {
greenlow->setDefaultEditedState (pedited->wavelet.greenlow ? Edited : UnEdited);
bluelow->setDefaultEditedState (pedited->wavelet.bluelow ? Edited : UnEdited);
greenmed->setDefaultEditedState (pedited->wavelet.greenmed ? Edited : UnEdited);
bluemed->setDefaultEditedState (pedited->wavelet.bluemed ? Edited : UnEdited);
greenhigh->setDefaultEditedState (pedited->wavelet.greenhigh ? Edited : UnEdited);
bluehigh->setDefaultEditedState (pedited->wavelet.bluehigh ? Edited : UnEdited);
rescon->setDefault (defParams->wavelet.rescon);
resconH->setDefault (defParams->wavelet.resconH);
reschro->setDefault (defParams->wavelet.reschro);
@@ -2215,7 +2371,42 @@ void Wavelet::adjusterChanged (Adjuster* a, double newval) {
Glib::ustring::format(std::fixed, std::setprecision(2), iter->getValue()))
);
}
else if (a == greenhigh ) {
listener->panelChanged (EvWavgreenhigh,
Glib::ustring::compose("%1",
Glib::ustring::format(std::fixed, std::setprecision(0), greenhigh->getValue()))
);
}
else if (a == bluehigh ) {
listener->panelChanged (EvWavbluehigh,
Glib::ustring::compose("%1",
Glib::ustring::format(std::fixed, std::setprecision(0), bluehigh->getValue()))
);
}
else if (a == greenmed ) {
listener->panelChanged (EvWavgreenmed,
Glib::ustring::compose("%1",
Glib::ustring::format(std::fixed, std::setprecision(0), greenmed->getValue()))
);
}
else if (a == bluemed ) {
listener->panelChanged (EvWavbluemed,
Glib::ustring::compose("%1",
Glib::ustring::format(std::fixed, std::setprecision(0), bluemed->getValue()))
);
}
else if (a == greenlow ) {
listener->panelChanged (EvWavgreenlow,
Glib::ustring::compose("%1",
Glib::ustring::format(std::fixed, std::setprecision(0), greenlow->getValue()))
);
}
else if (a == bluelow ) {
listener->panelChanged (EvWavbluelow,
Glib::ustring::compose("%1",
Glib::ustring::format(std::fixed, std::setprecision(0), bluelow->getValue()))
);
}
else if (a == correction[0] || a == correction[1] || a == correction[2] || a == correction[3] || a == correction[4] || a == correction[5] || a == correction[6] || a == correction[7] || a == correction[8] ) {
listener->panelChanged (EvWavelet,
@@ -2370,6 +2561,46 @@ void Wavelet::linkedgToggled () {
}
}
void Wavelet::cbenabToggled () {
if(cbenab->get_active ()) {
chanMixerHLFrame->show();
chanMixerMidFrame->show();
chanMixerShadowsFrame->show();
neutrHBox->show();
}
else {
chanMixerHLFrame->hide();
chanMixerMidFrame->hide();
chanMixerShadowsFrame->hide();
neutrHBox->hide();
}
if (batchMode) {
if (cbenab->get_inconsistent()) {
cbenab->set_inconsistent (false);
cbenabConn.block (true);
cbenab->set_active (false);
cbenabConn.block (false);
}
else if (lastcbenab)
cbenab->set_inconsistent (true);
lastcbenab = cbenab->get_active ();
}
if (listener && getEnabled()) {
if (cbenab->get_active () ){
listener->panelChanged (EvWavcbenab, M("GENERAL_ENABLED"));
}
else {
listener->panelChanged (EvWavcbenab, M("GENERAL_DISABLED"));
}
}
}
void Wavelet::lipstToggled () {

View File

@@ -44,6 +44,8 @@ protected:
CurveEditorGroup* curveEditorGAM;
Gtk::HSeparator* colorSep;
Gtk::HSeparator* separator3;
Gtk::HSeparator* separatorCB;
CurveEditorGroup* opaCurveEditorG;
FlatCurveEditor* opacityShapeRG;
CurveEditorGroup* opacityCurveEditorG;
@@ -55,6 +57,7 @@ protected:
FlatCurveEditor* hhshape;
FlatCurveEditor* Chshape;
DiagonalCurveEditor* clshape;
Gtk::VBox* chanMixerBox;
FlatCurveEditor* ccshape;
Gtk::CheckButton * display;
@@ -66,6 +69,7 @@ protected:
Gtk::CheckButton * medianlev;
Gtk::CheckButton * linkedg;
// Gtk::CheckButton * edgreinf;
Gtk::CheckButton * cbenab;
Gtk::CheckButton * lipst;
Gtk::CheckButton * avoid;
Gtk::CheckButton * tmr;
@@ -94,6 +98,12 @@ protected:
Adjuster* strength;
Adjuster* balance;
Adjuster* iter;
Adjuster* greenlow;
Adjuster* bluelow;
Adjuster* greenmed;
Adjuster* bluemed;
Adjuster* greenhigh;
Adjuster* bluehigh;
ThresholdAdjuster* hueskin;
ThresholdAdjuster* hueskin2;
@@ -148,12 +158,17 @@ protected:
Gtk::Frame* noiseFrame;
Gtk::Frame* contrastSHFrame;
Gtk::Frame* finalFrame;
Gtk::Frame *chanMixerHLFrame;
Gtk::Frame *chanMixerMidFrame;
Gtk::Frame *chanMixerShadowsFrame;
Gtk::Label* colLabel;
Gtk::Label* interLabel;
Gtk::Label* wavLabels;
Gtk::Label* wavLabelsch;
Gtk::Label* hsmethodLabel;
Gtk::Label* choiceLabel;
Gtk::Label* ColorBalanceLabel;
Gtk::Label* labmC;
Gtk::Label* labmch;
Gtk::Label* labmED;
@@ -180,6 +195,8 @@ protected:
Gtk::HBox* ctboxCH;
Gtk::HBox* ctboxED;
Gtk::HBox* ctboxTM;
Gtk::HBox* ctboxCB;
Gtk::HBox* ctboxBA;
Gtk::HBox* ctboxch;
Gtk::HBox* edbox;
@@ -190,14 +207,16 @@ protected:
Gtk::Label* tilesizeLabel;
Gtk::Label* previewLevelsLabel;
Gtk::Label* previewBackLabel;
Gtk::Button* neutral;
Gtk::HBox* neutrHBox;
sigc::connection expConn, medianConn, avoidConn, tmrConn, medianlevConn, linkedgConn, lipstConn;
sigc::connection expConn, medianConn, avoidConn, tmrConn, medianlevConn, linkedgConn, lipstConn, cbenabConn, neutralconn;
sigc::connection neutralPressedConn;
sigc::connection contrastPlusPressedConn;
sigc::connection contrastMinusPressedConn;
sigc::connection neutralchPressedConn;
bool lastdisplay, lastdisplaygam,lastdisplayres,lastdisplaychro, lastdisplaylevel,lastmedian, lastmedianlev, lastlinkedg, lastavoid, lastlipst, lasttmr;
bool lastdisplay, lastdisplaygam,lastdisplayres,lastdisplaychro, lastdisplaylevel,lastmedian, lastmedianlev, lastlinkedg, lastavoid, lastlipst, lasttmr, lastcbenab;
int nextnlevel;
double tr;
double br;
@@ -226,6 +245,7 @@ public:
void medianToggled ();
void medianlevToggled ();
void linkedgToggled ();
void cbenabToggled ();
void lipstToggled ();
void avoidToggled ();
void tmrToggled ();
@@ -250,6 +270,7 @@ public:
void wavChanged (double nlevel);
bool wavComputed_ ();
void updatewavLabel ();
void neutral_pressed ();
};