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 (OPTION_OMP)
if (UNIX)
install (PROGRAMS rtstart DESTINATION ${BINDIR})
endif (UNIX)
install (FILES AUTHORS.txt DESTINATION ${CREDITSDIR})
install (FILES LICENSE.txt DESTINATION ${LICENCEDIR})
install (FILES AboutThisBuild.txt DESTINATION ${CREDITSDIR})

View File

@ -351,6 +351,9 @@ HISTORY_MSG_159;Edge stopping
HISTORY_MSG_160;Scale
HISTORY_MSG_161;Reweighting iterates
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_NEWSNAPSHOT;Add
HISTORY_NEWSSDIALOGLABEL;Label of the snapshot:
@ -557,6 +560,7 @@ PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations
PARTIALPASTE_RAW_DMETHOD;Demosaic Method
PARTIALPASTE_RAW_FALSECOLOR;Demosaic False color suppression steps
PARTIALPASTE_RESIZE;Resize
PARTIALPASTE_RGBCURVES;RGB curves
PARTIALPASTE_ROTATION;Rotation
PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights
PARTIALPASTE_SHARPENEDGE;Edges
@ -957,6 +961,7 @@ TP_RESIZE_SCALE;Scale
TP_RESIZE_SPECIFY;Specify:
TP_RESIZE_WIDTH;Width
TP_RESIZE_W;W:
TP_RGBCURVES_LABEL;RGB Curves
TP_ROTATE_DEGREE;Degree
TP_ROTATE_LABEL;Rotate
TP_ROTATE_SELECTLINE; Select Straight Line

View File

@ -421,7 +421,7 @@ namespace rtengine {
DiagonalCurve* tcurve = NULL;
if (curvePoints.size()>0 && curvePoints[0]!=0) {
tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS/skip);
if (outBeforeCCurveHistogram && histogramCropped)
if (outBeforeCCurveHistogram /*&& histogramCropped*/)
histNeeded = true;
}
if (tcurve && tcurve->isIdentity()) {
@ -434,11 +434,12 @@ namespace rtengine {
if (histNeeded) {
float fi=i;
float hval = dcurve[shCurve[hlCurve[i]*fi]*fi];
float hval = hlCurve[i]*fi;
hval = dcurve[shCurve[hval]*hval];
//if (needigamma)
// hval = igamma2 (hval);
int hi = (int)(255.0*(hval));
outBeforeCCurveHistogram[hi] += histogramCropped[i] ;
outBeforeCCurveHistogram[hi] += histogram/*Cropped*/[i] ;
}
// apply custom/parametric/NURBS curve, if any
@ -585,7 +586,7 @@ namespace rtengine {
bool histNeeded = false;
if (curvePoints.size()>0 && curvePoints[0]!=0) {
tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS/skip);
if (outBeforeCCurveHistogram && histogramCropped)
if (outBeforeCCurveHistogram /*&& histogramCropped*/)
histNeeded = true;
}
if (tcurve && tcurve->isIdentity()) {
@ -601,7 +602,7 @@ namespace rtengine {
if (histNeeded) {
float hval = dcurve[i];
int hi = (int)(255.0*CLIPD(hval));
outBeforeCCurveHistogram[hi]+=histogramCropped[i] ;
outBeforeCCurveHistogram[hi]+=histogram/*Cropped*/[i] ;
}
// apply custom/parametric/NURBS curve, if any
@ -617,7 +618,7 @@ namespace rtengine {
if (histNeeded) {
float hval = dcurve[i];
int hi = (int)(255.0*CLIPD(hval));
outBeforeCCurveHistogram[hi]+=histogramCropped[i] ;
outBeforeCCurveHistogram[hi]+=histogram/*Cropped*/[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;

View File

@ -193,12 +193,14 @@ class CurveFactory {
}
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,
LUTu & histogram, LUTu & histogramCropped, LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip=1);
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, 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, \
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,
LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip);
static void complexLCurve (double br, double contr, const std::vector<double>& curvePoints, LUTu & histogram, LUTu & histogramCropped, \
LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip);
static void RGBCurve (const std::vector<double>& curvePoints, LUTf & outCurve, int skip);
};
class Curve {

View File

@ -128,7 +128,7 @@ void Crop::update (int todo) {
}
// shadows & highlights & tone curve & convert to cielab
int xref,yref;
/*int xref,yref;
xref=000;yref=000;
if (colortest && cropw>115 && croph>115)
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->b[(int)(xref/skip)][(int)(yref/skip)]/256,
parent->imgsrc->getGamma());
}
}*/
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)
for(int j=1;j<5;j++){
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->b[(int)(xref/skip)][(int)(yref/skip)]/327);
}
}
}*/
// apply luminance operations
if (todo & (M_LUMINANCE+M_COLOR)) {

View File

@ -56,6 +56,12 @@ ImProcCoordinator::ImProcCoordinator ()
histLCurve(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) {
@ -226,9 +232,14 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
imgsrc->getGamma(), true, params.toneCurve.curve, \
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 ( 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

View File

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

View File

@ -207,7 +207,8 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par
}
// 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;
if (shmap) {
@ -334,9 +335,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltone
b *= tonefactor;
//brightness/contrast and user tone curve
r = tonecurve[r];
g = tonecurve[g];
b = tonecurve[b];
r = rCurve[tonecurve[r]];
g = gCurve[tonecurve[g]];
b = bCurve[tonecurve[b]];
//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);
@ -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) {
@ -811,18 +812,18 @@ fclose(f);*/
contr = MAX(0,MIN(100,contr));
//diagnostics
printf ("**************** AUTO LEVELS ****************\n");
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 ("**************** AUTO LEVELS ****************\n");
//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 ("average: %f\n",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 ("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 ("ospread= %f\n",ospread);
//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);
/*

View File

@ -111,7 +111,8 @@ class ImProcFunctions {
bool needsTransform ();
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 chrominanceCurve (LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve);
void vibrance (LabImage* lab);//Jacques' vibrance

View File

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

View File

@ -92,6 +92,14 @@ void ProcParams::setDefaults () {
labCurve.bcurve.clear ();
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.passes = 2;
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", "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
keyFile.set_string ("RAW", "DarkFrame", raw.dark_frame );
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
if (keyFile.has_group ("RAW")) {
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.scurve == other.hsvequalizer.scurve
&& hsvequalizer.vcurve == other.hsvequalizer.vcurve
&& rgbCurves.rcurve == other.rgbCurves.rcurve
&& rgbCurves.gcurve == other.rgbCurves.gcurve
&& rgbCurves.bcurve == other.rgbCurves.bcurve
&& exif==other.exif
&& iptc==other.iptc
&& raw.expos==other.raw.expos

View File

@ -61,6 +61,17 @@ class LCurveParams {
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
*/
@ -476,6 +487,7 @@ class ProcParams {
public:
ToneCurveParams toneCurve; ///< Tone curve parameters
LCurveParams labCurve; ///< CIELAB luminance curve parameters
RGBCurvesParams rgbCurves; ///< RGB curves parameters
SharpeningParams sharpening; ///< Sharpening parameters
SharpenEdgeParams sharpenEdge; ///< Sharpen edge 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[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 ()
@ -1303,9 +1308,8 @@ void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur, int boxH,
for (int j=0; j<W; j++) {
if (j<2) {jprev=j+2;} else {jprev=j-2;}
if (j>W-3) {jnext=j-2;} else {jnext=j+2;}
med3x3(rawData[iprev][jprev],rawData[iprev][j],rawData[iprev][jnext], \
rawData[i][jprev],rawData[i][j],rawData[i][jnext], \
rawData[inext][jprev],rawData[inext][j],rawData[inext][jnext],cfatmp[i*W+j]);
med5(rawData[iprev][j], rawData[i][jprev],rawData[i][j], \
rawData[i][jnext], rawData[inext][j],cfatmp[i*W+j]);
}
}

View File

@ -181,7 +181,10 @@ SHARPENING, // EvEPDStrength
SHARPENING, // EvEPDEdgeStopping
SHARPENING, // EvEPDScale
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 curve (65536);
LUTf satcurve (65536);
LUTf rCurve (65536);
LUTf gCurve (65536);
LUTf bCurve (65536);
LUTu dummy;
//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.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);
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)
delete shmap;

View File

@ -159,14 +159,21 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
LUTf curve2 (65536,0);
LUTf curve (65536,0);
LUTf satcurve (65536,0);
LUTf rCurve (65536,0);
LUTf gCurve (65536,0);
LUTf bCurve (65536,0);
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,
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);
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
delete baseImg;

View File

@ -9,7 +9,7 @@ set (BASESOURCEFILES
resize.cc icmpanel.cc crop.cc shadowshighlights.cc
impulsedenoise.cc dirpyrdenoise.cc epd.cc
exifpanel.cc toolpanel.cc
sharpening.cc vibrance.cc
sharpening.cc vibrance.cc rgbcurves.cc
whitebalance.cc vignetting.cc rotate.cc distortion.cc
crophandler.cc dirbrowser.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) {
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() {

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) {

View File

@ -62,7 +62,7 @@ class LCurve : public Gtk::VBox, public AdjusterListener, public FoldableToolPan
void adjusterChanged (Adjuster* a, double newval);
void avoidclip_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);
};

View File

@ -48,6 +48,9 @@ void ParamsEdited::set (bool v) {
labCurve.avoidclip = v;
labCurve.enable_saturationlimiter = v;
labCurve.saturationlimit = v;
rgbCurves.rcurve = v;
rgbCurves.gcurve = v;
rgbCurves.bcurve = v;
sharpening.enabled = v;
sharpening.radius = 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.enable_saturationlimiter = labCurve.enable_saturationlimiter && p.labCurve.enable_saturationlimiter == other.labCurve.enable_saturationlimiter;
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.passes = sharpenEdge.passes && p.sharpenEdge.passes == other.sharpenEdge.passes;
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.enable_saturationlimiter) toEdit.labCurve.enable_saturationlimiter = mods.labCurve.enable_saturationlimiter;
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.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;

View File

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

View File

@ -63,6 +63,7 @@ PartialPasteDlg::PartialPasteDlg () {
chmixer = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CHANNELMIXER")));
dirpyrden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DIRPYRDENOISE")));
hsveq = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_HSVEQUALIZER")));
rgbcurves = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RGBCURVES")));
// options in lens:
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 (*chmixer, 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 (*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));
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));
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));
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);
chmixerConn.block (true);
hsveqConn.block (true);
rgbcurvesConn.block (true);
gamcsconn.block (true);
color->set_inconsistent (false);
vibrance->set_active (color->get_active ());
chmixer->set_active (color->get_active ());
hsveq->set_active (color->get_active ());
rgbcurves->set_active (color->get_active ());
icm->set_active (color->get_active ());
vibranceConn.block (false);
chmixerConn.block (false);
hsveqConn.block (false);
rgbcurvesConn.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 (chmixer->get_active ()) dst->chmixer = src->chmixer;
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 (distortion->get_active ()) dst->distortion = src->distortion;

View File

@ -59,6 +59,7 @@ class PartialPasteDlg : public Gtk::Dialog {
Gtk::CheckButton* vibrance;
Gtk::CheckButton* chmixer;
Gtk::CheckButton* hsveq;
Gtk::CheckButton* rgbcurves;
// Gtk::CheckButton* icm;
// options in lens:
@ -107,7 +108,7 @@ class PartialPasteDlg : public Gtk::Dialog {
sigc::connection wbConn, exposureConn, hlrecConn, shConn, labcurveConn;
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 coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn;
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);
}
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 expandCurve (bool isExpanded);
bool isCurveExpanded ();
void updateCurveBackgroundHistogram (LUTu & hist);
void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma);
};
#endif

View File

@ -50,6 +50,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
sharpenEdge = Gtk::manage (new SharpenEdge ());
sharpenMicro = Gtk::manage (new SharpenMicro ());
lcurve = Gtk::manage (new LCurve ());
rgbcurves = Gtk::manage (new RGBCurves ());
lensgeom = Gtk::manage (new LensGeometry ());
distortion = Gtk::manage (new Distortion ());
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, sharpenMicro, M("TP_SHARPENMICRO_LABEL")); toolPanels.push_back (sharpenMicro);
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, lcurve, M("TP_LABCURVE_LABEL")); toolPanels.push_back (lcurve);
addPanel (detailsPanel, impulsedenoise, M("TP_IMPULSEDENOISE_LABEL")); toolPanels.push_back (impulsedenoise);
@ -492,10 +494,11 @@ int ToolPanelCoordinator::getSpotWBRectSize () {
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);
lcurve->updateCurveBackgroundHistogram (histLCurve);
toneCurve->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histRed, histGreen, histBlue, histLuma);
rgbcurves->updateCurveBackgroundHistogram(histToneCurve, histLCurve,histRed,histGreen, histBlue, histLuma);
lcurve->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histRed, histGreen, histBlue, histLuma);
}
void ToolPanelCoordinator::foldAllButOne (Gtk::Box* parent, FoldableToolPanel* openedSection) {

View File

@ -62,6 +62,8 @@
#include <rawexposure.h>
#include <sharpenmicro.h>
#include <sharpenedge.h>
#include "rgbcurves.h"
class ImageEditorCoordinator;
class ToolPanelCoordinator : public ToolPanelListener,
@ -101,6 +103,7 @@ class ToolPanelCoordinator : public ToolPanelListener,
SharpenEdge* sharpenEdge;
SharpenMicro* sharpenMicro;
LCurve* lcurve;
RGBCurves* rgbcurves;
DirPyrEqualizer * dirpyrequalizer;
HSVEqualizer * hsvequalizer;
RawProcess* rawprocess;
@ -172,7 +175,7 @@ class ToolPanelCoordinator : public ToolPanelListener,
~ToolPanelCoordinator ();
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);
// multiple listeners can be added that are notified on changes (typical: profile panel and the history)