diff --git a/rtdata/languages/default b/rtdata/languages/default
index 15f0f8b57..307a742f9 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -235,6 +235,11 @@ HISTORY_MSG_97;'b' curve
HISTORY_MSG_98;Demozaicing
HISTORY_MSG_99;Preprocessing
HISTORY_MSG_9;Highlight Compression
+HISTORY_MSG_100;RGB saturation
+HISTORY_MSG_101;HSV EQ -- Hue
+HISTORY_MSG_102;HSV EQ -- Saturation
+HISTORY_MSG_103;HSV EQ -- Value
+HISTORY_MSG_104;HSV Equalizer
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOTAS;As...
HISTORY_NEWSSDIALOGLABEL;Label of the snapshot:
@@ -629,6 +634,20 @@ TP_HLREC_COLOR;Color Propagation
TP_HLREC_LABEL;Highlight Reconstruction
TP_HLREC_LUMINANCE;Luminance Recovery
TP_HLREC_METHOD;Method:
+TP_HSVEQUALIZER1;Red
+TP_HSVEQUALIZER2;Orange
+TP_HSVEQUALIZER3;Yellow
+TP_HSVEQUALIZER4;Green
+TP_HSVEQUALIZER5;Aqua
+TP_HSVEQUALIZER6;Blue
+TP_HSVEQUALIZER7;Purple
+TP_HSVEQUALIZER8;Magenta
+TP_HSVEQUALIZER_CHANNEL;HSV Channel
+TP_HSVEQUALIZER_HUE;Hue
+TP_HSVEQUALIZER_LABEL;HSV Equalizer
+TP_HSVEQUALIZER_NEUTRAL;Neutral
+TP_HSVEQUALIZER_SAT;Saturation
+TP_HSVEQUALIZER_VAL;Value
TP_ICM_FILEDLGFILTERANY;Any files
TP_ICM_FILEDLGFILTERICM;ICC Profile Files
TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma
diff --git a/rtdata/profiles/crisp.pp3 b/rtdata/profiles/crisp.pp3
index 888d0f708..04fdbf642 100644
--- a/rtdata/profiles/crisp.pp3
+++ b/rtdata/profiles/crisp.pp3
@@ -1,6 +1,6 @@
[Version]
-Version=20101019
+Version=20101111
[Exposure]
Auto=true
diff --git a/rtdata/profiles/default.pp3 b/rtdata/profiles/default.pp3
index 02d1cb9a6..ae5bcc611 100644
--- a/rtdata/profiles/default.pp3
+++ b/rtdata/profiles/default.pp3
@@ -1,6 +1,6 @@
[Version]
-Version=20101019
+Version=20101111
[Exposure]
Auto=true
diff --git a/rtdata/profiles/neutral.pp3 b/rtdata/profiles/neutral.pp3
index 4705aa2d4..e2fa6c34a 100644
--- a/rtdata/profiles/neutral.pp3
+++ b/rtdata/profiles/neutral.pp3
@@ -1,6 +1,6 @@
[Version]
-Version=20101019
+Version=20101111
[Exposure]
Auto=false
diff --git a/rtengine/curves.cc b/rtengine/curves.cc
index c4234a14c..5d24e90a0 100644
--- a/rtengine/curves.cc
+++ b/rtengine/curves.cc
@@ -704,7 +704,7 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
//val = basecurve (val*def_mul, a, black, def_mul, hlcompr/100.0, 1.5*shcompr/100.0);
//val = basecurvenew->getVal (val);
- hlCurve[i] = (int) (65535.0 * CLIPD(val));
+ hlCurve[i] = (65535.0 * CLIPD(val));
//%%%%%%%%%%%%%%%%%%%%%%%%%%
// change to [0,1] range
@@ -712,7 +712,7 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
val = basecurve (val, 1, black, def_mul, 1, 1.5*shcompr/100.0);
- shCurve[i] = (int) (65535.0 * CLIPD(val));
+ shCurve[i] = (65535.0 * CLIPD(val));
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -720,6 +720,8 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
// change to [0,1] range
double val = (double)i / 65535.0;
+ float val0 = val;
+ float cum = (int)shCurve[(int)(hlCurve[i])];
// gamma correction
if (gamma_>0)
@@ -732,7 +734,8 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou
// apply custom/parametric/NURBS curve, if any
if (tcurve) {
if (outBeforeCCurveHistogram) {
- double hval = brightcurve->getVal ((int)shCurve[(int)hlCurve[(int)val]]);
+ cum *= (float)val/val0;
+ float hval = brightcurve->getVal (cum);
//if (needigamma)
// hval = igamma2 (hval);
int hi = (int)(255.0*CLIPD(hval));
diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc
index 650e4b100..e2fd17fa6 100644
--- a/rtengine/improcfun.cc
+++ b/rtengine/improcfun.cc
@@ -281,7 +281,17 @@ void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, float* hltonecur
int tW = working->width;
int tH = working->height;
int r, g, b;
- #pragma omp parallel for private(r, g, b,factor,mapval) if (multiThread)
+ float h, s, v;
+ float satparam,valparam;
+ int hue, hueband, hueres, nbrband;
+ double pi = M_PI;
+
+ float* cossq = new float [8093];
+ for (int i=0; i<8093; i++)
+ cossq[i] = SQR(cos(pi*(float)i/16384));
+
+
+#pragma omp parallel for private(r, g, b,factor,mapval,h,s,v,hue,hueband,hueres,nbrband,satparam,valparam) if (multiThread)
for (int i=0; i
0 ? (float)tonecurve[Y]/Y : 1);
+ //r *= tonefactor;
+ //g *= tonefactor;
+ //b *= tonefactor;
r = tonecurve[CLIP(r)];
g = tonecurve[CLIP(g)];
b = tonecurve[CLIP(b)];
- if (abs(sat)>0.5) {
- float h, s, v;
+ if (abs(sat)>0.5 || params->hsvequalizer.enabled) {
rgb2hsv(r,g,b,h,s,v);
- if (sat>0) {
+ if (sat > 0.5) {
s = (1-(float)sat/100)*s+(float)sat/100*(1-SQR(SQR(1-s)));
} else {
- s *= 1+(float)sat/100;
+ if (sat < -0.5)
+ s *= 1+(float)sat/100;
+ }
+ //HSV equalizer
+ if (params->hsvequalizer.enabled) {
+ hue = (int)(65535*h);
+ hueres = hue & 8091;//location of hue within a band
+ hueband = (hue-hueres) >> 13;//divides hue range into 8 bands
+ nbrband = (hueband+1)&7;
+
+ //shift hue
+ h = fmod(h + 0.0025*(params->hsvequalizer.hue[hueband] * cossq[hueres] + params->hsvequalizer.hue[nbrband] * (1-cossq[hueres])),1);
+ if (h<0) h +=1;
+ hue = (int)(65535*h);
+ hueres = hue & 8091;//location of hue within a band
+ hueband = (hue-hueres) >> 13;//divides hue range into 8 bands
+ nbrband = (hueband+1)&7;
+
+ //change saturation
+ satparam = 0.01*(params->hsvequalizer.sat[hueband] * cossq[hueres] + params->hsvequalizer.sat[nbrband] * (1-cossq[hueres]));
+ if (satparam > 0.00001) {
+ s = (1-satparam)*s+satparam*(1-SQR(1-s));
+ } else {
+ if (satparam < -0.00001)
+ s *= 1+satparam;
+ }
+
+ //change value
+ valparam = 0.005*(params->hsvequalizer.val[hueband] * cossq[hueres] + params->hsvequalizer.val[nbrband] * (1-cossq[hueres]));
+ valparam *= (1-SQR(SQR(1-s)));
+ if (valparam > 0.00001) {
+ v = (1-valparam)*v+valparam*(1-SQR(1-v));
+ } else {
+ if (valparam < -0.00001)
+ v *= (1+valparam);
+ }
}
hsv2rgb(h,s,v,r,g,b);
}
@@ -375,6 +424,9 @@ void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, float* hltonecur
lab->b[i][j] = CLIPC(((cacheb[y] - cacheb[z]) * chroma_scale) >> 15);
}
}
+
+ delete [] cossq;
+
}
void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, int* curve, int row_from, int row_to) {
@@ -385,22 +437,23 @@ void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, int* curve
for (int j=0; jL[i][j] = curve[lold->L[i][j]];
}
-
- void ImProcFunctions::chrominanceCurve (LabImage* lold, LabImage* lnew, int channel, int* curve, int row_from, int row_to) {
- int W = lold->W;
- //int H = lold->H;
- if (channel==0) {
+
+void ImProcFunctions::chrominanceCurve (LabImage* lold, LabImage* lnew, int channel, int* curve, int row_from, int row_to) {
+
+ int W = lold->W;
+ //int H = lold->H;
+ if (channel==0) {
+ for (int i=row_from; ia[i][j] = curve[lold->a[i][j]+32768]-32768;
+ }
+ if (channel==1) {
for (int i=row_from; ia[i][j] = curve[lold->a[i][j]+32768]-32768;
- }
- if (channel==1) {
- for (int i=row_from; ib[i][j] = curve[lold->b[i][j]+32768]-32768;
- }
+ lnew->b[i][j] = curve[lold->b[i][j]+32768]-32768;
}
+}
#include "cubic.cc"
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index f4bfc7420..6d0313227 100644
--- a/rtengine/procevents.h
+++ b/rtengine/procevents.h
@@ -122,7 +122,11 @@ enum ProcEvent {
EvDemosaic=97,
EvPreProcess=98,
EvSaturation=99,
- NUMOFEVENTS=100
+ EvHSVEqualizerH=100,
+ EvHSVEqualizerS=101,
+ EvHSVEqualizerV=102,
+ EvHSVEqEnabled=103,
+ NUMOFEVENTS=104
};
}
#endif
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index 44faaf8d4..9f6d27e3e 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -187,6 +187,13 @@ void ProcParams::setDefaults () {
dirpyrequalizer.mult[i] = 1.0;
}
dirpyrequalizer.mult[4] = 0.0;
+ hsvequalizer.enabled = false;
+ for(int i = 0; i < 8; i ++)
+ {
+ hsvequalizer.sat[i] = 0;
+ hsvequalizer.val[i] = 0;
+ hsvequalizer.hue[i] = 0;
+ }
raw.df_autoselect = false;
raw.ca_autocorrect = false;
raw.hotdeadpix_filt = false;
@@ -380,6 +387,28 @@ int ProcParams::save (Glib::ustring fname) const {
ss << "Mult" << i;
keyFile.set_double("Directional Pyramid Equalizer", ss.str(), dirpyrequalizer.mult[i]);
}
+
+ // save hsv equalizer parameters
+ keyFile.set_boolean ("HSV Equalizer", "Enabled", hsvequalizer.enabled);
+ keyFile.set_string ("HSV Equalizer", "Channel", hsvequalizer.hsvchannel);
+ for(int i = 0; i < 8; i++)
+ {
+ std::stringstream ss;
+ ss << "Sat" << i;
+ keyFile.set_double("HSV Equalizer", ss.str(), hsvequalizer.sat[i]);
+ }
+ for(int i = 0; i < 8; i++)
+ {
+ std::stringstream ss;
+ ss << "Val" << i;
+ keyFile.set_double("HSV Equalizer", ss.str(), hsvequalizer.val[i]);
+ }
+ for(int i = 0; i < 8; i++)
+ {
+ std::stringstream ss;
+ ss << "Hue" << i;
+ keyFile.set_double("HSV Equalizer", ss.str(), hsvequalizer.hue[i]);
+ }
// save RAW parameters
keyFile.set_string ("RAW", "DarkFrame", raw.dark_frame );
@@ -663,6 +692,29 @@ if (keyFile.has_group ("Directional Pyramid Equalizer")) {
if(keyFile.has_key ("Directional Pyramid Equalizer", ss.str())) dirpyrequalizer.mult[i] = keyFile.get_double ("Directional Pyramid Equalizer", ss.str());
}
}
+
+ // load wavelet equalizer parameters
+if (keyFile.has_group ("HSV Equalizer")) {
+ if (keyFile.has_key ("HSV Equalizer", "Enabled")) hsvequalizer.enabled = keyFile.get_boolean ("HSV Equalizer", "Enabled");
+ for(int i = 0; i < 8; i ++)
+ {
+ std::stringstream ss;
+ ss << "Sat" << i;
+ if(keyFile.has_key ("HSV Equalizer", ss.str())) hsvequalizer.sat[i] = keyFile.get_double ("HSV Equalizer", ss.str());
+ }
+ for(int i = 0; i < 8; i ++)
+ {
+ std::stringstream ss;
+ ss << "Val" << i;
+ if(keyFile.has_key ("HSV Equalizer", ss.str())) hsvequalizer.val[i] = keyFile.get_double ("HSV Equalizer", ss.str());
+ }
+ for(int i = 0; i < 8; i ++)
+ {
+ std::stringstream ss;
+ ss << "Hue" << i;
+ if(keyFile.has_key ("HSV Equalizer", ss.str())) hsvequalizer.hue[i] = keyFile.get_double ("HSV Equalizer", ss.str());
+ }
+}
// load raw settings
if (keyFile.has_group ("RAW")) {
@@ -733,6 +785,17 @@ bool operator==(const DirPyrEqualizerParams & a, const DirPyrEqualizerParams & b
return true;
}
+bool operator==(const HSVEqualizerParams & a, const HSVEqualizerParams & b) {
+ if(a.enabled != b.enabled)
+ return false;
+
+ for(int i = 0; i < 8; i++) {
+ if(a.sat[i] != b.sat[i] && a.val[i] != b.val[i] && a.hue[i] != b.hue[i])
+ return false;
+ }
+ return true;
+}
+
bool operator==(const ExifPair& a, const ExifPair& b) {
return a.field == b.field && a.value == b.value;
@@ -856,6 +919,7 @@ bool ProcParams::operator== (const ProcParams& other) {
&& icm.output == other.icm.output
&& equalizer == other.equalizer
&& dirpyrequalizer == other.dirpyrequalizer
+ && hsvequalizer == other.hsvequalizer
&& exif==other.exif
&& iptc==other.iptc;
}
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 095eae1d0..70222141a 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -343,14 +343,27 @@ class EqualizerParams {
};
/**
- * Directional pyramid equalizer params
- */
- class DirPyrEqualizerParams {
-
- public:
- bool enabled;
- double mult[8];
- };
+* Directional pyramid equalizer params
+*/
+class DirPyrEqualizerParams {
+
+ public:
+ bool enabled;
+ double mult[8];
+};
+
+/**
+ * Wavelet equalizer params
+ */
+class HSVEqualizerParams {
+
+ public:
+ bool enabled;
+ Glib::ustring hsvchannel;
+ int sat[8];
+ int val[8];
+ int hue[8];
+};
/**
* Parameters for RAW demosaicing
@@ -407,7 +420,8 @@ class ProcParams {
ColorManagementParams icm; ///< profiles/color spaces used during the image processing
EqualizerParams equalizer; ///< wavelet equalizer parameters
RAWParams raw; ///< RAW parameters before demosaicing
- DirPyrEqualizerParams dirpyrequalizer;///< directional pyramid equalizer parameters
+ DirPyrEqualizerParams dirpyrequalizer; ///< directional pyramid equalizer parameters
+ HSVEqualizerParams hsvequalizer; ///< hsv equalizer parameters
std::vector exif; ///< List of modifications appplied on the exif tags of the input image
std::vector iptc; ///< The IPTC tags and values to be saved to the output image
int version; ///< Version of the file from which the parameters have been read
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index adae259c8..0069836f6 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -120,5 +120,9 @@ LUMINANCECURVE, // EvLbCurve,
DEMOSAIC, // EvDemosaic
DARKFRAME, //EvPreProcess
RGBCURVE, // EvSaturation,
+RGBCURVE, // EvHSVEqualizerH,
+RGBCURVE, // EvHSVEqualizerS,
+RGBCURVE, // EvHSVEqualizerV,
+RGBCURVE, // EvHSVEqEnabled,
};
diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt
index 06f751323..1a11190d1 100644
--- a/rtgui/CMakeLists.txt
+++ b/rtgui/CMakeLists.txt
@@ -26,7 +26,7 @@ set (BASESOURCEFILES
batchqueue.cc lwbutton.cc lwbuttonset.cc
batchqueuebuttonset.cc browserfilter.cc exiffiltersettings.cc
profilestore.cc partialpastedlg.cc rawprocess.cc preprocess.cc
- equalizer.cc dirpyrequalizer.cc
+ equalizer.cc dirpyrequalizer.cc hsvequalizer.cc
popupcommon.cc popupbutton.cc popuptogglebutton.cc)
if (WIN32)
diff --git a/rtgui/hsvequalizer.cc b/rtgui/hsvequalizer.cc
new file mode 100644
index 000000000..6ccb3b673
--- /dev/null
+++ b/rtgui/hsvequalizer.cc
@@ -0,0 +1,358 @@
+/*
+ * This file is part of RawTherapee.
+ *
+ * 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 .
+ *
+ * 2010 Ilya Popov
+ */
+
+#include
+
+using namespace rtengine;
+using namespace rtengine::procparams;
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+HSVEqualizer::HSVEqualizer () : ToolPanel () {
+
+ enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
+ enabled->set_active (true);
+ pack_start(*enabled);
+ enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &HSVEqualizer::enabledToggled) );
+
+ Gtk::HSeparator *hsvsepa = Gtk::manage (new Gtk::HSeparator());
+ pack_start(*hsvsepa, Gtk::PACK_SHRINK, 2);
+ hsvsepa->show ();
+
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ());
+ hb->set_border_width (4);
+ hb->show ();
+ Gtk::Label* hsvselect = Gtk::manage (new Gtk::Label (M("TP_HSVEQUALIZER_CHANNEL")+":"));
+ hsvselect->show ();
+ hsvchannel = Gtk::manage (new Gtk::ComboBoxText ());
+ hsvchannel->append_text (M("TP_HSVEQUALIZER_SAT"));
+ hsvchannel->append_text (M("TP_HSVEQUALIZER_VAL"));
+ hsvchannel->append_text (M("TP_HSVEQUALIZER_HUE"));
+ hsvchannel->show ();
+ hb->pack_start(*hsvselect, Gtk::PACK_SHRINK, 4);
+ hb->pack_start(*hsvchannel);
+
+ Gtk::Button * neutralButton = Gtk::manage (new Gtk::Button(M("TP_HSVEQUALIZER_NEUTRAL")));
+ hb->pack_start(*neutralButton, Gtk::PACK_SHRINK, 2);
+ neutralPressedConn = neutralButton->signal_pressed().connect( sigc::mem_fun(*this, &HSVEqualizer::neutralPressed));
+
+
+ pack_start (*hb);
+
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ /*
+ Gtk::HBox * buttonBox17 = Gtk::manage (new Gtk::HBox());
+ pack_start(*buttonBox17, Gtk::PACK_SHRINK, 2);
+
+ Gtk::Button * neutralButton = Gtk::manage (new Gtk::Button(M("TP_HSVEQUALIZER_NEUTRAL")));
+ buttonBox17->pack_start(*neutralButton, Gtk::PACK_SHRINK, 2);
+ neutralPressedConn = neutralButton->signal_pressed().connect( sigc::mem_fun(*this, &HSVEqualizer::neutralPressed));
+
+ buttonBox17->show();
+ */
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Gtk::HSeparator *hsvsepb = Gtk::manage (new Gtk::HSeparator());
+ pack_start(*hsvsepb, Gtk::PACK_SHRINK, 2);
+ hsvsepb->show ();
+
+ satbox = new Gtk::VBox ();
+ sat[0] = new Adjuster (M("TP_HSVEQUALIZER1"), -100, 100, 0.1, 0);
+ sat[1] = new Adjuster (M("TP_HSVEQUALIZER2"), -100, 100, 0.1, 0);
+ sat[2] = new Adjuster (M("TP_HSVEQUALIZER3"), -100, 100, 0.1, 0);
+ sat[3] = new Adjuster (M("TP_HSVEQUALIZER4"), -100, 100, 0.1, 0);
+ sat[4] = new Adjuster (M("TP_HSVEQUALIZER5"), -100, 100, 0.1, 0);
+ sat[5] = new Adjuster (M("TP_HSVEQUALIZER6"), -100, 100, 0.1, 0);
+ sat[6] = new Adjuster (M("TP_HSVEQUALIZER7"), -100, 100, 0.1, 0);
+ sat[7] = new Adjuster (M("TP_HSVEQUALIZER8"), -100, 100, 0.1, 0);
+ for(int i = 0; i < 8; i++)
+ {
+ sat[i]->setAdjusterListener(this);
+ satbox->pack_start(*sat[i]);
+ }
+
+ //show_all_children ();
+ satbox->show ();
+
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ valbox = new Gtk::VBox ();
+ val[0] = new Adjuster (M("TP_HSVEQUALIZER1"), -100, 100, 0.1, 0);
+ val[1] = new Adjuster (M("TP_HSVEQUALIZER2"), -100, 100, 0.1, 0);
+ val[2] = new Adjuster (M("TP_HSVEQUALIZER3"), -100, 100, 0.1, 0);
+ val[3] = new Adjuster (M("TP_HSVEQUALIZER4"), -100, 100, 0.1, 0);
+ val[4] = new Adjuster (M("TP_HSVEQUALIZER5"), -100, 100, 0.1, 0);
+ val[5] = new Adjuster (M("TP_HSVEQUALIZER6"), -100, 100, 0.1, 0);
+ val[6] = new Adjuster (M("TP_HSVEQUALIZER7"), -100, 100, 0.1, 0);
+ val[7] = new Adjuster (M("TP_HSVEQUALIZER8"), -100, 100, 0.1, 0);
+ for(int i = 0; i < 8; i++)
+ {
+ val[i]->setAdjusterListener(this);
+ valbox->pack_start(*val[i]);
+ }
+
+ //show_all_children ();
+ valbox->show ();
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ huebox = new Gtk::VBox ();
+
+
+ hue[0] = new Adjuster (M("TP_HSVEQUALIZER1"), -100, 100, 0.1, 0);
+ hue[1] = new Adjuster (M("TP_HSVEQUALIZER2"), -100, 100, 0.1, 0);
+ hue[2] = new Adjuster (M("TP_HSVEQUALIZER3"), -100, 100, 0.1, 0);
+ hue[3] = new Adjuster (M("TP_HSVEQUALIZER4"), -100, 100, 0.1, 0);
+ hue[4] = new Adjuster (M("TP_HSVEQUALIZER5"), -100, 100, 0.1, 0);
+ hue[5] = new Adjuster (M("TP_HSVEQUALIZER6"), -100, 100, 0.1, 0);
+ hue[6] = new Adjuster (M("TP_HSVEQUALIZER7"), -100, 100, 0.1, 0);
+ hue[7] = new Adjuster (M("TP_HSVEQUALIZER8"), -100, 100, 0.1, 0);
+ for(int i = 0; i < 8; i++)
+ {
+ hue[i]->setAdjusterListener(this);
+ huebox->pack_start(*hue[i]);
+ }
+
+ //huebox->show_all_children ();
+ huebox->show ();
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ huebox->reference ();
+ valbox->reference ();
+ satbox->reference ();
+
+ //enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &HSVEqualizer::enabled_toggled) );
+ hsvchannel->signal_changed().connect( sigc::mem_fun(*this, &HSVEqualizer::hsvchannelChanged) );
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+HSVEqualizer::~HSVEqualizer () {
+
+ delete hue;
+ delete val;
+ delete sat;
+}
+
+
+void HSVEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited) {
+
+ disableListener ();
+
+ if (pedited) {
+ for (int i=0; i<8; i++) {
+ sat[i]->setEditedState (pedited->hsvequalizer.sat[i] ? Edited : UnEdited);
+ val[i]->setEditedState (pedited->hsvequalizer.val[i] ? Edited : UnEdited);
+ hue[i]->setEditedState (pedited->hsvequalizer.hue[i] ? Edited : UnEdited);
+ }
+ enabled->set_inconsistent (!pedited->hsvequalizer.enabled);
+ }
+
+ enaConn.block (true);
+ enabled->set_active (pp->hsvequalizer.enabled);
+ enaConn.block (false);
+ lastEnabled = pp->hsvequalizer.enabled;
+
+ for (int i=0; i<8; i++) {
+ sat[i]->setValue (pp->hsvequalizer.sat[i]);
+ val[i]->setValue (pp->hsvequalizer.val[i]);
+ hue[i]->setValue (pp->hsvequalizer.hue[i]);
+ }
+
+ if (pedited && !pedited->hsvequalizer.hsvchannel)
+ hsvchannel->set_active (3);
+ else if (pp->hsvequalizer.hsvchannel=="sat")
+ hsvchannel->set_active (0);
+ else if (pp->hsvequalizer.hsvchannel=="val")
+ hsvchannel->set_active (1);
+ else if (pp->hsvequalizer.hsvchannel=="hue")
+ hsvchannel->set_active (2);
+
+ enableListener ();
+}
+
+void HSVEqualizer::write (ProcParams* pp, ParamsEdited* pedited) {
+
+ pp->hsvequalizer.enabled = enabled->get_active ();
+ for (int i=0; i<8; i++) {
+ pp->hsvequalizer.sat[i] = sat[i]->getValue();
+ pp->hsvequalizer.val[i] = val[i]->getValue();
+ pp->hsvequalizer.hue[i] = hue[i]->getValue();
+ }
+
+ if (hsvchannel->get_active_row_number()==0)
+ pp->hsvequalizer.hsvchannel = "sat";
+ else if (hsvchannel->get_active_row_number()==1)
+ pp->hsvequalizer.hsvchannel = "val";
+ else if (hsvchannel->get_active_row_number()==2)
+ pp->hsvequalizer.hsvchannel = "hue";
+
+ if (pedited) {
+ pedited->hsvequalizer.enabled = !enabled->get_inconsistent();//from dirpyreq
+ for (int i=0; i<8; i++) {
+ pedited->hsvequalizer.sat[i] = sat[i]->getEditedState ();
+ pedited->hsvequalizer.val[i] = val[i]->getEditedState ();
+ pedited->hsvequalizer.hue[i] = hue[i]->getEditedState ();
+ }
+ }
+}
+
+void HSVEqualizer::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
+
+ for (int i = 0; i < 8; i++) {
+ sat[i]->setDefault(defParams->hsvequalizer.sat[i]);
+ val[i]->setDefault(defParams->hsvequalizer.val[i]);
+ hue[i]->setDefault(defParams->hsvequalizer.hue[i]);
+ }
+
+ if (pedited) {
+ for (int i = 0; i < 8; i++) {
+ sat[i]->setDefaultEditedState(pedited->hsvequalizer.sat[i] ? Edited : UnEdited);
+ val[i]->setDefaultEditedState(pedited->hsvequalizer.val[i] ? Edited : UnEdited);
+ hue[i]->setDefaultEditedState(pedited->hsvequalizer.hue[i] ? Edited : UnEdited);
+ }
+ }
+ else {
+ for (int i = 0; i < 8; i++) {
+ sat[i]->setDefaultEditedState(Irrelevant);
+ val[i]->setDefaultEditedState(Irrelevant);
+ hue[i]->setDefaultEditedState(Irrelevant);
+ }
+ }
+}
+
+void HSVEqualizer::adjusterChanged (Adjuster* a, double newval) {
+
+ if (listener && enabled->get_active()) {
+ std::stringstream ss;
+ ss << "(";
+ int i;
+ if (hsvchannel->get_active_row_number()==0) {
+ for (i = 0; i < 8; i++) {
+ if (i > 0) {
+ ss << ", ";
+ }
+ ss << static_cast(sat[i]->getValue());
+ }
+ listener->panelChanged (EvHSVEqualizerS, ss.str());
+ }
+ else if (hsvchannel->get_active_row_number()==1) {
+ for (i = 0; i < 8; i++) {
+ if (i > 0) {
+ ss << ", ";
+ }
+ ss << static_cast(val[i]->getValue());
+ }
+ listener->panelChanged (EvHSVEqualizerV, ss.str());
+ }
+ else if (hsvchannel->get_active_row_number()==2) {
+ for (i = 0; i < 8; i++) {
+ if (i > 0) {
+ ss << ", ";
+ }
+ ss << static_cast(hue[i]->getValue());
+ }
+ listener->panelChanged (EvHSVEqualizerH, ss.str());
+ }
+
+ ss << ")";
+ //listener->panelChanged (EvHSVEqualizer, ss.str());
+ }
+}
+
+void HSVEqualizer::enabledToggled () {
+
+ 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 (EvHSVEqEnabled, M("GENERAL_ENABLED"));
+ else
+ listener->panelChanged (EvHSVEqEnabled, M("GENERAL_DISABLED"));
+ }
+}
+
+
+void HSVEqualizer::hsvchannelChanged () {
+
+ removeIfThere (this, satbox, false);
+ removeIfThere (this, valbox, false);
+ removeIfThere (this, huebox, false);
+
+ if (hsvchannel->get_active_row_number()==0)
+ pack_start (*satbox);
+ else if (hsvchannel->get_active_row_number()==1)
+ pack_start (*valbox);
+ else if (hsvchannel->get_active_row_number()==2)
+ pack_start (*huebox);
+
+ if (listener && enabled->get_active ()) {
+ if (hsvchannel->get_active_row_number()==0)
+ listener->panelChanged (EvHSVEqualizerS, hsvchannel->get_active_text ());
+ else if (hsvchannel->get_active_row_number()==1)
+ listener->panelChanged (EvHSVEqualizerV, hsvchannel->get_active_text ());
+ else if (hsvchannel->get_active_row_number()==2)
+ listener->panelChanged (EvHSVEqualizerH, hsvchannel->get_active_text ());
+ }
+}
+
+void HSVEqualizer::setBatchMode (bool batchMode) {
+
+ ToolPanel::setBatchMode (batchMode);
+
+ for (int i = 0; i < 8; i++) {
+ sat[i]->showEditedCB();
+ val[i]->showEditedCB();
+ hue[i]->showEditedCB();
+ }
+
+ hsvchannel->append_text (M("GENERAL_UNCHANGED"));
+}
+
+void HSVEqualizer::neutralPressed () {
+ if (hsvchannel->get_active_row_number()==0)
+ for (int i = 0; i < 8; i++) {
+ sat[i]->setValue(0);
+ adjusterChanged(sat[i], 0);
+ }
+ else if (hsvchannel->get_active_row_number()==1)
+ for (int i = 0; i < 8; i++) {
+ val[i]->setValue(0);
+ adjusterChanged(val[i], 0);
+ }
+ else if (hsvchannel->get_active_row_number()==2)
+ for (int i = 0; i < 8; i++) {
+ hue[i]->setValue(0);
+ adjusterChanged(hue[i], 0);
+ }
+
+
+}
\ No newline at end of file
diff --git a/rtgui/hsvequalizer.h b/rtgui/hsvequalizer.h
new file mode 100644
index 000000000..468c710c6
--- /dev/null
+++ b/rtgui/hsvequalizer.h
@@ -0,0 +1,68 @@
+/*
+ * This file is part of RawTherapee.
+ *
+ * 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 .
+ *
+ * 2010 Ilya Popov
+ */
+
+#ifndef HSVEQUALIZER_H_INCLUDED
+#define HSVEQUALIZER_H_INCLUDED
+
+#include
+#include
+#include
+#include
+
+
+class HSVEqualizer : public Gtk::VBox, public AdjusterListener, public ToolPanel
+{
+
+protected:
+
+ Gtk::CheckButton * enabled;
+ Gtk::ComboBoxText* hsvchannel;
+
+ Gtk::VBox* satbox;
+ Gtk::VBox* valbox;
+ Gtk::VBox* huebox;
+
+ Adjuster* sat[8];
+ Adjuster* val[8];
+ Adjuster* hue[8];
+
+ sigc::connection enaConn;
+ sigc::connection neutralPressedConn;
+
+ bool lastEnabled;
+
+public:
+
+ HSVEqualizer ();
+ virtual ~HSVEqualizer ();
+
+ 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 enabledToggled ();
+ void hsvchannelChanged ();
+
+ void neutralPressed ();
+
+};
+
+#endif
diff --git a/rtgui/navigator.cc b/rtgui/navigator.cc
index cda896052..8de4a3e5a 100644
--- a/rtgui/navigator.cc
+++ b/rtgui/navigator.cc
@@ -100,7 +100,7 @@ void Navigator::rgb2hsv (int r, int g, int b, int &h, int &s, int &v) {
volatile double var_G = g / 255.0;
volatile double var_B = b / 255.0;
- volatile double var_Min = MIN(MIN(var_R,var_G),var_B);
+ /*volatile double var_Min = MIN(MIN(var_R,var_G),var_B);
volatile double var_Max = MAX(MAX(var_R,var_G),var_B);
double del_Max = var_Max - var_Min;
double V = (var_Max + var_Min) / 2;
@@ -120,6 +120,27 @@ void Navigator::rgb2hsv (int r, int g, int b, int &h, int &s, int &v) {
else if ( var_G == var_Max ) H = (1.0 / 3.0) + del_R - del_B;
else if ( var_B == var_Max ) H = (2.0 / 3.0) + del_G - del_R;
+ if ( H < 0 ) H += 1;
+ if ( H > 1 ) H -= 1;
+ }*/
+
+ double var_Min = MIN(MIN(var_R,var_G),var_B);
+ double var_Max = MAX(MAX(var_R,var_G),var_B);
+ double del_Max = var_Max - var_Min;
+ double V = var_Max;
+ double H, S;
+ if (fabs(del_Max)<0.001) {
+ H = 0;
+ S = 0;
+ }
+ else {
+ S = del_Max/var_Max;
+
+ if ( var_R == var_Max ) H = (var_G - var_B)/del_Max;
+ else if ( var_G == var_Max ) H = 2.0 + (var_B - var_R)/del_Max;
+ else if ( var_B == var_Max ) H = 4.0 + (var_R - var_G)/del_Max;
+ H /= 6.0;
+
if ( H < 0 ) H += 1;
if ( H > 1 ) H -= 1;
}
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index 763cae160..43f2aadae 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -138,12 +138,18 @@ void ParamsEdited::set (bool v) {
raw.dcbEnhance = v;
equalizer.enabled = v;
dirpyrequalizer.enabled = v;
-
- for(int i = 0; i < 5; i++)
- {
+ hsvequalizer.enabled = v;
+ for(int i = 0; i < 8; i++) {
equalizer.c[i] = v;
- dirpyrequalizer.mult[i] = v;
}
+ for(int i = 0; i < 5; i++) {
+ dirpyrequalizer.mult[i] = v;
+ }
+ for(int i = 0; i < 8; i++) {
+ hsvequalizer.sat[i] = v;
+ hsvequalizer.val[i] = v;
+ hsvequalizer.hue[i] = v;
+ }
exif.clear ();
iptc.clear ();
}
@@ -286,6 +292,12 @@ void ParamsEdited::initFrom (const std::vector
for(int i = 0; i < 8; i++) {
dirpyrequalizer.mult[i] = dirpyrequalizer.mult[i] && p.dirpyrequalizer.mult[i] == other.dirpyrequalizer.mult[i];
}
+ hsvequalizer.enabled = hsvequalizer.enabled && p.hsvequalizer.enabled == other.hsvequalizer.enabled;
+ for(int i = 0; i < 8; i++) {
+ hsvequalizer.sat[i] = hsvequalizer.sat[i] && p.hsvequalizer.sat[i] == other.hsvequalizer.sat[i];
+ hsvequalizer.val[i] = hsvequalizer.val[i] && p.hsvequalizer.val[i] == other.hsvequalizer.val[i];
+ hsvequalizer.hue[i] = hsvequalizer.hue[i] && p.hsvequalizer.hue[i] == other.hsvequalizer.hue[i];
+ }
// exif = exif && p.exif==other.exif
// iptc = other.iptc;
}
@@ -415,9 +427,15 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if(equalizer.c[i]) toEdit.equalizer.c[i] = mods.equalizer.c[i];
}
if (dirpyrequalizer.enabled) toEdit.dirpyrequalizer.enabled = mods.dirpyrequalizer.enabled;
- for(int i = 0; i < 8; i++) {
+ for(int i = 0; i < 5; i++) {
if(dirpyrequalizer.mult[i]) toEdit.dirpyrequalizer.mult[i] = mods.dirpyrequalizer.mult[i];
}
+ if (hsvequalizer.enabled) toEdit.hsvequalizer.enabled = mods.hsvequalizer.enabled;
+ for(int i = 0; i < 8; i++) {
+ if(hsvequalizer.sat[i]) toEdit.hsvequalizer.sat[i] = mods.hsvequalizer.sat[i];
+ if(hsvequalizer.val[i]) toEdit.hsvequalizer.val[i] = mods.hsvequalizer.val[i];
+ if(hsvequalizer.hue[i]) toEdit.hsvequalizer.hue[i] = mods.hsvequalizer.hue[i];
+ }
// if (exif) toEdit.exif==mo.exif = mods.exif==other.exif;
// if (iptc;) toEdit.iptc==other.iptc; = mods.iptc==other.iptc;;
}
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index a70f26886..6fabc3e46 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -253,6 +253,16 @@ public:
bool mult[8];
};
+class HSVEqualizerParamsEdited {
+
+public:
+ bool enabled;
+ bool sat[6];
+ bool val[6];
+ bool hue[6];
+ int hsvchannel;
+};
+
class RAWParamsEdited {
public:
@@ -313,6 +323,7 @@ class ParamsEdited {
EqualizerParamsEdited equalizer;
RAWParamsEdited raw;
DirPyrEqualizerParamsEdited dirpyrequalizer;
+ HSVEqualizerParamsEdited hsvequalizer;
std::vector exif;
std::vector iptc;
diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc
index b903365af..88dd47e32 100644
--- a/rtgui/partialpastedlg.cc
+++ b/rtgui/partialpastedlg.cc
@@ -51,6 +51,7 @@ PartialPasteDlg::PartialPasteDlg () {
colorboost = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORBOOST")));
colorden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORDENOISE")));
dirpyrden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DIRPYRDENOISE")));
+ hsveq = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_HSVEQUALIZER")));
// options in lens:
distortion = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DISTORTION")));
@@ -97,6 +98,7 @@ PartialPasteDlg::PartialPasteDlg () {
vboxes[2]->pack_start (*colormixer, Gtk::PACK_SHRINK, 2);
vboxes[2]->pack_start (*colorshift, Gtk::PACK_SHRINK, 2);
vboxes[2]->pack_start (*colorboost, Gtk::PACK_SHRINK, 2);
+ vboxes[2]->pack_start (*hsveq, Gtk::PACK_SHRINK, 2);
vboxes[2]->pack_start (*colorden, Gtk::PACK_SHRINK, 2);
vboxes[2]->pack_start (*dirpyrden, Gtk::PACK_SHRINK, 2);
@@ -160,7 +162,8 @@ PartialPasteDlg::PartialPasteDlg () {
colormixerConn = colormixer->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
colorshiftConn = colorshift->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
colorboostConn = colorboost->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
- colordenConn = colorden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
+ hsveqConn = hsveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
+ colordenConn = colorden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
dirpyrdenConn = dirpyrden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
distortionConn = distortion->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true));
@@ -242,6 +245,7 @@ void PartialPasteDlg::colorToggled () {
colormixer->set_active (color->get_active ());
colorshift->set_active (color->get_active ());
colorboost->set_active (color->get_active ());
+ hsveq->set_active (color->get_active ());
colorden->set_active (color->get_active ());
dirpyrden->set_active (color->get_active ());
@@ -324,6 +328,7 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dst, const r
if (colormixer->get_active ()) dst->chmixer = src->chmixer;
if (colorshift->get_active ()) dst->colorShift = src->colorShift;
if (colorboost->get_active ()) dst->colorBoost = src->colorBoost;
+ if (hsveq->get_active ()) dst->hsvequalizer = src->hsvequalizer;
if (colorden->get_active ()) dst->colorDenoise = src->colorDenoise;
if (dirpyrden->get_active ()) dst->dirpyrDenoise = src->dirpyrDenoise;
diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h
index 2ea23772a..127b83833 100644
--- a/rtgui/partialpastedlg.h
+++ b/rtgui/partialpastedlg.h
@@ -51,6 +51,7 @@ class PartialPasteDlg : public Gtk::Dialog {
Gtk::CheckButton* colormixer;
Gtk::CheckButton* colorshift;
Gtk::CheckButton* colorboost;
+ Gtk::CheckButton* hsveq;
Gtk::CheckButton* colorden;
Gtk::CheckButton* dirpyrden;
@@ -73,7 +74,7 @@ class PartialPasteDlg : public Gtk::Dialog {
sigc::connection basicConn, luminanceConn, colorConn, lensConn, compositionConn, metaicmConn;
sigc::connection wbConn, exposureConn, hlrecConn;
- sigc::connection sharpenConn, impdenConn, lumadenConn, labcurveConn, shConn, dirpyreqConn, waveqConn;
+ sigc::connection sharpenConn, impdenConn, lumadenConn, labcurveConn, shConn, dirpyreqConn, waveqConn, hsveqConn;
sigc::connection colormixerConn, colorshiftConn, colorboostConn, colordenConn, dirpyrdenConn;
sigc::connection distortionConn, cacorrConn, vignettingConn;
sigc::connection coarserotConn, finerotConn, cropConn, resizeConn;
diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc
index 9a8a200af..4b95b93ca 100644
--- a/rtgui/toolpanelcoord.cc
+++ b/rtgui/toolpanelcoord.cc
@@ -58,6 +58,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
iptcpanel = Gtk::manage (new IPTCPanel ());
equalizer = Gtk::manage (new Equalizer ());
dirpyrequalizer = Gtk::manage (new DirPyrEqualizer ());
+ hsvequalizer = Gtk::manage (new HSVEqualizer ());
rawprocess = Gtk::manage (new RawProcess ());
preprocess = Gtk::manage (new PreProcess ());
@@ -69,7 +70,8 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
addPanel (detailsPanel, sharpening, M("TP_SHARPENING_LABEL")); toolPanels.push_back (sharpening);
addPanel (colorPanel, colorboost, M("TP_COLORBOOST_LABEL")); toolPanels.push_back (colorboost);
addPanel (colorPanel, colorshift, M("TP_COLORSHIFT_LABEL")); toolPanels.push_back (colorshift);
- addPanel (exposurePanel, lcurve, M("TP_LABCURVE_LABEL")); toolPanels.push_back (lcurve);
+ addPanel (colorPanel, hsvequalizer, M("TP_HSVEQUALIZER_LABEL")); toolPanels.push_back (hsvequalizer);
+ addPanel (exposurePanel, lcurve, M("TP_LABCURVE_LABEL")); toolPanels.push_back (lcurve);
addPanel (detailsPanel, impulsedenoise, M("TP_IMPULSEDENOISE_LABEL")); toolPanels.push_back (impulsedenoise);
addPanel (detailsPanel, lumadenoise, M("TP_LUMADENOISE_LABEL")); toolPanels.push_back (lumadenoise);
addPanel (detailsPanel, colordenoise, M("TP_COLORDENOISE_LABEL")); toolPanels.push_back (colordenoise);
diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h
index e17c1940d..669066afb 100644
--- a/rtgui/toolpanelcoord.h
+++ b/rtgui/toolpanelcoord.h
@@ -55,6 +55,7 @@
#include
#include
#include
+#include
#include
#include
@@ -95,6 +96,7 @@ class ToolPanelCoordinator : public ToolPanelListener,
LCurve* lcurve;
Equalizer * equalizer;
DirPyrEqualizer * dirpyrequalizer;
+ HSVEqualizer * hsvequalizer;
RawProcess* rawprocess;
PreProcess* preprocess;
|