New Vibrance tool from Jacques Desmis ; see issue 1065, and it's attached HTML document describing how to use it

This commit is contained in:
Hombre
2011-10-27 21:23:37 +02:00
parent 885308c2c8
commit 55541cff12
31 changed files with 3077 additions and 94 deletions

View File

@@ -9,6 +9,13 @@ endif (WIN32)
if (CMAKE_BUILD_TYPE STREQUAL "")
set (CMAKE_BUILD_TYPE Debug CACHE STRING "One of: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
endif ()
string (TOUPPER ${CMAKE_BUILD_TYPE} UPPER_CMAKE_BUILD_TYPE)
if (UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
add_definitions (-D_DEBUG)
endif ()
message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
set (CACHE_NAME_SUFFIX "" CACHE STRING "RawTherapee's cache folder suffix (leave empty to use the default suffix, i.e. latesttag)")
@@ -203,8 +210,6 @@ else (AUTOMATED_BUILD_SYSTEM)
set(PROC_BIT_DEPTH 64 bits)
endif (CMAKE_SIZEOF_VOID_P EQUAL 4)
string (TOUPPER ${CMAKE_BUILD_TYPE} UPPER_CMAKE_BUILD_TYPE)
#generating AboutThisBuild.txt
if (WIN32)

View File

@@ -247,6 +247,13 @@ HISTORY_MSG_148;Microcontraste
HISTORY_MSG_149;Microcontraste - Matrice 3x3
HISTORY_MSG_14;Luminance - Luminosité
HISTORY_MSG_150;Réduction du bruit/artefact post-dématriçage
HISTORY_MSG_151;Vibrance
HISTORY_MSG_152;Vibrance - Tons pastels
HISTORY_MSG_153;Vibrance - Tons saturés
HISTORY_MSG_154;Vibrance - Protéger les tons chairs
HISTORY_MSG_155;Vibrance - Éviter les dérives de teinte
HISTORY_MSG_156;Vibrance - Lier Pastels et Saturés
HISTORY_MSG_157;Vibrance - Seuil entre Pastels/Saturés
HISTORY_MSG_15;Luminance - Contraste
HISTORY_MSG_16;Luminance - Noir
HISTORY_MSG_17;Luminance - Compression Hautes lumières
@@ -549,6 +556,7 @@ PARTIALPASTE_SHADOWSHIGHLIGHTS;Ombres/Hautes lumières
PARTIALPASTE_SHARPENEDGE;Bords
PARTIALPASTE_SHARPENING;Netteté
PARTIALPASTE_SHARPENMICRO;Microcontraste
PARTIALPASTE_VIBRANCE;Vibrance
PARTIALPASTE_VIGNETTING;Correction du vignettage
PARTIALPASTE_WAVELETEQUALIZER;Égaliseur d'ondelette
PARTIALPASTE_WHITEBALANCE;Balance des blancs
@@ -973,6 +981,13 @@ TP_SHARPENMICRO_AMOUNT;Quantité
TP_SHARPENMICRO_LABEL;Microcontraste
TP_SHARPENMICRO_MATRIX;Matrice 3×3 au lieu de 5×5
TP_SHARPENMICRO_UNIFORMITY;Uniformité
TP_VIBRANCE_AVOIDCOLORSHIFT;Éviter les dérives de teinte
TP_VIBRANCE_LABEL;Vibrance
TP_VIBRANCE_PASTELS;Tons pastels
TP_VIBRANCE_PASTSATTOG;Lier Pastels et Saturés
TP_VIBRANCE_PROTECTSKINS;Protéger les tons chairs
TP_VIBRANCE_SATURATED;Tons saturés
TP_VIBRANCE_PSTHRESHOLD;Seuil entre Pastels/Saturés
TP_VIGNETTING_AMOUNT;Quantité
TP_VIGNETTING_CENTER;Centre
TP_VIGNETTING_CENTER_X;Centre X

View File

@@ -246,6 +246,13 @@ HISTORY_MSG_148;Microcontrast
HISTORY_MSG_149;Microcontrast - 3x3 matrix
HISTORY_MSG_14;Luminance Brightness
HISTORY_MSG_150;Post demosaic artifact/noise reduction
HISTORY_MSG_151;Vibrance
HISTORY_MSG_152;Vibrance - Pastels tones
HISTORY_MSG_153;Vibrance - Saturated tones
HISTORY_MSG_154;Vibrance - Protect skin tones
HISTORY_MSG_155;Vibrance - Avoid color drift
HISTORY_MSG_156;Vibrance - Link Pastels & Saturated
HISTORY_MSG_157;Vibrance - Pastels/Saturated threshold
HISTORY_MSG_15;Luminance Contrast
HISTORY_MSG_16;Luminance Black
HISTORY_MSG_17;Luminance Highlight Compr.
@@ -549,6 +556,7 @@ PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights
PARTIALPASTE_SHARPENEDGE;Edges
PARTIALPASTE_SHARPENING;Sharpening (USM/RL)
PARTIALPASTE_SHARPENMICRO;Microcontrast
PARTIALPASTE_VIBRANCE;Vibrance
PARTIALPASTE_VIGNETTING;Vignetting correction
PARTIALPASTE_WAVELETEQUALIZER;Wavelet equalizer
PARTIALPASTE_WHITEBALANCE;White balance
@@ -973,6 +981,13 @@ TP_SHARPENMICRO_AMOUNT;Quantity
TP_SHARPENMICRO_LABEL;Microcontrast
TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5
TP_SHARPENMICRO_UNIFORMITY;Uniformity
TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift
TP_VIBRANCE_LABEL;Vibrance
TP_VIBRANCE_PASTELS;Pastels tones
TP_VIBRANCE_PASTSATTOG;Link Pastels & Saturated
TP_VIBRANCE_PROTECTSKINS;Protect skin tones
TP_VIBRANCE_SATURATED;Saturated tones
TP_VIBRANCE_PSTHRESHOLD;Pastels/Saturated threshold
TP_VIGNETTING_AMOUNT;Amount
TP_VIGNETTING_CENTER;Center
TP_VIGNETTING_CENTER_X;Center X

View File

@@ -12,7 +12,7 @@ set (RTENGINESOURCEFILES safegtk.cc colortemp.cc curves.cc flatcurves.cc diagona
loadinitial.cc procparams.cc rawimagesource.cc demosaic_algos.cc shmap.cc simpleprocess.cc refreshmap.cc
stdimagesource.cc myfile.cc iccjpeg.c hlmultipliers.cc improccoordinator.cc
processingjob.cc rtthumbnail.cc utils.cc labimage.cc slicer.cc
iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc
iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc ipvibrance.cc
jpeg_memsrc.c jdatasrc.c
PF_correct_RT.cc
wavelet_dec.cc dirpyrLab_denoise.cc dirpyrLab_equalizer.cc dirpyr_equalizer.cc

View File

@@ -163,8 +163,8 @@ void Crop::update (int todo) {
if (todo & (M_LUMINANCE+M_COLOR)) {
parent->ipf.luminanceCurve (laboCrop, labnCrop, parent->lumacurve);
parent->ipf.chrominanceCurve (laboCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve);
//parent->ipf.colorCurve (labnCrop, labnCrop);
parent->ipf.vibrance (labnCrop);
if (skip==1) {
parent->ipf.impulsedenoise (labnCrop);

View File

@@ -90,7 +90,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
mProcessing.lock ();
int numofphases = 10;
int numofphases = 14;
int readyphase = 0;
ipf.setScale (scale);
@@ -115,7 +115,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
rp.all_enhance = false;
}
progress ("Applying white balance, color correction & sRBG conversion...",100*readyphase/numofphases);
progress ("Applying white balance, color correction & sRGB conversion...",100*readyphase/numofphases);
if ( todo & M_PREPROC) {
imgsrc->preprocess( rp );
imgsrc->getRAWHistogram( histRedRaw, histGreenRaw, histBlueRaw );
@@ -245,6 +245,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
readyphase++;
if ((todo & M_LUMACURVE) || todo==CROP) {
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lhist16Cropped,
lumacurve, histLCurve, scale==1 ? 1 : 16);
}
@@ -256,28 +257,34 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
if (todo & (M_LUMINANCE+M_COLOR) ) {
progress ("Applying Luminance Curve...",100*readyphase/numofphases);
ipf.luminanceCurve (oprevl, nprevl, lumacurve);
readyphase++;
progress ("Applying Color Boost...",100*readyphase/numofphases);
ipf.chrominanceCurve (oprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve/*, params.labCurve.saturation*/);
//ipf.colorCurve (nprevl, nprevl);
ipf.vibrance(nprevl);
readyphase++;
if (scale==1) {
progress ("Denoising luminance impulse...",100*readyphase/numofphases);
ipf.impulsedenoise (nprevl);
readyphase++;
progress ("Defringing...",100*readyphase/numofphases);
ipf.defringe (nprevl);
readyphase++;
progress ("Denoising luma/chroma...",100*readyphase/numofphases);
ipf.dirpyrdenoise (nprevl);
readyphase++;
if (params.sharpenEdge.enabled) {
progress ("Edge sharpening...",100*readyphase/numofphases);
ipf.MLsharpen (nprevl);
readyphase++;
}
if (params.sharpenMicro.enabled) {
progress ("Microcontrast...",100*readyphase/numofphases);
ipf.MLmicrocontrast (nprevl);
readyphase++;
}
if (params.sharpening.enabled) {
progress ("Sharpening...",100*readyphase/numofphases);
@@ -291,10 +298,12 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
for (int i=0; i<pH; i++)
delete [] buffer[i];
delete [] buffer;
readyphase++;
}
progress ("Pyramid equalizer...",100*readyphase/numofphases);
ipf.dirpyrequalizer (nprevl);
readyphase++;
}
}

View File

@@ -477,7 +477,7 @@ void ImProcFunctions::chrominanceCurve (LabImage* lold, LabImage* lnew, LUTf & a
float atmp = acurve[lold->a[i][j]+32768.0f]-32768.0f;
float btmp = bcurve[lold->b[i][j]+32768.0f]-32768.0f;
if (params->labCurve.saturation && fabs(atmp)<32768.0f && fabs(btmp)<32768.0f) {
if (params->labCurve.saturation) {
float chroma = sqrt(SQR(atmp)+SQR(btmp)+0.001);
float satfactor = (satcurve[chroma+32768.0f]-32768.0f)/chroma;
atmp *= satfactor;

View File

@@ -61,10 +61,46 @@ class ImProcFunctions {
public:
static LUTf cachef;
// 195 LUTf for Munsell Lch correction
static LUTf _4P10,_4P20,_4P30,_4P40,_4P50,_4P60;
static LUTf _1P10,_1P20,_1P30,_1P40,_1P50,_1P60;
static LUTf _5B40,_5B50,_5B60, _5B70,_5B80;
static LUTf _7B40,_7B50,_7B60, _7B70,_7B80;
static LUTf _9B40,_9B50,_9B60, _9B70,_9B80;
static LUTf _10B40,_10B50,_10B60, _10B70,_10B80;
static LUTf _05PB40,_05PB50,_05PB60, _05PB70,_05PB80;
static LUTf _10PB10,_10PB20,_10PB30,_10PB40,_10PB50,_10PB60;
static LUTf _9PB10,_9PB20,_9PB30,_9PB40,_9PB50,_9PB60,_9PB70,_9PB80;
static LUTf _75PB10,_75PB20,_75PB30,_75PB40,_75PB50,_75PB60,_75PB70,_75PB80;
static LUTf _6PB10,_6PB20,_6PB30,_6PB40,_6PB50,_6PB60,_6PB70,_6PB80;
static LUTf _45PB10,_45PB20,_45PB30,_45PB40,_45PB50,_45PB60,_45PB70,_45PB80;
static LUTf _3PB10,_3PB20,_3PB30,_3PB40,_3PB50,_3PB60,_3PB70,_3PB80;
static LUTf _15PB10,_15PB20,_15PB30,_15PB40,_15PB50,_15PB60, _15PB70,_15PB80;
static LUTf _10YR20, _10YR30, _10YR40,_10YR50,_10YR60,_10YR70,_10YR80,_10YR90;
static LUTf _85YR20, _85YR30, _85YR40,_85YR50,_85YR60,_85YR70,_85YR80,_85YR90;
static LUTf _7YR30, _7YR40,_7YR50,_7YR60,_7YR70,_7YR80;
static LUTf _55YR30, _55YR40,_55YR50,_55YR60,_55YR70,_55YR80,_55YR90;
static LUTf _4YR30, _4YR40,_4YR50,_4YR60,_4YR70,_4YR80;
static LUTf _25YR30, _25YR40,_25YR50,_25YR60,_25YR70;
static LUTf _10R30, _10R40,_10R50,_10R60,_10R70;
static LUTf _9R30, _9R40,_9R50,_9R60,_9R70;
static LUTf _7R30, _7R40,_7R50,_7R60,_7R70;
static LUTf _5R10, _5R20,_5R30;
static LUTf _25R10, _25R20,_25R30;
static LUTf _10RP10, _10RP20,_10RP30;
static LUTf _7G30, _7G40,_7G50,_7G60,_7G70,_7G80;
static LUTf _5G30, _5G40,_5G50,_5G60,_5G70,_5G80;
static LUTf _25G30, _25G40,_25G50,_25G60,_25G70,_25G80;
static LUTf _1G30, _1G40,_1G50,_1G60,_1G70,_1G80;
static LUTf _10GY30, _10GY40,_10GY50,_10GY60,_10GY70,_10GY80;
static LUTf _75GY30, _75GY40,_75GY50,_75GY60,_75GY70,_75GY80;
static LUTf _5GY30, _5GY40,_5GY50,_5GY60,_5GY70,_5GY80;
double lumimul[3];
static void initCache ();
static void cleanupCache ();
static void initMunsell ();
ImProcFunctions (const ProcParams* iparams, bool imultiThread=true)
: monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread) {}
@@ -78,6 +114,9 @@ class ImProcFunctions {
void rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat);
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
void skinsat (float lum, float hue, float chrom, float &satreduc);//jacques Skin color
void MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone);//jacques: Munsell correction
void colorCurve (LabImage* lold, LabImage* lnew);
void sharpening (LabImage* lab, float** buffer);
void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH);
@@ -124,21 +163,21 @@ class ImProcFunctions {
void hsv2rgb (float h, float s, float v, float &r, float &g, float &b);
void xyz2srgb (float x, float y, float z, float &r, float &g, float &b);
void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, float rgb_xyz[3][3]);
void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z);
void XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b);
void Lab2Yuv(float L, float a, float b, float &Y, float &u, float &v);
void Yuv2Lab(float Y, float u, float v, float &L, float &a, float &b, double wp[3][3]);
void calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4,double &gamma5);
void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z);
void XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b);
void Lab2Yuv(float L, float a, float b, float &Y, float &u, float &v);
void Yuv2Lab(float Y, float u, float v, float &L, float &a, float &b, double wp[3][3]);
void calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4,double &gamma5);
//void gamutmap(LabImage* );
void gamutmap(float &X, float &Y, float &Z, const double p[3][3]);
//void gamutmap(LabImage* );
void gamutmap(float &X, float &Y, float &Z, const double p[3][3]);
static inline float f2xyz(float f) {
const float epsilonExpInv3 = 6.0/29.0;
const float kappaInv = 27.0/24389.0; // inverse of kappa
static inline float f2xyz(float f) {
const float epsilonExpInv3 = 6.0/29.0;
const float kappaInv = 27.0/24389.0; // inverse of kappa
return (f > epsilonExpInv3) ? f*f*f : (116 * f - 16) * kappaInv;
}
return (f > epsilonExpInv3) ? f*f*f : (116 * f - 16) * kappaInv;
}
};
}
#endif

View File

@@ -38,6 +38,7 @@ int init (const Settings* s, Glib::ustring baseDir) {
iccStore->findDefaultMonitorProfile();
CurveFactory::init ();
ImProcFunctions::initMunsell();
ImProcFunctions::initCache ();
Thumbnail::initGamma ();
delete lcmsMutex;

2336
rtengine/ipvibrance.cc Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -172,9 +172,14 @@ enum ProcEvent {
EvSharpenMicroEnabled=147,
EvSharpenMicroMatrix=148,
EvDemosaicALLEnhanced=149,
NUMOFEVENTS=150
};
EvVibranceEnabled=150,
EvVibrancePastels=151,
EvVibranceSaturated=152,
EvVibranceProtectSkins=153,
EvVibranceAvoidColorShift=154,
EvVibrancePastSatTog=155,
EvVibrancePastSatThreshold=156,
NUMOFEVENTS=157
};
}
#endif

View File

@@ -116,6 +116,14 @@ void ProcParams::setDefaults () {
sharpening.deconvdamping = 20;
sharpening.deconvamount = 75;
vibrance.enabled = false;
vibrance.pastels = 0;
vibrance.saturated = 0;
vibrance.psthreshold = 75;
vibrance.protectskins = false;
vibrance.avoidcolorshift = true;
vibrance.pastsattog = true;
colorBoost.amount = 0;
colorBoost.avoidclip = false;
colorBoost.enable_saturationlimiter = false;
@@ -338,6 +346,15 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2) const {
keyFile.set_integer ("Sharpening", "DeconvDamping", sharpening.deconvdamping);
keyFile.set_integer ("Sharpening", "DeconvIterations", sharpening.deconviter);
// save vibrance
keyFile.set_boolean ("Vibrance", "Enabled", vibrance.enabled);
keyFile.set_integer ("Vibrance", "Pastels", vibrance.pastels);
keyFile.set_integer ("Vibrance", "Saturated", vibrance.saturated);
keyFile.set_integer ("Vibrance", "PSThreshold", vibrance.psthreshold);
keyFile.set_boolean ("Vibrance", "ProtectSkins", vibrance.protectskins);
keyFile.set_boolean ("Vibrance", "AvoidColorShift", vibrance.avoidcolorshift);
keyFile.set_boolean ("Vibrance", "PastSatTog", vibrance.pastsattog);
//save edge sharpening
keyFile.set_boolean ("SharpenEdge", "Enabled", sharpenEdge.enabled);
keyFile.set_integer ("SharpenEdge", "Passes", sharpenEdge.passes);
@@ -652,7 +669,7 @@ if (keyFile.has_group ("Sharpening")) {
if (keyFile.has_group ("SharpenEdge")) {
if (keyFile.has_key ("SharpenEdge", "Enabled")) sharpenEdge.enabled = keyFile.get_boolean ("SharpenEdge", "Enabled");
if (keyFile.has_key ("SharpenEdge", "Passes")) sharpenEdge.passes = keyFile.get_integer ("SharpenEdge", "Passes");
if (keyFile.has_key ("SharpenEdge", "Strength")) sharpenEdge.amount = keyFile.get_double ("SharpenEdge", "Strength");
if (keyFile.has_key ("SharpenEdge", "Strength")) sharpenEdge.amount = keyFile.get_double ("SharpenEdge", "Strength");
if (keyFile.has_key ("SharpenEdge", "ThreeChannels")) sharpenEdge.threechannels = keyFile.get_boolean ("SharpenEdge", "ThreeChannels");
}
@@ -660,10 +677,21 @@ if (keyFile.has_group ("SharpenEdge")) {
if (keyFile.has_group ("SharpenMicro")) {
if (keyFile.has_key ("SharpenMicro", "Enabled")) sharpenMicro.enabled = keyFile.get_boolean ("SharpenMicro", "Enabled");
if (keyFile.has_key ("SharpenMicro", "Matrix")) sharpenMicro.matrix = keyFile.get_boolean ("SharpenMicro", "Matrix");
if (keyFile.has_key ("SharpenMicro", "Strength")) sharpenMicro.amount = keyFile.get_double ("SharpenMicro", "Strength");
if (keyFile.has_key ("SharpenMicro", "Strength")) sharpenMicro.amount = keyFile.get_double ("SharpenMicro", "Strength");
if (keyFile.has_key ("SharpenMicro", "Uniformity")) sharpenMicro.uniformity = keyFile.get_double ("SharpenMicro", "Uniformity");
}
// load vibrance
if (keyFile.has_group ("Vibrance")) {
if (keyFile.has_key ("Vibrance", "Enabled")) vibrance.enabled = keyFile.get_boolean ("Vibrance", "Enabled");
if (keyFile.has_key ("Vibrance", "Pastels")) vibrance.pastels = keyFile.get_integer ("Vibrance", "Pastels");
if (keyFile.has_key ("Vibrance", "Saturated")) vibrance.saturated = keyFile.get_integer ("Vibrance", "Saturated");
if (keyFile.has_key ("Vibrance", "PSThreshold")) vibrance.psthreshold = keyFile.get_integer ("Vibrance", "PSThreshold");
if (keyFile.has_key ("Vibrance", "ProtectSkins")) vibrance.protectskins = keyFile.get_boolean ("Vibrance", "ProtectSkins");
if (keyFile.has_key ("Vibrance", "AvoidColorShift")) vibrance.avoidcolorshift = keyFile.get_boolean ("Vibrance", "AvoidColorShift");
if (keyFile.has_key ("Vibrance", "PastSatTog")) vibrance.pastsattog = keyFile.get_boolean ("Vibrance", "PastSatTog");
}
// load colorBoost
if (keyFile.has_group ("Color Boost")) {
if (keyFile.has_key ("Color Boost", "Amount")) colorBoost.amount = keyFile.get_integer ("Color Boost", "Amount");
@@ -976,6 +1004,13 @@ bool ProcParams::operator== (const ProcParams& other) {
&& sharpening.deconvradius == other.sharpening.deconvradius
&& sharpening.deconviter == other.sharpening.deconviter
&& sharpening.deconvdamping == other.sharpening.deconvdamping
&& vibrance.enabled == other.vibrance.enabled
&& vibrance.pastels == other.vibrance.pastels
&& vibrance.saturated == other.vibrance.saturated
&& vibrance.psthreshold == other.vibrance.psthreshold
&& vibrance.protectskins == other.vibrance.protectskins
&& vibrance.avoidcolorshift == other.vibrance.avoidcolorshift
&& vibrance.pastsattog == other.vibrance.pastsattog
&& colorBoost.amount == other.colorBoost.amount
&& colorBoost.avoidclip == other.colorBoost.avoidclip
&& colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter

View File

@@ -96,6 +96,22 @@ class SharpenMicroParams {
double amount;
double uniformity;
};
/**
* Parameters of the vibrance
*/
class VibranceParams {
public:
bool enabled;
int pastels;
int saturated;
int psthreshold;
bool protectskins;
bool avoidcolorshift;
bool pastsattog;
};
/**
* Parameters of the color boost
*/
@@ -451,6 +467,7 @@ class ProcParams {
SharpeningParams sharpening; ///< Sharpening parameters
SharpenEdgeParams sharpenEdge; ///< Sharpen edge parameters
SharpenMicroParams sharpenMicro; ///< Sharpen microcontrast parameters
VibranceParams vibrance; ///< Vibrance parameters
ColorBoostParams colorBoost; ///< Color boost parameters
WBParams wb; ///< White balance parameters
ColorShiftParams colorShift; ///< Color shift parameters

View File

@@ -32,6 +32,8 @@
#include <iostream>
#include <options.h>
#include <improcfun.h>
#ifdef _OPENMP
#include <omp.h>
@@ -40,7 +42,6 @@
namespace rtengine {
extern const Settings* settings;
#undef ABS
#undef MAX
#undef MIN
@@ -1607,10 +1608,8 @@ void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams
//MyTime t1, t2, t3;
//t1.set ();
cmsHPROFILE in;
if (!findInputProfile(cmp.input, embedded, camName, in)) return;
// Calculate matrix for direct conversion raw>working space
TMatrix work = iccStore->workingSpaceInverseMatrix (cmp.working);
float mat[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
@@ -1649,9 +1648,76 @@ void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams
im->g[h][w] /= 65535.0f ;
im->b[h][w] /= 65535.0f ;
}
cmsHPROFILE out = iccStore->workingSpace (cmp.working);
// out = iccStore->workingSpaceGamma (wProfile);
if(settings->gamutICC)
// use Prophoto to apply profil ICC, then converted to cmp.working (sRGB..., Adobe.., Wide..) to avoid color shifts due to relative colorimetric
// LCMS use intent for applying profil => suppression of negatives values and > 65535
//useful for correcting Munsell Lch
{ if( settings->verbose ) printf("With Gamut ICC correction float\n");
Glib::ustring profi ="ProPhoto";
cmsHPROFILE out = iccStore->workingSpace (profi);//Prophoto
TMatrix wprof = iccStore->workingSpaceMatrix (profi);
TMatrix wiprof = iccStore->workingSpaceInverseMatrix (cmp.working);//sRGB .. Adobe...Wide...
float toxyz[3][3] = {
{
( wprof[0][0]),
( wprof[0][1]),
( wprof[0][2])
},{
( wprof[1][0] ),
( wprof[1][1] ),
( wprof[1][2] )
},{
( wprof[2][0]),
( wprof[2][1]),
( wprof[2][2])
}
};
float wip[3][3] = {
{wiprof[0][0],wiprof[0][1],wiprof[0][2]},
{wiprof[1][0],wiprof[1][1],wiprof[1][2]},
{wiprof[2][0],wiprof[2][1],wiprof[2][2]}};
lcmsMutex->lock ();
cmsHTRANSFORM hTransform = cmsCreateTransform (in, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), out, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)),
INTENT_RELATIVE_COLORIMETRIC, // float is clipless, so don't trim it
settings->LCMSSafeMode ? 0 : cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety
lcmsMutex->unlock ();
if (hTransform) {
im->ExecCMSTransform(hTransform, settings->LCMSSafeMode);
}
else {
// create the profile from camera
lcmsMutex->lock ();
hTransform = cmsCreateTransform (camprofile, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), out, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), settings->colorimetricIntent,
settings->LCMSSafeMode ? cmsFLAGS_NOOPTIMIZE : cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety
lcmsMutex->unlock ();
im->ExecCMSTransform(hTransform, settings->LCMSSafeMode);
}
float x, y,z;
Glib::ustring choiceprofile;
choiceprofile=cmp.working;
if(choiceprofile!="ProPhoto") {
for ( int h = 0; h < im->height; ++h )
for ( int w = 0; w < im->width; ++w ) {//convert from Prophoto to XYZ
x = (toxyz[0][0] * im->r[h][w] + toxyz[0][1] * im->g[h][w] + toxyz[0][2] * im->b[h][w] ) ;
y = (toxyz[1][0] * im->r[h][w] + toxyz[1][1] * im->g[h][w] + toxyz[1][2] * im->b[h][w] ) ;
z = (toxyz[2][0] * im->r[h][w] + toxyz[2][1] * im->g[h][w] + toxyz[2][2] * im->b[h][w] ) ;
//convert from XYZ to cmp.working (sRGB...Adobe...Wide..)
im->r[h][w] = ((wiprof[0][0]*x + wiprof[0][1]*y + wiprof[0][2]*z)) ;
im->g[h][w] = ((wiprof[1][0]*x + wiprof[1][1]*y + wiprof[1][2]*z)) ;
im->b[h][w] = ((wiprof[2][0]*x + wiprof[2][1]*y + wiprof[2][2]*z)) ;
}
}
cmsDeleteTransform(hTransform);
}
else {
if( settings->verbose ) printf("Without Gamut ICC correction float\n");
cmsHPROFILE out = iccStore->workingSpace (cmp.working);
// out = iccStore->workingSpaceGamma (wProfile);
lcmsMutex->lock ();
cmsHTRANSFORM hTransform = cmsCreateTransform (in, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)), out, (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|PLANAR_SH(1)),
INTENT_RELATIVE_COLORIMETRIC, // float is clipless, so don't trim it
@@ -1672,6 +1738,7 @@ void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams
}
cmsDeleteTransform(hTransform);
}
// restore normalization to the range (0,65535) and blend matrix colors if LCMS is clipping
const float RecoverTresh = 65535.0 * 0.98; // just the last few percent highlights are merged
@@ -1736,7 +1803,6 @@ void RawImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams
// Converts raw image including ICC input profile to working space - 16bit int version
void RawImageSource::colorSpaceConversion16 (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded, cmsHPROFILE camprofile, double camMatrix[3][3], std::string camName, double& defgain) {
cmsHPROFILE in;
if (!findInputProfile(cmp.input, embedded, camName, in)) return;
@@ -1763,7 +1829,8 @@ TMatrix work = iccStore->workingSpaceInverseMatrix (cmp.working);
im->b[i][j] = CLIP((int)newb);
}
}
else {
else
{
cmsHPROFILE out = iccStore->workingSpace (cmp.working);
// out = iccStore->workingSpaceGamma (wProfile);
lcmsMutex->lock ();

View File

@@ -170,6 +170,13 @@ SHARPENING, // EvSharpenEdgeThreechannels
SHARPENING, // EvSharpenMicroEnabled
SHARPENING, // EvSharpenMicroMatrix
DEMOSAIC, // EvDemosaicALLEnhanced
RGBCURVE, // EvVibranceEnabled
RGBCURVE, // EvVibrancePastels
RGBCURVE, // EvVibranceSaturated
RGBCURVE, // EvVibranceProtectSkins
RGBCURVE, // EvVibranceAvoidColorShift
RGBCURVE, // EvVibrancePastSatTog
RGBCURVE // EvVibrancePastSatThreshold
};

View File

@@ -751,6 +751,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, \
params.labCurve.acurve, params.labCurve.bcurve, curve1, curve2, satcurve, 16);
ipf.chrominanceCurve (labView, labView, curve1, curve2, satcurve);
ipf.vibrance(labView);
// color processing
//ipf.colorCurve (labView, labView);

View File

@@ -40,6 +40,7 @@ namespace rtengine {
Glib::ustring best; // default name of BestRGB
Glib::ustring bruce; // default name of Bruce
Glib::ustring srgb; // default name of SRGB space profile
bool gamutICC; //
/** Creates a new instance of Settings.
* @return a pointer to the new Settings instance. */

View File

@@ -170,11 +170,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
hist16[CLIP((int)((labView->L[i][j])))]++;
// luminance processing
CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, hist16, curve, dummy, 1);
ipf.luminanceCurve (labView, labView, curve);
CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, \
params.labCurve.acurve, params.labCurve.bcurve, curve1, curve2, satcurve, 1);
ipf.chrominanceCurve (labView, labView, curve1, curve2, satcurve);
ipf.vibrance(labView);
ipf.impulsedenoise (labView);
ipf.defringe (labView);

View File

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

View File

@@ -47,7 +47,11 @@
#define ADDSET_SHARPENMICRO_AMOUNT 37
#define ADDSET_SHARPENEDGE_PASS 38
#define ADDSET_SHARPENMICRO_UNIFORMITY 39
#define ADDSET_VIBRANCE_PASTELS 40
#define ADDSET_VIBRANCE_SATURATED 41
#define ADDSET_VIBRANCE_PSTHRESHOLD 42
// When adding items, make sure to update ADDSET_PARAM_NUM
#define ADDSET_PARAM_NUM 40 // THIS IS USED AS A DELIMITER!!
#define ADDSET_PARAM_NUM 43 // THIS IS USED AS A DELIMITER!!
#endif

View File

@@ -122,6 +122,7 @@ void BatchToolPanelCoordinator::initSession () {
toneCurve->setAdjusterBehavior (false, false, false, false, false, false, false, false);
lcurve->setAdjusterBehavior (false, false, false);
whitebalance->setAdjusterBehavior (false, false);
vibrance->setAdjusterBehavior (false, false, false);
vignetting->setAdjusterBehavior (false);
rotate->setAdjusterBehavior (false);
distortion->setAdjusterBehavior (false);
@@ -144,6 +145,7 @@ void BatchToolPanelCoordinator::initSession () {
toneCurve->setAdjusterBehavior (options.baBehav[ADDSET_TC_EXPCOMP], options.baBehav[ADDSET_TC_HLCOMPAMOUNT],options.baBehav[ADDSET_TC_HLCOMPTHRESH], options.baBehav[ADDSET_TC_BRIGHTNESS], options.baBehav[ADDSET_TC_BLACKLEVEL],options.baBehav[ADDSET_TC_SHCOMP], options.baBehav[ADDSET_TC_CONTRAST], options.baBehav[ADDSET_TC_SATURATION]);
lcurve->setAdjusterBehavior (options.baBehav[ADDSET_LC_BRIGHTNESS], options.baBehav[ADDSET_LC_CONTRAST], options.baBehav[ADDSET_LC_SATURATION]);
whitebalance->setAdjusterBehavior (options.baBehav[ADDSET_WB_TEMPERATURE], options.baBehav[ADDSET_WB_GREEN]);
vibrance->setAdjusterBehavior (options.baBehav[ADDSET_VIBRANCE_PASTELS], options.baBehav[ADDSET_VIBRANCE_SATURATED], options.baBehav[ADDSET_VIBRANCE_PSTHRESHOLD]);
vignetting->setAdjusterBehavior (options.baBehav[ADDSET_VIGN_AMOUNT]);
rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]);
distortion->setAdjusterBehavior (options.baBehav[ADDSET_DIST_AMOUNT]);
@@ -189,6 +191,9 @@ void BatchToolPanelCoordinator::initSession () {
if (options.baBehav[ADDSET_WB_TEMPERATURE]) pparams.wb.temperature = 0;
if (options.baBehav[ADDSET_WB_GREEN]) pparams.wb.green = 0;
if (options.baBehav[ADDSET_VIBRANCE_PASTELS]) pparams.vibrance.pastels = 0;
if (options.baBehav[ADDSET_VIBRANCE_SATURATED]) pparams.vibrance.saturated = 0;
if (options.baBehav[ADDSET_CBOOST_AMOUNT]) pparams.colorBoost.amount = 0;
if (options.baBehav[ADDSET_CS_BLUEYELLOW]) pparams.colorShift.a = 0;

View File

@@ -168,6 +168,7 @@ void Options::setDefaults () {
sndEnable=true;
sndLngEditProcDoneSecs=3.0;
// Reminder: 0 = SET mode, 1 = ADD mode
int babehav[] = {
1, // ADDSET_TC_EXPCOMP
1, // ADDSET_TC_BRIGHTNESS
@@ -208,7 +209,11 @@ void Options::setDefaults () {
0, // ADDSET_SHARPENEDGE_AMOUNT
0, // ADDSET_SHARPENMICRO_AMOUNT
0, // ADDSET_SHARPENEDGE_PASS
0 // ADDSET_SHARPENMICRO_UNIFORMITY
0, // ADDSET_SHARPENMICRO_UNIFORMITY
1, // ADDSET_VIBRANCE_PASTELS
1, // ADDSET_VIBRANCE_SATURATED
0 // ADDSET_VIBRANCE_SATURATED
};
baBehav = std::vector<int> (babehav, babehav+ADDSET_PARAM_NUM);
@@ -234,8 +239,8 @@ void Options::setDefaults () {
rtSettings.bruce = "Bruce";
rtSettings.beta = "BetaRGB";
rtSettings.best = "BestRGB";
rtSettings.verbose = false;
rtSettings.gamutICC = true;
}
Options* Options::copyFrom (Options* other) {
@@ -423,7 +428,8 @@ if (keyFile.has_group ("Color Management")) {
if (keyFile.has_key ("Color Management", "Intent")) rtSettings.colorimetricIntent = keyFile.get_integer("Color Management", "Intent");
if (keyFile.has_key ("Color Management", "WhiteBalanceSpotSize")) whiteBalanceSpotSize = keyFile.get_integer("Color Management", "WhiteBalanceSpotSize");
if (keyFile.has_key ("Color Management", "WhiteBalanceSpotSize")) whiteBalanceSpotSize = keyFile.get_integer("Color Management", "WhiteBalanceSpotSize");
if( keyFile.has_key ("Color Management", "GamutICC")) rtSettings.gamutICC = keyFile.get_boolean("Color Management", "GamutICC");
// Disabled (default is true) till issues are sorted out
//if (keyFile.has_key ("Color Management", "LCMSSafeMode")) rtSettings.LCMSSafeMode = keyFile.get_boolean ("Color Management", "LCMSSafeMode");
@@ -602,6 +608,7 @@ int Options::saveToFile (Glib::ustring fname) {
keyFile.set_string ("Color Management", "B_est", rtSettings.best);
keyFile.set_string ("Color Management", "B_ruce", rtSettings.bruce);
keyFile.set_integer ("Color Management", "WhiteBalanceSpotSize", whiteBalanceSpotSize);
keyFile.set_boolean ("Color Management", "GamutICC", rtSettings.gamutICC);
Glib::ArrayHandle<int> bab = baBehav;
keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab);

View File

@@ -42,57 +42,64 @@ void ParamsEdited::set (bool v) {
labCurve.lcurve = v;
labCurve.acurve = v;
labCurve.bcurve = v;
labCurve.brightness = v;
labCurve.contrast = v;
labCurve.saturation = v;
labCurve.avoidclip = v;
labCurve.brightness = v;
labCurve.contrast = v;
labCurve.saturation = v;
labCurve.avoidclip = v;
labCurve.enable_saturationlimiter = v;
labCurve.saturationlimit = v;
sharpening.enabled = v;
sharpening.radius = v;
sharpening.amount = v;
sharpening.threshold = v;
sharpening.edgesonly = v;
sharpening.edges_radius = v;
sharpening.edges_tolerance = v;
sharpening.halocontrol = v;
sharpening.halocontrol_amount= v;
sharpening.method = v;
sharpening.deconvamount = v;
sharpening.deconvradius = v;
sharpening.deconviter = v;
sharpening.deconvdamping = v;
labCurve.saturationlimit = v;
sharpening.enabled = v;
sharpening.radius = v;
sharpening.amount = v;
sharpening.threshold = v;
sharpening.edgesonly = v;
sharpening.edges_radius = v;
sharpening.edges_tolerance = v;
sharpening.halocontrol = v;
sharpening.halocontrol_amount = v;
sharpening.method = v;
sharpening.deconvamount = v;
sharpening.deconvradius = v;
sharpening.deconviter = v;
sharpening.deconvdamping = v;
sharpenEdge.enabled = v;
sharpenEdge.passes = v;
sharpenEdge.amount = v;
sharpenEdge.amount = v;
sharpenEdge.threechannels = v;
sharpenMicro.enabled = v;
sharpenMicro.matrix = v;
sharpenMicro.amount = v;
sharpenMicro.amount = v;
sharpenMicro.uniformity = v;
vibrance.enabled = v;
vibrance.pastels = v;
vibrance.saturated = v;
vibrance.psthreshold = v;
vibrance.protectskins = v;
vibrance.avoidcolorshift = v;
vibrance.pastsattog = v;
colorBoost.amount = v;
colorBoost.avoidclip = v;
colorBoost.enable_saturationlimiter = v;
colorBoost.saturationlimit = v;
wb.method = v;
wb.green = v;
wb.temperature = v;
colorShift.a = v;
colorShift.b = v;
lumaDenoise.enabled = v;
lumaDenoise.radius = v;
lumaDenoise.edgetolerance = v;
colorDenoise.enabled = v;
colorDenoise.amount = v;
defringe.enabled = v;
defringe.radius = v;
defringe.threshold = v;
impulseDenoise.enabled = v;
impulseDenoise.thresh = v;
dirpyrDenoise.enabled = v;
dirpyrDenoise.luma = v;
dirpyrDenoise.chroma = v;
dirpyrDenoise.gamma = v;
wb.method = v;
wb.green = v;
wb.temperature = v;
colorShift.a = v;
colorShift.b = v;
lumaDenoise.enabled = v;
lumaDenoise.radius = v;
lumaDenoise.edgetolerance = v;
colorDenoise.enabled = v;
colorDenoise.amount = v;
defringe.enabled = v;
defringe.radius = v;
defringe.threshold = v;
impulseDenoise.enabled = v;
impulseDenoise.thresh = v;
dirpyrDenoise.enabled = v;
dirpyrDenoise.luma = v;
dirpyrDenoise.chroma = v;
dirpyrDenoise.gamma = v;
sh.enabled = v;
sh.hq = v;
sh.highlights = v;
@@ -217,7 +224,7 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
labCurve.brightness = labCurve.brightness && p.labCurve.brightness == other.labCurve.brightness;
labCurve.contrast = labCurve.contrast && p.labCurve.contrast == other.labCurve.contrast;
labCurve.saturation = labCurve.saturation && p.labCurve.saturation == other.labCurve.saturation;
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.saturationlimit = labCurve.saturationlimit && p.labCurve.saturationlimit == other.labCurve.saturationlimit;
sharpenEdge.enabled = sharpenEdge.enabled && p.sharpenEdge.enabled == other.sharpenEdge.enabled;
@@ -242,6 +249,13 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
sharpening.deconvradius = sharpening.deconvradius && p.sharpening.deconvradius == other.sharpening.deconvradius;
sharpening.deconviter = sharpening.deconviter && p.sharpening.deconviter == other.sharpening.deconviter;
sharpening.deconvdamping = sharpening.deconvdamping && p.sharpening.deconvdamping == other.sharpening.deconvdamping;
vibrance.enabled = vibrance.enabled && p.vibrance.enabled == other.vibrance.enabled;
vibrance.pastels = vibrance.pastels && p.vibrance.pastels == other.vibrance.pastels;
vibrance.saturated = vibrance.saturated && p.vibrance.saturated == other.vibrance.saturated;
vibrance.psthreshold = vibrance.psthreshold && p.vibrance.psthreshold == other.vibrance.psthreshold;
vibrance.protectskins = vibrance.protectskins && p.vibrance.protectskins == other.vibrance.protectskins;
vibrance.avoidcolorshift = vibrance.avoidcolorshift && p.vibrance.avoidcolorshift == other.vibrance.avoidcolorshift;
vibrance.pastsattog = vibrance.pastsattog && p.vibrance.pastsattog == other.vibrance.pastsattog;
colorBoost.amount = colorBoost.amount && p.colorBoost.amount == other.colorBoost.amount;
colorBoost.avoidclip = colorBoost.avoidclip && p.colorBoost.avoidclip == other.colorBoost.avoidclip;
colorBoost.enable_saturationlimiter = colorBoost.enable_saturationlimiter && p.colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter;
@@ -390,7 +404,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (labCurve.saturationlimit) toEdit.labCurve.saturationlimit = mods.labCurve.saturationlimit;
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;
if (sharpenEdge.amount) toEdit.sharpenEdge.amount = dontforceSet && options.baBehav[ADDSET_SHARPENEDGE_AMOUNT] ? toEdit.sharpenEdge.amount + mods.sharpenEdge.amount : mods.sharpenEdge.amount;
if (sharpenEdge.threechannels) toEdit.sharpenEdge.threechannels = mods.sharpenEdge.threechannels;
if (sharpenMicro.enabled) toEdit.sharpenMicro.enabled = mods.sharpenMicro.enabled;
if (sharpenMicro.matrix) toEdit.sharpenMicro.matrix = mods.sharpenMicro.matrix;
@@ -402,15 +416,22 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (sharpening.threshold) toEdit.sharpening.threshold = mods.sharpening.threshold;
if (sharpening.edgesonly) toEdit.sharpening.edgesonly = mods.sharpening.edgesonly;
if (sharpening.edges_radius) toEdit.sharpening.edges_radius = mods.sharpening.edges_radius;
if (sharpening.edges_tolerance) toEdit.sharpening.edges_tolerance = mods.sharpening.edges_tolerance;
if (sharpening.halocontrol) toEdit.sharpening.halocontrol = mods.sharpening.halocontrol;
if (sharpening.halocontrol_amount) toEdit.sharpening.halocontrol_amount = mods.sharpening.halocontrol_amount;
if (sharpening.method) toEdit.sharpening.method = mods.sharpening.method;
if (sharpening.edges_tolerance) toEdit.sharpening.edges_tolerance = mods.sharpening.edges_tolerance;
if (sharpening.halocontrol) toEdit.sharpening.halocontrol = mods.sharpening.halocontrol;
if (sharpening.halocontrol_amount) toEdit.sharpening.halocontrol_amount = mods.sharpening.halocontrol_amount;
if (sharpening.method) toEdit.sharpening.method = mods.sharpening.method;
if (sharpening.deconvamount) toEdit.sharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.deconvamount + mods.sharpening.deconvamount : mods.sharpening.deconvamount;
if (sharpening.deconvradius) toEdit.sharpening.deconvradius = mods.sharpening.deconvradius;
if (sharpening.deconviter) toEdit.sharpening.deconviter = mods.sharpening.deconviter;
if (sharpening.deconvdamping) toEdit.sharpening.deconvdamping = mods.sharpening.deconvdamping;
if (colorBoost.amount) toEdit.colorBoost.amount = dontforceSet && options.baBehav[ADDSET_CBOOST_AMOUNT] ? toEdit.colorBoost.amount + mods.colorBoost.amount : mods.colorBoost.amount;
if (sharpening.deconvdamping) toEdit.sharpening.deconvdamping = mods.sharpening.deconvdamping;
if (vibrance.enabled) toEdit.vibrance.enabled = mods.vibrance.enabled;
if (vibrance.pastels) toEdit.vibrance.pastels = dontforceSet && options.baBehav[ADDSET_VIBRANCE_PASTELS] ? toEdit.vibrance.pastels + mods.vibrance.pastels : mods.vibrance.pastels;
if (vibrance.saturated) toEdit.vibrance.saturated = dontforceSet && options.baBehav[ADDSET_VIBRANCE_SATURATED] ? toEdit.vibrance.saturated + mods.vibrance.saturated : mods.vibrance.saturated;
if (vibrance.psthreshold) toEdit.vibrance.psthreshold = dontforceSet && options.baBehav[ADDSET_VIBRANCE_PSTHRESHOLD] ? toEdit.vibrance.psthreshold + mods.vibrance.psthreshold : mods.vibrance.psthreshold;
if (vibrance.protectskins) toEdit.vibrance.protectskins = mods.vibrance.protectskins;
if (vibrance.avoidcolorshift) toEdit.vibrance.avoidcolorshift = mods.vibrance.avoidcolorshift;
if (vibrance.pastsattog) toEdit.vibrance.pastsattog = mods.vibrance.pastsattog;
if (colorBoost.amount) toEdit.colorBoost.amount = dontforceSet && options.baBehav[ADDSET_CBOOST_AMOUNT] ? toEdit.colorBoost.amount + mods.colorBoost.amount : mods.colorBoost.amount;
if (colorBoost.avoidclip) toEdit.colorBoost.avoidclip = mods.colorBoost.avoidclip;
if (colorBoost.enable_saturationlimiter)toEdit.colorBoost.enable_saturationlimiter = mods.colorBoost.enable_saturationlimiter;
if (colorBoost.saturationlimit) toEdit.colorBoost.saturationlimit = mods.colorBoost.saturationlimit;

View File

@@ -91,6 +91,18 @@ class SharpeningParamsEdited {
bool deconvdamping;
};
class VibranceParamsEdited {
public:
bool enabled;
bool pastels;
bool saturated;
bool psthreshold;
bool protectskins;
bool avoidcolorshift;
bool pastsattog;
};
class ColorBoostParamsEdited {
public:
@@ -342,6 +354,7 @@ class ParamsEdited {
SharpeningParamsEdited sharpening;
SharpenEdgeParamsEdited sharpenEdge;
SharpenMicroParamsEdited sharpenMicro;
VibranceParamsEdited vibrance;
ColorBoostParamsEdited colorBoost;
WBParamsEdited wb;
ColorShiftParamsEdited colorShift;

View File

@@ -58,7 +58,8 @@ PartialPasteDlg::PartialPasteDlg () {
defringe = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DEFRINGE")));
// options in color:
chmixer = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CHANNELMIXER")));
vibrance = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_VIBRANCE")));
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")));
@@ -133,6 +134,7 @@ PartialPasteDlg::PartialPasteDlg () {
vboxes[2]->pack_start (*color, Gtk::PACK_SHRINK, 2);
vboxes[2]->pack_start (*hseps[2], 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 (*hsveq, Gtk::PACK_SHRINK, 2);
@@ -242,7 +244,8 @@ PartialPasteDlg::PartialPasteDlg () {
//waveqConn = waveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
defringeConn = defringe->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
chmixerConn = chmixer->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));
hsveqConn = hsveq->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));
@@ -453,14 +456,17 @@ void PartialPasteDlg::detailToggled () {
void PartialPasteDlg::colorToggled () {
vibranceConn.block (true);
chmixerConn.block (true);
hsveqConn.block (true);
color->set_inconsistent (false);
vibrance->set_active (color->get_active ());
chmixer->set_active (color->get_active ());
hsveq->set_active (color->get_active ());
vibranceConn.block (false);
chmixerConn.block (false);
hsveqConn.block (false);
}
@@ -542,7 +548,8 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dst, const r
if (defringe->get_active ()) dst->defringe = src->defringe;
if (dirpyrden->get_active ()) dst->dirpyrDenoise = src->dirpyrDenoise;
if (chmixer->get_active ()) dst->chmixer = src->chmixer;
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 (distortion->get_active ()) dst->distortion = src->distortion;
if (cacorr->get_active ()) dst->cacorrection = src->cacorrection;

View File

@@ -55,6 +55,7 @@ class PartialPasteDlg : public Gtk::Dialog {
Gtk::CheckButton* dirpyreq;
// options in color:
Gtk::CheckButton* vibrance;
Gtk::CheckButton* chmixer;
Gtk::CheckButton* hsveq;
@@ -103,7 +104,7 @@ class PartialPasteDlg : public Gtk::Dialog {
sigc::connection wbConn, exposureConn, hlrecConn, shConn, labcurveConn;
sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, waveqConn, defringeConn, dirpyreqConn;
sigc::connection chmixerConn, hsveqConn;
sigc::connection vibranceConn, chmixerConn, hsveqConn;
sigc::connection distortionConn, cacorrConn, vignettingConn;
sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn;
sigc::connection exifchConn, iptcConn, icmConn;

View File

@@ -189,6 +189,12 @@ Gtk::Widget* Preferences::getBatchProcPanel () {
appendBehavList (mi, M("TP_WBALANCE_TEMPERATURE"), ADDSET_WB_TEMPERATURE, true);
appendBehavList (mi, M("TP_WBALANCE_GREEN"), ADDSET_WB_GREEN, true);
mi = behModel->append ();
mi->set_value (behavColumns.label, M("TP_VIBRANCE_LABEL"));
appendBehavList (mi, M("TP_VIBRANCE_PASTELS"), ADDSET_VIBRANCE_PASTELS, false);
appendBehavList (mi, M("TP_VIBRANCE_SATURATED"), ADDSET_VIBRANCE_SATURATED, false);
appendBehavList (mi, M("TP_VIBRANCE_PSTHRESHOLD"), ADDSET_VIBRANCE_PSTHRESHOLD, false);
mi = behModel->append ();
mi->set_value (behavColumns.label, M("TP_CHMIXER_LABEL"));
appendBehavList (mi, M("TP_CHMIXER_RED")+", "+M("TP_CHMIXER_GREEN")+", "+M("TP_CHMIXER_BLUE"), ADDSET_CHMIXER, false);

View File

@@ -52,6 +52,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
lensgeom = Gtk::manage (new LensGeometry ());
distortion = Gtk::manage (new Distortion ());
rotate = Gtk::manage (new Rotate ());
vibrance = Gtk::manage (new Vibrance ());
whitebalance = Gtk::manage (new WhiteBalance ());
vignetting = Gtk::manage (new Vignetting ());
perspective = Gtk::manage (new PerspCorrection ());
@@ -75,6 +76,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
addPanel (colorPanel, whitebalance, M("TP_WBALANCE_LABEL")); toolPanels.push_back (whitebalance);
addPanel (exposurePanel, toneCurve, M("TP_EXPOSURE_LABEL")); toolPanels.push_back (toneCurve);
addPanel (exposurePanel, hlrecovery, M("TP_HLREC_LABEL")); toolPanels.push_back (hlrecovery);
addPanel (colorPanel, vibrance, M("TP_VIBRANCE_LABEL")); toolPanels.push_back (vibrance);
addPanel (colorPanel, chmixer, M("TP_CHMIXER_LABEL")); toolPanels.push_back (chmixer);
addPanel (exposurePanel, shadowshighlights, M("TP_SHADOWSHLIGHTS_LABEL")); toolPanels.push_back (shadowshighlights);
addPanel (detailsPanel, sharpening, M("TP_SHARPENING_LABEL")); toolPanels.push_back (sharpening);

View File

@@ -29,6 +29,7 @@
#include <whitebalance.h>
#include <coarsepanel.h>
#include <tonecurve.h>
#include <vibrance.h>
#include <shadowshighlights.h>
#include <impulsedenoise.h>
#include <defringe.h>
@@ -84,6 +85,7 @@ class ToolPanelCoordinator : public ToolPanelListener,
PerspCorrection* perspective;
CACorrection* cacorrection;
HLRecovery* hlrecovery;
Vibrance* vibrance;
ChMixer* chmixer;
Resize* resize;
ICMPanel* icm;

294
rtgui/vibrance.cc Normal file
View File

@@ -0,0 +1,294 @@
/*
* 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 <vibrance.h>
using namespace rtengine;
using namespace rtengine::procparams;
Vibrance::Vibrance () : Gtk::VBox(), FoldableToolPanel(this) {
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
enabled->set_active (false);
pack_start(*enabled, Gtk::PACK_SHRINK, 0);
pastels = Gtk::manage(new Adjuster (M("TP_VIBRANCE_PASTELS"),-100,100,5,0));
pastels->setAdjusterListener (this);
//if (pastels->delay < 1000) pastels->delay = 1000;
pack_start( *pastels, Gtk::PACK_SHRINK, 0);
saturated = Gtk::manage(new Adjuster (M("TP_VIBRANCE_SATURATED"),-100,100,5,0));
saturated->setAdjusterListener (this);
saturated->set_sensitive(false);
//if (saturated->delay < 1000) saturated->delay = 1000;
pack_start( *saturated, Gtk::PACK_SHRINK, 0);
psThreshold = Gtk::manage(new Adjuster (M("TP_VIBRANCE_PSTHRESHOLD"),0,100,5,75));
psThreshold->setAdjusterListener (this);
psThreshold->set_sensitive(false);
//if (psThreshold->delay < 1000) psThreshold->delay = 1000;
pack_start( *psThreshold, Gtk::PACK_SHRINK, 0);
protectSkins = Gtk::manage (new Gtk::CheckButton (M("TP_VIBRANCE_PROTECTSKINS")));
protectSkins->set_active (true);
pack_start(*protectSkins, Gtk::PACK_SHRINK, 0);
avoidColorShift = Gtk::manage (new Gtk::CheckButton (M("TP_VIBRANCE_AVOIDCOLORSHIFT")));
avoidColorShift->set_active (true);
pack_start(*avoidColorShift, Gtk::PACK_SHRINK, 0);
pastSatTog = Gtk::manage (new Gtk::CheckButton (M("TP_VIBRANCE_PASTSATTOG")));
pastSatTog->set_active (true);
pack_start(*pastSatTog, Gtk::PACK_SHRINK, 0);
show ();
enaconn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::enabled_toggled) );
pskinsconn = protectSkins->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::protectskins_toggled) );
ashiftconn = avoidColorShift->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::avoidcolorshift_toggled) );
pastsattogconn = pastSatTog->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::pastsattog_toggled) );
}
void Vibrance::read(const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
if(pedited ){
enabled->set_inconsistent (!pedited->vibrance.enabled);
pastels->setEditedState (pedited->vibrance.pastels ? Edited : UnEdited);
saturated->setEditedState (pedited->vibrance.saturated ? Edited : UnEdited);
psThreshold->setEditedState (pedited->vibrance.psthreshold ? Edited : UnEdited);
protectSkins->set_inconsistent (!pedited->vibrance.protectskins);
avoidColorShift->set_inconsistent (!pedited->vibrance.avoidcolorshift);
pastSatTog->set_inconsistent (!pedited->vibrance.pastsattog);
}
enaconn.block (true);
enabled->set_active (pp->vibrance.enabled);
enaconn.block (false);
lastEnabled = pp->vibrance.enabled;
pskinsconn.block (true);
protectSkins->set_active (pp->vibrance.protectskins);
pskinsconn.block (false);
lastProtectSkins = pp->vibrance.protectskins;
ashiftconn.block (true);
avoidColorShift->set_active (pp->vibrance.avoidcolorshift);
ashiftconn.block (false);
lastAvoidColorShift = pp->vibrance.avoidcolorshift;
pastsattogconn.block (true);
pastSatTog->set_active (pp->vibrance.pastsattog);
pastsattogconn.block (false);
lastPastSatTog = pp->vibrance.pastsattog;
pastels->setValue (pp->vibrance.pastels);
psThreshold->setValue (pp->vibrance.psthreshold);
if (lastPastSatTog) {
// Link both slider, so we set saturated and psThresholds unsensitive
psThreshold->set_sensitive(false);
saturated->set_sensitive(false);
saturated->setValue (pp->vibrance.pastels); // Pastels and Saturated are linked
}
else {
// Separate sliders, so we set saturated and psThresholds sensitive again
psThreshold->set_sensitive(true);
saturated->set_sensitive(true);
saturated->setValue (pp->vibrance.saturated); // Pastels and Saturated are separate
}
enableListener ();
}
void Vibrance::write( ProcParams* pp, ParamsEdited* pedited) {
pp->vibrance.enabled = enabled->get_active ();
pp->vibrance.pastels = pastels->getIntValue();
pp->vibrance.saturated = pastSatTog->get_active() ? pp->vibrance.pastels : saturated->getIntValue ();
pp->vibrance.psthreshold = psThreshold->getIntValue ();
pp->vibrance.protectskins = protectSkins->get_active ();
pp->vibrance.avoidcolorshift = avoidColorShift->get_active ();
pp->vibrance.pastsattog = pastSatTog->get_active ();
if (pedited) {
pedited->vibrance.enabled = !enabled->get_inconsistent();
pedited->vibrance.pastels = pastels->getEditedState ();
pedited->vibrance.saturated = saturated->getEditedState ();
pedited->vibrance.psthreshold = psThreshold->getEditedState ();
pedited->vibrance.protectskins = !protectSkins->get_inconsistent();
pedited->vibrance.avoidcolorshift = !avoidColorShift->get_inconsistent();
pedited->vibrance.pastsattog = !pastSatTog->get_inconsistent();
}
}
void Vibrance::enabled_toggled () {
if (batchMode) {
if (enabled->get_inconsistent()) {
enabled->set_inconsistent (false);
enaconn.block (true);
enabled->set_active (false);
enaconn.block (false);
}
else if (lastEnabled)
enabled->set_inconsistent (true);
lastEnabled = enabled->get_active ();
}
if (listener) {
if (enabled->get_active ())
listener->panelChanged (EvVibranceEnabled, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvVibranceEnabled, M("GENERAL_DISABLED"));
}
}
void Vibrance::protectskins_toggled () {
if (batchMode) {
if (protectSkins->get_inconsistent()) {
protectSkins->set_inconsistent (false);
pskinsconn.block (true);
protectSkins->set_active (false);
pskinsconn.block (false);
}
else if (lastProtectSkins)
protectSkins->set_inconsistent (true);
lastProtectSkins = protectSkins->get_active ();
}
if (listener && enabled->get_active()) {
if (protectSkins->get_active ())
listener->panelChanged (EvVibranceProtectSkins, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvVibranceProtectSkins, M("GENERAL_DISABLED"));
}
}
void Vibrance::avoidcolorshift_toggled () {
if (batchMode) {
if (avoidColorShift->get_inconsistent()) {
avoidColorShift->set_inconsistent (false);
ashiftconn.block (true);
avoidColorShift->set_active (false);
ashiftconn.block (false);
}
else if (lastAvoidColorShift)
avoidColorShift->set_inconsistent (true);
lastAvoidColorShift = avoidColorShift->get_active ();
}
if (listener && enabled->get_active()) {
if (avoidColorShift->get_active ())
listener->panelChanged (EvVibranceAvoidColorShift, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvVibranceAvoidColorShift, M("GENERAL_DISABLED"));
}
}
void Vibrance::pastsattog_toggled () {
if (batchMode) {
if (pastSatTog->get_inconsistent()) {
pastSatTog->set_inconsistent (false);
pastsattogconn.block (true);
pastSatTog->set_active (false);
pastsattogconn.block (false);
}
else if (lastPastSatTog)
pastSatTog->set_inconsistent (true);
lastPastSatTog = pastSatTog->get_active ();
}
if (pastSatTog->get_active()) {
// Link both slider, so we set saturated and psThresholds unsensitive
psThreshold->set_sensitive(false);
saturated->set_sensitive(false);
saturated->setValue (pastels->getValue()); // Pastels and Saturated are linked
}
else {
// Separate sliders, so we set saturated and psThresholds sensitive again
psThreshold->set_sensitive(true);
saturated->set_sensitive(true);
}
if (listener && enabled->get_active()) {
if (pastSatTog->get_active ()) {
listener->panelChanged (EvVibrancePastSatTog, M("GENERAL_ENABLED"));
}
else
listener->panelChanged (EvVibrancePastSatTog, M("GENERAL_DISABLED"));
}
}
void Vibrance::adjusterChanged (Adjuster* a, double newval) {
if (a == pastels && pastSatTog->get_active())
saturated->setValue (newval);
if (listener && enabled->get_active()) {
Glib::ustring value = a->getTextValue();
if (a == pastels )
listener->panelChanged (EvVibrancePastels, value );
else if (a == saturated && !pastSatTog->get_active())
listener->panelChanged (EvVibranceSaturated, value );
else if (a == psThreshold){
listener->panelChanged (EvVibrancePastSatThreshold, value );
}
}
}
void Vibrance::setBatchMode(bool batchMode) {
ToolPanel::setBatchMode (batchMode);
pastels->showEditedCB ();
saturated->showEditedCB ();
psThreshold->showEditedCB ();
}
void Vibrance::setDefaults(const ProcParams* defParams, const ParamsEdited* pedited) {
pastels->setDefault (defParams->vibrance.pastels);
saturated->setDefault (defParams->vibrance.saturated);
psThreshold->setDefault (defParams->vibrance.psthreshold);
if (pedited) {
pastels->setDefaultEditedState (pedited->vibrance.pastels ? Edited : UnEdited);
saturated->setDefaultEditedState (pedited->vibrance.saturated ? Edited : UnEdited);
psThreshold->setDefaultEditedState (pedited->vibrance.psthreshold ? Edited : UnEdited);
} else {
pastels->setDefaultEditedState (Irrelevant);
saturated->setDefaultEditedState (Irrelevant);
psThreshold->setDefaultEditedState (Irrelevant);
}
}
void Vibrance::setAdjusterBehavior (bool pastelsadd, bool saturatedadd, bool psthreshdadd) {
pastels->setAddMode (pastelsadd);
saturated->setAddMode (saturatedadd);
psThreshold->setAddMode (psthreshdadd);
}
void Vibrance::trimValues (ProcParams* pp) {
pastels->trimValue (pp->vibrance.pastels);
saturated->trimValue (pp->vibrance.saturated);
psThreshold->trimValue (pp->vibrance.psthreshold);
}

66
rtgui/vibrance.h Normal file
View File

@@ -0,0 +1,66 @@
/*
* 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 _VIBRANCE_
#define _VIBRANCE_
#include <gtkmm.h>
#include <adjuster.h>
//#include <guiutils.h>
#include <toolpanel.h>
class Vibrance : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel {
protected:
Gtk::CheckButton* enabled;
Adjuster* pastels;
Adjuster* saturated;
Adjuster* psThreshold;
Gtk::CheckButton* protectSkins;
Gtk::CheckButton* avoidColorShift;
Gtk::CheckButton* pastSatTog;
bool lastEnabled;
bool lastProtectSkins;
bool lastAvoidColorShift;
bool lastPastSatTog;
sigc::connection enaconn;
sigc::connection pskinsconn;
sigc::connection ashiftconn;
sigc::connection pastsattogconn;
public:
Vibrance ();
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 trimValues (rtengine::procparams::ProcParams* pp);
void setAdjusterBehavior (bool amountadd, bool passadd, bool psthreshdadd);
void adjusterChanged (Adjuster* a, double newval);
void enabled_toggled ();
void protectskins_toggled ();
void avoidcolorshift_toggled ();
void pastsattog_toggled ();
};
#endif