Black & White tool: GUI cleanup (issue 2010) + bugfix (issue 1779)
This commit is contained in:
@@ -971,7 +971,7 @@ TP_BWMIX_LABEL;Noir & Blanc
|
||||
TP_BWMIX_CC_ENABLED;Ajuster les couleurs complémentaires
|
||||
TP_BWMIX_CHANNEL;Égaliseur de Luminance
|
||||
TP_BWMIX_VAL;L
|
||||
TP_BWMIX_CC_TOOLTIP;Activer pour permettre l'ajustage automatique des couleur complémentaire dans le mode ROJVCBMP
|
||||
TP_BWMIX_CC_TOOLTIP;Activer pour permettre l'ajustage automatique des couleur complémentaire dans le mode ROJVCBPM
|
||||
TP_BWMIX_SETTING_TOOLTIP;Différents préréglages (films, paysage, ...) ou réglages manuel du mixeur de canaux
|
||||
TP_BWMIX_FILTER_TOOLTIP;Le filtre de couleur simule les prises de vue avec un filtre coloré placé devant l'objectif. Les filtres colorés réduisent la transmission d'une plage de couleur spécifique et en affectent donc leur luminosité. Ex: un filtre rouge assombri les ciels bleus.
|
||||
TP_BWMIX_AUTOCH;Auto
|
||||
@@ -992,6 +992,8 @@ TP_BWMIX_GAM_GREEN;Canal Vert
|
||||
TP_BWMIX_GAM_BLUE;Canal Bleu
|
||||
TP_BWMIX_MIXC;Mixeur
|
||||
TP_BWMIX_MIXF;Mixeur de Filtres
|
||||
TP_BWMIX_RGBLABEL;R: %1%% V: %2%% B: %3%% Total: %4%%
|
||||
TP_BWMIX_RGBLABEL_HINT;Coefficients RVB finaux qui tiennent compte de toutes les options du mixeur\nTotal affiche la somme des valeurs RVB actuellement appliqué:\n- toujours 100% en mode relatif\n- supérieur (plus clair) ou inférieur (plus sombre) à 100% en mode absolu.
|
||||
TP_BWMIX_FILTER;Filtre de couleur
|
||||
TP_BWMIX_FILTER_NONE;Aucun
|
||||
TP_BWMIX_FILTER_RED;Rouge
|
||||
@@ -1015,8 +1017,8 @@ TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatique
|
||||
TP_BWMIX_SET_ORTHOCHRO;Orthochromatique
|
||||
TP_BWMIX_SET_RGBABS;Mixeur de Canaux - RVB Absolu
|
||||
TP_BWMIX_SET_RGBREL;Mixeur de Canaux - RVB Relatif
|
||||
TP_BWMIX_SET_ROYGCBMPABS;Mixeur de Canaux - ROJVCBMP Absolu
|
||||
TP_BWMIX_SET_ROYGCBMPREL;Mixeur de Canaux - ROJVCBMP Relatif
|
||||
TP_BWMIX_SET_ROYGCBPMABS;Mixeur de Canaux - ROJVCBPM Absolu
|
||||
TP_BWMIX_SET_ROYGCBPMREL;Mixeur de Canaux - ROJVCBPM Relatif
|
||||
TP_BWMIX_SET_INFRARED;Infrarouge
|
||||
TP_BWMIX_GAMMA;Correction Gamma
|
||||
TP_BWMIX_GAM_TOOLTIP;Corrige le gamma pour chaque canaux RVB
|
||||
|
||||
@@ -975,7 +975,7 @@ TP_BWMIX_LABEL;Black & White
|
||||
TP_BWMIX_CC_ENABLED;Adjust complementary color
|
||||
TP_BWMIX_CHANNEL;Luminance Equalizer
|
||||
TP_BWMIX_VAL;L
|
||||
TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBMP mode
|
||||
TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode
|
||||
TP_BWMIX_SETTING_TOOLTIP;Different presets (films, landscape, ...) or manual settings of channel-mixer
|
||||
TP_BWMIX_FILTER_TOOLTIP;The color filter simulate shots taken with a colored filter placed in front of the lens. Colored filters reduce transmission of specific range of colors and correspondingly affect their lightness. E.g. a Red filter darkens Blue skies.
|
||||
TP_BWMIX_AUTOCH;Auto
|
||||
@@ -996,6 +996,8 @@ TP_BWMIX_GAM_GREEN;Green Channel
|
||||
TP_BWMIX_GAM_BLUE;Blue Channel
|
||||
TP_BWMIX_MIXC;Mixer
|
||||
TP_BWMIX_MIXF;Mixer Filters
|
||||
TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%%
|
||||
TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all of the mixer options\nTotal displays the sum of RGB values actually applied:\n*always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode.
|
||||
TP_BWMIX_FILTER;Color Filter
|
||||
TP_BWMIX_FILTER_NONE;None
|
||||
TP_BWMIX_FILTER_RED;Red
|
||||
@@ -1019,8 +1021,8 @@ TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic
|
||||
TP_BWMIX_SET_ORTHOCHRO;Orthochromatic
|
||||
TP_BWMIX_SET_RGBABS;Channel-Mixer absolute RGB
|
||||
TP_BWMIX_SET_RGBREL;Channel-Mixer relative RGB
|
||||
TP_BWMIX_SET_ROYGCBMPABS;Channel-Mixer absolute ROYGCBMP
|
||||
TP_BWMIX_SET_ROYGCBMPREL;Channel-Mixer relative ROYGCBMP
|
||||
TP_BWMIX_SET_ROYGCBPMABS;Channel-Mixer absolute ROYGCBPM
|
||||
TP_BWMIX_SET_ROYGCBPMREL;Channel-Mixer relative ROYGCBPM
|
||||
TP_BWMIX_SET_INFRARED;Infrared
|
||||
TP_BWMIX_GAMMA;Gamma Correction
|
||||
TP_BWMIX_GAM_TOOLTIP;Correct gamma for each channel RGB
|
||||
|
||||
@@ -88,7 +88,17 @@ private:
|
||||
__m128i sizeiv __attribute__ ((aligned (16)));
|
||||
#endif
|
||||
public:
|
||||
/// convenience flag! If one doesn't want to delete the buffer but want to flag it to be recomputed...
|
||||
/// The user have to handle it itself, even if some method can (re)initialize it
|
||||
bool dirty;
|
||||
|
||||
LUT(int s, int flags = 0xfffffff) {
|
||||
#ifndef NDEBUG
|
||||
if (s<=0)
|
||||
printf("s<=0!\n");
|
||||
assert (s>0);
|
||||
#endif
|
||||
dirty = true;
|
||||
clip = flags;
|
||||
data = new T[s];
|
||||
owner = 1;
|
||||
@@ -102,8 +112,14 @@ public:
|
||||
#endif
|
||||
}
|
||||
void operator ()(int s, int flags = 0xfffffff) {
|
||||
#ifndef NDEBUG
|
||||
if (s<=0)
|
||||
printf("s<=0!\n");
|
||||
assert (s>0);
|
||||
#endif
|
||||
if (owner&&data)
|
||||
delete[] data;
|
||||
dirty = true; // Assumption!
|
||||
clip = flags;
|
||||
data = new T[s];
|
||||
owner = 1;
|
||||
@@ -118,6 +134,15 @@ public:
|
||||
}
|
||||
|
||||
LUT(int s, T * source, int flags = 0xfffffff) {
|
||||
#ifndef NDEBUG
|
||||
if (s<=0)
|
||||
printf("s<=0!\n");
|
||||
assert (s>0);
|
||||
if (source==NULL)
|
||||
printf("source is NULL!\n");
|
||||
assert (source != NULL);
|
||||
#endif
|
||||
dirty = false; // Assumption
|
||||
clip = flags;
|
||||
data = new T[s];
|
||||
owner = 1;
|
||||
@@ -134,14 +159,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
LUT(void) {
|
||||
LUT() {
|
||||
data = NULL;
|
||||
reset();
|
||||
}
|
||||
|
||||
~LUT() {
|
||||
if (owner)
|
||||
if (owner) {
|
||||
delete[] data;
|
||||
#ifndef NDEBUG
|
||||
data=(T*)0xBAADF00D;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void setClip(int flags) {
|
||||
@@ -321,11 +350,11 @@ public:
|
||||
if (size) {
|
||||
Glib::ustring fname_ = fname + ".xyz"; // TopSolid'Design "plot" file format
|
||||
std::ofstream f (fname_.c_str());
|
||||
f << "$" << std::endl;;
|
||||
f << "$" << std::endl;
|
||||
for (unsigned int iter=0; iter<size; iter++) {
|
||||
f << iter << ", " << data[iter] << ", 0." << std::endl;;
|
||||
f << iter << ", " << data[iter] << ", 0." << std::endl;
|
||||
}
|
||||
f << "$" << std::endl;;
|
||||
f << "$" << std::endl;
|
||||
f.close ();
|
||||
}
|
||||
}
|
||||
@@ -338,11 +367,13 @@ public:
|
||||
}
|
||||
|
||||
void clear(void) {
|
||||
memset(data, 0, size * sizeof(T));
|
||||
if (data && size)
|
||||
memset(data, 0, size * sizeof(T));
|
||||
}
|
||||
|
||||
void reset(void) {
|
||||
delete[] data;
|
||||
if (data) delete[] data;
|
||||
dirty = true;
|
||||
data = NULL;
|
||||
owner = 1;
|
||||
size = 0;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace rtengine {
|
||||
extern const Settings* settings;
|
||||
|
||||
LUTf Color::cachef;
|
||||
LUTf Color::gamma2curve = 0;
|
||||
LUTf Color::gamma2curve;
|
||||
|
||||
LUTf Color::gammatab;
|
||||
LUTf Color::igammatab_srgb;
|
||||
@@ -414,19 +414,157 @@ namespace rtengine {
|
||||
b = ((rgb_xyz[2][0]*x + rgb_xyz[2][1]*y + rgb_xyz[2][2]*z)) ;
|
||||
}
|
||||
|
||||
void Color::trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb) {
|
||||
// correct gamma for black and white image : pseudo TRC curve of ICC profil
|
||||
b/=65535.0f;
|
||||
b= pow (max(b,0.0f), gammabwb);
|
||||
b *=65535.0f;
|
||||
r/=65535.0f;
|
||||
r= pow (max(r,0.0f), gammabwr);
|
||||
r *=65535.0f;
|
||||
g/=65535.0f;
|
||||
g= pow (max(g,0.0f), gammabwg);
|
||||
g *=65535.0f;
|
||||
}
|
||||
|
||||
void Color::trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb) {
|
||||
// correct gamma for black and white image : pseudo TRC curve of ICC profil
|
||||
b/=65535.0f;
|
||||
b= pow (max(b,0.0f), gammabwb);
|
||||
b *=65535.0f;
|
||||
r/=65535.0f;
|
||||
r= pow (max(r,0.0f), gammabwr);
|
||||
r *=65535.0f;
|
||||
g/=65535.0f;
|
||||
g= pow (max(g,0.0f), gammabwg);
|
||||
g *=65535.0f;
|
||||
}
|
||||
|
||||
/** @brief Compute the B&W constants for the B&W processing and its tool's GUI
|
||||
*
|
||||
* @param setting BlackWhite::setting
|
||||
* @param setting BlackWhite::filter
|
||||
*/
|
||||
void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::ustring &filter, float &mixerRed, float &mixerGreen,
|
||||
float &mixerBlue, float mixerOrange, float mixerYellow, float mixerCyan, float mixerPurple, float mixerMagenta,
|
||||
bool autoc, bool complement, float &kcorec, double &rrm, double &ggm, double &bbm)
|
||||
{
|
||||
float somm;
|
||||
float som = mixerRed+mixerGreen+mixerBlue;
|
||||
// rM = mixerRed, gM = mixerGreen, bM = mixerBlue !
|
||||
|
||||
//presets
|
||||
if (setting=="RGB-Abs" || setting=="ROYGCBPM-Abs")
|
||||
kcorec=som/100.f;
|
||||
|
||||
if (!autoc) {
|
||||
//if (setting=="RGB-Abs" || setting=="ROYGCBPM-Abs") {} //Keep the RGB mixer values as is!
|
||||
//else if(setting=="RGB-Rel" || setting=="ROYGCBPM-Rel") {} //Keep the RGB mixer values as is!
|
||||
if (setting=="NormalContrast") { mixerRed=43.f ; mixerGreen=33.f; mixerBlue=30.f; }
|
||||
else if(setting=="Panchromatic") { mixerRed=33.3f; mixerGreen=33.3f; mixerBlue=33.3f; }
|
||||
else if(setting=="HyperPanchromatic") { mixerRed=41.f ; mixerGreen=25.f; mixerBlue=34.f; }
|
||||
else if(setting=="LowSensitivity") { mixerRed=27.f ; mixerGreen=27.f; mixerBlue=46.f; }
|
||||
else if(setting=="HighSensitivity") { mixerRed=30.f ; mixerGreen=28.f; mixerBlue=42.f; }
|
||||
else if(setting=="Orthochromatic") { mixerRed=0.f ; mixerGreen=42.f; mixerBlue=58.f; }
|
||||
else if(setting=="HighContrast") { mixerRed=40.f ; mixerGreen=34.f; mixerBlue=60.f; }
|
||||
else if(setting=="Luminance") { mixerRed=30.f ; mixerGreen=59.f; mixerBlue=11.f; }
|
||||
else if(setting=="Landscape") { mixerRed=66.f ; mixerGreen=24.f; mixerBlue=10.f; }
|
||||
else if(setting=="Portrait") { mixerRed=54.f ; mixerGreen=44.f; mixerBlue=12.f; }
|
||||
else if(setting=="InfraRed") { mixerRed=-40.f; mixerGreen=200.f; mixerBlue=-17.f; }
|
||||
}
|
||||
|
||||
rrm=mixerRed;
|
||||
ggm=mixerGreen;
|
||||
bbm=mixerBlue;
|
||||
|
||||
somm=mixerRed+mixerGreen+mixerBlue;
|
||||
mixerRed=mixerRed/somm; mixerGreen=mixerGreen/somm; mixerBlue=mixerBlue/somm;
|
||||
float koymcp=0.f;
|
||||
|
||||
if(setting=="ROYGCBPM-Abs" || setting=="ROYGCBPM-Rel") {
|
||||
float obM=0.f;
|
||||
float ogM=0.f;
|
||||
float orM=0.f;
|
||||
|
||||
float ybM=0.f;
|
||||
float yrM=0.f;
|
||||
float ygM=0.f;
|
||||
|
||||
float mgM=0.f;
|
||||
float mrM=0.f;
|
||||
float mbM=0.f;
|
||||
|
||||
float pgM=0.f;
|
||||
float prM=0.f;
|
||||
float pbM=0.f;
|
||||
|
||||
float crM=0.f;
|
||||
float cgM=0.f;
|
||||
float cbM=0.f;
|
||||
|
||||
|
||||
float fcompl = 1.f;
|
||||
if(complement) fcompl = 3.f;
|
||||
// ponderate filters: report to R=G=B=33
|
||||
// I ponder RGB channel, not only orange or yellow or cyan, etc...it's my choice !
|
||||
if(mixerOrange != 33) {
|
||||
if (mixerOrange >= 33) orM = fcompl*(mixerOrange*0.67f - 22.11f)/100.f; else orM = fcompl*(-0.3f*mixerOrange +9.9f)/100.f;
|
||||
if (mixerOrange >= 33) ogM = fcompl*(-0.164f*mixerOrange+5.412f)/100.f; else ogM = fcompl*(0.4f*mixerOrange-13.2f)/100.f;
|
||||
if(complement) obM =(-0.492f*mixerOrange+16.236f)/100.f;
|
||||
mixerRed += orM;
|
||||
mixerGreen += ogM;
|
||||
mixerBlue += obM;
|
||||
koymcp += (orM+ogM+obM);
|
||||
}
|
||||
if(mixerYellow != 33) {
|
||||
yrM = fcompl*(-0.134f*mixerYellow+4.422f)/100.f;//22.4
|
||||
ygM = fcompl*( 0.5f *mixerYellow-16.5f )/100.f;
|
||||
if(complement) ybM =(-0.492f*mixerYellow+16.236f)/100.f;
|
||||
mixerRed += yrM;
|
||||
mixerGreen += ygM;
|
||||
mixerBlue += ybM;
|
||||
koymcp += (yrM+ygM+ybM);
|
||||
}
|
||||
if(mixerMagenta != 33) {
|
||||
if(mixerMagenta >= 33) mrM = fcompl*( 0.67f *mixerMagenta-22.11f)/100.f; else mrM = fcompl*(-0.3f*mixerMagenta +9.9f)/100.f;
|
||||
if(mixerMagenta >= 33) mbM = fcompl*(-0.164f*mixerMagenta+5.412f)/100.f; else mbM = fcompl*( 0.4f*mixerMagenta-13.2f)/100.f;
|
||||
if(complement) mgM =(-0.492f*mixerMagenta+16.236f)/100.f;
|
||||
mixerRed += mrM;
|
||||
mixerGreen += mgM;
|
||||
mixerBlue += mbM;
|
||||
koymcp += (mrM+mgM+mbM);
|
||||
}
|
||||
if(mixerPurple != 33) {
|
||||
prM = fcompl*(-0.134f*mixerPurple+4.422f)/100.f;
|
||||
pbM = fcompl*(0.5f*mixerPurple-16.5f)/100.f;
|
||||
if(complement) pgM = (-0.492f*mixerPurple+16.236f)/100.f;
|
||||
mixerRed += prM;
|
||||
mixerGreen += pgM;
|
||||
mixerBlue += pbM;
|
||||
koymcp += (prM+pgM+pbM);
|
||||
}
|
||||
if(mixerCyan != 33) {
|
||||
cgM = fcompl*(-0.134f*mixerCyan +4.422f)/100.f;
|
||||
cbM = fcompl*(0.5f*mixerCyan-16.5f)/100.f;
|
||||
if(complement) crM = (-0.492f*mixerCyan+16.236f)/100.f;
|
||||
mixerRed += crM;
|
||||
mixerGreen += cgM;
|
||||
mixerBlue += cbM;
|
||||
koymcp += (crM+cgM+cbM);
|
||||
}
|
||||
}
|
||||
if(setting=="ROYGCBPM-Abs")
|
||||
kcorec = koymcp+som/100.f;
|
||||
//Color filters
|
||||
float filred,filgreen,filblue;
|
||||
filred=1.f;filgreen=1.f;filblue=1.f;
|
||||
if (filter=="None") {filred=1.f; filgreen=1.f; filblue=1.f;}
|
||||
else if (filter=="Red") {filred=1.f; filgreen=0.05f;filblue=0.f;}
|
||||
else if (filter=="Orange") {filred=1.f; filgreen=0.6f; filblue=0.f;}
|
||||
else if (filter=="Yellow") {filred=1.f; filgreen=1.f; filblue=0.05f;}
|
||||
else if (filter=="YellowGreen") {filred=0.6f; filgreen=1.f; filblue=0.3f;}
|
||||
else if (filter=="Green") {filred=0.2f; filgreen=1.f; filblue=0.3f;}
|
||||
else if (filter=="Cyan") {filred=0.05f;filgreen=1.f; filblue=1.f;}
|
||||
else if (filter=="Blue") {filred=0.f; filgreen=0.05f;filblue=1.f;}
|
||||
else if (filter=="Purple") {filred=1.f; filgreen=0.05f;filblue=1.f;}
|
||||
|
||||
|
||||
mixerRed = mixerRed * filred;
|
||||
mixerGreen = mixerGreen * filgreen;
|
||||
mixerBlue = mixerBlue * filblue;
|
||||
|
||||
mixerRed = mixerRed / (mixerRed + mixerGreen + mixerBlue);
|
||||
mixerGreen = mixerGreen / (mixerRed + mixerGreen + mixerBlue);
|
||||
mixerBlue = mixerBlue / (mixerRed + mixerGreen + mixerBlue);
|
||||
}
|
||||
|
||||
void Color::calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4, double &gamma5) {
|
||||
//from Dcraw (D.Coffin)
|
||||
int i;
|
||||
|
||||
@@ -128,45 +128,48 @@ public:
|
||||
static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, double rgb_xyz[3][3]);
|
||||
static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, float rgb_xyz[3][3]);
|
||||
static void rgbxyz (float r, float g, float b, float &x, float &y, float &z, double xyz_rgb[3][3]);
|
||||
|
||||
|
||||
static void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z);
|
||||
static void XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b);
|
||||
static void Lab2Yuv(float L, float a, float b, float &Y, float &u, float &v);
|
||||
static void Yuv2Lab(float Y, float u, float v, float &L, float &a, float &b, double wp[3][3]);
|
||||
static double f2xyz(double f);
|
||||
static double f2xyz(double f);
|
||||
static void calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4,double &gamma5);
|
||||
static void trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb);
|
||||
static void computeBWMixerConstants (const Glib::ustring &setting, const Glib::ustring &filter, float &mixerRed, float &mixerGreen,
|
||||
float &mixerBlue, float mixerOrange, float mixerYellow, float mixerCyan, float mixerPurple, float mixerMagenta,
|
||||
bool autoc, bool complement, float &kcorec, double &rrm, double &ggm, double &bbm);
|
||||
|
||||
static void huelab_to_huehsv (float HH, double &hr);
|
||||
|
||||
// standard srgb gamma and its inverse
|
||||
static inline double gamma2 (double x) {
|
||||
static inline double gamma2 (double x) {
|
||||
return x <= 0.003041 ? x*12.92 : 1.055011*exp(log(x)/sRGBGammaCurve)-0.055011;
|
||||
}
|
||||
static inline double igamma2 (double x) {
|
||||
return x <= 0.039293 ? x/12.92 : exp(log((x+0.055011)/1.055011)*sRGBGammaCurve);
|
||||
}
|
||||
static inline double igamma2 (double x) {
|
||||
return x <= 0.039293 ? x/12.92 : exp(log((x+0.055011)/1.055011)*sRGBGammaCurve);
|
||||
}
|
||||
/* static inline double gamma709 (double x) {
|
||||
return x <= 0.0176 ? x*4.5 : 1.0954*exp(log(x)/2.2)-0.0954;
|
||||
}
|
||||
static inline double igamma709 (double x) {
|
||||
return x <= 0.0795 ? x/4.5 : exp(log((x+0.0954)/1.0954)*2.2);
|
||||
return x <= 0.0795 ? x/4.5 : exp(log((x+0.0954)/1.0954)*2.2);
|
||||
}
|
||||
*/
|
||||
static inline double gamma24_17 (double x) {
|
||||
return x <= 0.001867 ? x*17.0 : 1.044445*exp(log(x)/2.4)-0.044445;
|
||||
}
|
||||
static inline double igamma24_17 (double x) {
|
||||
return x <= 0.031746 ? x/17.0 : exp(log((x+0.044445)/1.044445)*2.4);
|
||||
return x <= 0.031746 ? x/17.0 : exp(log((x+0.044445)/1.044445)*2.4);
|
||||
}
|
||||
|
||||
|
||||
static inline double gamma26_11 (double x) {
|
||||
return x <= 0.004921 ? x*11.0 : 1.086603*exp(log(x)/2.6)-0.086603;
|
||||
}
|
||||
static inline double igamma26_11 (double x) {
|
||||
return x <= 0.054127 ? x/11.0 : exp(log((x+0.086603)/1.086603)*2.6);
|
||||
return x <= 0.054127 ? x/11.0 : exp(log((x+0.086603)/1.086603)*2.6);
|
||||
}
|
||||
|
||||
|
||||
// gamma function with adjustable parameters
|
||||
static inline double gamma (double x, double gamma, double start, double slope, double mul, double add){
|
||||
return (x <= start ? x*slope : exp(log(x)/gamma)*mul-add);
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace rtengine {
|
||||
|
||||
void CurveFactory::updatechroma (
|
||||
const std::vector<double>& cccurvePoints,
|
||||
LUTu & histogramC, LUTu & histogramCroppedC, LUTu & outBeforeCCurveHistogramC,//for chroma
|
||||
LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,//for chroma
|
||||
int skip)
|
||||
{
|
||||
LUTf dCcurve(65536,0);
|
||||
@@ -184,7 +184,7 @@ void CurveFactory::curveLightBrightColor (
|
||||
procparams::ColorAppearanceParams::eTCModeId curveMode2, const std::vector<double>& curvePoints2,
|
||||
procparams::ColorAppearanceParams::eCTCModeId curveMode3, const std::vector<double>& curvePoints3,
|
||||
LUTu & histogram, LUTu & histogramCropped, LUTu & outBeforeCCurveHistogram,//for Luminance
|
||||
LUTu & histogramC, LUTu & histogramCroppedC, LUTu & outBeforeCCurveHistogramC,//for chroma
|
||||
LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,//for chroma
|
||||
ColorAppearance & customColCurve1,
|
||||
ColorAppearance & customColCurve2,
|
||||
ColorAppearance & customColCurve3,
|
||||
@@ -289,12 +289,9 @@ void CurveFactory::curveLightBrightColor (
|
||||
}
|
||||
|
||||
void CurveFactory::curveBW (
|
||||
procparams::BlackWhiteParams::eTCModeId curveModeb, const std::vector<double>& curvePointsbw,
|
||||
procparams::BlackWhiteParams::eTCModeId curveModeb2, const std::vector<double>& curvePointsbw2,
|
||||
LUTu & histogrambw, LUTu & histogramCropped, LUTu & outBeforeCCurveHistogrambw,//for Luminance
|
||||
ChMixerbw & customToneCurvebw1,
|
||||
ChMixerbw & customToneCurvebw2,
|
||||
int skip)
|
||||
const std::vector<double>& curvePointsbw, const std::vector<double>& curvePointsbw2,
|
||||
LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw,//for Luminance
|
||||
ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip)
|
||||
{
|
||||
LUTf dcurve(65536,0);
|
||||
|
||||
@@ -317,11 +314,7 @@ void CurveFactory::curveBW (
|
||||
|
||||
}
|
||||
if (tcurve) {
|
||||
if (tcurve->isIdentity()) {
|
||||
delete tcurve;
|
||||
tcurve = NULL;
|
||||
}
|
||||
else
|
||||
if (!tcurve->isIdentity())
|
||||
customToneCurvebw2.Set(tcurve);
|
||||
delete tcurve;
|
||||
tcurve = NULL;
|
||||
@@ -336,11 +329,7 @@ void CurveFactory::curveBW (
|
||||
|
||||
}
|
||||
if (tcurve) {
|
||||
if (tcurve->isIdentity()) {
|
||||
delete tcurve;
|
||||
tcurve = NULL;
|
||||
}
|
||||
else
|
||||
if (!tcurve->isIdentity())
|
||||
customToneCurvebw1.Set(tcurve);
|
||||
delete tcurve;
|
||||
tcurve = NULL;
|
||||
@@ -404,7 +393,7 @@ void CurveFactory::curveCL ( bool & clcutili,const std::vector<double>& clcurveP
|
||||
void CurveFactory::complexsgnCurve ( bool & autili, bool & butili, bool & ccutili, bool & cclutili, double saturation, double rstprotection,
|
||||
const std::vector<double>& acurvePoints, const std::vector<double>& bcurvePoints,const std::vector<double>& cccurvePoints,
|
||||
const std::vector<double>& lccurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, LUTf & lhskCurve,
|
||||
LUTu & histogramC, LUTu & histogramLC, LUTu & histogramCroppedC, LUTu & outBeforeCCurveHistogram,LUTu & outBeforeLCurveHistogram, //for chroma
|
||||
LUTu & histogramC, LUTu & histogramLC, LUTu & outBeforeCCurveHistogram,LUTu & outBeforeLCurveHistogram, //for chroma
|
||||
int skip) {
|
||||
|
||||
|
||||
@@ -414,7 +403,6 @@ void CurveFactory::curveCL ( bool & clcutili,const std::vector<double>& clcurveP
|
||||
DiagonalCurve* dCurve = NULL;
|
||||
LUTf dCcurve(65536,0);
|
||||
|
||||
float val;
|
||||
for (int i=0; i<48000; i++) { //# 32768*1.414 approximation maxi for chroma
|
||||
dCcurve[i] = (float)i / 47999.0;
|
||||
}
|
||||
@@ -1058,14 +1046,5 @@ void ToneCurve::Set(Curve *pCurve) {
|
||||
lutToneCurve(65536);
|
||||
for (int i=0; i<65536; i++) lutToneCurve[i] = pCurve->getVal(double(i)/65535.) * 65535.;
|
||||
}
|
||||
void ChMixerbw::Reset() {
|
||||
lutBWCurve.reset();
|
||||
}
|
||||
|
||||
// Fill a LUT with X/Y, ranged 0xffff
|
||||
void ChMixerbw::Set(Curve *pCurve) {
|
||||
lutBWCurve(65536);
|
||||
for (int i=0; i<65536; i++) lutBWCurve[i] = pCurve->getVal(double(i)/65535.) * 65535.;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ using namespace std;
|
||||
namespace rtengine {
|
||||
class ToneCurve;
|
||||
class ColorAppearance;
|
||||
class ChMixerbw;
|
||||
|
||||
class CurveFactory {
|
||||
|
||||
@@ -187,26 +186,21 @@ class CurveFactory {
|
||||
LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & outToneCurve, ToneCurve & outToneCurve2,
|
||||
|
||||
int skip=1);
|
||||
static void curveBW (
|
||||
procparams::BlackWhiteParams::eTCModeId curveModeb, const std::vector<double>& curvePointsbw,
|
||||
procparams::BlackWhiteParams::eTCModeId curveModeb2, const std::vector<double>& curvePointsbw2,
|
||||
LUTu & histogrambw, LUTu & histogramCropped, LUTu & outBeforeCCurveHistogrambw,
|
||||
ChMixerbw & customToneCurvebw1,
|
||||
ChMixerbw & customToneCurvebw2,
|
||||
int skip);
|
||||
static void curveBW (const std::vector<double>& curvePointsbw, const std::vector<double>& curvePointsbw2, LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw,
|
||||
ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip);
|
||||
|
||||
static void curveCL ( bool & clcutili, const std::vector<double>& clcurvePoints, LUTf & clCurve, LUTu & histogramcl, LUTu & outBeforeCLurveHistogram, int skip);
|
||||
|
||||
static void complexsgnCurve ( bool & autili, bool & butili, bool & ccutili, bool & clcutili, double saturation, double rstprotection, const std::vector<double>& acurvePoints,
|
||||
const std::vector<double>& bcurvePoints,const std::vector<double>& cccurvePoints,const std::vector<double>& lccurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, LUTf & lhskCurve,
|
||||
LUTu & histogramC, LUTu & histogramLC, LUTu & histogramCroppedC, LUTu & outBeforeCCurveHistogram,LUTu & outBeforeLCurveHistogram,///for chroma
|
||||
LUTu & histogramC, LUTu & histogramLC, LUTu & outBeforeCCurveHistogram,LUTu & outBeforeLCurveHistogram,///for chroma
|
||||
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, bool & utili);
|
||||
|
||||
static void updatechroma (
|
||||
const std::vector<double>& cccurvePoints,
|
||||
LUTu & histogramC, LUTu & histogramCroppedC, LUTu & outBeforeCCurveHistogramC,//for chroma
|
||||
LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,//for chroma
|
||||
int skip=1);
|
||||
|
||||
static void curveLightBrightColor (
|
||||
@@ -214,7 +208,7 @@ class CurveFactory {
|
||||
procparams::ColorAppearanceParams::eTCModeId curveMode2, const std::vector<double>& curvePoints2,
|
||||
procparams::ColorAppearanceParams::eCTCModeId curveMode3, const std::vector<double>& curvePoints3,
|
||||
LUTu & histogram, LUTu & histogramCropped, LUTu & outBeforeCCurveHistogram,
|
||||
LUTu & histogramC, LUTu & histogramCroppedC, LUTu & outBeforeCCurveHistogramC,
|
||||
LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,
|
||||
ColorAppearance & outColCurve1,
|
||||
ColorAppearance & outColCurve2,
|
||||
ColorAppearance & outColCurve3,
|
||||
@@ -326,17 +320,6 @@ class ToneCurve {
|
||||
operator bool (void) const { return lutToneCurve; }
|
||||
};
|
||||
|
||||
class ChMixerbw {
|
||||
public:
|
||||
LUTf lutBWCurve; // 0xffff range
|
||||
|
||||
virtual ~ChMixerbw() {};
|
||||
|
||||
void Reset();
|
||||
void Set(Curve *pCurve);
|
||||
operator bool (void) const { return lutBWCurve; }
|
||||
};
|
||||
|
||||
class ColorAppearance {
|
||||
public:
|
||||
LUTf lutColCurve; // 0xffff range
|
||||
@@ -417,7 +400,7 @@ class StandardToneCurve : public ToneCurve {
|
||||
public:
|
||||
void Apply(float& r, float& g, float& b) const;
|
||||
};
|
||||
class StandardToneCurvebw : public ChMixerbw {
|
||||
class StandardToneCurvebw : public ToneCurve {
|
||||
public:
|
||||
void Apply(float& r, float& g, float& b) const;
|
||||
};
|
||||
@@ -430,7 +413,7 @@ class AdobeToneCurve : public ToneCurve {
|
||||
void Apply(float& r, float& g, float& b) const;
|
||||
};
|
||||
|
||||
class AdobeToneCurvebw : public ChMixerbw {
|
||||
class AdobeToneCurvebw : public ToneCurve {
|
||||
private:
|
||||
void RGBTone(float& r, float& g, float& b) const; // helper for tone curve
|
||||
|
||||
@@ -443,7 +426,7 @@ class SatAndValueBlendingToneCurve : public ToneCurve {
|
||||
void Apply(float& r, float& g, float& b) const;
|
||||
};
|
||||
|
||||
class SatAndValueBlendingToneCurvebw : public ChMixerbw {
|
||||
class SatAndValueBlendingToneCurvebw : public ToneCurve {
|
||||
public:
|
||||
void Apply(float& r, float& g, float& b) const;
|
||||
};
|
||||
@@ -455,7 +438,7 @@ class WeightedStdToneCurve : public ToneCurve {
|
||||
void Apply(float& r, float& g, float& b) const;
|
||||
};
|
||||
|
||||
class WeightedStdToneCurvebw : public ChMixerbw {
|
||||
class WeightedStdToneCurvebw : public ToneCurve {
|
||||
private:
|
||||
float Triangle(float refX, float refY, float X2) const;
|
||||
public:
|
||||
@@ -474,11 +457,11 @@ inline void StandardToneCurve::Apply (float& r, float& g, float& b) const {
|
||||
// Standard tone curve
|
||||
inline void StandardToneCurvebw::Apply (float& r, float& g, float& b) const {
|
||||
|
||||
assert (lutBWCurve);
|
||||
assert (lutToneCurve);
|
||||
|
||||
r = lutBWCurve[r];
|
||||
g = lutBWCurve[g];
|
||||
b = lutBWCurve[b];
|
||||
r = lutToneCurve[r];
|
||||
g = lutToneCurve[g];
|
||||
b = lutToneCurve[b];
|
||||
}
|
||||
|
||||
// Tone curve according to Adobe's reference implementation
|
||||
@@ -506,15 +489,15 @@ inline void AdobeToneCurve::Apply (float& r, float& g, float& b) const {
|
||||
}
|
||||
inline void AdobeToneCurvebw::Apply (float& r, float& g, float& b) const {
|
||||
|
||||
assert (lutBWCurve);
|
||||
assert (lutToneCurve);
|
||||
|
||||
if (r >= g) {
|
||||
if (g > b) RGBTone (r, g, b); // Case 1: r >= g > b
|
||||
else if (b > r) RGBTone (b, r, g); // Case 2: b > r >= g
|
||||
else if (b > g) RGBTone (r, b, g); // Case 3: r >= b > g
|
||||
else { // Case 4: r >= g == b
|
||||
r = lutBWCurve[r];
|
||||
g = lutBWCurve[g];
|
||||
r = lutToneCurve[r];
|
||||
g = lutToneCurve[g];
|
||||
b = g;
|
||||
}
|
||||
}
|
||||
@@ -535,8 +518,8 @@ inline void AdobeToneCurve::RGBTone (float& r, float& g, float& b) const {
|
||||
inline void AdobeToneCurvebw::RGBTone (float& r, float& g, float& b) const {
|
||||
float rold=r,gold=g,bold=b;
|
||||
|
||||
r = lutBWCurve[rold];
|
||||
b = lutBWCurve[bold];
|
||||
r = lutToneCurve[rold];
|
||||
b = lutToneCurve[bold];
|
||||
g = b + ((r - b) * (gold - bold) / (rold - bold));
|
||||
}
|
||||
|
||||
@@ -586,17 +569,17 @@ inline void WeightedStdToneCurve::Apply (float& r, float& g, float& b) const {
|
||||
|
||||
inline void WeightedStdToneCurvebw::Apply (float& r, float& g, float& b) const {
|
||||
|
||||
assert (lutBWCurve);
|
||||
assert (lutToneCurve);
|
||||
|
||||
float r1 = lutBWCurve[r];
|
||||
float r1 = lutToneCurve[r];
|
||||
float g1 = Triangle(r, r1, g);
|
||||
float b1 = Triangle(r, r1, b);
|
||||
|
||||
float g2 = lutBWCurve[g];
|
||||
float g2 = lutToneCurve[g];
|
||||
float r2 = Triangle(g, g2, r);
|
||||
float b2 = Triangle(g, g2, b);
|
||||
|
||||
float b3 = lutBWCurve[b];
|
||||
float b3 = lutToneCurve[b];
|
||||
float r3 = Triangle(b, b3, r);
|
||||
float g3 = Triangle(b, b3, g);
|
||||
|
||||
@@ -638,12 +621,12 @@ inline void SatAndValueBlendingToneCurve::Apply (float& r, float& g, float& b) c
|
||||
|
||||
inline void SatAndValueBlendingToneCurvebw::Apply (float& r, float& g, float& b) const {
|
||||
|
||||
assert (lutBWCurve);
|
||||
assert (lutToneCurve);
|
||||
|
||||
float h, s, v;
|
||||
float lum = (r+g+b)/3.f;
|
||||
//float lum = Color::rgbLuminance(r, g, b);
|
||||
float newLum = lutBWCurve[lum];
|
||||
float newLum = lutToneCurve[lum];
|
||||
if (newLum == lum)
|
||||
return;
|
||||
bool increase = newLum > lum;
|
||||
|
||||
@@ -164,11 +164,13 @@ void Crop::update (int todo) {
|
||||
baseCrop->b[(int)(xref/skip)][(int)(yref/skip)]/256,
|
||||
parent->imgsrc->getGamma());
|
||||
}*/
|
||||
double rrm, ggm, bbm;
|
||||
double rrm, ggm, bbm;
|
||||
|
||||
if (todo & M_RGBCURVE)
|
||||
parent->ipf.rgbProc (baseCrop, laboCrop, parent->hltonecurve, parent->shtonecurve, parent->tonecurve, cshmap,
|
||||
params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve, parent->customToneCurve1, parent->customToneCurve2, parent->customToneCurvebw1, parent->customToneCurvebw2,rrm, ggm, bbm);
|
||||
params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve, parent->customToneCurve1,
|
||||
parent->customToneCurve2, parent->beforeToneCurveBW, parent->afterToneCurveBW,rrm, ggm, bbm,
|
||||
parent->bwAutoR, parent->bwAutoG, parent->bwAutoB);
|
||||
|
||||
/*xref=000;yref=000;
|
||||
if (colortest && cropw>115 && croph>115)
|
||||
@@ -245,11 +247,13 @@ void Crop::update (int todo) {
|
||||
|
||||
if(settings->ciecamfloat) {
|
||||
float d; // not used after this block
|
||||
parent->ipf.ciecam_02float (cieCrop, float(adap), begh, endh, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp, d);
|
||||
parent->ipf.ciecam_02float (cieCrop, float(adap), begh, endh, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3,
|
||||
dummy, dummy, parent->CAMBrightCurveJ, parent->CAMBrightCurveQ, parent->CAMMean, 5, 1,(float**)cbuffer, execsharp, d);
|
||||
}
|
||||
else {
|
||||
double dd; // not used after this block
|
||||
parent->ipf.ciecam_02 (cieCrop,adap, begh, endh, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp, dd);
|
||||
parent->ipf.ciecam_02 (cieCrop,adap, begh, endh, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3,
|
||||
dummy, dummy, parent->CAMBrightCurveJ, parent->CAMBrightCurveQ, parent->CAMMean, 5, 1,(float**)cbuffer, execsharp, dd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -465,10 +469,12 @@ bool Crop::tryUpdate() {
|
||||
|
||||
/* @brief Handles Crop updating in its own thread
|
||||
*
|
||||
* This method will cycle updates ss long as Crop::newUpdatePending will be true. During the processing,
|
||||
* This method will cycle updates as long as Crop::newUpdatePending will be true. During the processing,
|
||||
* intermediary update will be automatically flushed by Crop::tryUpdate.
|
||||
*
|
||||
* This method is called when the visible part of the crop has changed (resize, zoom, etc..), so it needs a full update
|
||||
*/
|
||||
void Crop::fullUpdate () {
|
||||
void Crop::fullUpdate () {
|
||||
|
||||
parent->updaterThreadStart.lock ();
|
||||
if (parent->updaterRunning && parent->thread) {
|
||||
|
||||
@@ -32,6 +32,7 @@ ImProcCoordinator::ImProcCoordinator ()
|
||||
: orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL),
|
||||
ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), scale(10),
|
||||
highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false),
|
||||
bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.f),
|
||||
|
||||
hltonecurve(65536,0),
|
||||
shtonecurve(65536,2),//clip above
|
||||
@@ -47,26 +48,29 @@ ImProcCoordinator::ImProcCoordinator ()
|
||||
vhist16(65536),vhist16bw(65536),
|
||||
lhist16(65536), lhist16Cropped(65536),
|
||||
lhist16CAM(65536), lhist16CroppedCAM(65536),
|
||||
lhist16CCAM(65536), lhist16CroppedCCAM(65536),
|
||||
lhist16CCAM(65536),
|
||||
lhist16CCAMAF(65536), lhist16ClabAF(65536),
|
||||
histCropped(65536),
|
||||
lhist16Clad(65536),lhist16CroppedClad(65536),lhist16CLlad(65536),
|
||||
lhist16LClad(65536), lhist16LLClad(65536),
|
||||
lhist16Clad(65536),lhist16CLlad(65536),
|
||||
lhist16LClad(65536), lhist16LLClad(65536),
|
||||
histRed(256), histRedRaw(256),
|
||||
histGreen(256), histGreenRaw(256),
|
||||
histBlue(256), histBlueRaw(256),
|
||||
histLuma(256), histChroma(256),
|
||||
histLuma(256),
|
||||
histToneCurve(256),
|
||||
histToneCurveBW(256),
|
||||
histLCurve(256),
|
||||
histCCurve(256),
|
||||
histCLurve(256),
|
||||
histLLCurve(256),
|
||||
|
||||
|
||||
histLCAM(256),
|
||||
histCCAM(256),
|
||||
histClad(256),
|
||||
bcabhist(256),
|
||||
histChroma(256),
|
||||
|
||||
CAMBrightCurveJ(), CAMBrightCurveQ(),
|
||||
|
||||
rCurve(),
|
||||
gCurve(),
|
||||
@@ -117,6 +121,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
int numofphases = 14;
|
||||
int readyphase = 0;
|
||||
|
||||
bwAutoR = bwAutoG = bwAutoB = -9000.f;
|
||||
|
||||
if (todo==CROP && ipf.needsPCVignetting())
|
||||
todo |= TRANSFORM; // Change about Crop does affect TRANSFORM
|
||||
|
||||
@@ -298,20 +304,22 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, scale==1 ? 1 : 1);
|
||||
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale==1 ? 1 : 1);
|
||||
|
||||
CurveFactory::curveBW (params.blackwhite.beforeCurveMode, params.blackwhite.beforeCurve, params.blackwhite.afterCurveMode, params.blackwhite.afterCurve,
|
||||
vhist16bw, histCropped, histToneCurveBW, customToneCurvebw1, customToneCurvebw2,scale==1 ? 1 : 1);
|
||||
CurveFactory::curveBW (params.blackwhite.beforeCurve,params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW,scale==1 ? 1 : 1);
|
||||
|
||||
//initialize rrm bbm ggm different from zero to avoid black screen in somme cases
|
||||
//initialize rrm bbm ggm different from zero to avoid black screen in some cases
|
||||
double rrm=33.;
|
||||
double ggm=33.;
|
||||
double bbm=33.;
|
||||
|
||||
|
||||
// if it's just crop we just need the histogram, no image updates
|
||||
if ( todo!=MINUPDATE ) {
|
||||
ipf.rgbProc (oprevi, oprevl, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation,
|
||||
rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2,customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm,params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh);
|
||||
if(params.blackwhite.enabled && abwListener) abwListener->BWChanged((float) rrm, (float) ggm, (float) bbm);
|
||||
rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2,beforeToneCurveBW, afterToneCurveBW, rrm, ggm, bbm, bwAutoR, bwAutoG, bwAutoB, params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh);
|
||||
if(params.blackwhite.enabled && params.blackwhite.autoc && abwListener) {
|
||||
if (settings->verbose)
|
||||
printf("ImProcCoordinator / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", bwAutoR, bwAutoG, bwAutoB);
|
||||
abwListener->BWChanged((float) rrm, (float) ggm, (float) bbm);
|
||||
}
|
||||
// correct GUI black and white with value
|
||||
}
|
||||
|
||||
@@ -319,13 +327,13 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
int x1, y1, x2, y2, pos, poscc;
|
||||
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
|
||||
lhist16.clear(); lhist16Cropped.clear();
|
||||
lhist16Clad.clear(); lhist16CroppedClad.clear();lhist16CLlad.clear();lhist16LLClad.clear();
|
||||
lhist16Clad.clear(); lhist16CLlad.clear();lhist16LLClad.clear();
|
||||
lhist16ClabAF.clear();
|
||||
for (int x=0; x<pH; x++)
|
||||
for (int y=0; y<pW; y++) {
|
||||
pos=CLIP((int)(oprevl->L[x][y]));
|
||||
lhist16[pos]++;
|
||||
if (y>=y1 && y<y2 && x>=x1 && x<x2) {lhist16Cropped[pos]++;lhist16CroppedClad[poscc]++;}
|
||||
if (y>=y1 && y<y2 && x>=x1 && x<x2) {lhist16Cropped[pos]++;}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -346,7 +354,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
|
||||
CurveFactory::complexsgnCurve (autili, butili,ccutili,cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection,
|
||||
params.labCurve.acurve, params.labCurve.bcurve,params.labCurve.cccurve,params.labCurve.lccurve,chroma_acurve, chroma_bcurve, satcurve,lhskcurve,
|
||||
lhist16Clad,lhist16LLClad,lhist16CroppedClad, histCCurve, histLLCurve, scale==1 ? 1 : 16);
|
||||
lhist16Clad, lhist16LLClad, histCCurve, histLLCurve, scale==1 ? 1 : 16);
|
||||
}
|
||||
if (todo & (M_LUMINANCE+M_COLOR) ) {
|
||||
nprevl->CopyFrom(oprevl);
|
||||
@@ -408,7 +416,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
int x1, y1, x2, y2, pos, posc;
|
||||
params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2);
|
||||
lhist16CAM.clear(); lhist16CroppedCAM.clear();
|
||||
lhist16CCAM.clear(); lhist16CroppedCCAM.clear();
|
||||
lhist16CCAM.clear();
|
||||
lhist16CCAMAF.clear();
|
||||
for (int x=0; x<pH; x++)
|
||||
for (int y=0; y<pW; y++) {
|
||||
@@ -416,7 +424,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
posc=CLIP((int)sqrt(nprevl->a[x][y]*nprevl->a[x][y] + nprevl->b[x][y]*nprevl->b[x][y]));
|
||||
if(!params.colorappearance.datacie) lhist16CCAM[posc]++;
|
||||
if(!params.colorappearance.datacie)lhist16CAM[pos]++;
|
||||
if (y>=y1 && y<y2 && x>=x1 && x<x2) {lhist16CroppedCAM[pos]++;lhist16CroppedCCAM[posc]++;}
|
||||
if (y>=y1 && y<y2 && x>=x1 && x<x2) {lhist16CroppedCAM[pos]++;}
|
||||
}
|
||||
LUTu dummy;
|
||||
CurveFactory::curveLightBrightColor (
|
||||
@@ -424,7 +432,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
params.colorappearance.curveMode2, params.colorappearance.curve2,
|
||||
params.colorappearance.curveMode3, params.colorappearance.curve3,
|
||||
lhist16CAM, lhist16CroppedCAM,histLCAM,
|
||||
lhist16CCAM, lhist16CroppedCCAM,histCCAM,
|
||||
lhist16CCAM, histCCAM,
|
||||
customColCurve1,
|
||||
customColCurve2,
|
||||
customColCurve3,
|
||||
@@ -459,13 +467,17 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
if(!ncie)
|
||||
ncie = new CieImage (pW, pH);
|
||||
|
||||
if (!CAMBrightCurveJ && (params.colorappearance.algo=="JC" || params.colorappearance.algo=="JS" || params.colorappearance.algo=="ALL"))
|
||||
CAMBrightCurveJ(65536,0);
|
||||
if (!CAMBrightCurveQ && (params.colorappearance.algo=="QM" || params.colorappearance.algo=="ALL"))
|
||||
CAMBrightCurveQ(65536,0);
|
||||
if(settings->ciecamfloat){
|
||||
ipf.ciecam_02float (ncie, float(adap), begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, execsharp, d);
|
||||
ipf.ciecam_02float (ncie, float(adap), begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, execsharp, d);
|
||||
if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) acListener->autoCamChanged(100.*(double)d);
|
||||
if(params.colorappearance.autoadapscen && acListener && params.colorappearance.enabled) acListener->adapCamChanged(adap);//real value of adapt scene luminosity
|
||||
}
|
||||
else {
|
||||
ipf.ciecam_02 (ncie, adap, begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, execsharp, dd);
|
||||
ipf.ciecam_02 (ncie, adap, begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, execsharp, dd);
|
||||
if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) acListener->autoCamChanged(100.*dd);
|
||||
if(params.colorappearance.autoadapscen && acListener && params.colorappearance.enabled) acListener->adapCamChanged(adap);
|
||||
}
|
||||
@@ -476,9 +488,12 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
readyphase++;
|
||||
}
|
||||
else {
|
||||
// CIECAM is disbaled, we free up its image buffer to save some space
|
||||
// CIECAM is disabled, we free up its image buffer to save some space
|
||||
if (ncie)
|
||||
delete ncie; ncie=NULL;
|
||||
|
||||
if (CAMBrightCurveJ) CAMBrightCurveJ.reset();
|
||||
if (CAMBrightCurveQ) CAMBrightCurveQ.reset();
|
||||
}
|
||||
}
|
||||
// process crop, if needed
|
||||
@@ -486,6 +501,11 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
if (crops[i]->hasListener () && cropCall != crops[i] )
|
||||
crops[i]->update (todo); // may call ourselves
|
||||
|
||||
// Flagging some LUT as dirty now, whether they have been freed up or not
|
||||
CAMBrightCurveJ.dirty = true;
|
||||
CAMBrightCurveQ.dirty = true;
|
||||
|
||||
|
||||
progress ("Conversion to RGB...",100*readyphase/numofphases);
|
||||
if (todo!=CROP && todo!=MINUPDATE) {
|
||||
MyMutex::MyLock prevImgLock(previmg->getMutex());
|
||||
|
||||
@@ -77,6 +77,11 @@ class ImProcCoordinator : public StagedImageProcessor {
|
||||
|
||||
void freeAll ();
|
||||
|
||||
// Precomputed values used by DetailedCrop ----------------------------------------------
|
||||
|
||||
float bwAutoR, bwAutoG, bwAutoB;
|
||||
float CAMMean;
|
||||
|
||||
LUTf hltonecurve;
|
||||
LUTf shtonecurve;
|
||||
LUTf tonecurve;
|
||||
@@ -91,15 +96,18 @@ class ImProcCoordinator : public StagedImageProcessor {
|
||||
LUTu vhist16,vhist16bw;
|
||||
LUTu lhist16,lhist16Cropped;
|
||||
LUTu lhist16CAM,lhist16CroppedCAM;
|
||||
LUTu lhist16CCAM,lhist16CroppedCCAM;
|
||||
LUTu lhist16CCAM;
|
||||
LUTu lhist16CCAMAF;
|
||||
LUTu lhist16ClabAF;
|
||||
LUTu histCropped;
|
||||
LUTu lhist16Clad,lhist16CroppedClad,lhist16CLlad,lhist16LClad,lhist16LLClad;
|
||||
LUTu lhist16Clad,lhist16CLlad,lhist16LClad,lhist16LLClad;
|
||||
LUTu histRed, histRedRaw;
|
||||
LUTu histGreen, histGreenRaw;
|
||||
LUTu histBlue, histBlueRaw;
|
||||
LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve, histCLurve, histLLCurve, histLCAM, histCCAM, histClad, bcabhist, histChroma;
|
||||
LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve, histCLurve;
|
||||
LUTu histLLCurve, histLCAM, histCCAM, histClad, bcabhist, histChroma;
|
||||
|
||||
LUTf CAMBrightCurveJ, CAMBrightCurveQ;
|
||||
|
||||
LUTf rCurve;
|
||||
LUTf gCurve;
|
||||
@@ -116,13 +124,15 @@ class ImProcCoordinator : public StagedImageProcessor {
|
||||
ColorAppearance customColCurve1;
|
||||
ColorAppearance customColCurve2;
|
||||
ColorAppearance customColCurve3;
|
||||
ChMixerbw customToneCurvebw1;
|
||||
ChMixerbw customToneCurvebw2;
|
||||
ToneCurve beforeToneCurveBW;
|
||||
ToneCurve afterToneCurveBW;
|
||||
|
||||
LUTu rcurvehist, rcurvehistCropped, rbeforehist;
|
||||
LUTu gcurvehist, gcurvehistCropped, gbeforehist;
|
||||
LUTu bcurvehist, bcurvehistCropped, bbeforehist;
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
int fw, fh, tr, fullw, fullh;
|
||||
int pW, pH;
|
||||
|
||||
@@ -131,7 +141,7 @@ class ImProcCoordinator : public StagedImageProcessor {
|
||||
AutoExpListener* aeListener;
|
||||
AutoCamListener* acListener;
|
||||
AutoBWListener* abwListener;
|
||||
|
||||
|
||||
HistogramListener* hListener;
|
||||
std::vector<SizeListener*> sizeListeners;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -195,20 +195,26 @@ class ImProcFunctions {
|
||||
|
||||
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, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ChMixerbw & customToneCurvebw1,const ChMixerbw & customToneCurvebw2, double &rrm, double &ggm, double &bbm);
|
||||
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2,
|
||||
const ToneCurve & customToneCurvebw1,const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob);
|
||||
void rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
|
||||
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ChMixerbw & customToneCurvebw1,const ChMixerbw & customToneCurvebw2, double &rrm, double &ggm, double &bbm,
|
||||
double expcomp, int hlcompr, int hlcomprthresh);
|
||||
void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve);
|
||||
void ciecam_02float (CieImage* ncie, float adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, LUTu &histLCAM, LUTu &histCCAM,int Iterates, int scale, float** buffer, bool execsharp, float &d);
|
||||
void ciecam_02 (CieImage* ncie, double adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, LUTu &histLCAM, LUTu &histCCAM,int Iterates, int scale, float** buffer, bool execsharp, double &d);
|
||||
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2,
|
||||
const ToneCurve & customToneCurvebw1,const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob,
|
||||
double expcomp, int hlcompr, int hlcomprthresh);
|
||||
void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve);
|
||||
void ciecam_02float (CieImage* ncie, float adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params,
|
||||
const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3,
|
||||
LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, float** buffer, bool execsharp, float &d);
|
||||
void ciecam_02 (CieImage* ncie, double adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params,
|
||||
const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3,
|
||||
LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, float** buffer, bool execsharp, double &d);
|
||||
void chromiLuminanceCurve (int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve,LUTf & satclcurve, LUTf &clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histCLurve, LUTu &histLCurve, LUTu &histLurve);
|
||||
void vibrance (LabImage* lab);//Jacques' vibrance
|
||||
void vibrance (LabImage* lab);//Jacques' vibrance
|
||||
void colorCurve (LabImage* lold, LabImage* lnew);
|
||||
void sharpening (LabImage* lab, float** buffer);
|
||||
void sharpeningcam (CieImage* ncie, float** buffer);
|
||||
void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH,
|
||||
double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage);
|
||||
double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage);
|
||||
void lab2monitorRgb (LabImage* lab, Image8* image);
|
||||
void resize (Image16* src, Image16* dst, float dScale);
|
||||
void deconvsharpening (LabImage* lab, float** buffer);
|
||||
|
||||
@@ -748,8 +748,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
|
||||
ColorAppearance customColCurve1;
|
||||
ColorAppearance customColCurve2;
|
||||
ColorAppearance customColCurve3;
|
||||
ChMixerbw customToneCurvebw1;
|
||||
ChMixerbw customToneCurvebw2;
|
||||
ToneCurve customToneCurvebw1;
|
||||
ToneCurve customToneCurvebw2;
|
||||
|
||||
ipf.g = gamma;
|
||||
ipf.iGamma = true;
|
||||
@@ -766,11 +766,12 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
|
||||
LabImage* labView = new LabImage (fw,fh);
|
||||
CieImage* cieView = new CieImage (fw,fh);
|
||||
|
||||
CurveFactory::curveBW (params.blackwhite.beforeCurveMode, params.blackwhite.beforeCurve, params.blackwhite.afterCurveMode, params.blackwhite.afterCurve,
|
||||
hist16, dummy, dummy, customToneCurvebw1, customToneCurvebw2, 16);
|
||||
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 16);
|
||||
|
||||
double rrm, ggm, bbm;
|
||||
ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2,rrm, ggm, bbm,expcomp, hlcompr, hlcomprthresh);
|
||||
float autor, autog, autob;
|
||||
autor = autog = autob = -9000.f; // This will ask to compute the "auto" values for the B&W tool
|
||||
ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2,rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh);
|
||||
|
||||
if (shmap)
|
||||
delete shmap;
|
||||
@@ -799,7 +800,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
|
||||
|
||||
CurveFactory::complexsgnCurve (autili, butili, ccutili, cclutili,params.labCurve.chromaticity, params.labCurve.rstprotection,
|
||||
params.labCurve.acurve, params.labCurve.bcurve,params.labCurve.cccurve,params.labCurve.lccurve, curve1, curve2, satcurve,lhskcurve,
|
||||
hist16C, hist16C, hist16C, dummy, dummy,
|
||||
hist16C, hist16C, dummy, dummy,
|
||||
16);
|
||||
//ipf.luminanceCurve (labView, labView, curve);
|
||||
ipf.chromiLuminanceCurve (1,labView, labView, curve1, curve2, satcurve,lhskcurve, clcurve, curve, utili, autili, butili, ccutili,cclutili, clcutili, dummy, dummy, dummy, dummy);
|
||||
@@ -816,46 +817,48 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
|
||||
params.colorappearance.curveMode2, params.colorappearance.curve2,
|
||||
params.colorappearance.curveMode3, params.colorappearance.curve3,
|
||||
hist16, hist16, dummy,
|
||||
hist16C, hist16C, dummy,
|
||||
hist16C, dummy,
|
||||
customColCurve1,
|
||||
customColCurve2,
|
||||
customColCurve3,
|
||||
16);
|
||||
|
||||
int f_h=2,f_w=2;
|
||||
if(params.colorappearance.enabled){
|
||||
float** buffer = new float*[fh];
|
||||
for (int i=0; i<fh; i++)
|
||||
buffer[i] = new float[fw];
|
||||
bool execsharp=false;
|
||||
float d;
|
||||
float fnum = fnumber;// F number
|
||||
float fiso = iso;// ISO
|
||||
float fspeed = shutter;//speed
|
||||
char * writ = new char[expcomp_.size() + 1];//convert expcomp_ to char
|
||||
std::copy(expcomp_.begin(), expcomp_.end(), writ);
|
||||
writ[expcomp_.size()] = '\0';
|
||||
float fcomp = atof(writ); //compensation + -
|
||||
delete[] writ;
|
||||
float adap2,adap;
|
||||
double ada, ada2;
|
||||
if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) {adap=adap=2000.f;ada=2000.;}//if no exif data or wrong
|
||||
else {
|
||||
float E_V = fcomp + log2 ((fnum*fnum) / fspeed / (fiso/100.f));
|
||||
float expo2= params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
||||
E_V += expo2;
|
||||
float expo1;//exposure raw white point
|
||||
expo1=log2(params.raw.expos);//log2 ==>linear to EV
|
||||
E_V += expo1;
|
||||
adap2 = adap= powf(2.f, E_V-3.f);//cd / m2
|
||||
ada=ada2=(double) adap;
|
||||
//end calculation adaptation scene luminosity
|
||||
}
|
||||
float** buffer = new float*[fh];
|
||||
for (int i=0; i<fh; i++)
|
||||
buffer[i] = new float[fw];
|
||||
bool execsharp=false;
|
||||
float d;
|
||||
float fnum = fnumber;// F number
|
||||
float fiso = iso;// ISO
|
||||
float fspeed = shutter;//speed
|
||||
char * writ = new char[expcomp_.size() + 1];//convert expcomp_ to char
|
||||
std::copy(expcomp_.begin(), expcomp_.end(), writ);
|
||||
writ[expcomp_.size()] = '\0';
|
||||
float fcomp = atof(writ); //compensation + -
|
||||
delete[] writ;
|
||||
float adap;
|
||||
if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f)
|
||||
//if no exif data or wrong
|
||||
adap=2000.f;
|
||||
else {
|
||||
float E_V = fcomp + log2 ((fnum*fnum) / fspeed / (fiso/100.f));
|
||||
float expo2= params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
||||
E_V += expo2;
|
||||
float expo1;//exposure raw white point
|
||||
expo1=log2(params.raw.expos);//log2 ==>linear to EV
|
||||
E_V += expo1;
|
||||
adap= powf(2.f, E_V-3.f);//cd / m2
|
||||
//end calculation adaptation scene luminosity
|
||||
}
|
||||
|
||||
ipf.ciecam_02float (cieView, adap, begh, endh, 1, 2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 6, (float**)buffer, execsharp, d);
|
||||
for (int i=0; i<fh; i++)
|
||||
delete [] buffer[i];
|
||||
delete [] buffer; buffer=NULL;
|
||||
LUTf CAMBrightCurveJ;
|
||||
LUTf CAMBrightCurveQ;
|
||||
float CAMMean;
|
||||
ipf.ciecam_02float (cieView, adap, begh, endh, 1, 2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 6, (float**)buffer, execsharp, d);
|
||||
for (int i=0; i<fh; i++)
|
||||
delete [] buffer[i];
|
||||
delete [] buffer; buffer=NULL;
|
||||
}
|
||||
// color processing
|
||||
//ipf.colorCurve (labView, labView);
|
||||
|
||||
@@ -187,8 +187,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
||||
|
||||
ToneCurve customToneCurve1, customToneCurve2;
|
||||
ColorAppearance customColCurve1, customColCurve2,customColCurve3 ;
|
||||
ChMixerbw customToneCurvebw1;
|
||||
ChMixerbw customToneCurvebw2;
|
||||
ToneCurve customToneCurvebw1;
|
||||
ToneCurve customToneCurvebw2;
|
||||
|
||||
ipf.g = imgsrc->getGamma();
|
||||
ipf.iGamma = true;
|
||||
@@ -203,10 +203,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
||||
LabImage* labView = new LabImage (fw,fh);
|
||||
|
||||
|
||||
CurveFactory::curveBW (params.blackwhite.beforeCurveMode, params.blackwhite.beforeCurve, params.blackwhite.afterCurveMode, params.blackwhite.afterCurve,
|
||||
hist16, dummy, dummy, customToneCurvebw1, customToneCurvebw2, 1);
|
||||
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1);
|
||||
double rrm, ggm, bbm;
|
||||
ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2,customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, expcomp, hlcompr, hlcomprthresh);
|
||||
float autor, autog, autob;
|
||||
autor = -9000.f; // This will ask to compute the "auto" values for the B&W tool (have to be inferior to -5000)
|
||||
ipf.rgbProc (baseImg, labView, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, customToneCurve1, customToneCurve2,customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh);
|
||||
if (settings->verbose)
|
||||
printf("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", autor, autog, autob);
|
||||
|
||||
// Freeing baseImg because not used anymore
|
||||
delete baseImg;
|
||||
@@ -227,16 +230,24 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
||||
if(params.labCurve.contrast !=0) {//only use hist16 for contrast
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma<EFBFBD>omp<EFBFBD>parallel<EFBFBD>shared(hist16,labView, fh, fw)
|
||||
#pragma omp parallel shared(hist16,labView, fh, fw)
|
||||
#endif
|
||||
{
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(static)
|
||||
LUTu hist16thr (65536); // one temporary lookup table per thread
|
||||
hist16thr.clear();
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(static) nowait
|
||||
#endif
|
||||
for (int i=0; i<fh; i++)
|
||||
for (int j=0; j<fw; j++){
|
||||
hist16[CLIP((int)((labView->L[i][j])))]++;
|
||||
}
|
||||
hist16thr[CLIP((int)((labView->L[i][j])))]++;
|
||||
}
|
||||
|
||||
#pragma omp critical
|
||||
{
|
||||
for(int i=0;i<65536;i++)
|
||||
hist16[i] += hist16thr[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -253,7 +264,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
||||
|
||||
CurveFactory::complexsgnCurve (autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection,
|
||||
params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve,params.labCurve.lccurve,curve1, curve2, satcurve,lhskcurve,
|
||||
hist16C, hist16C, hist16C, dummy,dummy,
|
||||
hist16C, hist16C, dummy,dummy,
|
||||
1);
|
||||
|
||||
ipf.chromiLuminanceCurve (1,labView, labView, curve1, curve2, satcurve,lhskcurve,clcurve, lumacurve, utili, autili, butili, ccutili,cclutili, clcutili, dummy, dummy, dummy, dummy);
|
||||
@@ -303,58 +314,60 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
||||
params.colorappearance.curveMode2, params.colorappearance.curve2,
|
||||
params.colorappearance.curveMode3, params.colorappearance.curve3,
|
||||
hist16, hist16,dummy,
|
||||
hist16C, hist16C,dummy,
|
||||
hist16C, dummy,
|
||||
customColCurve1,
|
||||
customColCurve2,
|
||||
customColCurve3,
|
||||
customColCurve3,
|
||||
1);
|
||||
float adap2,adap;
|
||||
double ada, ada2;
|
||||
if(params.colorappearance.enabled){
|
||||
float fnum = imgsrc->getMetaData()->getFNumber ();// F number
|
||||
float fiso = imgsrc->getMetaData()->getISOSpeed () ;// ISO
|
||||
float fspeed = imgsrc->getMetaData()->getShutterSpeed () ;//speed
|
||||
float fcomp = imgsrc->getMetaData()->getExpComp ();//compensation + -
|
||||
if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) {adap=adap2=2000.f;ada=ada2=2000.;}//if no exif data or wrong
|
||||
else {
|
||||
float E_V = fcomp + log2 ((fnum*fnum) / fspeed / (fiso/100.f));
|
||||
float expo2= params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
||||
E_V += expo2;
|
||||
float expo1;//exposure raw white point
|
||||
expo1=log2(params.raw.expos);//log2 ==>linear to EV
|
||||
E_V += expo1;
|
||||
adap2 = adap= powf(2.f, E_V-3.f);//cd / m2
|
||||
ada=ada2=(double) adap;
|
||||
}
|
||||
if (params.sharpening.enabled) {
|
||||
float d;
|
||||
double dd;
|
||||
|
||||
float** buffer = new float*[fh];
|
||||
for (int i=0; i<fh; i++)
|
||||
buffer[i] = new float[fw];
|
||||
if(settings->ciecamfloat) ipf.ciecam_02float (cieView, adap, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true, d);
|
||||
else ipf.ciecam_02 (cieView, ada, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true, dd);
|
||||
if(params.colorappearance.enabled){
|
||||
float fnum = imgsrc->getMetaData()->getFNumber ();// F number
|
||||
float fiso = imgsrc->getMetaData()->getISOSpeed () ;// ISO
|
||||
float fspeed = imgsrc->getMetaData()->getShutterSpeed () ;//speed
|
||||
float fcomp = imgsrc->getMetaData()->getExpComp ();//compensation + -
|
||||
if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) {adap=adap2=2000.f;ada=ada2=2000.;}//if no exif data or wrong
|
||||
else {
|
||||
float E_V = fcomp + log2 ((fnum*fnum) / fspeed / (fiso/100.f));
|
||||
float expo2= params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV
|
||||
E_V += expo2;
|
||||
float expo1;//exposure raw white point
|
||||
expo1=log2(params.raw.expos);//log2 ==>linear to EV
|
||||
E_V += expo1;
|
||||
adap2 = adap= powf(2.f, E_V-3.f);//cd / m2
|
||||
ada=ada2=(double) adap;
|
||||
}
|
||||
LUTf CAMBrightCurveJ;
|
||||
LUTf CAMBrightCurveQ;
|
||||
float CAMMean;
|
||||
if (params.sharpening.enabled) {
|
||||
float d;
|
||||
double dd;
|
||||
|
||||
for (int i=0; i<fh; i++)
|
||||
delete [] buffer[i];
|
||||
float** buffer = new float*[fh];
|
||||
for (int i=0; i<fh; i++)
|
||||
buffer[i] = new float[fw];
|
||||
if(settings->ciecamfloat) ipf.ciecam_02float (cieView, adap, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, d);
|
||||
else ipf.ciecam_02 (cieView, ada, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, dd);
|
||||
for (int i=0; i<fh; i++)
|
||||
delete [] buffer[i];
|
||||
delete [] buffer;
|
||||
}
|
||||
else {
|
||||
}
|
||||
else {
|
||||
int f_h=2,f_w=2;
|
||||
float d;
|
||||
|
||||
double dd;
|
||||
float** buffer = new float*[f_h];
|
||||
for (int i=0; i<f_h; i++)
|
||||
buffer[i] = new float[f_w];
|
||||
if(settings->ciecamfloat) ipf.ciecam_02float (cieView, adap, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true, d);
|
||||
else ipf.ciecam_02 (cieView, adap, begh, endh,1, 2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true, dd);
|
||||
|
||||
for (int i=0; i<f_h; i++)
|
||||
delete [] buffer[i];
|
||||
double dd;
|
||||
float** buffer = new float*[f_h];
|
||||
for (int i=0; i<f_h; i++)
|
||||
buffer[i] = new float[f_w];
|
||||
if(settings->ciecamfloat) ipf.ciecam_02float (cieView, adap, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, d);
|
||||
else ipf.ciecam_02 (cieView, adap, begh, endh,1, 2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, dd);
|
||||
|
||||
for (int i=0; i<f_h; i++)
|
||||
delete [] buffer[i];
|
||||
delete [] buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete cieView;
|
||||
cieView = NULL;
|
||||
|
||||
@@ -32,6 +32,10 @@ BlackWhite::BlackWhite (): Gtk::VBox(), FoldableToolPanel(this) {
|
||||
set_border_width(4);
|
||||
set_spacing(4);
|
||||
|
||||
nextredbw = 0.3333;
|
||||
nextgreenbw = 0.3333;
|
||||
nextbluebw = 0.3333;
|
||||
|
||||
//----------- Enables checkbox ------------------------------
|
||||
|
||||
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
|
||||
@@ -89,7 +93,7 @@ BlackWhite::BlackWhite (): Gtk::VBox(), FoldableToolPanel(this) {
|
||||
mixerFrame = Gtk::manage (new Gtk::Frame (M("TP_BWMIX_MET_CHANMIX")));
|
||||
pack_start (*mixerFrame, Gtk::PACK_SHRINK, 0);
|
||||
|
||||
Gtk::VBox *mixerVBox = Gtk::manage (new Gtk::VBox ());
|
||||
mixerVBox = Gtk::manage (new Gtk::VBox ());
|
||||
mixerVBox->set_border_width(4);
|
||||
mixerVBox->set_spacing(4);
|
||||
|
||||
@@ -122,9 +126,6 @@ BlackWhite::BlackWhite (): Gtk::VBox(), FoldableToolPanel(this) {
|
||||
settingHBox->set_tooltip_markup (M("TP_BWMIX_SETTING_TOOLTIP"));
|
||||
Gtk::Label *settingLabel = Gtk::manage (new Gtk::Label (M("TP_BWMIX_SETTING")+":"));
|
||||
|
||||
Gtk::SeparatorMenuItem *menuSep1 = Gtk::manage (new Gtk::SeparatorMenuItem ());
|
||||
Gtk::SeparatorMenuItem *menuSep2 = Gtk::manage (new Gtk::SeparatorMenuItem ());
|
||||
|
||||
settingHBox->pack_start (*settingLabel, Gtk::PACK_SHRINK);
|
||||
setting = Gtk::manage (new MyComboBoxText ());
|
||||
setting->append_text (M("TP_BWMIX_SET_NORMCONTAST"));
|
||||
@@ -139,8 +140,8 @@ BlackWhite::BlackWhite (): Gtk::VBox(), FoldableToolPanel(this) {
|
||||
setting->append_text (M("TP_BWMIX_SET_ORTHOCHRO"));
|
||||
setting->append_text (M("TP_BWMIX_SET_RGBABS"));
|
||||
setting->append_text (M("TP_BWMIX_SET_RGBREL"));
|
||||
setting->append_text (M("TP_BWMIX_SET_ROYGCBMPABS"));
|
||||
setting->append_text (M("TP_BWMIX_SET_ROYGCBMPREL"));
|
||||
setting->append_text (M("TP_BWMIX_SET_ROYGCBPMABS"));
|
||||
setting->append_text (M("TP_BWMIX_SET_ROYGCBPMREL"));
|
||||
setting->append_text (M("TP_BWMIX_SET_INFRARED"));
|
||||
|
||||
setting->set_active (0);
|
||||
@@ -148,6 +149,10 @@ BlackWhite::BlackWhite (): Gtk::VBox(), FoldableToolPanel(this) {
|
||||
mixerVBox->pack_start (*settingHBox);
|
||||
settingconn = setting->signal_changed().connect ( sigc::mem_fun(*this, &BlackWhite::settingChanged) );
|
||||
|
||||
RGBLabels = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER));
|
||||
RGBLabels->set_tooltip_text(M("TP_BWMIX_RGBLABEL_HINT"));
|
||||
mixerVBox->pack_start (*RGBLabels);
|
||||
|
||||
//----------- Complementary Color checkbox ------------------------------
|
||||
|
||||
enabledccSep= Gtk::manage (new Gtk::HSeparator());
|
||||
@@ -189,16 +194,16 @@ BlackWhite::BlackWhite (): Gtk::VBox(), FoldableToolPanel(this) {
|
||||
mixerVBox->pack_start (*filterHBox);
|
||||
filterconn = filter->signal_changed().connect ( sigc::mem_fun(*this, &BlackWhite::filterChanged) );
|
||||
|
||||
//----------- RGB / ROYGCBMP Mixer ------------------------------
|
||||
//----------- RGB / ROYGCBPM Mixer ------------------------------
|
||||
|
||||
imgIcon[0] = Gtk::manage (new RTImage ("Chanmixer-R.png"));
|
||||
imgIcon[1] = Gtk::manage (new RTImage ("Chanmixer-G.png"));
|
||||
imgIcon[2] = Gtk::manage (new RTImage ("Chanmixer-B.png"));
|
||||
imgIcon[3] = Gtk::manage (new RTImage ("Chanmixer-O.png"));
|
||||
imgIcon[4] = Gtk::manage (new RTImage ("Chanmixer-Y.png"));
|
||||
imgIcon[5] = Gtk::manage (new RTImage ("Chanmixer-C.png"));
|
||||
imgIcon[6] = Gtk::manage (new RTImage ("Chanmixer-M.png"));
|
||||
imgIcon[7] = Gtk::manage (new RTImage ("Chanmixer-P.png"));
|
||||
imgIcon[1] = Gtk::manage (new RTImage ("Chanmixer-O.png"));
|
||||
imgIcon[2] = Gtk::manage (new RTImage ("Chanmixer-Y.png"));
|
||||
imgIcon[3] = Gtk::manage (new RTImage ("Chanmixer-G.png"));
|
||||
imgIcon[4] = Gtk::manage (new RTImage ("Chanmixer-C.png"));
|
||||
imgIcon[5] = Gtk::manage (new RTImage ("Chanmixer-B.png"));
|
||||
imgIcon[6] = Gtk::manage (new RTImage ("Chanmixer-P.png"));
|
||||
imgIcon[7] = Gtk::manage (new RTImage ("Chanmixer-M.png"));
|
||||
|
||||
imgIcon[8] = Gtk::manage (new RTImage ("Chanmixer-Rgamma.png"));
|
||||
imgIcon[9] = Gtk::manage (new RTImage ("Chanmixer-Ggamma.png"));
|
||||
@@ -213,55 +218,58 @@ BlackWhite::BlackWhite (): Gtk::VBox(), FoldableToolPanel(this) {
|
||||
mixerRed->show();
|
||||
mixerVBox->pack_start( *mixerRed, Gtk::PACK_SHRINK, 0);
|
||||
|
||||
mixerOrange= Gtk::manage(new Adjuster (/*M("TP_BWMIX_ORANGE")*/"", -100, 200, 1, 33, imgIcon[3]));
|
||||
if (mixerOrange->delay < 50) mixerOrange->delay = 50;
|
||||
mixerOrange->setAdjusterListener (this);
|
||||
mixerOrange->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP"));
|
||||
mixerOrange->show();
|
||||
mixerVBox->pack_start( *mixerOrange, Gtk::PACK_SHRINK, 0);
|
||||
|
||||
mixerYellow= Gtk::manage(new Adjuster (/*M("TP_BWMIX_YELLOW")*/"", -100, 200, 1, 33, imgIcon[4]));
|
||||
if (mixerYellow->delay < 50) mixerYellow->delay = 50;
|
||||
mixerYellow->setAdjusterListener (this);
|
||||
mixerYellow->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP"));
|
||||
mixerYellow->show();
|
||||
mixerVBox->pack_start( *mixerYellow, Gtk::PACK_SHRINK, 0);
|
||||
|
||||
mixerGreen= Gtk::manage(new Adjuster (/*M("TP_BWMIX_GREEN")*/"", -100, 200, 1, 33, imgIcon[1]));
|
||||
mixerGreen= Gtk::manage(new Adjuster (/*M("TP_BWMIX_GREEN")*/"", -100, 200, 1, 33, imgIcon[3]));
|
||||
if (mixerGreen->delay < 50) mixerGreen->delay = 50;
|
||||
mixerGreen->setAdjusterListener (this);
|
||||
mixerGreen->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP"));
|
||||
mixerGreen->show();
|
||||
mixerVBox->pack_start( *mixerGreen, Gtk::PACK_SHRINK, 0);
|
||||
|
||||
mixerCyan= Gtk::manage(new Adjuster (/*M("TP_BWMIX_CYAN")*/"", -100, 200, 1, 33, imgIcon[5]));
|
||||
if (mixerCyan->delay < 50) mixerCyan->delay = 50;
|
||||
mixerCyan->setAdjusterListener (this);
|
||||
mixerCyan->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP"));
|
||||
mixerCyan->show();
|
||||
mixerVBox->pack_start( *mixerCyan, Gtk::PACK_SHRINK, 0);
|
||||
|
||||
mixerBlue= Gtk::manage(new Adjuster (/*M("TP_BWMIX_BLUE")*/"", -100, 200, 1, 33, imgIcon[2]));
|
||||
mixerBlue= Gtk::manage(new Adjuster (/*M("TP_BWMIX_BLUE")*/"", -100, 200, 1, 33, imgIcon[5]));
|
||||
if (mixerBlue->delay < 50) mixerBlue->delay = 50;
|
||||
mixerBlue->setAdjusterListener (this);
|
||||
mixerBlue->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP"));
|
||||
mixerBlue->show();
|
||||
mixerVBox->pack_start( *mixerBlue, Gtk::PACK_SHRINK, 0);
|
||||
|
||||
mixerMagenta= Gtk::manage(new Adjuster (/*M("TP_BWMIX_MAGENTA")*/"", -100, 200, 1, 33, imgIcon[6]));
|
||||
if (mixerMagenta->delay < 50) mixerMagenta->delay = 50;
|
||||
mixerMagenta->setAdjusterListener (this);
|
||||
mixerMagenta->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP"));
|
||||
mixerMagenta->show();
|
||||
mixerVBox->pack_start( *mixerMagenta, Gtk::PACK_SHRINK, 0);
|
||||
filterSep2 = Gtk::manage (new Gtk::HSeparator());
|
||||
mixerVBox->pack_start (*filterSep2);
|
||||
|
||||
mixerPurple= Gtk::manage(new Adjuster (/*M("TP_BWMIX_PURPLE")*/"", -100, 200, 1, 33, imgIcon[7]));
|
||||
mixerOrange= Gtk::manage(new Adjuster (/*M("TP_BWMIX_ORANGE")*/"", -100, 200, 1, 33, imgIcon[1]));
|
||||
if (mixerOrange->delay < 50) mixerOrange->delay = 50;
|
||||
mixerOrange->setAdjusterListener (this);
|
||||
mixerOrange->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP"));
|
||||
mixerOrange->show();
|
||||
mixerVBox->pack_start( *mixerOrange, Gtk::PACK_SHRINK, 0);
|
||||
|
||||
mixerYellow= Gtk::manage(new Adjuster (/*M("TP_BWMIX_YELLOW")*/"", -100, 200, 1, 33, imgIcon[2]));
|
||||
if (mixerYellow->delay < 50) mixerYellow->delay = 50;
|
||||
mixerYellow->setAdjusterListener (this);
|
||||
mixerYellow->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP"));
|
||||
mixerYellow->show();
|
||||
mixerVBox->pack_start( *mixerYellow, Gtk::PACK_SHRINK, 0);
|
||||
|
||||
mixerCyan= Gtk::manage(new Adjuster (/*M("TP_BWMIX_CYAN")*/"", -100, 200, 1, 33, imgIcon[4]));
|
||||
if (mixerCyan->delay < 50) mixerCyan->delay = 50;
|
||||
mixerCyan->setAdjusterListener (this);
|
||||
mixerCyan->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP"));
|
||||
mixerCyan->show();
|
||||
mixerVBox->pack_start( *mixerCyan, Gtk::PACK_SHRINK, 0);
|
||||
|
||||
mixerPurple= Gtk::manage(new Adjuster (/*M("TP_BWMIX_PURPLE")*/"", -100, 200, 1, 33, imgIcon[6]));
|
||||
if (mixerPurple->delay < 50) mixerPurple->delay = 50;
|
||||
mixerPurple->setAdjusterListener (this);
|
||||
mixerPurple->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP"));
|
||||
mixerPurple->show();
|
||||
mixerVBox->pack_start( *mixerPurple, Gtk::PACK_SHRINK, 0);
|
||||
|
||||
mixerMagenta= Gtk::manage(new Adjuster (/*M("TP_BWMIX_MAGENTA")*/"", -100, 200, 1, 33, imgIcon[7]));
|
||||
if (mixerMagenta->delay < 50) mixerMagenta->delay = 50;
|
||||
mixerMagenta->setAdjusterListener (this);
|
||||
mixerMagenta->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP"));
|
||||
mixerMagenta->show();
|
||||
mixerVBox->pack_start( *mixerMagenta, Gtk::PACK_SHRINK, 0);
|
||||
|
||||
mixerFrame->add(*mixerVBox);
|
||||
|
||||
//----------- Gamma sliders ------------------------------
|
||||
@@ -376,6 +384,8 @@ bool BlackWhite::BWComputed_ () {
|
||||
mixerBlue->setValue (nextbluebw);
|
||||
enableListener ();
|
||||
|
||||
updateRGBLabel();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -389,7 +399,6 @@ void BlackWhite::read (const ProcParams* pp, const ParamsEdited* pedited) {
|
||||
enaccconn.block (true);
|
||||
enaconn.block (true);
|
||||
|
||||
|
||||
if (pedited && !pedited->blackwhite.setting)
|
||||
setting->set_active (15); // "Unchanged"
|
||||
else if (pp->blackwhite.setting=="NormalContrast")
|
||||
@@ -416,9 +425,9 @@ void BlackWhite::read (const ProcParams* pp, const ParamsEdited* pedited) {
|
||||
setting->set_active (10);
|
||||
else if (pp->blackwhite.setting=="RGB-Rel")
|
||||
setting->set_active (11);
|
||||
else if (pp->blackwhite.setting=="ROYGCBMP-Abs")
|
||||
else if (pp->blackwhite.setting=="ROYGCBPM-Abs")
|
||||
setting->set_active (12);
|
||||
else if (pp->blackwhite.setting=="ROYGCBMP-Rel")
|
||||
else if (pp->blackwhite.setting=="ROYGCBPM-Rel")
|
||||
setting->set_active (13);
|
||||
else if (pp->blackwhite.setting=="InfraRed")
|
||||
setting->set_active (14);
|
||||
@@ -515,6 +524,8 @@ void BlackWhite::read (const ProcParams* pp, const ParamsEdited* pedited) {
|
||||
enaconn.block (false);
|
||||
enaccconn.block (false);
|
||||
|
||||
updateRGBLabel();
|
||||
|
||||
enableListener ();
|
||||
}
|
||||
|
||||
@@ -578,55 +589,8 @@ void BlackWhite::write (ProcParams* pp, ParamsEdited* pedited) {
|
||||
else if (method->get_active_row_number()==2)
|
||||
pp->blackwhite.method = "ChannelMixer";
|
||||
|
||||
if (setting->get_active_row_number()==0)
|
||||
pp->blackwhite.setting = "NormalContrast";
|
||||
else if (setting->get_active_row_number()==1)
|
||||
pp->blackwhite.setting = "HighContrast";
|
||||
else if (setting->get_active_row_number()==2)
|
||||
pp->blackwhite.setting = "Luminance";
|
||||
else if (setting->get_active_row_number()==3)
|
||||
pp->blackwhite.setting = "Landscape";
|
||||
else if (setting->get_active_row_number()==4)
|
||||
pp->blackwhite.setting = "Portrait";
|
||||
else if (setting->get_active_row_number()==5)
|
||||
pp->blackwhite.setting = "LowSensitivity";
|
||||
else if (setting->get_active_row_number()==6)
|
||||
pp->blackwhite.setting = "HighSensitivity";
|
||||
else if (setting->get_active_row_number()==7)
|
||||
pp->blackwhite.setting = "Panchromatic";
|
||||
else if (setting->get_active_row_number()==8)
|
||||
pp->blackwhite.setting = "HyperPanchromatic";
|
||||
else if (setting->get_active_row_number()==9)
|
||||
pp->blackwhite.setting = "Orthochromatic";
|
||||
else if (setting->get_active_row_number()==10)
|
||||
pp->blackwhite.setting = "RGB-Abs";
|
||||
else if (setting->get_active_row_number()==11)
|
||||
pp->blackwhite.setting = "RGB-Rel";
|
||||
else if (setting->get_active_row_number()==12)
|
||||
pp->blackwhite.setting = "ROYGCBMP-Abs";
|
||||
else if (setting->get_active_row_number()==13)
|
||||
pp->blackwhite.setting = "ROYGCBMP-Rel";
|
||||
else if (setting->get_active_row_number()==14)
|
||||
pp->blackwhite.setting = "InfraRed";
|
||||
|
||||
if (filter->get_active_row_number()==0)
|
||||
pp->blackwhite.filter = "None";
|
||||
else if (filter->get_active_row_number()==1)
|
||||
pp->blackwhite.filter = "Red";
|
||||
else if (filter->get_active_row_number()==2)
|
||||
pp->blackwhite.filter = "Orange";
|
||||
else if (filter->get_active_row_number()==3)
|
||||
pp->blackwhite.filter = "Yellow";
|
||||
else if (filter->get_active_row_number()==4)
|
||||
pp->blackwhite.filter = "YellowGreen";
|
||||
else if (filter->get_active_row_number()==5)
|
||||
pp->blackwhite.filter = "Green";
|
||||
else if (filter->get_active_row_number()==6)
|
||||
pp->blackwhite.filter = "Cyan";
|
||||
else if (filter->get_active_row_number()==7)
|
||||
pp->blackwhite.filter = "Blue";
|
||||
else if (filter->get_active_row_number()==8)
|
||||
pp->blackwhite.filter = "Purple";
|
||||
pp->blackwhite.setting = getSettingString();
|
||||
pp->blackwhite.filter = getFilterString();
|
||||
}
|
||||
|
||||
void BlackWhite::curveChanged (CurveEditor* ce) {
|
||||
@@ -698,7 +662,7 @@ void BlackWhite::settingChanged () {
|
||||
showFilter();
|
||||
}
|
||||
else if ( setting->get_active_row_number()==12 || setting->get_active_row_number()==13 ) {
|
||||
// ROYGCBMP Channel Mixer
|
||||
// ROYGCBPM Channel Mixer
|
||||
showMixer(7);
|
||||
showEnabledCC();
|
||||
showFilter();
|
||||
@@ -717,6 +681,18 @@ void BlackWhite::settingChanged () {
|
||||
showFilter();
|
||||
}
|
||||
|
||||
// Checking "listener" to avoid "autoch" getting toggled off because it has to change the sliders when toggling on
|
||||
if (listener){
|
||||
if (multiImage && autoch->get_inconsistent())
|
||||
autoch->set_inconsistent (false);
|
||||
autoconn.block(true);
|
||||
autoch->set_active (false);
|
||||
autoconn.block(false);
|
||||
lastAuto = false;
|
||||
}
|
||||
|
||||
updateRGBLabel();
|
||||
|
||||
if (listener && (multiImage||enabled->get_active())) {
|
||||
listener->panelChanged (EvBWsetting, setting->get_active_text ());
|
||||
}
|
||||
@@ -724,6 +700,18 @@ void BlackWhite::settingChanged () {
|
||||
|
||||
|
||||
void BlackWhite::filterChanged () {
|
||||
// Checking "listener" to avoid "autoch" getting toggled off because it has to change the sliders when toggling on
|
||||
if (listener){
|
||||
if (multiImage && autoch->get_inconsistent())
|
||||
autoch->set_inconsistent (false);
|
||||
autoconn.block(true);
|
||||
autoch->set_active (false);
|
||||
autoconn.block(false);
|
||||
lastAuto = false;
|
||||
}
|
||||
|
||||
updateRGBLabel();
|
||||
|
||||
if (listener && (multiImage||enabled->get_active())) {
|
||||
listener->panelChanged (EvBWfilter, filter->get_active_text ());
|
||||
}
|
||||
@@ -803,15 +791,17 @@ void BlackWhite::neutral_pressed () {
|
||||
// This method deselects auto chmixer and sets "neutral" values to params
|
||||
disableListener();
|
||||
|
||||
if (multiImage) {
|
||||
if (multiImage && autoch->get_inconsistent())
|
||||
autoch->set_inconsistent (false);
|
||||
autoch->set_active (false);
|
||||
autoconn.block(true);
|
||||
autoch->set_active (false);
|
||||
autoconn.block(false);
|
||||
lastAuto = false;
|
||||
|
||||
lastAuto = autoch->get_active ();
|
||||
}
|
||||
else { //!batchMode
|
||||
autoch->set_active (false);
|
||||
}
|
||||
int activeSetting = setting->get_active_row_number();
|
||||
if (activeSetting < 10 || activeSetting > 13)
|
||||
setting->set_active (11);
|
||||
filter->set_active (0);
|
||||
mixerRed->resetValue(false);
|
||||
mixerGreen->resetValue(false);
|
||||
mixerBlue->resetValue(false);
|
||||
@@ -820,23 +810,23 @@ void BlackWhite::neutral_pressed () {
|
||||
mixerMagenta->resetValue(false);
|
||||
mixerPurple->resetValue(false);
|
||||
mixerCyan->resetValue(false);
|
||||
int activeSetting = setting->get_active_row_number();
|
||||
if (activeSetting < 10 || activeSetting > 13)
|
||||
setting->set_active (11);
|
||||
filter->set_active (0);
|
||||
|
||||
enableListener();
|
||||
|
||||
updateRGBLabel();
|
||||
|
||||
listener->panelChanged (EvNeutralBW, M("ADJUSTER_RESET_TO_DEFAULT"));
|
||||
}
|
||||
|
||||
void BlackWhite::enabledcc_toggled () {
|
||||
|
||||
// toggling off the Complementary Colors does switch off the Auto button
|
||||
if (multiImage) {
|
||||
// multiple image editing (batch)
|
||||
if (enabledcc->get_inconsistent()) {
|
||||
enabledcc->set_inconsistent (false);
|
||||
enabledcc->set_inconsistent (false); // set consistent
|
||||
enaccconn.block (true);
|
||||
enabledcc->set_active (false);
|
||||
enabledcc->set_active (false); // ... and deactivated
|
||||
enaccconn.block (false);
|
||||
}
|
||||
else if (lastEnabledcc)
|
||||
@@ -844,6 +834,16 @@ void BlackWhite::enabledcc_toggled () {
|
||||
|
||||
lastEnabledcc = enabledcc->get_active ();
|
||||
}
|
||||
|
||||
if (multiImage && autoch->get_inconsistent())
|
||||
autoch->set_inconsistent (false);
|
||||
autoconn.block(true);
|
||||
autoch->set_active (false);
|
||||
autoconn.block(false);
|
||||
lastAuto = false;
|
||||
|
||||
updateRGBLabel();
|
||||
|
||||
if (listener) {
|
||||
if (enabledcc->get_inconsistent())
|
||||
listener->panelChanged (EvBWChmixEnabledLm, M("GENERAL_UNCHANGED"));
|
||||
@@ -902,14 +902,16 @@ void BlackWhite::setDefaults (const ProcParams* defParams, const ParamsEdited* p
|
||||
void BlackWhite::autoch_toggled () {
|
||||
|
||||
if (batchMode) {
|
||||
if (autoch->get_inconsistent()) {
|
||||
autoch->set_inconsistent (false);
|
||||
autoconn.block (true);
|
||||
autoch->set_active (false);
|
||||
autoconn.block (false);
|
||||
if (multiImage) {
|
||||
if (autoch->get_inconsistent()) {
|
||||
autoch->set_inconsistent (false);
|
||||
autoconn.block (true);
|
||||
autoch->set_active (false);
|
||||
autoconn.block (false);
|
||||
}
|
||||
else if (lastAuto)
|
||||
autoch->set_inconsistent (true);
|
||||
}
|
||||
else if (lastAuto)
|
||||
autoch->set_inconsistent (true);
|
||||
|
||||
lastAuto = autoch->get_active ();
|
||||
|
||||
@@ -937,18 +939,19 @@ void BlackWhite::autoch_toggled () {
|
||||
mixerMagenta->resetValue(true);
|
||||
if (mixerPurple->getAddMode())
|
||||
mixerPurple->resetValue(true);
|
||||
if (mixerMagenta->getAddMode())
|
||||
mixerPurple->resetValue(true);
|
||||
if (mixerCyan->getAddMode())
|
||||
mixerCyan->resetValue(true);
|
||||
setting->set_active (11);
|
||||
filter->set_active (0);
|
||||
if (wasEnabled) enableListener();
|
||||
|
||||
if (listener) {
|
||||
if (!autoch->get_inconsistent()) {
|
||||
if (autoch->get_active ())
|
||||
listener->panelChanged (EvAutoch, M("GENERAL_ENABLED"));}
|
||||
else
|
||||
listener->panelChanged (EvAutoch, M("GENERAL_DISABLED"));
|
||||
if (autoch->get_inconsistent())
|
||||
listener->panelChanged (EvAutoch, M("GENERAL_UNCHANGED"));
|
||||
else if (autoch->get_active ())
|
||||
listener->panelChanged (EvAutoch, M("GENERAL_ENABLED"));
|
||||
else
|
||||
listener->panelChanged (EvAutoch, M("GENERAL_DISABLED"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -966,6 +969,8 @@ void BlackWhite::autoch_toggled () {
|
||||
filter->set_active (0);
|
||||
if (wasEnabled) enableListener();
|
||||
|
||||
updateRGBLabel();
|
||||
|
||||
if (listener)
|
||||
listener->panelChanged (EvAutoch, M("GENERAL_ENABLED"));
|
||||
}
|
||||
@@ -979,13 +984,22 @@ void BlackWhite::autoch_toggled () {
|
||||
|
||||
void BlackWhite::adjusterChanged (Adjuster* a, double newval) {
|
||||
|
||||
if (autoch->get_active() && (a==mixerRed || a==mixerGreen || a==mixerBlue || a==mixerOrange || a==mixerYellow || a==mixerMagenta || a==mixerPurple || a==mixerCyan )) {
|
||||
// Checking "listener" to avoid "autoch" getting toggled off because it has to change the sliders when toggling on
|
||||
if (listener && (a==mixerRed || a==mixerGreen || a==mixerBlue || a==mixerOrange || a==mixerYellow || a==mixerMagenta || a==mixerPurple || a==mixerCyan) ) {
|
||||
if (multiImage && autoch->get_inconsistent())
|
||||
autoch->set_inconsistent (false);
|
||||
autoconn.block(true);
|
||||
autoch->set_active (false);
|
||||
autoconn.block(false);
|
||||
autoch->set_inconsistent (false);
|
||||
lastAuto = false;
|
||||
}
|
||||
|
||||
if (a == mixerRed || a==mixerGreen || a== mixerBlue
|
||||
|| a == mixerOrange || a == mixerYellow ||a == mixerCyan
|
||||
|| a == mixerMagenta || a == mixerPurple)
|
||||
|
||||
updateRGBLabel();
|
||||
|
||||
if (listener && (multiImage||enabled->get_active())) {
|
||||
Glib::ustring value = a->getTextValue();
|
||||
if (a == mixerRed)
|
||||
@@ -1013,6 +1027,41 @@ void BlackWhite::adjusterChanged (Adjuster* a, double newval) {
|
||||
}
|
||||
}
|
||||
|
||||
void BlackWhite::updateRGBLabel () {
|
||||
if (!batchMode) {
|
||||
float kcorrec=1.f;
|
||||
float r, g, b;
|
||||
if (autoch->get_active()) {
|
||||
r = nextredbw;
|
||||
g = nextgreenbw;
|
||||
b = nextbluebw;
|
||||
}
|
||||
else {
|
||||
r = mixerRed->getValue();
|
||||
g = mixerGreen->getValue();
|
||||
b = mixerBlue->getValue();
|
||||
}
|
||||
double mixR, mixG, mixB;
|
||||
Glib::ustring sSetting = getSettingString();
|
||||
Color::computeBWMixerConstants(sSetting, getFilterString(), r, g, b,
|
||||
mixerOrange->getValue(), mixerYellow->getValue(), mixerCyan->getValue(), mixerPurple->getValue(), mixerMagenta->getValue(),
|
||||
autoch->get_active(), enabledcc->get_active(), kcorrec, mixR, mixG, mixB);
|
||||
RGBLabels->set_text(
|
||||
Glib::ustring::compose(M("TP_BWMIX_RGBLABEL"),
|
||||
Glib::ustring::format(std::fixed, std::setprecision(1), r*100.),
|
||||
Glib::ustring::format(std::fixed, std::setprecision(1), g*100.),
|
||||
Glib::ustring::format(std::fixed, std::setprecision(1), b*100.),
|
||||
Glib::ustring::format(std::fixed, std::setprecision(0), (r+g+b)*100.))
|
||||
);
|
||||
// We have to update the RGB sliders too if preset values has been chosen
|
||||
if (sSetting != "RGB-Abs" && sSetting != "RGB-Rel" && sSetting != "ROYGCBPM-Abs" && sSetting != "ROYGCBPM-Rel") {
|
||||
mixerRed->setValue(mixR);
|
||||
mixerGreen->setValue(mixG);
|
||||
mixerBlue->setValue(mixB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BlackWhite::setBatchMode (bool batchMode) {
|
||||
removeIfThere (autoHBox, autoch, false);
|
||||
autoch = Gtk::manage (new Gtk::CheckButton (M("TP_BWMIX_AUTOCH")));
|
||||
@@ -1020,6 +1069,10 @@ void BlackWhite::setBatchMode (bool batchMode) {
|
||||
autoconn = autoch->signal_toggled().connect( sigc::mem_fun(*this, &BlackWhite::autoch_toggled) );
|
||||
autoHBox->pack_start (*autoch);
|
||||
|
||||
removeIfThere (mixerVBox, RGBLabels, false);
|
||||
delete RGBLabels;
|
||||
RGBLabels = NULL;
|
||||
|
||||
ToolPanel::setBatchMode (batchMode);
|
||||
mixerRed->showEditedCB ();
|
||||
mixerOrange->showEditedCB ();
|
||||
@@ -1122,10 +1175,14 @@ void BlackWhite::hideEnabledCC() {
|
||||
}
|
||||
|
||||
void BlackWhite::showMixer(int nChannels, bool RGBIsSensitive) {
|
||||
if (!batchMode)
|
||||
RGBLabels->show();
|
||||
|
||||
if (!batchMode && nChannels == 3) {
|
||||
mixerRed->show(); mixerRed->set_sensitive (RGBIsSensitive);
|
||||
mixerGreen->show(); mixerGreen->set_sensitive (RGBIsSensitive);
|
||||
mixerBlue->show(); mixerBlue->set_sensitive (RGBIsSensitive);
|
||||
filterSep2->hide();
|
||||
mixerOrange->hide();
|
||||
mixerYellow->hide();
|
||||
mixerCyan->hide();
|
||||
@@ -1136,6 +1193,7 @@ void BlackWhite::showMixer(int nChannels, bool RGBIsSensitive) {
|
||||
mixerRed->show(); mixerRed->set_sensitive (true);
|
||||
mixerGreen->show(); mixerGreen->set_sensitive (true);
|
||||
mixerBlue->show(); mixerBlue->set_sensitive (true);
|
||||
filterSep2->show();
|
||||
mixerOrange->show();
|
||||
mixerYellow->show();
|
||||
mixerCyan->show();
|
||||
@@ -1158,3 +1216,61 @@ void BlackWhite::hideGamma() {
|
||||
if (!batchMode)
|
||||
gammaFrame->hide();
|
||||
}
|
||||
|
||||
Glib::ustring BlackWhite::getSettingString() {
|
||||
Glib::ustring retVal;
|
||||
if (setting->get_active_row_number()==0)
|
||||
retVal = "NormalContrast";
|
||||
else if (setting->get_active_row_number()==1)
|
||||
retVal = "HighContrast";
|
||||
else if (setting->get_active_row_number()==2)
|
||||
retVal = "Luminance";
|
||||
else if (setting->get_active_row_number()==3)
|
||||
retVal = "Landscape";
|
||||
else if (setting->get_active_row_number()==4)
|
||||
retVal = "Portrait";
|
||||
else if (setting->get_active_row_number()==5)
|
||||
retVal = "LowSensitivity";
|
||||
else if (setting->get_active_row_number()==6)
|
||||
retVal = "HighSensitivity";
|
||||
else if (setting->get_active_row_number()==7)
|
||||
retVal = "Panchromatic";
|
||||
else if (setting->get_active_row_number()==8)
|
||||
retVal = "HyperPanchromatic";
|
||||
else if (setting->get_active_row_number()==9)
|
||||
retVal = "Orthochromatic";
|
||||
else if (setting->get_active_row_number()==10)
|
||||
retVal = "RGB-Abs";
|
||||
else if (setting->get_active_row_number()==11)
|
||||
retVal = "RGB-Rel";
|
||||
else if (setting->get_active_row_number()==12)
|
||||
retVal = "ROYGCBPM-Abs";
|
||||
else if (setting->get_active_row_number()==13)
|
||||
retVal = "ROYGCBPM-Rel";
|
||||
else if (setting->get_active_row_number()==14)
|
||||
retVal = "InfraRed";
|
||||
return retVal;
|
||||
}
|
||||
|
||||
Glib::ustring BlackWhite::getFilterString() {
|
||||
Glib::ustring retVal;
|
||||
if (filter->get_active_row_number()==0)
|
||||
retVal = "None";
|
||||
else if (filter->get_active_row_number()==1)
|
||||
retVal = "Red";
|
||||
else if (filter->get_active_row_number()==2)
|
||||
retVal = "Orange";
|
||||
else if (filter->get_active_row_number()==3)
|
||||
retVal = "Yellow";
|
||||
else if (filter->get_active_row_number()==4)
|
||||
retVal = "YellowGreen";
|
||||
else if (filter->get_active_row_number()==5)
|
||||
retVal = "Green";
|
||||
else if (filter->get_active_row_number()==6)
|
||||
retVal = "Cyan";
|
||||
else if (filter->get_active_row_number()==7)
|
||||
retVal = "Blue";
|
||||
else if (filter->get_active_row_number()==8)
|
||||
retVal = "Purple";
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ class BlackWhite : public Gtk::VBox, public AdjusterListener, public FoldableToo
|
||||
Gtk::ToggleButton* autoch;
|
||||
Gtk::HBox* autoHBox;
|
||||
Gtk::Button* neutral;
|
||||
Gtk::Label* RGBLabels;
|
||||
|
||||
Adjuster *mixerRed;
|
||||
Adjuster *mixerGreen;
|
||||
@@ -58,13 +59,14 @@ class BlackWhite : public Gtk::VBox, public AdjusterListener, public FoldableToo
|
||||
MyComboBoxText* method;
|
||||
sigc::connection methodconn;
|
||||
Gtk::HBox* filterHBox;
|
||||
Gtk::HSeparator* filterSep;
|
||||
Gtk::HSeparator* filterSep, *filterSep2;
|
||||
MyComboBoxText* filter;
|
||||
sigc::connection filterconn;
|
||||
Gtk::HBox* settingHBox;
|
||||
MyComboBoxText* setting;
|
||||
sigc::connection settingconn;
|
||||
Gtk::Frame* mixerFrame;
|
||||
Gtk::VBox * mixerVBox;
|
||||
Gtk::Frame* gammaFrame;
|
||||
|
||||
Gtk::Image *imgIcon[11];
|
||||
@@ -106,6 +108,7 @@ class BlackWhite : public Gtk::VBox, public AdjusterListener, public FoldableToo
|
||||
void autoch_toggled ();
|
||||
void neutral_pressed ();
|
||||
|
||||
void updateRGBLabel ();
|
||||
void adjusterChanged (Adjuster* a, double newval);
|
||||
void setAdjusterBehavior (bool bwadd, bool bwgadd);
|
||||
void trimValues (rtengine::procparams::ProcParams* pp);
|
||||
@@ -122,6 +125,9 @@ class BlackWhite : public Gtk::VBox, public AdjusterListener, public FoldableToo
|
||||
bool curveMode1Changed_ ();
|
||||
void curveMode1Changed2 ();
|
||||
bool curveMode1Changed2_ ();
|
||||
|
||||
Glib::ustring getSettingString ();
|
||||
Glib::ustring getFilterString ();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user