Implementing RGB curves.

This commit is contained in:
Emil Martinec 2011-12-15 09:43:22 -06:00
parent f3826e82a9
commit ce1e28c03f
30 changed files with 418 additions and 57 deletions

View File

@ -306,6 +306,10 @@ if (OPTION_OMP)
endif (OPENMP_FOUND) endif (OPENMP_FOUND)
endif (OPTION_OMP) endif (OPTION_OMP)
if (UNIX)
install (PROGRAMS rtstart DESTINATION ${BINDIR})
endif (UNIX)
install (FILES AUTHORS.txt DESTINATION ${CREDITSDIR}) install (FILES AUTHORS.txt DESTINATION ${CREDITSDIR})
install (FILES LICENSE.txt DESTINATION ${LICENCEDIR}) install (FILES LICENSE.txt DESTINATION ${LICENCEDIR})
install (FILES AboutThisBuild.txt DESTINATION ${CREDITSDIR}) install (FILES AboutThisBuild.txt DESTINATION ${CREDITSDIR})

View File

@ -351,6 +351,9 @@ HISTORY_MSG_159;Edge stopping
HISTORY_MSG_160;Scale HISTORY_MSG_160;Scale
HISTORY_MSG_161;Reweighting iterates HISTORY_MSG_161;Reweighting iterates
HISTORY_MSG_162;Tone Mapping HISTORY_MSG_162;Tone Mapping
HISTORY_MSG_163;RGB Curves - R
HISTORY_MSG_164;RGB Curves - G
HISTORY_MSG_165;RGB Curves - B
HISTORY_NEWSNAPSHOTAS;As... HISTORY_NEWSNAPSHOTAS;As...
HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSSDIALOGLABEL;Label of the snapshot: HISTORY_NEWSSDIALOGLABEL;Label of the snapshot:
@ -557,6 +560,7 @@ PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations
PARTIALPASTE_RAW_DMETHOD;Demosaic Method PARTIALPASTE_RAW_DMETHOD;Demosaic Method
PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps
PARTIALPASTE_RESIZE;Resize PARTIALPASTE_RESIZE;Resize
PARTIALPASTE_RGBCURVES;RGB curves
PARTIALPASTE_ROTATION;Rotation PARTIALPASTE_ROTATION;Rotation
PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights
PARTIALPASTE_SHARPENEDGE;Edges PARTIALPASTE_SHARPENEDGE;Edges
@ -957,6 +961,7 @@ TP_RESIZE_SCALE;Scale
TP_RESIZE_SPECIFY;Specify: TP_RESIZE_SPECIFY;Specify:
TP_RESIZE_WIDTH;Width TP_RESIZE_WIDTH;Width
TP_RESIZE_W;W: TP_RESIZE_W;W:
TP_RGBCURVES_LABEL;RGB Curves
TP_ROTATE_DEGREE;Degree TP_ROTATE_DEGREE;Degree
TP_ROTATE_LABEL;Rotate TP_ROTATE_LABEL;Rotate
TP_ROTATE_SELECTLINE; Select Straight Line TP_ROTATE_SELECTLINE; Select Straight Line

View File

@ -421,7 +421,7 @@ namespace rtengine {
DiagonalCurve* tcurve = NULL; DiagonalCurve* tcurve = NULL;
if (curvePoints.size()>0 && curvePoints[0]!=0) { if (curvePoints.size()>0 && curvePoints[0]!=0) {
tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS/skip); tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS/skip);
if (outBeforeCCurveHistogram && histogramCropped) if (outBeforeCCurveHistogram /*&& histogramCropped*/)
histNeeded = true; histNeeded = true;
} }
if (tcurve && tcurve->isIdentity()) { if (tcurve && tcurve->isIdentity()) {
@ -434,11 +434,12 @@ namespace rtengine {
if (histNeeded) { if (histNeeded) {
float fi=i; float fi=i;
float hval = dcurve[shCurve[hlCurve[i]*fi]*fi]; float hval = hlCurve[i]*fi;
hval = dcurve[shCurve[hval]*hval];
//if (needigamma) //if (needigamma)
// hval = igamma2 (hval); // hval = igamma2 (hval);
int hi = (int)(255.0*(hval)); int hi = (int)(255.0*(hval));
outBeforeCCurveHistogram[hi] += histogramCropped[i] ; outBeforeCCurveHistogram[hi] += histogram/*Cropped*/[i] ;
} }
// apply custom/parametric/NURBS curve, if any // apply custom/parametric/NURBS curve, if any
@ -585,7 +586,7 @@ namespace rtengine {
bool histNeeded = false; bool histNeeded = false;
if (curvePoints.size()>0 && curvePoints[0]!=0) { if (curvePoints.size()>0 && curvePoints[0]!=0) {
tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS/skip); tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS/skip);
if (outBeforeCCurveHistogram && histogramCropped) if (outBeforeCCurveHistogram /*&& histogramCropped*/)
histNeeded = true; histNeeded = true;
} }
if (tcurve && tcurve->isIdentity()) { if (tcurve && tcurve->isIdentity()) {
@ -601,7 +602,7 @@ namespace rtengine {
if (histNeeded) { if (histNeeded) {
float hval = dcurve[i]; float hval = dcurve[i];
int hi = (int)(255.0*CLIPD(hval)); int hi = (int)(255.0*CLIPD(hval));
outBeforeCCurveHistogram[hi]+=histogramCropped[i] ; outBeforeCCurveHistogram[hi]+=histogram/*Cropped*/[i] ;
} }
// apply custom/parametric/NURBS curve, if any // apply custom/parametric/NURBS curve, if any
@ -617,7 +618,7 @@ namespace rtengine {
if (histNeeded) { if (histNeeded) {
float hval = dcurve[i]; float hval = dcurve[i];
int hi = (int)(255.0*CLIPD(hval)); int hi = (int)(255.0*CLIPD(hval));
outBeforeCCurveHistogram[hi]+=histogramCropped[i] ; outBeforeCCurveHistogram[hi]+=histogram/*Cropped*/[i] ;
} }
outCurve[i] = 32767.0*dcurve[i]; outCurve[i] = 32767.0*dcurve[i];
@ -636,6 +637,46 @@ namespace rtengine {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void CurveFactory::RGBCurve (const std::vector<double>& curvePoints, LUTf & outCurve, int skip) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// create a curve if needed
DiagonalCurve* tcurve = NULL;
bool histNeeded = false;
if (curvePoints.size()>0 && curvePoints[0]!=0) {
tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS/skip);
}
if (tcurve && tcurve->isIdentity()) {
delete tcurve;
tcurve = NULL;
}
if (tcurve) {
for (int i=0; i<65536; i++) {
// apply custom/parametric/NURBS curve, if any
float val = tcurve->getVal ((float)i/65536.0f);
outCurve[i] = (65536.0f * val);
}
}
else {
// Skip the slow getval method if no curve is used (or an identity curve)
for (int i=0; i<65536; i++) {
outCurve[i] = i;
}
}
if (tcurve)
delete tcurve;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
LUTf CurveFactory::gammatab; LUTf CurveFactory::gammatab;

View File

@ -193,12 +193,14 @@ class CurveFactory {
} }
public: public:
static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, double gamma_, bool igamma_, const std::vector<double>& curvePoints, static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, \
LUTu & histogram, LUTu & histogramCropped, LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip=1); double gamma_, bool igamma_, const std::vector<double>& curvePoints, LUTu & histogram, LUTu & histogramCropped, \
LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip=1);
static void complexsgnCurve (double saturation, bool satlimit, double satlimthresh, const std::vector<double>& acurvePoints, \ static void complexsgnCurve (double saturation, bool satlimit, double satlimthresh, const std::vector<double>& acurvePoints, \
const std::vector<double>& bcurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, int skip=1); const std::vector<double>& bcurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, int skip=1);
static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, LUTu & histogram, LUTu & histogramCropped, static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, LUTu & histogram, LUTu & histogramCropped, \
LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip); LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip);
static void RGBCurve (const std::vector<double>& curvePoints, LUTf & outCurve, int skip);
}; };
class Curve { class Curve {

View File

@ -128,7 +128,7 @@ void Crop::update (int todo) {
} }
// shadows & highlights & tone curve & convert to cielab // shadows & highlights & tone curve & convert to cielab
int xref,yref; /*int xref,yref;
xref=000;yref=000; xref=000;yref=000;
if (colortest && cropw>115 && croph>115) if (colortest && cropw>115 && croph>115)
for(int j=1;j<5;j++){ for(int j=1;j<5;j++){
@ -138,12 +138,13 @@ void Crop::update (int todo) {
baseCrop->g[(int)(xref/skip)][(int)(yref/skip)]/256, \ baseCrop->g[(int)(xref/skip)][(int)(yref/skip)]/256, \
baseCrop->b[(int)(xref/skip)][(int)(yref/skip)]/256, baseCrop->b[(int)(xref/skip)][(int)(yref/skip)]/256,
parent->imgsrc->getGamma()); parent->imgsrc->getGamma());
} }*/
if (todo & M_RGBCURVE) if (todo & M_RGBCURVE)
parent->ipf.rgbProc (baseCrop, laboCrop, parent->hltonecurve, parent->shtonecurve, parent->tonecurve, cshmap, params.toneCurve.saturation); parent->ipf.rgbProc (baseCrop, laboCrop, parent->hltonecurve, parent->shtonecurve, parent->tonecurve, cshmap, \
params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve );
xref=000;yref=000; /*xref=000;yref=000;
if (colortest && cropw>115 && croph>115) if (colortest && cropw>115 && croph>115)
for(int j=1;j<5;j++){ for(int j=1;j<5;j++){
xref+=j*30;yref+=j*30; xref+=j*30;yref+=j*30;
@ -157,7 +158,7 @@ void Crop::update (int todo) {
laboCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327, \ laboCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327, \
laboCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327); laboCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327);
} }
} }*/
// apply luminance operations // apply luminance operations
if (todo & (M_LUMINANCE+M_COLOR)) { if (todo & (M_LUMINANCE+M_COLOR)) {

View File

@ -56,6 +56,12 @@ ImProcCoordinator::ImProcCoordinator ()
histLCurve(256); histLCurve(256);
bcabhist(256); bcabhist(256);
rCurve(65536,0);
rcurvehist(256); rcurvehistCropped(256); rbeforehist(256);
gCurve(65536,0);
gcurvehist(256); gcurvehistCropped(256); gbeforehist(256);
bCurve(65536,0);
bcurvehist(256); bcurvehistCropped(256); bbeforehist(256);
} }
void ImProcCoordinator::assign (ImageSource* imgsrc) { void ImProcCoordinator::assign (ImageSource* imgsrc) {
@ -226,9 +232,14 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
imgsrc->getGamma(), true, params.toneCurve.curve, \ imgsrc->getGamma(), true, params.toneCurve.curve, \
vhist16, histCropped, hltonecurve, shtonecurve, tonecurve, histToneCurve, scale==1 ? 1 : 1); vhist16, histCropped, hltonecurve, shtonecurve, tonecurve, histToneCurve, scale==1 ? 1 : 1);
CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, scale==1 ? 1 : 1);
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, scale==1 ? 1 : 1);
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale==1 ? 1 : 1);
// if it's just crop we just need the histogram, no image updates // if it's just crop we just need the histogram, no image updates
if ( todo!=CROP ) { if ( todo!=CROP ) {
ipf.rgbProc (oprevi, oprevl, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation); ipf.rgbProc (oprevi, oprevl, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation, \
rCurve, gCurve, bCurve);
} }
// compute L channel histogram // compute L channel histogram

View File

@ -74,6 +74,14 @@ class ImProcCoordinator : public StagedImageProcessor {
LUTf chroma_bcurve; LUTf chroma_bcurve;
LUTf satcurve; LUTf satcurve;
LUTf rCurve;
LUTf gCurve;
LUTf bCurve;
LUTu rcurvehist, rcurvehistCropped, rbeforehist;
LUTu gcurvehist, gcurvehistCropped, gbeforehist;
LUTu bcurvehist, bcurvehistCropped, bbeforehist;
LUTu vhist16; LUTu vhist16;
LUTu lhist16,lhist16Cropped; LUTu lhist16,lhist16Cropped;
LUTu histCropped; LUTu histCropped;

View File

@ -207,7 +207,8 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par
} }
// Process RGB image and convert to LAB space // Process RGB image and convert to LAB space
void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat) { void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, \
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve) {
int h_th, s_th; int h_th, s_th;
if (shmap) { if (shmap) {
@ -334,9 +335,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltone
b *= tonefactor; b *= tonefactor;
//brightness/contrast and user tone curve //brightness/contrast and user tone curve
r = tonecurve[r]; r = rCurve[tonecurve[r]];
g = tonecurve[g]; g = gCurve[tonecurve[g]];
b = tonecurve[b]; b = bCurve[tonecurve[b]];
//if (r<0 || g<0 || b<0) { //if (r<0 || g<0 || b<0) {
// printf("negative values row=%d col=%d r=%f g=%f b=%f \n", i,j,r,g,b); // printf("negative values row=%d col=%d r=%f g=%f b=%f \n", i,j,r,g,b);
@ -505,7 +506,7 @@ void ImProcFunctions::chrominanceCurve (LabImage* lold, LabImage* lnew, LUTf & a
} }
#include "cubic.cc" //#include "cubic.cc"
void ImProcFunctions::colorCurve (LabImage* lold, LabImage* lnew) { void ImProcFunctions::colorCurve (LabImage* lold, LabImage* lnew) {
@ -811,18 +812,18 @@ fclose(f);*/
contr = MAX(0,MIN(100,contr)); contr = MAX(0,MIN(100,contr));
//diagnostics //diagnostics
printf ("**************** AUTO LEVELS ****************\n"); //printf ("**************** AUTO LEVELS ****************\n");
printf ("gain1= %f gain2= %f gain= %f\n",expcomp1,expcomp2,gain); //printf ("gain1= %f gain2= %f gain= %f\n",expcomp1,expcomp2,gain);
printf ("median: %i average: %f median/average: %f\n",median,ave, median/ave); //printf ("median: %i average: %f median/average: %f\n",median,ave, median/ave);
//printf ("average: %f\n",ave); //printf ("average: %f\n",ave);
//printf ("median/average: %f\n",median/ave); //printf ("median/average: %f\n",median/ave);
printf ("lodev: %f hidev: %f hidev/lodev: %f\n",lodev,hidev,hidev/lodev); //printf ("lodev: %f hidev: %f hidev/lodev: %f\n",lodev,hidev,hidev/lodev);
//printf ("lodev: %f\n",lodev); //printf ("lodev: %f\n",lodev);
//printf ("hidev: %f\n",hidev); //printf ("hidev: %f\n",hidev);
printf ("rawmax= %d whiteclip= %d gain= %f\n",rawmax,whiteclip,gain); //printf ("rawmax= %d whiteclip= %d gain= %f\n",rawmax,whiteclip,gain);
printf ("octiles: %f %f %f %f %f %f %f %f\n",octile[0],octile[1],octile[2],octile[3],octile[4],octile[5],octile[6],octile[7]); //printf ("octiles: %f %f %f %f %f %f %f %f\n",octile[0],octile[1],octile[2],octile[3],octile[4],octile[5],octile[6],octile[7]);
printf ("ospread= %f\n",ospread); //printf ("ospread= %f\n",ospread);
/* /*

View File

@ -111,7 +111,8 @@ class ImProcFunctions {
bool needsTransform (); bool needsTransform ();
void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16, double gamma); void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16, double gamma);
void rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat); void rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, \
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve);
void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve); void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve);
void chrominanceCurve (LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve); void chrominanceCurve (LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve);
void vibrance (LabImage* lab);//Jacques' vibrance void vibrance (LabImage* lab);//Jacques' vibrance

View File

@ -184,7 +184,10 @@ enum ProcEvent {
EvEPDScale=159, EvEPDScale=159,
EvEPDReweightingIterates=160, EvEPDReweightingIterates=160,
EvEPDEnabled=161, EvEPDEnabled=161,
NUMOFEVENTS=162 EvRGBrCurve=162,
EvRGBgCurve=163,
EvRGBbCurve=164,
NUMOFEVENTS=165
}; };
} }
#endif #endif

View File

@ -92,6 +92,14 @@ void ProcParams::setDefaults () {
labCurve.bcurve.clear (); labCurve.bcurve.clear ();
labCurve.bcurve.push_back(DCT_Linear); labCurve.bcurve.push_back(DCT_Linear);
rgbCurves.rcurve.clear ();
rgbCurves.rcurve.push_back(DCT_Linear);
rgbCurves.gcurve.clear ();
rgbCurves.gcurve.push_back(DCT_Linear);
rgbCurves.bcurve.clear ();
rgbCurves.bcurve.push_back(DCT_Linear);
sharpenEdge.enabled = false; sharpenEdge.enabled = false;
sharpenEdge.passes = 2; sharpenEdge.passes = 2;
sharpenEdge.amount = 50.0; sharpenEdge.amount = 50.0;
@ -521,6 +529,13 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2) const {
keyFile.set_double_list("HSV Equalizer", "SCurve", scurve); keyFile.set_double_list("HSV Equalizer", "SCurve", scurve);
keyFile.set_double_list("HSV Equalizer", "VCurve", vcurve); keyFile.set_double_list("HSV Equalizer", "VCurve", vcurve);
Glib::ArrayHandle<double> RGBrcurve = rgbCurves.rcurve;
Glib::ArrayHandle<double> RGBgcurve = rgbCurves.gcurve;
Glib::ArrayHandle<double> RGBbcurve = rgbCurves.bcurve;
keyFile.set_double_list("RGB Curves", "rCurve", RGBrcurve);
keyFile.set_double_list("RGB Curves", "gCurve", RGBgcurve);
keyFile.set_double_list("RGB Curves", "bCurve", RGBbcurve);
// save RAW parameters // save RAW parameters
keyFile.set_string ("RAW", "DarkFrame", raw.dark_frame ); keyFile.set_string ("RAW", "DarkFrame", raw.dark_frame );
keyFile.set_boolean ("RAW", "DarkFrameAuto", raw.df_autoselect ); keyFile.set_boolean ("RAW", "DarkFrameAuto", raw.df_autoselect );
@ -906,6 +921,13 @@ if (keyFile.has_group ("HSV Equalizer")) {
} }
} }
// load RGB curves
if (keyFile.has_group ("RGB Curves")) {
if (keyFile.has_key ("RGB Curves", "rCurve")) rgbCurves.rcurve = keyFile.get_double_list ("RGB Curves", "rCurve");
if (keyFile.has_key ("RGB Curves", "gCurve")) rgbCurves.gcurve = keyFile.get_double_list ("RGB Curves", "gCurve");
if (keyFile.has_key ("RGB Curves", "bCurve")) rgbCurves.bcurve = keyFile.get_double_list ("RGB Curves", "bCurve");
}
// load raw settings // load raw settings
if (keyFile.has_group ("RAW")) { if (keyFile.has_group ("RAW")) {
if (keyFile.has_key ("RAW", "DarkFrame")) raw.dark_frame = keyFile.get_string ("RAW", "DarkFrame" ); if (keyFile.has_key ("RAW", "DarkFrame")) raw.dark_frame = keyFile.get_string ("RAW", "DarkFrame" );
@ -1148,6 +1170,9 @@ bool ProcParams::operator== (const ProcParams& other) {
&& hsvequalizer.hcurve == other.hsvequalizer.hcurve && hsvequalizer.hcurve == other.hsvequalizer.hcurve
&& hsvequalizer.scurve == other.hsvequalizer.scurve && hsvequalizer.scurve == other.hsvequalizer.scurve
&& hsvequalizer.vcurve == other.hsvequalizer.vcurve && hsvequalizer.vcurve == other.hsvequalizer.vcurve
&& rgbCurves.rcurve == other.rgbCurves.rcurve
&& rgbCurves.gcurve == other.rgbCurves.gcurve
&& rgbCurves.bcurve == other.rgbCurves.bcurve
&& exif==other.exif && exif==other.exif
&& iptc==other.iptc && iptc==other.iptc
&& raw.expos==other.raw.expos && raw.expos==other.raw.expos

View File

@ -61,6 +61,17 @@ class LCurveParams {
double saturationlimit; double saturationlimit;
}; };
/**
* Parameters of the RGB curves
*/
class RGBCurvesParams {
public:
std::vector<double> rcurve;
std::vector<double> gcurve;
std::vector<double> bcurve;
};
/** /**
* Parameters of the sharpening * Parameters of the sharpening
*/ */
@ -476,6 +487,7 @@ class ProcParams {
public: public:
ToneCurveParams toneCurve; ///< Tone curve parameters ToneCurveParams toneCurve; ///< Tone curve parameters
LCurveParams labCurve; ///< CIELAB luminance curve parameters LCurveParams labCurve; ///< CIELAB luminance curve parameters
RGBCurvesParams rgbCurves; ///< RGB curves parameters
SharpeningParams sharpening; ///< Sharpening parameters SharpeningParams sharpening; ///< Sharpening parameters
SharpenEdgeParams sharpenEdge; ///< Sharpen edge parameters SharpenEdgeParams sharpenEdge; ///< Sharpen edge parameters
SharpenMicroParams sharpenMicro; ///< Sharpen microcontrast parameters SharpenMicroParams sharpenMicro; ///< Sharpen microcontrast parameters

View File

@ -67,6 +67,11 @@ PIX_SORT(p[3],p[6]); PIX_SORT(p[1],p[4]); PIX_SORT(p[2],p[5]); \
PIX_SORT(p[4],p[7]); PIX_SORT(p[4],p[2]); PIX_SORT(p[6],p[4]); \ PIX_SORT(p[4],p[7]); PIX_SORT(p[4],p[2]); PIX_SORT(p[6],p[4]); \
PIX_SORT(p[4],p[2]); median=p[4];} //a4 is the median PIX_SORT(p[4],p[2]); median=p[4];} //a4 is the median
#define med5(a0,a1,a2,a3,a4,median) { \
p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; \
PIX_SORT(p[0],p[1]) ; PIX_SORT(p[3],p[4]) ; PIX_SORT(p[0],p[3]) ; \
PIX_SORT(p[1],p[4]) ; PIX_SORT(p[1],p[2]) ; PIX_SORT(p[2],p[3]) ; \
PIX_SORT(p[1],p[2]) ; median=p[2] ;}
RawImageSource::RawImageSource () RawImageSource::RawImageSource ()
@ -1303,9 +1308,8 @@ void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur, int boxH,
for (int j=0; j<W; j++) { for (int j=0; j<W; j++) {
if (j<2) {jprev=j+2;} else {jprev=j-2;} if (j<2) {jprev=j+2;} else {jprev=j-2;}
if (j>W-3) {jnext=j-2;} else {jnext=j+2;} if (j>W-3) {jnext=j-2;} else {jnext=j+2;}
med3x3(rawData[iprev][jprev],rawData[iprev][j],rawData[iprev][jnext], \ med5(rawData[iprev][j], rawData[i][jprev],rawData[i][j], \
rawData[i][jprev],rawData[i][j],rawData[i][jnext], \ rawData[i][jnext], rawData[inext][j],cfatmp[i*W+j]);
rawData[inext][jprev],rawData[inext][j],rawData[inext][jnext],cfatmp[i*W+j]);
} }
} }

View File

@ -181,7 +181,10 @@ SHARPENING, // EvEPDStrength
SHARPENING, // EvEPDEdgeStopping SHARPENING, // EvEPDEdgeStopping
SHARPENING, // EvEPDScale SHARPENING, // EvEPDScale
SHARPENING, // EvEPDReweightingIterates SHARPENING, // EvEPDReweightingIterates
SHARPENING // EvEPDEnabled SHARPENING, // EvEPDEnabled
RGBCURVE, // EvRGBrCurve
RGBCURVE, // EvRGBgCurve
RGBCURVE // EvRGBbCurve
}; };

View File

@ -733,6 +733,9 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
LUTf curve2 (65536); LUTf curve2 (65536);
LUTf curve (65536); LUTf curve (65536);
LUTf satcurve (65536); LUTf satcurve (65536);
LUTf rCurve (65536);
LUTf gCurve (65536);
LUTf bCurve (65536);
LUTu dummy; LUTu dummy;
//CurveFactory::complexCurve (expcomp, black/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, \ //CurveFactory::complexCurve (expcomp, black/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, \
@ -742,10 +745,13 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
params.toneCurve.shcompr, bright, contr, gamma, true, params.toneCurve.shcompr, bright, contr, gamma, true,
params.toneCurve.curve, hist16, dummy, curve1, curve2, curve, dummy, 16); params.toneCurve.curve, hist16, dummy, curve1, curve2, curve, dummy, 16);
CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 16);
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 16);
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 16);
LabImage* labView = new LabImage (fw,fh); LabImage* labView = new LabImage (fw,fh);
ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation); ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve );
if (shmap) if (shmap)
delete shmap; delete shmap;

View File

@ -159,14 +159,21 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
LUTf curve2 (65536,0); LUTf curve2 (65536,0);
LUTf curve (65536,0); LUTf curve (65536,0);
LUTf satcurve (65536,0); LUTf satcurve (65536,0);
LUTf rCurve (65536,0);
LUTf gCurve (65536,0);
LUTf bCurve (65536,0);
LUTu dummy; LUTu dummy;
CurveFactory::complexCurve (expcomp, black/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, params.toneCurve.shcompr, bright, params.toneCurve.contrast, imgsrc->getGamma(), true, params.toneCurve.curve, CurveFactory::complexCurve (expcomp, black/65535.0, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, params.toneCurve.shcompr, bright, params.toneCurve.contrast, imgsrc->getGamma(), true, params.toneCurve.curve,
hist16, dummy, curve1, curve2, curve, dummy); hist16, dummy, curve1, curve2, curve, dummy);
CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 1);
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 1);
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 1);
LabImage* labView = new LabImage (fw,fh); LabImage* labView = new LabImage (fw,fh);
ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation); ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve);
// Freeing baseImg because not used anymore // Freeing baseImg because not used anymore
delete baseImg; delete baseImg;

View File

@ -9,7 +9,7 @@ set (BASESOURCEFILES
resize.cc icmpanel.cc crop.cc shadowshighlights.cc resize.cc icmpanel.cc crop.cc shadowshighlights.cc
impulsedenoise.cc dirpyrdenoise.cc epd.cc impulsedenoise.cc dirpyrdenoise.cc epd.cc
exifpanel.cc toolpanel.cc exifpanel.cc toolpanel.cc
sharpening.cc vibrance.cc sharpening.cc vibrance.cc rgbcurves.cc
whitebalance.cc vignetting.cc rotate.cc distortion.cc whitebalance.cc vignetting.cc rotate.cc distortion.cc
crophandler.cc dirbrowser.cc crophandler.cc dirbrowser.cc
curveeditor.cc curveeditorgroup.cc diagonalcurveeditorsubgroup.cc flatcurveeditorsubgroup.cc curveeditor.cc curveeditorgroup.cc diagonalcurveeditorsubgroup.cc flatcurveeditorsubgroup.cc

View File

@ -1307,7 +1307,7 @@ void EditorPanel::histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & his
LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) { LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) {
if (histogramPanel) histogramPanel->histogramChanged (histRed, histGreen, histBlue, histLuma, histRedRaw, histGreenRaw, histBlueRaw); if (histogramPanel) histogramPanel->histogramChanged (histRed, histGreen, histBlue, histLuma, histRedRaw, histGreenRaw, histBlueRaw);
tpc->updateCurveBackgroundHistogram (histToneCurve, histLCurve); tpc->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histRed, histGreen, histBlue, histLuma);
} }
bool EditorPanel::CheckSidePanelsVisibility() { bool EditorPanel::CheckSidePanelsVisibility() {

View File

@ -328,9 +328,9 @@ void LCurve::setBatchMode (bool batchMode) {
} }
void LCurve::updateCurveBackgroundHistogram (LUTu & hist) { void LCurve::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma){
lshape->updateBackgroundHistogram (hist); lshape->updateBackgroundHistogram (histLCurve);
} }
void LCurve::setAdjusterBehavior (bool bradd, bool contradd, bool satadd) { void LCurve::setAdjusterBehavior (bool bradd, bool contradd, bool satadd) {

View File

@ -62,7 +62,7 @@ class LCurve : public Gtk::VBox, public AdjusterListener, public FoldableToolPan
void adjusterChanged (Adjuster* a, double newval); void adjusterChanged (Adjuster* a, double newval);
void avoidclip_toggled (); void avoidclip_toggled ();
void enablelimiter_toggled (); void enablelimiter_toggled ();
void updateCurveBackgroundHistogram (LUTu & hist); void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma);
virtual void colorForValue (double valX, double valY); virtual void colorForValue (double valX, double valY);
}; };

View File

@ -48,6 +48,9 @@ void ParamsEdited::set (bool v) {
labCurve.avoidclip = v; labCurve.avoidclip = v;
labCurve.enable_saturationlimiter = v; labCurve.enable_saturationlimiter = v;
labCurve.saturationlimit = v; labCurve.saturationlimit = v;
rgbCurves.rcurve = v;
rgbCurves.gcurve = v;
rgbCurves.bcurve = v;
sharpening.enabled = v; sharpening.enabled = v;
sharpening.radius = v; sharpening.radius = v;
sharpening.amount = v; sharpening.amount = v;
@ -232,6 +235,9 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
labCurve.avoidclip = labCurve.avoidclip && p.labCurve.avoidclip == other.labCurve.avoidclip; 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.enable_saturationlimiter = labCurve.enable_saturationlimiter && p.labCurve.enable_saturationlimiter == other.labCurve.enable_saturationlimiter;
labCurve.saturationlimit = labCurve.saturationlimit && p.labCurve.saturationlimit == other.labCurve.saturationlimit; labCurve.saturationlimit = labCurve.saturationlimit && p.labCurve.saturationlimit == other.labCurve.saturationlimit;
rgbCurves.rcurve = rgbCurves.rcurve && p.rgbCurves.rcurve == other.rgbCurves.rcurve;
rgbCurves.gcurve = rgbCurves.gcurve && p.rgbCurves.gcurve == other.rgbCurves.gcurve;
rgbCurves.bcurve = rgbCurves.bcurve && p.rgbCurves.bcurve == other.rgbCurves.bcurve;
sharpenEdge.enabled = sharpenEdge.enabled && p.sharpenEdge.enabled == other.sharpenEdge.enabled; sharpenEdge.enabled = sharpenEdge.enabled && p.sharpenEdge.enabled == other.sharpenEdge.enabled;
sharpenEdge.passes = sharpenEdge.passes && p.sharpenEdge.passes == other.sharpenEdge.passes; sharpenEdge.passes = sharpenEdge.passes && p.sharpenEdge.passes == other.sharpenEdge.passes;
sharpenEdge.amount = sharpenEdge.amount && p.sharpenEdge.amount == other.sharpenEdge.amount; sharpenEdge.amount = sharpenEdge.amount && p.sharpenEdge.amount == other.sharpenEdge.amount;
@ -413,6 +419,11 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (labCurve.avoidclip) toEdit.labCurve.avoidclip = mods.labCurve.avoidclip; if (labCurve.avoidclip) toEdit.labCurve.avoidclip = mods.labCurve.avoidclip;
if (labCurve.enable_saturationlimiter) toEdit.labCurve.enable_saturationlimiter = mods.labCurve.enable_saturationlimiter; if (labCurve.enable_saturationlimiter) toEdit.labCurve.enable_saturationlimiter = mods.labCurve.enable_saturationlimiter;
if (labCurve.saturationlimit) toEdit.labCurve.saturationlimit = mods.labCurve.saturationlimit; if (labCurve.saturationlimit) toEdit.labCurve.saturationlimit = mods.labCurve.saturationlimit;
if (rgbCurves.rcurve) toEdit.rgbCurves.rcurve = mods.rgbCurves.rcurve;
if (rgbCurves.gcurve) toEdit.rgbCurves.gcurve = mods.rgbCurves.gcurve;
if (rgbCurves.bcurve) toEdit.rgbCurves.bcurve = mods.rgbCurves.bcurve;
if (sharpenEdge.enabled) toEdit.sharpenEdge.enabled = mods.sharpenEdge.enabled; if (sharpenEdge.enabled) toEdit.sharpenEdge.enabled = mods.sharpenEdge.enabled;
if (sharpenEdge.passes) toEdit.sharpenEdge.passes = dontforceSet && options.baBehav[ADDSET_SHARPENEDGE_PASS] ? toEdit.sharpenEdge.passes + mods.sharpenEdge.passes : mods.sharpenEdge.passes; if (sharpenEdge.passes) toEdit.sharpenEdge.passes = dontforceSet && options.baBehav[ADDSET_SHARPENEDGE_PASS] ? toEdit.sharpenEdge.passes + mods.sharpenEdge.passes : mods.sharpenEdge.passes;
if (sharpenEdge.amount) toEdit.sharpenEdge.amount = dontforceSet && options.baBehav[ADDSET_SHARPENEDGE_AMOUNT] ? toEdit.sharpenEdge.amount + mods.sharpenEdge.amount : mods.sharpenEdge.amount; if (sharpenEdge.amount) toEdit.sharpenEdge.amount = dontforceSet && options.baBehav[ADDSET_SHARPENEDGE_AMOUNT] ? toEdit.sharpenEdge.amount + mods.sharpenEdge.amount : mods.sharpenEdge.amount;

View File

@ -54,6 +54,14 @@ class LCurveParamsEdited {
bool bcurve; bool bcurve;
}; };
class RGBCurvesParamsEdited {
public:
bool rcurve;
bool gcurve;
bool bcurve;
};
class SharpenEdgeParamsEdited { class SharpenEdgeParamsEdited {
public : public :
@ -361,6 +369,7 @@ class ParamsEdited {
public: public:
ToneCurveParamsEdited toneCurve; ToneCurveParamsEdited toneCurve;
LCurveParamsEdited labCurve; LCurveParamsEdited labCurve;
RGBCurvesParamsEdited rgbCurves;
SharpeningParamsEdited sharpening; SharpeningParamsEdited sharpening;
SharpenEdgeParamsEdited sharpenEdge; SharpenEdgeParamsEdited sharpenEdge;
SharpenMicroParamsEdited sharpenMicro; SharpenMicroParamsEdited sharpenMicro;

View File

@ -63,6 +63,7 @@ PartialPasteDlg::PartialPasteDlg () {
chmixer = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CHANNELMIXER"))); chmixer = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CHANNELMIXER")));
dirpyrden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DIRPYRDENOISE"))); dirpyrden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DIRPYRDENOISE")));
hsveq = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_HSVEQUALIZER"))); hsveq = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_HSVEQUALIZER")));
rgbcurves = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RGBCURVES")));
// options in lens: // options in lens:
distortion = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DISTORTION"))); distortion = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DISTORTION")));
@ -140,6 +141,7 @@ PartialPasteDlg::PartialPasteDlg () {
vboxes[2]->pack_start (*vibrance, Gtk::PACK_SHRINK, 2); vboxes[2]->pack_start (*vibrance, Gtk::PACK_SHRINK, 2);
vboxes[2]->pack_start (*chmixer, Gtk::PACK_SHRINK, 2); vboxes[2]->pack_start (*chmixer, Gtk::PACK_SHRINK, 2);
vboxes[2]->pack_start (*hsveq, Gtk::PACK_SHRINK, 2); vboxes[2]->pack_start (*hsveq, Gtk::PACK_SHRINK, 2);
vboxes[2]->pack_start (*rgbcurves, Gtk::PACK_SHRINK, 2);
vboxes[3]->pack_start (*lens, Gtk::PACK_SHRINK, 2); vboxes[3]->pack_start (*lens, Gtk::PACK_SHRINK, 2);
vboxes[3]->pack_start (*hseps[3], Gtk::PACK_SHRINK, 2); vboxes[3]->pack_start (*hseps[3], Gtk::PACK_SHRINK, 2);
@ -252,6 +254,7 @@ PartialPasteDlg::PartialPasteDlg () {
vibranceConn = vibrance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); vibranceConn = vibrance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
chmixerConn = chmixer->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); chmixerConn = chmixer->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)); hsveqConn = hsveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
rgbcurvesConn = rgbcurves->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)); distortionConn = distortion->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true));
cacorrConn = cacorr->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); cacorrConn = cacorr->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true));
@ -468,17 +471,20 @@ void PartialPasteDlg::colorToggled () {
vibranceConn.block (true); vibranceConn.block (true);
chmixerConn.block (true); chmixerConn.block (true);
hsveqConn.block (true); hsveqConn.block (true);
rgbcurvesConn.block (true);
gamcsconn.block (true); gamcsconn.block (true);
color->set_inconsistent (false); color->set_inconsistent (false);
vibrance->set_active (color->get_active ()); vibrance->set_active (color->get_active ());
chmixer->set_active (color->get_active ()); chmixer->set_active (color->get_active ());
hsveq->set_active (color->get_active ()); hsveq->set_active (color->get_active ());
rgbcurves->set_active (color->get_active ());
icm->set_active (color->get_active ()); icm->set_active (color->get_active ());
vibranceConn.block (false); vibranceConn.block (false);
chmixerConn.block (false); chmixerConn.block (false);
hsveqConn.block (false); hsveqConn.block (false);
rgbcurvesConn.block (false);
gamcsconn.block (false); gamcsconn.block (false);
} }
@ -566,6 +572,7 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dst, const r
if (vibrance->get_active ()) dst->vibrance = src->vibrance; if (vibrance->get_active ()) dst->vibrance = src->vibrance;
if (chmixer->get_active ()) dst->chmixer = src->chmixer; if (chmixer->get_active ()) dst->chmixer = src->chmixer;
if (hsveq->get_active ()) dst->hsvequalizer = src->hsvequalizer; if (hsveq->get_active ()) dst->hsvequalizer = src->hsvequalizer;
if (rgbcurves->get_active ()) dst->rgbCurves = src->rgbCurves;
if (icm->get_active ()) dst->icm = src->icm; if (icm->get_active ()) dst->icm = src->icm;
if (distortion->get_active ()) dst->distortion = src->distortion; if (distortion->get_active ()) dst->distortion = src->distortion;

View File

@ -59,6 +59,7 @@ class PartialPasteDlg : public Gtk::Dialog {
Gtk::CheckButton* vibrance; Gtk::CheckButton* vibrance;
Gtk::CheckButton* chmixer; Gtk::CheckButton* chmixer;
Gtk::CheckButton* hsveq; Gtk::CheckButton* hsveq;
Gtk::CheckButton* rgbcurves;
// Gtk::CheckButton* icm; // Gtk::CheckButton* icm;
// options in lens: // options in lens:
@ -107,7 +108,7 @@ class PartialPasteDlg : public Gtk::Dialog {
sigc::connection wbConn, exposureConn, hlrecConn, shConn, labcurveConn; sigc::connection wbConn, exposureConn, hlrecConn, shConn, labcurveConn;
sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, waveqConn, defringeConn, edgePreservingDecompositionUIConn, dirpyreqConn; sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, waveqConn, defringeConn, edgePreservingDecompositionUIConn, dirpyreqConn;
sigc::connection vibranceConn, chmixerConn, hsveqConn; sigc::connection vibranceConn, chmixerConn, hsveqConn, rgbcurvesConn;
sigc::connection distortionConn, cacorrConn, vignettingConn; sigc::connection distortionConn, cacorrConn, vignettingConn;
sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn; sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn;
sigc::connection exifchConn, iptcConn, icmConn, gamcsconn; sigc::connection exifchConn, iptcConn, icmConn, gamcsconn;

141
rtgui/rgbcurves.cc Normal file
View File

@ -0,0 +1,141 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "rgbcurves.h"
#include <iomanip>
using namespace rtengine;
using namespace rtengine::procparams;
RGBCurves::RGBCurves () : Gtk::VBox(), FoldableToolPanel(this) {
curveEditorG = new CurveEditorGroup ();
curveEditorG->setCurveListener (this);
curveEditorG->setColorProvider (this);
Rshape = (DiagonalCurveEditor*)curveEditorG->addCurve(CT_Diagonal, "R");
Gshape = (DiagonalCurveEditor*)curveEditorG->addCurve(CT_Diagonal, "G");
Bshape = (DiagonalCurveEditor*)curveEditorG->addCurve(CT_Diagonal, "B");
// This will add the reset button at the end of the curveType buttons
curveEditorG->curveListComplete();
pack_start (*curveEditorG, Gtk::PACK_SHRINK, 4);
}
RGBCurves::~RGBCurves () {
delete curveEditorG;
}
void RGBCurves::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
if (pedited) {
Rshape->setUnChanged (!pedited->rgbCurves.rcurve);
Gshape->setUnChanged (!pedited->rgbCurves.gcurve);
Bshape->setUnChanged (!pedited->rgbCurves.bcurve);
}
Rshape->setCurve (pp->rgbCurves.rcurve);
Gshape->setCurve (pp->rgbCurves.gcurve);
Bshape->setCurve (pp->rgbCurves.bcurve);
// Open up the first curve if selected
bool active = Rshape->openIfNonlinear();
if (!active) Gshape->openIfNonlinear();
if (!active) Bshape->openIfNonlinear();
enableListener ();
}
void RGBCurves::write (ProcParams* pp, ParamsEdited* pedited) {
pp->rgbCurves.rcurve = Rshape->getCurve ();
pp->rgbCurves.gcurve = Gshape->getCurve ();
pp->rgbCurves.bcurve = Bshape->getCurve ();
if (pedited) {
pedited->rgbCurves.rcurve = !Rshape->isUnChanged ();
pedited->rgbCurves.gcurve = !Gshape->isUnChanged ();
pedited->rgbCurves.bcurve = !Bshape->isUnChanged ();
}
}
/*
* Curve listener
*
* If more than one curve has been added, the curve listener is automatically
* set to 'multi=true', and send a pointer of the modified curve in a parameter
*/
void RGBCurves::curveChanged (CurveEditor* ce) {
if (listener) {
if (ce == Rshape)
listener->panelChanged (EvRGBrCurve, M("HISTORY_CUSTOMCURVE"));
if (ce == Gshape)
listener->panelChanged (EvRGBgCurve, M("HISTORY_CUSTOMCURVE"));
if (ce == Bshape)
listener->panelChanged (EvRGBbCurve, M("HISTORY_CUSTOMCURVE"));
}
}
//!!! TODO: change
void RGBCurves::colorForValue (double valX, double valY) {
CurveEditor* ce = curveEditorG->getDisplayedCurve();
if (ce == Rshape) { // L = f(L)
red = (double)valY;
green = (double)valY;
blue = (double)valY;
}
else if (ce == Gshape) { // a = f(a)
// TODO: To be implemented
red = (double)valY;
green = (double)valY;
blue = (double)valY;
}
else if (ce == Bshape) { // b = f(b)
red = (double)valY;
green = (double)valY;
blue = (double)valY;
}
else {
printf("Error: no curve displayed!\n");
}
}
void RGBCurves::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
curveEditorG->setBatchMode (batchMode);
}
void RGBCurves::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma) {
//Rshape->updateBackgroundHistogram (histRed);
//Gshape->updateBackgroundHistogram (histGreen);
//Bshape->updateBackgroundHistogram (histBlue);
}

52
rtgui/rgbcurves.h Normal file
View File

@ -0,0 +1,52 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef _RGBCURVES_H_
#define _RGBCURVES_H_
#include <gtkmm.h>
#include <adjuster.h>
#include <toolpanel.h>
#include <curveeditor.h>
#include <curveeditorgroup.h>
#include <colorprovider.h>
class RGBCurves : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider {
protected:
CurveEditorGroup* curveEditorG;
DiagonalCurveEditor* Rshape;
DiagonalCurveEditor* Gshape;
DiagonalCurveEditor* Bshape;
public:
RGBCurves ();
~RGBCurves ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode);
void curveChanged (CurveEditor* ce);
void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma);
virtual void colorForValue (double valX, double valY);
};
#endif

View File

@ -410,7 +410,7 @@ void ToneCurve::trimValues (rtengine::procparams::ProcParams* pp) {
saturation->trimValue(pp->toneCurve.saturation); saturation->trimValue(pp->toneCurve.saturation);
} }
void ToneCurve::updateCurveBackgroundHistogram (LUTu & hist) { void ToneCurve::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma) {
shape->updateBackgroundHistogram (hist); shape->updateBackgroundHistogram (histToneCurve);
} }

View File

@ -78,7 +78,7 @@ class ToneCurve : public Gtk::VBox, public AdjusterListener, public FoldableTool
void curveChanged (); void curveChanged ();
void expandCurve (bool isExpanded); void expandCurve (bool isExpanded);
bool isCurveExpanded (); bool isCurveExpanded ();
void updateCurveBackgroundHistogram (LUTu & hist); void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma);
}; };
#endif #endif

View File

@ -50,6 +50,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
sharpenEdge = Gtk::manage (new SharpenEdge ()); sharpenEdge = Gtk::manage (new SharpenEdge ());
sharpenMicro = Gtk::manage (new SharpenMicro ()); sharpenMicro = Gtk::manage (new SharpenMicro ());
lcurve = Gtk::manage (new LCurve ()); lcurve = Gtk::manage (new LCurve ());
rgbcurves = Gtk::manage (new RGBCurves ());
lensgeom = Gtk::manage (new LensGeometry ()); lensgeom = Gtk::manage (new LensGeometry ());
distortion = Gtk::manage (new Distortion ()); distortion = Gtk::manage (new Distortion ());
rotate = Gtk::manage (new Rotate ()); rotate = Gtk::manage (new Rotate ());
@ -84,6 +85,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
addPanel (detailsPanel, sharpenEdge, M("TP_SHARPENEDGE_LABEL")); toolPanels.push_back (sharpenEdge); addPanel (detailsPanel, sharpenEdge, M("TP_SHARPENEDGE_LABEL")); toolPanels.push_back (sharpenEdge);
addPanel (detailsPanel, sharpenMicro, M("TP_SHARPENMICRO_LABEL")); toolPanels.push_back (sharpenMicro); addPanel (detailsPanel, sharpenMicro, M("TP_SHARPENMICRO_LABEL")); toolPanels.push_back (sharpenMicro);
addPanel (colorPanel, hsvequalizer, M("TP_HSVEQUALIZER_LABEL")); toolPanels.push_back (hsvequalizer); addPanel (colorPanel, hsvequalizer, M("TP_HSVEQUALIZER_LABEL")); toolPanels.push_back (hsvequalizer);
addPanel (colorPanel, rgbcurves, M("TP_RGBCURVES_LABEL")); toolPanels.push_back (rgbcurves);
addPanel (exposurePanel, edgePreservingDecompositionUI, M("TP_EPD_LABEL")); toolPanels.push_back (edgePreservingDecompositionUI); addPanel (exposurePanel, edgePreservingDecompositionUI, M("TP_EPD_LABEL")); toolPanels.push_back (edgePreservingDecompositionUI);
addPanel (exposurePanel, lcurve, M("TP_LABCURVE_LABEL")); toolPanels.push_back (lcurve); addPanel (exposurePanel, lcurve, M("TP_LABCURVE_LABEL")); toolPanels.push_back (lcurve);
addPanel (detailsPanel, impulsedenoise, M("TP_IMPULSEDENOISE_LABEL")); toolPanels.push_back (impulsedenoise); addPanel (detailsPanel, impulsedenoise, M("TP_IMPULSEDENOISE_LABEL")); toolPanels.push_back (impulsedenoise);
@ -492,10 +494,11 @@ int ToolPanelCoordinator::getSpotWBRectSize () {
return whitebalance->getSize (); return whitebalance->getSize ();
} }
void ToolPanelCoordinator::updateCurveBackgroundHistogram (LUTu &histToneCurve, LUTu &histLCurve) { void ToolPanelCoordinator::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma) {
toneCurve->updateCurveBackgroundHistogram (histToneCurve); toneCurve->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histRed, histGreen, histBlue, histLuma);
lcurve->updateCurveBackgroundHistogram (histLCurve); rgbcurves->updateCurveBackgroundHistogram(histToneCurve, histLCurve,histRed,histGreen, histBlue, histLuma);
lcurve->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histRed, histGreen, histBlue, histLuma);
} }
void ToolPanelCoordinator::foldAllButOne (Gtk::Box* parent, FoldableToolPanel* openedSection) { void ToolPanelCoordinator::foldAllButOne (Gtk::Box* parent, FoldableToolPanel* openedSection) {

View File

@ -62,6 +62,8 @@
#include <rawexposure.h> #include <rawexposure.h>
#include <sharpenmicro.h> #include <sharpenmicro.h>
#include <sharpenedge.h> #include <sharpenedge.h>
#include "rgbcurves.h"
class ImageEditorCoordinator; class ImageEditorCoordinator;
class ToolPanelCoordinator : public ToolPanelListener, class ToolPanelCoordinator : public ToolPanelListener,
@ -101,6 +103,7 @@ class ToolPanelCoordinator : public ToolPanelListener,
SharpenEdge* sharpenEdge; SharpenEdge* sharpenEdge;
SharpenMicro* sharpenMicro; SharpenMicro* sharpenMicro;
LCurve* lcurve; LCurve* lcurve;
RGBCurves* rgbcurves;
DirPyrEqualizer * dirpyrequalizer; DirPyrEqualizer * dirpyrequalizer;
HSVEqualizer * hsvequalizer; HSVEqualizer * hsvequalizer;
RawProcess* rawprocess; RawProcess* rawprocess;
@ -172,7 +175,7 @@ class ToolPanelCoordinator : public ToolPanelListener,
~ToolPanelCoordinator (); ~ToolPanelCoordinator ();
bool getChangedState () { return hasChanged; } bool getChangedState () { return hasChanged; }
void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurves); void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma);
void foldAllButOne (Gtk::Box* parent, FoldableToolPanel* openedSection); void foldAllButOne (Gtk::Box* parent, FoldableToolPanel* openedSection);
// multiple listeners can be added that are notified on changes (typical: profile panel and the history) // multiple listeners can be added that are notified on changes (typical: profile panel and the history)