diff --git a/rtdata/images/Dark/actions/wb-auto.png b/rtdata/images/Dark/actions/wb-auto.png new file mode 100644 index 000000000..d044bdf82 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-auto.png differ diff --git a/rtdata/images/Dark/actions/wb-camera.png b/rtdata/images/Dark/actions/wb-camera.png new file mode 100644 index 000000000..f349007f7 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-camera.png differ diff --git a/rtdata/images/Dark/actions/wb-cloudy.png b/rtdata/images/Dark/actions/wb-cloudy.png new file mode 100644 index 000000000..45a2c6f12 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-cloudy.png differ diff --git a/rtdata/images/Dark/actions/wb-custom.png b/rtdata/images/Dark/actions/wb-custom.png new file mode 100644 index 000000000..90fbb0059 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-custom.png differ diff --git a/rtdata/images/Dark/actions/wb-flash.png b/rtdata/images/Dark/actions/wb-flash.png new file mode 100644 index 000000000..5678dc496 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-flash.png differ diff --git a/rtdata/images/Dark/actions/wb-fluorescent.png b/rtdata/images/Dark/actions/wb-fluorescent.png new file mode 100644 index 000000000..9294a3fcb Binary files /dev/null and b/rtdata/images/Dark/actions/wb-fluorescent.png differ diff --git a/rtdata/images/Dark/actions/wb-lamp.png b/rtdata/images/Dark/actions/wb-lamp.png new file mode 100644 index 000000000..c07f3b36c Binary files /dev/null and b/rtdata/images/Dark/actions/wb-lamp.png differ diff --git a/rtdata/images/Dark/actions/wb-led.png b/rtdata/images/Dark/actions/wb-led.png new file mode 100644 index 000000000..5d5f9c593 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-led.png differ diff --git a/rtdata/images/Dark/actions/wb-shade.png b/rtdata/images/Dark/actions/wb-shade.png new file mode 100644 index 000000000..ffdb5fbb7 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-shade.png differ diff --git a/rtdata/images/Dark/actions/wb-sun.png b/rtdata/images/Dark/actions/wb-sun.png new file mode 100644 index 000000000..17dc495b2 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-sun.png differ diff --git a/rtdata/images/Dark/actions/wb-tungsten.png b/rtdata/images/Dark/actions/wb-tungsten.png new file mode 100644 index 000000000..fe388c48d Binary files /dev/null and b/rtdata/images/Dark/actions/wb-tungsten.png differ diff --git a/rtdata/images/Light/actions/wb-auto.png b/rtdata/images/Light/actions/wb-auto.png new file mode 100644 index 000000000..2decab69d Binary files /dev/null and b/rtdata/images/Light/actions/wb-auto.png differ diff --git a/rtdata/images/Light/actions/wb-camera.png b/rtdata/images/Light/actions/wb-camera.png new file mode 100644 index 000000000..088a00d39 Binary files /dev/null and b/rtdata/images/Light/actions/wb-camera.png differ diff --git a/rtdata/images/Light/actions/wb-cloudy.png b/rtdata/images/Light/actions/wb-cloudy.png new file mode 100644 index 000000000..0271e9783 Binary files /dev/null and b/rtdata/images/Light/actions/wb-cloudy.png differ diff --git a/rtdata/images/Light/actions/wb-custom.png b/rtdata/images/Light/actions/wb-custom.png new file mode 100644 index 000000000..020971e9d Binary files /dev/null and b/rtdata/images/Light/actions/wb-custom.png differ diff --git a/rtdata/images/Light/actions/wb-flash.png b/rtdata/images/Light/actions/wb-flash.png new file mode 100644 index 000000000..98d055fd2 Binary files /dev/null and b/rtdata/images/Light/actions/wb-flash.png differ diff --git a/rtdata/images/Light/actions/wb-fluorescent.png b/rtdata/images/Light/actions/wb-fluorescent.png new file mode 100644 index 000000000..7b18e38e7 Binary files /dev/null and b/rtdata/images/Light/actions/wb-fluorescent.png differ diff --git a/rtdata/images/Light/actions/wb-lamp.png b/rtdata/images/Light/actions/wb-lamp.png new file mode 100644 index 000000000..31b124269 Binary files /dev/null and b/rtdata/images/Light/actions/wb-lamp.png differ diff --git a/rtdata/images/Light/actions/wb-led.png b/rtdata/images/Light/actions/wb-led.png new file mode 100644 index 000000000..d1f7f0552 Binary files /dev/null and b/rtdata/images/Light/actions/wb-led.png differ diff --git a/rtdata/images/Light/actions/wb-shade.png b/rtdata/images/Light/actions/wb-shade.png new file mode 100644 index 000000000..17b98bb83 Binary files /dev/null and b/rtdata/images/Light/actions/wb-shade.png differ diff --git a/rtdata/images/Light/actions/wb-sun.png b/rtdata/images/Light/actions/wb-sun.png new file mode 100644 index 000000000..8d08df721 Binary files /dev/null and b/rtdata/images/Light/actions/wb-sun.png differ diff --git a/rtdata/images/Light/actions/wb-tungsten.png b/rtdata/images/Light/actions/wb-tungsten.png new file mode 100644 index 000000000..646db7706 Binary files /dev/null and b/rtdata/images/Light/actions/wb-tungsten.png differ diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index 8b87e5b50..b94d205ad 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -600,7 +600,7 @@ PREFERENCES_DIRSOFTWARE;Dossier d'installation PREFERENCES_EDITORCMDLINE;Autre ligne de commande PREFERENCES_EDITORLAYOUT;Disposition de l'éditeur PREFERENCES_EXTERNALEDITOR;Éditeur externe -PREFERENCES_FBROWSEROPTS;Options du navigateur de fichiers +PREFERENCES_FBROWSEROPTS;Options du navigateur de fichiers et de vignettes PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Barre de menu de l'explorateur de fichiers uni-ligne (à désactiver pour les écrans de faible résolution) PREFERENCES_FILEFORMAT;Format du fichier PREFERENCES_FLATFIELDAUTOSELECT;Sélection auto. du Champ Uniforme @@ -996,13 +996,45 @@ TP_VIGNETTING_RADIUS;Rayon TP_VIGNETTING_STRENGTH;Force TP_WBALANCE_AUTO;Auto TP_WBALANCE_CAMERA;Appareil photo +TP_WBALANCE_CLOUDY;Nuageux TP_WBALANCE_CUSTOM;Personnalisé +TP_WBALANCE_FLASH_HEADER;Flash +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLUO1;F1 - Lumière du jour +TP_WBALANCE_FLUO2;F2 - Blanc froid +TP_WBALANCE_FLUO3;F3 - Blanc +TP_WBALANCE_FLUO4;F4 - Blanc chaud +TP_WBALANCE_FLUO5;F5 - Lumière du jour +TP_WBALANCE_FLUO6;F6 - Blanc lumineux +TP_WBALANCE_FLUO7;F7 - D65 Lumière du jour +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Blanc froid deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescent TP_WBALANCE_GREEN;Teinte +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII TP_WBALANCE_LABEL;Balance des blancs +TP_WBALANCE_LAMP_HEADER;Lampe +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 TP_WBALANCE_METHOD;Méthode +TP_WBALANCE_SHADE;Ombre TP_WBALANCE_SIZE;Taille: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (fabricant) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) TP_WBALANCE_SPOTWB;Point de mesure +TP_WBALANCE_DAYLIGHT;Lumière du jour (ensoleillé) TP_WBALANCE_TEMPERATURE;Température +TP_WBALANCE_TUNGSTEN;Tungstène ZOOMBAR_DETAIL;Détail ZOOMBAR_HUGE;Énorme ZOOMBAR_LARGE;Large diff --git a/rtdata/languages/default b/rtdata/languages/default index c6ea80166..f783845ca 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1011,13 +1011,45 @@ TP_VIGNETTING_RADIUS;Radius TP_VIGNETTING_STRENGTH;Strength TP_WBALANCE_AUTO;Auto TP_WBALANCE_CAMERA;Camera +TP_WBALANCE_CLOUDY;Cloudy TP_WBALANCE_CUSTOM;Custom +TP_WBALANCE_FLASH_HEADER;Flash +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLUO1;F1 - Daylight +TP_WBALANCE_FLUO2;F2 - Cool white +TP_WBALANCE_FLUO3;F3 - White +TP_WBALANCE_FLUO4;F4 - Warm white +TP_WBALANCE_FLUO5;F5 - Daylight +TP_WBALANCE_FLUO6;F6 - Lite white +TP_WBALANCE_FLUO7;F7 - D65 Daylight simulator +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Cool white deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescent TP_WBALANCE_GREEN;Tint +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII TP_WBALANCE_LABEL;White Balance +TP_WBALANCE_LAMP_HEADER;Lamp +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 TP_WBALANCE_METHOD;Method +TP_WBALANCE_SHADE;Shade TP_WBALANCE_SIZE;Size: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) TP_WBALANCE_SPOTWB;Spot WB +TP_WBALANCE_DAYLIGHT;Daylight (sunny) TP_WBALANCE_TEMPERATURE;Temperature +TP_WBALANCE_TUNGSTEN;Tungsten ZOOMBAR_DETAIL;Detail ZOOMBAR_HUGE;Huge ZOOMBAR_LARGE;Large diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index de5dbc218..4bb27d709 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -18,10 +18,15 @@ */ #include #include +#include +#include +#include -using namespace rtengine; +namespace rtengine { -ColorTemp::ColorTemp (double t, double g) : temp(t), green(g) { +extern const Settings* settings; + +ColorTemp::ColorTemp (double t, double g, Glib::ustring m) : temp(t), green(g), method(m) { clip (temp, green); } @@ -39,50 +44,534 @@ void ColorTemp::clip (double &temp, double &green) { green = MAXGREEN; } +ColorTemp::ColorTemp (double mulr, double mulg, double mulb) { + method = "Custom"; + mul2temp (mulr, mulg, mulb, temp, green); +} + void ColorTemp::mul2temp (double rmul, double gmul, double bmul, double& temp, double& green) { - double maxtemp=20000, mintemp=1000; + double maxtemp=(double)MAXTEMP, mintemp=(double)MINTEMP; double tmpr, tmpg, tmpb; temp=(maxtemp+mintemp)/2; + while (maxtemp-mintemp>1) { - temp2mul (temp, 1.0, tmpr, tmpg, tmpb); - if (tmpb/tmpr > bmul/rmul) - maxtemp = temp; - else - mintemp = temp; + temp2mul (temp, 1.0, tmpr, tmpg, tmpb); + if (tmpb/tmpr > bmul/rmul) + maxtemp = temp; + else + mintemp = temp; temp=(maxtemp+mintemp)/2; } green = (tmpg/tmpr) / (gmul/rmul); clip (temp, green); } +/* + Calculate Planck's radiation +*/ + //calculate spectral data for blackbody at temp! +double ColorTemp::blackbody_spect(double wavelength, double m1, double m2, double temp) +{ + double wlm = wavelength * 1e-9; /* Wavelength in meters */ + return (3.7417715247e-16 * pow(wlm, -5.0)) / //3.7417..= c1 = 2*Pi*h*c2 where h=Planck constant, c=velocity of light + (exp(1.438786e-2 / (wlm * temp)) - 1.0); //1.4387..= c2 = h*c/k where k=Boltzmann constant +} + +void ColorTemp::spectrum_to_xyz(double (*spec_intens)(double wavelength, double m1, double m2, double temp), double _m1, double _m2, double _temp, double &x, double &y, double &z) +{ + int i; + double lambda, X = 0, Y = 0, Z = 0, XYZ; + +/* + Inspired from: + + a) Colour Rendering of Spectra by John Walker + http://www.fourmilab.ch/ + This program is in the public domain. + + b) Bruce Lindbloom + Adapted to Rawtherapee by J.Desmis + + this values are often called xBar yBar zBar and are characteristics of a color / illuminant + + values cie_colour_match[][3] = Observer 2° x2, y2, z2 + E.g. for 380nm: x2=0.001368 y2=0.000039 z2=0.00645 round in J.Walker to 0.0014 0.0000 0.0065 above + I have increase precision used by J.Walker and pass to 350nm to 830nm +*/ + + static const double cie_colour_match[97][3] = {//350nm to 830nm + {0.0000000,0.000000,0.000000}, {0.0000000,0.000000,0.000000}, {0.0001299,0.000392,0.000606}, + {0.0002321,0.000007,0.001086}, {0.0004149,0.000012,0.001946}, {0.0007416,0.000022,0.003846}, + {0.001368,0.000039,0.006450}, {0.002236,0.000064,0.010550}, {0.004243,0.000120,0.020050}, + {0.007650,0.000217,0.036210}, {0.014310,0.000396,0.067850}, {0.023190,0.000640,0.110200}, + {0.043510,0.001210,0.207400}, {0.077630,0.002180,0.371300}, {0.134380,0.004000,0.645600}, + {0.214770,0.007300,1.039050}, {0.283900,0.011600,1.385600}, {0.328500,0.016840,1.622960}, + {0.348280,0.023000,1.747100}, {0.348060,0.029800,1.782600}, {0.336200,0.038000,1.772110}, + {0.318700,0.048000,1.744100}, {0.290800,0.060000,1.669200}, {0.251100,0.073900,1.528100}, + {0.195360,0.090980,1.287640}, {0.142100,0.112600,1.041900}, {0.095640,0.139020,0.812950}, + {0.057950,0.169300,0.616200}, {0.032010,0.208020,0.465180}, {0.014700,0.258600,0.353300}, + {0.004900,0.323000,0.272000}, {0.002400,0.407300,0.212300}, {0.009300,0.503000,0.158200}, + {0.029100,0.608200,0.111700}, {0.063270,0.710000,0.078250}, {0.109600,0.793200,0.057250}, + {0.165500,0.862000,0.042160}, {0.225750,0.914850,0.029840}, {0.290400,0.954000,0.020300}, + {0.359700,0.980300,0.013400}, {0.433450,0.994950,0.008750}, {0.512050,1.000000,0.005750}, + {0.594500,0.995000,0.003900}, {0.678400,0.978600,0.002750}, {0.762100,0.952000,0.002100}, + {0.842500,0.915400,0.001800}, {0.916300,0.870000,0.001650}, {0.978600,0.816300,0.001400}, + {1.026300,0.757000,0.001100}, {1.056700,0.694900,0.001000}, {1.062200,0.631000,0.000800}, + {1.045600,0.566800,0.000600}, {1.002600,0.503000,0.000340}, {0.938400,0.441200,0.000240}, + {0.854450,0.381000,0.000190}, {0.751400,0.321000,0.000100}, {0.642400,0.265000,0.000050}, + {0.541900,0.217000,0.000030}, {0.447900,0.175000,0.000020}, {0.360800,0.138200,0.000010}, + {0.283500,0.107000,0.000000}, {0.218700,0.081600,0.000000}, {0.164900,0.061000,0.000000}, + {0.121200,0.044580,0.000000}, {0.087400,0.032000,0.000000}, {0.063600,0.023200,0.000000}, + {0.046770,0.017000,0.000000}, {0.032900,0.011920,0.000000}, {0.022700,0.008210,0.000000}, + {0.015840,0.005723,0.000000}, {0.011359,0.004102,0.000000}, {0.008111,0.002929,0.000000}, + {0.005790,0.002091,0.000000}, {0.004109,0.001484,0.000000}, {0.002899,0.001047,0.000000}, + {0.002049,0.000740,0.000000}, {0.001440,0.000520,0.000000}, {0.001000,0.000361,0.000000}, + {0.000690,0.000249,0.000000}, {0.000476,0.000172,0.000000}, {0.000332,0.000120,0.000000}, + {0.000235,0.000085,0.000000}, {0.000166,0.000060,0.000000}, {0.000117,0.000042,0.000000}, + {0.000083,0.000030,0.000000}, {0.000059,0.000021,0.000000}, {0.000042,0.000015,0.000000}, + {0.000029,0.000011,0.000000}, {0.000021,0.000007,0.000000}, {0.000015,0.000005,0.000000}, + {0.000010,0.000004,0.000000}, {0.000007,0.000003,0.000000}, {0.000005,0.000002,0.000000}, + {0.000004,0.000001,0.000000}, {0.000003,0.000001,0.000000}, {0.000002,0.000001,0.000000}, + {0.000001,0.000001,0.000000} + }; + + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + + double Me; + + Me = (*spec_intens)(lambda, _m1, _m2, _temp); + X += Me * cie_colour_match[i][0]; + Y += Me * cie_colour_match[i][1]; + Z += Me * cie_colour_match[i][2]; + } + XYZ = (X + Y + Z); + x = X / XYZ; + y = Y / XYZ; + z = Z / XYZ; +} + +double ColorTemp::daylight_spect(double wavelength, double m1, double m2, double temp) +{ + //Values for Daylight illuminant: s0 s1 s2 + //s0 + static const double s0[97]={61.80,61.65,61.50,65.15,68.80,66.10,63.40,64.60,65.80,80.30,94.80,99.80,104.80,105.35,105.90,101.35,96.80,105.35,113.90,119.75,125.60,125.55,125.50,123.40,121.30,121.30,121.30,117.40,113.50,113.30, + 113.10,111.95,110.80,108.65,106.50,107.65,108.80,107.05,105.30,104.85,104.40,102.20,100.00,98.00,96.00,95.55,95.10,92.10,89.10,89.80,90.50,90.40,90.30,89.35,88.40,86.20,84.00,84.55,85.10, + 83.50,81.90,82.25,82.60,83.75,84.90,83.10,81.30,76.60,71.90,73.10,74.30,75.35,76.40,69.85,63.30,67.50,71.70,74.35,77.00,71.10,65.20,56.45,47.70,58.15,68.60,66.80,65.00,65.50,66.00,63.50,61.00,57.15, + 53.30,56.10,58.90,60.40,61.90}; + //s1 + static const double s1[97]={41.60,39.80,38.00,40.70,43.40,40.95,38.50,36.75,35.00,39.20,43.40,44.85,46.30,45.10,43.90,40.50,37.10,36.90,36.70,36.30,35.90,34.25,32.60,30.25,27.90,26.10,24.30,22.20,20.10,18.15,16.20,14.70, + 13.20,10.90,8.60,7.35,6.10,5.15,4.20,3.05,1.90,0.95,0.00,-0.80,-1.60,-2.55,-3.50,-3.50,-3.50,-4.65,-5.80,-6.50,-7.20,-7.90,-8.60,-9.05,-9.50,-10.20,-10.90,-10.80,-10.70,-11.35,-12.00,-13.00,-14.00, + -13.80,-13.60,-12.80,-12.00,-12.65,-13.30,-13.10,-12.90,-11.75,-10.60,-11.10,-11.60,-11.90,-12.20,-11.20,-10.20,-9.00,-7.80,-9.50,-11.20,-10.80,-10.50,-10.60,-10.15,-9.70,-9.00,-8.30, + -8.80,-9.30,-9.55,-9.80}; + //s2 + static const double s2[97]={6.70,6.00,5.30,5.70,6.10,4.55,3.00,2.10,1.20,0.05,-1.10,-0.80,-0.50,-0.60,-0.70,-0.95,-1.20,-1.90,-2.60,-2.75,-2.90,-2.85,-2.80,-2.70,-2.60,-2.60,-2.60,-2.20,-1.80,-1.65,-1.50,-1.40,-1.30, + -1.25,-1.20,-1.10,-1.00,-0.75,-0.50,-0.40,-0.30,-0.15,0.00,0.10,0.20,0.35,0.50,1.30,2.10,2.65,3.65,4.10,4.40,4.70,4.90,5.10,5.90,6.70,7.00,7.30,7.95,8.60,9.20,9.80,10.00,10.20,9.25,8.30,8.95, + 9.60,9.05,8.50,7.75,7.00,7.30,7.60,7.80,8.00,7.35,6.70,5.95,5.20,6.30,7.40,7.10,6.80,6.90,7.00,6.70,6.40,5.95,5.50,5.80,6.10,6.30,6.50}; + + int wlm = (int) ((wavelength -350.)/5.); + return (s0[wlm]+m1*s1[wlm]+m2*s2[wlm]); +} + +// spectral data for Daylight direct Sun: I have choose 5300K beacuse Nikon=5200K, Olympus=5300K, Panasonic=5500K, Leica=5400K, Minolta=5100K +double ColorTemp::Daylight5300_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Su53[97]={24.82,26.27,27.72,28.97,30.22,29.71,29.19,31.95,34.71,45.49,56.26,59.97,63.68,65.30,66.92,65.39,63.86,72.59,81.32,87.53,93.73,95.15,96.56,96.55,96.54,98.13,99.73,97.70,95.66,97.19,98.72, + 98.90,99.08,98.98,98.87,101.13,103.39,102.48,101.57,102.14,102.71,101.36,100.00,98.71,97.42,97.81,98.21,95.20,92.20,93.92,95.63,96.15,96.67,96.34,96.01,94.21,92.41,93.58,94.74,93.05,91.36,92.29, + 93.21,95.25,97.28,95.30,93.32,87.92,82.51,84.29,86.06,86.94,87.81,80.24,72.68,77.32,81.96,84.88,87.79,81.01,74.22,64.41,54.60,66.55,78.51,76.35,74.20,74.79,75.38,72.48,69.58,65.11,60.64, + 63.88,67.13,68.85,70.57}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Su53[wlm]); +} + +//spectral data for Daylight Cloudy: I have choose 6200K beacuse Nikon=6000K, Olympus=6000K, Panasonic=6200K, Leica=6400K, Minolta=6500K +double ColorTemp::Cloudy6200_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Clo62[97]={39.50,40.57,41.63,43.85,46.08,45.38,44.69,47.20,49.71,63.06,76.41,80.59,84.77,85.91,87.05,84.14,81.23,90.29,99.35,105.47,111.58,112.23,112.87,111.74,110.62,111.41,112.20,108.98,105.76,106.32, + 106.89,106.34,105.79,104.62,103.45,105.09,106.72,105.24,103.76,103.75,103.75,101.87,100.00,98.29,96.58,96.46,96.34,92.85,89.37,90.25,91.12,91.06,90.99,90.17,89.35,87.22,85.10,85.48,85.85, + 84.03,82.20,82.45,82.69,83.92,85.15,83.14,81.13,76.65,72.17,73.27,74.36,75.65,76.95,70.34,63.74,67.98,72.22,74.88,77.54,71.59,65.65,56.82,47.99,58.53,69.06,67.27,65.47,65.96,66.44,63.92,61.41,57.52, + 53.63,56.47,59.31,60.80,62.29}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Clo62[wlm]); +} + +//spectral data for Daylight Shade: I have choose 7600K beacuse Nikon=8000K, Olympus=7500K, Panasonic=7500K, Leica=7500K, Minolta=7500K +double ColorTemp::Shade7600_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Sha76[97]={64.42,64.46,64.51,68.35,72.20,70.22,68.24,69.79,71.35,87.49,103.64,108.68,113.72,114.12,114.53,109.54,104.55,113.59,122.63,128.52,134.41,134.02,133.63,131.02,128.41,128.08,127.75,123.16, + 118.57,117.89,117.22,115.72,114.22,111.60,108.99,109.84,110.68,108.57,106.45,105.71,104.98,102.49,100.00,97.78,95.55,94.82,94.08,90.47,86.87,86.94,87.01,86.45,85.88,84.57,83.27,80.83,78.40,78.21, + 78.03,76.22,74.42,74.15,73.89,74.41,74.92,73.01,71.09,67.26,63.42,64.01,64.60,66.10,67.60,61.83,56.06,59.94,63.82,66.27,68.71,63.49,58.26,50.30,42.34,51.64,60.95,59.45,57.95,58.35,58.76,56.57, + 54.38,51.00,47.62,50.10,52.58,53.88,55.19}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Sha76[wlm]); +} + +//spectral data for tungsten - incandescent 2856K +double ColorTemp::A2856_spect(double wavelength, double m1, double m2, double temp) +{ + static const double A2856[97]={4.75,5.42,6.15,6.95,7.83,8.78,9.80,10.91,12.09,13.36,14.72,16.16,17.69,19.30,21.01,22.80,24.68,26.65,28.71,30.86,33.10,35.42,37.82,40.31,42.88,45.53,48.25,51.05,53.92,56.87,59.87,62.94,66.07,69.26,72.50, + 75.80,79.14,82.53,85.95,89.42,92.91,96.44,100.00,103.58,107.18,110.80,114.43,118.07,121.72,125.38,129.03,132.68,136.33,139.97,143.60,147.21,150.81,154.39,157.95,161.48,164.99,168.47,171.92,175.34, + 178.72,182.07,185.38,188.65,191.88,195.06,198.20,201.30,204.34,207.34,210.29,213.19,216.04,218.84,221.58,224.28,226.91,229.49,232.02,234.49,236.91,239.27,241.57,243.82,246.01,248.14,250.21,252.23,254.19, + 256.10,257.95,259.74,261.47}; + + int wlm = (int) ((wavelength -350.)/5.); + return (A2856[wlm]); +} + +//spectral data for fluo F1 Daylight 6430K +double ColorTemp::FluoF1_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF1[97]={0.0,0.0,0.0,0.0,0.0,0.0,1.87,2.36,2.94,3.47,5.17,19.49,6.13,6.24,7.01,7.79,8.56,43.67,16.94,10.72,11.35,11.89,12.37,12.75,13.00,13.15,13.23,13.17,13.13,12.85,12.52, + 12.20,11.83,11.50,11.22,11.05,11.03,11.18,11.53,27.74,17.05,13.55,14.33,15.01,15.52,18.29,19.55,15.48,14.91,14.15,13.22,12.19,11.12,10.03,8.95,7.96,7.02,6.20,5.42,4.73,4.15,3.64,3.20,2.81, + 2.47,2.18,1.93,1.72,1.67,1.43,1.29,1.19,1.08,0.96,0.88,0.81,0.77,0.75,0.73,0.68,0.69,0.64,0.68,0.69,0.61,0.52,0.43,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF1[wlm]); +} + +//spectral data for fluo F2 Cool white 4230K +double ColorTemp::FluoF2_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF2[97]={0.0,0.0,0.0,0.0,0.0,0.0,1.18,1.48,1.84,2.15,3.44,15.69,3.85,3.74,4.19,4.62,5.06,34.98,11.81,6.27,6.63,6.93,7.19,7.40,7.54,7.62,7.65,7.62,7.62,7.45,7.28,7.15,7.05,7.04,7.16,7.47,8.04,8.88,10.01,24.88,16.64,14.59,16.16,17.60,18.62,21.47,22.79,19.29,18.66,17.73,16.54,15.21,13.80,12.36,10.95,9.65,8.40,7.32,6.31,5.43,4.68,4.02,3.45, + 2.96,2.55,2.19,1.89,1.64,1.53,1.27,1.10,0.99,0.88,0.76,0.68,0.61,0.56,0.54,0.51,0.47,0.47,0.43,0.46,0.47,0.40,0.33,0.27,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF2[wlm]); +} + +//spectral data for fluo F3 White 3450K +double ColorTemp::FluoF3_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF3[97]={0.0,0.0,0.0,0.0,0.0,0.0,0.82,1.02,1.26,1.44,2.57,14.36,2.70,2.45,2.73,3.00,3.28,31.85,9.47,4.02,4.25,4.44,4.59,4.72,4.80,4.86,4.87,4.85,4.88,4.77,4.67,4.62,4.62,4.73,4.99,5.48,6.25, + 7.34,8.78,23.82,16.14,14.59,16.63,18.49,19.95,23.11,24.69,21.41,20.85,19.93,18.67,17.22,15.65,14.04,12.45,10.95,9.51,8.27,7.11,6.09,5.22,4.45,3.80,3.23,2.75,2.33,1.99,1.70,1.55, + 1.27,1.09,0.96,0.83,0.71,0.62,0.54,0.49,0.46,0.43,0.39,0.39,0.35,0.38,0.39,0.33,0.28,0.21,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF3[wlm]); +} + +//spectral data for fluo F4 Warm white 2940K +double ColorTemp::FluoF4_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF4[97]={0.0,0.0,0.0,0.0,0.0,0.0,0.57,0.70,0.87,0.98,2.01,13.75,1.95,1.59,1.76,1.93,2.10,30.28,8.03,2.55,2.70,2.82,2.91,2.99,3.04,3.08,3.09,3.09,3.14,3.06,3.00,2.98,3.01, + 3.14,3.41,3.90,4.69,5.81,7.32,22.59,15.11,13.88,16.33,18.68,20.64,24.28,26.26,23.28,22.94,22.14,20.91,19.43,17.74,16.00,14.42,12.56,10.93,9.52,8.18,7.01,6.00,5.11,4.36,3.69,3.13,2.64, + 2.24,1.91,1.70,1.39,1.18,1.03,0.88,0.74,0.64,0.54,0.49,0.46,0.42,0.37,0.37,0.33,0.35,0.36,0.31,0.26,0.19,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF4[wlm]); +} + +//spectral data for fluo F5 Daylight 6350K +double ColorTemp::FluoF5_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF5[97]={0.0,0.0,0.0,0.0,0.0,0.0,1.87,2.35,2.92,3.45,5.10,18.91,6.00,6.11,6.85,7.58,8.31,40.76,16.06,10.32,10.91,11.40,11.83,12.17,12.40,12.54,12.58,12.52,12.47,12.20,11.89, + 11.61,11.33,11.10,10.96,10.97,11.16,11.54,12.12,27.78,17.73,14.47,15.20,15.77,16.10,18.54,19.50,15.39,14.64,13.72,12.69,11.57,10.45,9.35,8.29,7.32,6.41,5.63,4.90,4.26, + 3.72,3.25,2.83,2.49,2.19,1.93,1.71,1.52,1.43,1.26,1.13,1.05,0.96,0.85,0.78,0.72,0.68,0.67,0.65,0.61,0.62,0.59,0.62,0.64,0.55,0.47,0.40,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF5[wlm]); +} + +//spectral data for fluo F6 Lite white 4150K +double ColorTemp::FluoF6_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF6[97]={0.0,0.0,0.0,0.0,0.0,0.0,1.05,1.31,1.63,1.90,3.11,14.8,3.43,3.30,3.68,4.07,4.45,32.61,10.74,5.48,5.78,6.03,6.25,6.41,6.52,6.58,6.59,6.56,6.56,6.42,6.28,6.20,6.19,6.30,6.60,7.12,7.94,9.07,10.49,25.22,17.46,15.63,17.22,18.53, + 19.43,21.97,23.01,19.41,18.56,17.42,16.09,14.64,13.15,11.68,10.25,8.96,7.74,6.69,5.71,4.87,4.16,3.55,3.02,2.57,2.20,1.87,1.60,1.37,1.29,1.05,0.91,0.81,0.71,0.61,0.54,0.48,0.44, + 0.43,0.40,0.37,0.38,0.35,0.39,0.41,0.33,0.26,0.21,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF6[wlm]); +} + +//spectral data for fluo F7 D65 Daylight simulator 6500K +double ColorTemp::FluoF7_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF7[97]={0.0,0.0,0.0,0.0,0.0,0.0,2.56,3.18,3.84,4.53,6.15,19.37,7.37,7.05,7.71,8.41,9.15,44.14,17.52,11.35,12.00,12.58,13.08,13.45,13.71,13.88,13.95,13.93,13.82,13.64,13.43,13.25,13.08,12.93,12.78,12.60, + 12.44,12.33,12.26,29.52,17.05,12.44,12.58,12.72,12.83,15.46,16.75,12.83,12.67,12.43,12.19,11.89,11.60,11.35,11.12,10.95,10.76,10.42,10.11,10.04,10.02,10.11,9.87,8.65,7.27,6.44,5.83,5.41, + 5.04,4.57,4.12,3.77,3.46,3.08,2.73,2.47,2.25,2.06,1.90,1.75,1.62,1.54,1.45,1.32,1.17,0.99,0.81,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF7[wlm]); +} + +//spectral data for fluo F8 D50 simulator Sylvania F40 Design 5000K +double ColorTemp::FluoF8_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF8[97]={0.0,0.0,0.0,0.0,0.0,0.0,1.21,1.5,1.81,2.13,3.17,13.08,3.83,3.45,3.86,4.42,5.09,34.1,12.42,7.68,8.60,9.46,10.24,10.84,11.33,11.71,11.98,12.17,12.28,12.32,12.35,12.44,12.55,12.68,12.77,12.72, + 12.60,12.43,12.22,28.96,16.51,11.79,11.76,11.77,11.84,14.61,16.11,12.34,13.61,13.87,14.07,14.20,14.16,14.13,14.34,14.50,14.46,14.00,12.58,10.99,9.98,9.22,8.62,8.07,7.39,6.71,6.16,5.63,5.03,4.46,4.02,3.66, + 3.36,3.09,2.85,2.65,2.51,2.37,2.15,1.89,1.61,1.32,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF8[wlm]); +} + +//spectral data for fluo F9 Cool white deluxe 4150K +double ColorTemp::FluoF9_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF9[97]={0.0,0.0,0.0,0.0,0.0,0.0,0.9,1.12,1.36,1.60,2.59,12.8,3.05,2.56,2.86,3.30,3.82,32.62,10.77,5.84,6.57,7.25,7.86,8.35,8.75,9.06,9.31,9.48,9.61,9.68,10.04,10.26,10.48,10.63,10.76,10.96, + 11.18,27.71,16.29,12.28,12.74,13.21,13.65,16.57,18.14,14.55,14.65,14.66,14.61,14.50,14.39,14.40,14.47,14.62,14.72,14.55,14.4,14.58,14.88,15.51,15.47,13.20,10.57,9.18,8.25,7.57,7.03, + 6.35,5.72,5.25,4.80,4.29,3.80,3.43,3.12,2.86,2.64,2.43,2.26,2.14,2.02,1.83,1.61,1.38,1.12,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF9[wlm]); +} + +//spectral data for fluo F10 Philips TL85 - 5000K +double ColorTemp::FluoF10_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF10[97]={0.0,0.0,0.0,0.0,0.0,0.0,1.11,0.63,0.62,0.57,1.48,12.16,2.12,2.70,3.74,5.14,6.75,34.39,14.86,10.4,10.76,10.11,9.27,8.29,7.29,7.91,16.64,16.73,10.44,5.94,3.34,2.35,1.88,1.59,1.47, + 1.80,5.71,40.98,73.69,33.61,8.24,3.38,2.47,4.86,11.45,14.79,12.16,8.97,6.52,8.81,44.12,34.55,12.09,12.15,10.52,4.43,1.95,2.19,3.19,2.77,2.29,2.00,1.52,1.35,1.47,1.79,1.74,1.02,1.14, + 3.32,4.49,2.05,0.49,0.24,0.21,0.21,0.24,0.24,0.21,0.17,0.21,0.22,0.17,0.12,0.09,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF10[wlm]); +} + +//spectral data for fluo F11 Philips TL84 4150K +double ColorTemp::FluoF11_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF11[97]={0.0,0.0,0.0,0.0,0.0,0.0,0.91,0.63,0.46,0.37,1.29,12.68,1.59,1.79,2.46,3.38,4.49,33.94,12.13,6.95,7.19,7.12,6.72,6.13,5.46,4.79,5.66,14.29,14.96,8.97,4.72,2.33,1.47,1.10,0.89,0.83,1.18,4.90,39.59, + 72.84,32.61,7.52,2.83,1.96,1.67,4.43,11.28,14.76,12.73,9.74,7.33,9.72,55.27,42.58,13.18,13.16,12.26,5.11,2.07,2.34,3.58,3.01,2.48,2.14,1.54,1.33,1.46,1.94,2.00,1.20,1.35,4.10,5.58, + 2.51,0.57,0.27,0.23,0.21,0.24,0.24,0.20,0.24,0.32,0.26,0.16,0.12,0.09,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF11[wlm]); +} + +//spectral data for fluo F12 Philips TL83 3000K +double ColorTemp::FluoF12_spect(double wavelength, double m1, double m2, double temp) +{ + static const double fluoF12[97]={0.0,0.0,0.0,0.0,0.0,0.0,0.96,0.64,0.45,0.33,1.19,12.48,1.12,0.94,1.08,1.37,1.78,29.05,7.90,2.65,2.71,2.65,2.49,2.33,2.10,1.91,3.01,10.83,11.88,6.88,3.43,1.49,0.92,0.71,0.60,0.63,1.10,4.56,34.4,65.40,29.48, + 7.16,3.08,2.47,2.27,5.09,11.96,15.32,14.27,11.86,9.28,12.31,68.53,53.02,14.67,14.38,14.71,6.46,2.57,2.75,4.18,3.44,2.81,2.42,1.64,1.36,1.49,2.14,2.34,1.42,1.61,5.04,6.98,3.19,0.71,0.30,0.26,0.23,0.28,0.28,0.21, + 0.17,0.21,0.19,0.15,0.10,0.05,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (fluoF12[wlm]); +} + +//spectral data for HMI lamp studio "Osram" 4800K (for film, spectacle, studio...) +double ColorTemp::HMI_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Hmi[97]={0.0,0.0,0.0,0.0,0.0,0.0,9.66,11.45,13.24,14.93,16.63,17.90,19.20,20.12,21.03,23.84,26.65,26.38,26.12,26.52,27.92,31.15,34.37,34.98,35.61,35.71,35.81,34.90,34.02,34.06,34.08,34.68,35.28,34.72,34.20,33.63, + 33.05,34.70,36.35,38.01,39.48,37.29,35.10,36.22,37.28,38.76,40.24,39.56,38.90,39.35,39.79,38.90,38.01,38.05,38.10,37.45,36.64,35.82,35.00,35.06,33.13,33.85,34.55,35.26,35.77,34.92, + 34.09,33.40,32.72,32.08,31.45,26.83,22.23,21.50,20.79,21.41,22.03,11.01,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Hmi[wlm]); +} + +//spectral data for GTI lamp : Graphiclite & ColorMatch for Photography 5000K +double ColorTemp::GTI_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Gti[97]={0.0,0.0,0.0,0.0,0.0,0.0,3.26,4.71,6.17,12.71,19.27,20.53,21.80,19.15,16.53,28.25,39.97,48.52,57.06,43.66,30.27,30.22,30.16,31.48,32.98,34.01,35.04,35.83,36.62,37.12,37.62,37.99,38.19,38.29,38.48, + 38.82,39.16,45.40,51.63,51.83,62.04,52.41,42.80,42.95,43.09,45.64,48.20,46.23,44.27,43.74,43.22,43.30,43.41,43.10,42.78,42.03,41.29,40.29,39.29,37.89,36.58,34.92,33.27,31.47,29.68,27.90, + 26.13,24.55,22.98,21.42,19.86,18.40,16.92,14.46,13.99,12.36,11.73,5.86,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Gti[wlm]); +} + +//spectral data for JudgeIII Lamp D50 +double ColorTemp::JudgeIII_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Jud[97]={0.0,0.0,0.0,0.0,0.0,0.0,4.08,4.25,4.43,6.90,9.40,9.75,10.11,9.30,8.54,14.90,21.16,26.01,30.83,24.90,19.00,19.00,19.00,19.56,20.13,20.28,20.44,20.64,20.85,21.05,21.24,21.65,22.11,22.85,23.58,24.00,24.43, + 27.75,31.27,33.90,36.59,30.90,25.32,25.05,24.76,26.03,27.31,25.90,24.48,23.85,23.29,23.10,22.94,23.24,23.53,24.02,24.52,23.80,23.13,24.51,25.76,27.90,29.15,24.70,20.25,16.60,12.98,11.63,10.27,9.30,8.34, + 7.60,6.91,6.25,5.67,5.15,4.68,2.34,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Jud[wlm]); +} + +//spectral data for Solux lamp : 3500K +double ColorTemp::Solux3500_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Solux35[97]={0.5268,0.93,1.3278,1.51,1.6987,2.65,3.6100,3.80,3.9927,6.08,8.1680,11.02,13.863,15.66,17.4600,18.78,20.130,21.43,22.749,24.02,25.290,27.40,29.504,31.77,34.031,36.35,38.672,40.55,42.426,44.15,45.865,47.37,48.879, + 49.71,50.531,51.2,51.872,51.9,51.928,52.97,54.015,55.93,57.846,60.25,62.650,64.36,66.065,66.72,67.369,68.81,70.260,71.37,72.487,72.53,72.578,72.51,72.447,72.46,72.471, + 72.76,73.047,74.25,75.449,76.5,77.543,78.79,80.040,80.72,81.394,82.12,82.840,83.23,83.614,83.36,83.100,82.36,81.615,80.11,78.606,75.91,73.221,69.61,66.006,62.43,58.844,56.07,53.292, + 51.07,48.839,46.93,45.013,43.54,42.070,40.61,39.150,37.79,36.425}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Solux35[wlm]); +} + +//spectral data for Solux lamp : 4100K +double ColorTemp::Solux4100_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Solux41[97]={0.5717,0.70,0.8286,1.16,1.522,2.01,2.384,3.45,4.57,6.46,8.4548,11.31,14.205,16.10,17.949,19.51,21.068,22.60,24.197,25.37,26.566,28.15,29.742,30.90,32.060,33.26,34.481,34.80,35.130,35.42,35.697,36.20,36.763, + 37.90,39.004,40.26,41.494,43.10,44.690,45.80,46.900,47.45,47.885,47.75,47.635,47.00,46.410,46.22,46.058,46.70,47.344,48.65,50.005,51.02,52.045,53.55,55.075,55.98,56.823, + 56.85,56.884,56.15,55.523,54.60,53.732,52.55,51.425,50.30,49.1830,48.76,48.273,48.22,48.169,49.92,49.915,51.90,53.099,54.95,56.852,58.45,60.090,61.67,63.2530,63.55,63.834,63.55,63.468, + 62.40,61.373,59.75,58.1810,56.25,54.395,51.90,49.496,47.05,44.620}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Solux41[wlm]); +} + +//spectral data for Solux lamp : near Daylight (for example "musée d'Orsay..") - 4700K +double ColorTemp::Solux4700_spect(double wavelength, double m1, double m2, double temp) +{ + static const double Solux47[97]={0.4590,0.83,1.2011,1.53,1.8647,2.15,2.5338,3.06,3.5809,3.99,4.4137,4.82,5.2228,5.63,6.0387,6.53,6.9944,7.55,8.0266,8.475,8.9276,8.90,9.7840,10.20,10.6390,11.00,11.3600,11.75,12.1340,12.36,12.5880,12.74,12.8790, + 13.07,13.2560,13.38,13.5220,13.41,13.3070,13.35,13.3990,13.37,13.3420,13.39,13.4220,13.65,13.2710,13.25,13.2330,13.12,13.0110,12.93,12.8470,12.805,12.7630,12.66,12.5760,12.563,12.5490, + 12.59,12.6330,12.617,12.6010,12.616,12.6310,12.6275,12.6240,12.70,12.7710,12.776,12.7810,12.786,12.7950,12.74,12.6850,12.64,12.5950,12.55,12.5420,12.43,12.3180,12.07,11.8340,11.72,11.6190,11.55,11.5020, + 11.32,11.1510,11.05,10.9530,10.80,10.6550,10.495,10.4390,10.31,10.1790}; + + int wlm = (int) ((wavelength -350.)/5.); + return (Solux47[wlm]); +} + +//spectral data for Solux lamp : near Daylight 4400K - test National Gallery +double ColorTemp::NG_Solux4700_spect(double wavelength, double m1, double m2, double temp) +{ + static const double NGSolux[97]={0.0,0.0,0.0,0.0,0.0,0.0,139,152,170,185,202,223,240,257,270,282,293,305,317,329,342,355,367,378,387,395,401,405,408,411,414,415,416,415,414,414,416,419,423,427,432,437,442,447,452, + 456,461,467,475,483,488,490,491,490,487,485,481,477,472,466,461,455,449,442,434,427,419,411,403,395,386,377,367,359,351,343,335,327,322,316,312,306,305,301,299,299,298, + 0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (NGSolux[wlm]); +} + +//spectral data for LED LSI Lumelex 2040 - test National Gallery +double ColorTemp::NG_LEDLSI2040_spect(double wavelength, double m1, double m2, double temp) +{ + static const double NGLsi[97]={0.0,0.0,0.0,0.0,0.0,0.0,1.5,1.2,0.5,0.7,0.6,1.6,1.7,7.0,16.6,35.5,64,106,162.5,230.5,272.2,249,213.4,214,227.6,231.9,233,235.2,241.4,253.7,270.3,288.5,306.2,322.3,337.6,352.5,367.2,381.7,395.9,409.6,416.2,423.2,429.7,435.8,442.8, + 451.7,464.2,480.3,501,526.3,555.9,587.5,625.4,655.1,681.7,705.3,721.5,728.5,729,719.8,702.5,676.7,646.2,611.5,571.7,530.3,488.3,445.9,404,365.2,326.8,290.8,257.6,226.9,199.8,175.2,154.2,133.8,116.4,101.5,88.5,76.6,67.3,57.9,50.7,44.2,38.2, + 0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (NGLsi[wlm]); +} +//spectral data for LED CRS SP12 WWMR16 - test National Gallery +double ColorTemp::NG_CRSSP12WWMR16_spect(double wavelength, double m1, double m2, double temp) +{ + static const double NGCRSSP12[97]={0.0,0.0,0.0,0.0,0.0,0.0,0.,0.,0.,0.,0.,0.14,0.33,1.31,3.34,7.9,17.4,36.5,72.6,145.4,260.5,359.2,365.3,303.1,256.1,221.7,193.6,185.8,191.4,207.3,232.8,257.5,285.1,310.5,333.4,351.5,368.8,383.7,398.8,411.6,424.7,435.6,447.9,459.7,471.7, + 484.6,497.9,512.3,531.1,548.9,567.9,587.5,608.6,625.3,640.1,648.6,654.0,654.3,647.2,633.9,616.1,590.5,561.5,526.5,494.8,457.9,420.8,382.4,347.3,309.9,280.5,249.2,220.0,194.9,170.8,149.1,130.0,112.3,97.5,84.9,73.2,63.1,54.1,45.6,39.0,32.6,27.4, + 0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0}; + + int wlm = (int) ((wavelength -350.)/5.); + return (NGCRSSP12[wlm]); +} + +//spectral data for Flash daylight 5500K (Leica...) +double ColorTemp::Flash5500_spect(double wavelength, double m1, double m2, double temp) +{ + static const double FL55[97]={27.77,29.17,30.58,32.02,33.47,33.00,32.53,35.28,38.04,49.46,60.88,64.68,68.48,69.99,71.51,69.68,67.85,76.70,85.54,91.74,97.93,99.17,100.41,100.14,99.86,101.28,102.70,100.37,98.04,99.35,100.65, + 100.66,100.67,100.32,99.97,102.08,104.20,103.15,102.09,102.53,102.96,101.48,100.00,98.61,97.22,97.49,97.76,94.60,91.44,92.94,94.44,94.80,95.16,94.70,94.25,92.36,90.48,91.42,92.36,90.63, + 88.89,89.62,90.36,92.18,94.00,92.00,90.00,84.86,79.72,81.30,82.88,83.88,84.89,77.58,70.27,74.80,82.19,85.03,78.47,71.91,62.37,52.82,64.39,75.96,73.91,71.85,72.41,72.97,70.17,67.38,63.07, + 58.75,61.89,65.02,66.68,68.34}; + + int wlm = (int) ((wavelength -350.)/5.); + return (FL55[wlm]); +} + +//spectral data for Flash daylight 6000K (Canon, Pentax, Olympus,...Standard) +double ColorTemp::Flash6000_spect(double wavelength, double m1, double m2, double temp) +{ + static const double FL60[97]={36.00,37.18,38.36,40.36,42.35,41.77,41.19,43.79,46.40,59.24,72.09,76.15,80.22,81.47,82.71,80.12,77.52,86.54,95.56,101.70,107.85,108.66,109.46,108.57,107.68,108.65,109.61,106.63,103.65,104.42, + 105.19,104.79,104.39,103.45,102.51,104.28,106.05,104.68,103.31,103.42,103.54,101.77,100.00,98.38,96.75,96.74,96.72,93.30,89.89,90.92,91.95,91.99,92.03,91.30,90.57,88.51,86.45,86.96, + 87.47,85.66,83.85,84.21,84.57,85.95,87.32,85.31,83.30,78.66,74.03,75.24,76.45,77.68,78.91,72.13,65.35,69.67,73.98,76.68,79.39,73.29,67.19,58.19,49.19,59.98,70.77,68.91,67.05,67.55,68.05, + 65.47,62.88,58.89,54.90,57.81,60.72,62.25,63.78}; + + int wlm = (int) ((wavelength -350.)/5.); + return (FL60[wlm]); +} + +//spectral data for Flash daylight 6500K (Nikon, Minolta, Panasonic, Sony...) +double ColorTemp::Flash6500_spect(double wavelength, double m1, double m2, double temp) +{ + static const double FL65[97]={44.86,45.72,46.59,49.16,51.74,50.83,49.92,52.26,54.60,68.65,82.69,87.06,91.42,92.39,93.37,90.00,86.63,95.72,104.81,110.88,116.96,117.36,117.76,116.29,114.82,115.35,115.89,112.33,108.78,109.06, + 109.33,108.56,107.78,106.28,104.78,106.23,107.68,106.04,104.40,104.22,104.04,102.02,100.00,98.17,96.34,96.06,95.79,92.24,88.69,89.35,90.02,89.81,89.61,88.66,87.71,85.51,83.30,83.51,83.72, + 81.88,80.05,80.14,80.24,81.27,82.30,80.31,78.31,74.03,69.74,70.69,71.63,73.00,74.37,68.00,61.62,65.76,69.91,72.51,75.11,69.36,63.61,55.02,46.43,56.63,66.83,65.11,63.40,63.86,64.32,61.90,59.47, + 55.72,51.97,54.72,57.46,58.89,60.33}; + + int wlm = (int) ((wavelength -350.)/5.); + return (FL65[wlm]); +} + void ColorTemp::temp2mul (double temp, double green, double& rmul, double& gmul, double& bmul) { - clip (temp, green); + clip (temp, green); + + double xD, yD, x_D, y_D, interm; + double x, y, z; + + // We first test for specially handled methods + if (method == "Daylight" ) spectrum_to_xyz(Daylight5300_spect, 0., 0., 0., x, y, z); + else if(method == "Cloudy" ) spectrum_to_xyz(Cloudy6200_spect, 0., 0., 0., x, y, z); + else if(method == "Shade" ) spectrum_to_xyz(Shade7600_spect, 0., 0., 0., x, y, z); + else if(method == "Tungsten" ) spectrum_to_xyz(A2856_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F1" ) spectrum_to_xyz(FluoF1_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F2" ) spectrum_to_xyz(FluoF2_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F3" ) spectrum_to_xyz(FluoF3_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F4" ) spectrum_to_xyz(FluoF4_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F5" ) spectrum_to_xyz(FluoF5_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F6" ) spectrum_to_xyz(FluoF6_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F7" ) spectrum_to_xyz(FluoF7_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F8" ) spectrum_to_xyz(FluoF8_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F9" ) spectrum_to_xyz(FluoF9_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F10" ) spectrum_to_xyz(FluoF10_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F11" ) spectrum_to_xyz(FluoF11_spect, 0., 0., 0., x, y, z); + else if(method == "Fluo F12" ) spectrum_to_xyz(FluoF12_spect, 0., 0., 0., x, y, z); + else if(method == "HMI Lamp" ) spectrum_to_xyz(HMI_spect, 0., 0., 0., x, y, z); + else if(method == "GTI Lamp" ) spectrum_to_xyz(GTI_spect, 0., 0., 0., x, y, z); + else if(method == "JudgeIII Lamp" ) spectrum_to_xyz(JudgeIII_spect, 0., 0., 0., x, y, z); + else if(method == "Solux Lamp 3500K" ) spectrum_to_xyz(Solux3500_spect, 0., 0., 0., x, y, z); + else if(method == "Solux Lamp 4100K" ) spectrum_to_xyz(Solux4100_spect, 0., 0., 0., x, y, z); + else if(method == "Solux Lamp 4700K" ) spectrum_to_xyz(Solux4700_spect, 0., 0., 0., x, y, z); + else if(method == "NG Solux Lamp 4700K") spectrum_to_xyz(NG_Solux4700_spect, 0., 0., 0., x, y, z); + else if(method == "Flash 5500K" ) spectrum_to_xyz(Flash5500_spect, 0., 0., 0., x, y, z); + else if(method == "Flash 6000K" ) spectrum_to_xyz(Flash6000_spect, 0., 0., 0., x, y, z); + else if(method == "Flash 6500K" ) spectrum_to_xyz(Flash6500_spect, 0., 0., 0., x, y, z); + else { + // otherwise we use the Temp+Green generic solution + if (temp <= 4000) { + // if temperature is between 2000K and 4000K we use blackbody, because there will be no Daylight reference below 4000K... + // of course, the previous version of RT used the "magical" but wrong formula of U.Fuchs (Ufraw). + spectrum_to_xyz(blackbody_spect, 0., 0., temp, x, y, z); + } + else { + // from 4000K up to 25000K: using the D illuminant (daylight) which is standard + double m1, m2; + if (temp<=7000) + x_D = -4.6070e9/(temp*temp*temp) + 2.9678e6/(temp*temp) + 0.09911e3/temp + 0.244063; + else + x_D = -2.0064e9/(temp*temp*temp) + 1.9018e6/(temp*temp) + 0.24748e3/temp + 0.237040; + + y_D = -3.0*x_D*x_D + 2.87*x_D - 0.275; + //calculate D -daylight in function of s0, s1, s2 and temp ==> x_D y_D + //S(lamda)=So(lambda)+m1*s1(lambda)+m2*s2(lambda) + interm=(0.0241+0.2562*x_D-0.734*y_D); + m1=(-1.3515-1.7703*x_D+5.9114*y_D)/interm; + m2=(0.03-31.4424*x_D+30.0717*y_D)/interm; + spectrum_to_xyz(daylight_spect, m1, m2, 0., x, y, z); + xD=x;yD=y; + } - double xD; - if (temp<=4000) { - xD = 0.27475e9/(temp*temp*temp) - 0.98598e6/(temp*temp) + 1.17444e3/temp + 0.145986; - } else if (temp<=7000) { - xD = -4.6070e9/(temp*temp*temp) + 2.9678e6/(temp*temp) + 0.09911e3/temp + 0.244063; - } else { - xD = -2.0064e9/(temp*temp*temp) + 1.9018e6/(temp*temp) + 0.24748e3/temp + 0.237040; } - double yD = -3.0*xD*xD + 2.87*xD - 0.275; + + xD=x; yD=y; + + if (settings->verbose) { + double u=4*xD/(-2*xD+12*yD+3); + double v=6*yD/(-2*xD+12*yD+3); + printf("xD=%f yD=%f u=%f v=%f\n",xD,yD,u,v); + } double X = xD/yD; double Y = 1.0; double Z = (1.0-xD-yD)/yD; - - /*if (isRaw) { - rmul = sRGB_xyz[0][0]*X + sRGB_xyz[0][1]*Y + sRGB_xyz[0][2]*Z; - gmul = sRGB_xyz[1][0]*X + sRGB_xyz[1][1]*Y + sRGB_xyz[1][2]*Z; - bmul = sRGB_xyz[2][0]*X + sRGB_xyz[2][1]*Y + sRGB_xyz[2][2]*Z; - } else {*/ - rmul = sRGBd65_xyz[0][0]*X + sRGBd65_xyz[0][1]*Y + sRGBd65_xyz[0][2]*Z; - gmul = sRGBd65_xyz[1][0]*X + sRGBd65_xyz[1][1]*Y + sRGBd65_xyz[1][2]*Z; - bmul = sRGBd65_xyz[2][0]*X + sRGBd65_xyz[2][1]*Y + sRGBd65_xyz[2][2]*Z; - //}; + + /*if (isRaw) { + rmul = sRGB_xyz[0][0]*X + sRGB_xyz[0][1]*Y + sRGB_xyz[0][2]*Z; + gmul = sRGB_xyz[1][0]*X + sRGB_xyz[1][1]*Y + sRGB_xyz[1][2]*Z; + bmul = sRGB_xyz[2][0]*X + sRGB_xyz[2][1]*Y + sRGB_xyz[2][2]*Z; + } else {*/ + //recalculate channels multipliers with new values of XYZ tue to whitebalance + rmul = sRGBd65_xyz[0][0]*X + sRGBd65_xyz[0][1]*Y + sRGBd65_xyz[0][2]*Z; + gmul = sRGBd65_xyz[1][0]*X + sRGBd65_xyz[1][1]*Y + sRGBd65_xyz[1][2]*Z; + bmul = sRGBd65_xyz[2][0]*X + sRGBd65_xyz[2][1]*Y + sRGBd65_xyz[2][2]*Z; + //}; gmul /= green; double max = rmul; @@ -92,3 +581,5 @@ void ColorTemp::temp2mul (double temp, double green, double& rmul, double& gmul, gmul /= max; bmul /= max; } + +} diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h index 3fb4aa237..412e725d9 100644 --- a/rtengine/colortemp.h +++ b/rtengine/colortemp.h @@ -19,39 +19,76 @@ #ifndef _COLORTEMP_ #define _COLORTEMP_ +#include #include namespace rtengine { -#define MINTEMP 1200 -#define MAXTEMP 12000 +#define MINTEMP 2000 +#define MAXTEMP 25000 #define MINGREEN 0.02 #define MAXGREEN 5.0 +#define INITIALBLACKBODY 4000 class ColorTemp { private: double temp; double green; + Glib::ustring method; static void clip (double &temp, double &green); - + public: - - ColorTemp () : temp(-1), green(-1) {} - ColorTemp (double t, double g); - ColorTemp (double mulr, double mulg, double mulb) { mul2temp (mulr, mulg, mulb, temp, green); } - + + ColorTemp () : temp(-1), green(-1), method("Custom") {} + ColorTemp (double t, double g, Glib::ustring m); + ColorTemp (double mulr, double mulg, double mulb); + inline double getTemp () { return temp; } inline double getGreen () { return green; } - + void getMultipliers (double &mulr, double &mulg, double &mulb) { temp2mul (temp, green, mulr, mulg, mulb); } - static void mul2temp (double rmul, double gmul, double bmul, double& temp, double& green); - static void temp2mul (double temp, double green, double& rmul, double& gmul, double& bmul); + void mul2temp (double rmul, double gmul, double bmul, double& temp, double& green); + void temp2mul (double temp, double green, double& rmul, double& gmul, double& bmul); + //void temp2mul (double& rmul, double& gmul, double& bmul); bool operator== (const ColorTemp& other) { return fabs(temp-other.temp)<1e-10 && fabs(green-other.green)<1e-10; } bool operator!= (const ColorTemp& other) { return !(*this==other); } + + static double blackbody_spect (double wavelength, double m1, double m2, double temp); + static double daylight_spect (double wavelength, double m1, double m2, double temp); + static double Cloudy6200_spect (double wavelength, double m1, double m2, double temp); + static double Daylight5300_spect (double wavelength, double m1, double m2, double temp); + static double Shade7600_spect (double wavelength, double m1, double m2, double temp); + static double A2856_spect (double wavelength, double m1, double m2, double temp); + static double FluoF1_spect (double wavelength, double m1, double m2, double temp); + static double FluoF2_spect (double wavelength, double m1, double m2, double temp); + static double FluoF3_spect (double wavelength, double m1, double m2, double temp); + static double FluoF4_spect (double wavelength, double m1, double m2, double temp); + static double FluoF5_spect (double wavelength, double m1, double m2, double temp); + static double FluoF6_spect (double wavelength, double m1, double m2, double temp); + static double FluoF7_spect (double wavelength, double m1, double m2, double temp); + static double FluoF8_spect (double wavelength, double m1, double m2, double temp); + static double FluoF9_spect (double wavelength, double m1, double m2, double temp); + static double FluoF10_spect (double wavelength, double m1, double m2, double temp); + static double FluoF11_spect (double wavelength, double m1, double m2, double temp); + static double FluoF12_spect (double wavelength, double m1, double m2, double temp); + static double HMI_spect (double wavelength, double m1, double m2, double temp); + static double GTI_spect (double wavelength, double m1, double m2, double temp); + static double JudgeIII_spect (double wavelength, double m1, double m2, double temp); + static double Solux3500_spect (double wavelength, double m1, double m2, double temp); + static double Solux4100_spect (double wavelength, double m1, double m2, double temp); + static double Solux4700_spect (double wavelength, double m1, double m2, double temp); + static double NG_Solux4700_spect (double wavelength, double m1, double m2, double temp); + static double NG_LEDLSI2040_spect (double wavelength, double m1, double m2, double temp); + static double NG_CRSSP12WWMR16_spect (double wavelength, double m1, double m2, double temp); + static double Flash5500_spect (double wavelength, double m1, double m2, double temp); + static double Flash6000_spect (double wavelength, double m1, double m2, double temp); + static double Flash6500_spect (double wavelength, double m1, double m2, double temp); + + static void spectrum_to_xyz (double (*spec_intens)(double wavelength, double m1, double m2, double temp), double _m1, double _m2, double _temp, double &x, double &y, double &z); }; }; #endif diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index b60ecbb03..8eeece861 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -56,12 +56,12 @@ ImProcCoordinator::ImProcCoordinator () histLCurve(256); bcabhist(256); - rCurve(65536,0); - rcurvehist(256); rcurvehistCropped(256); rbeforehist(256); - gCurve(65536,0); - gcurvehist(256); gcurvehistCropped(256); gbeforehist(256); - bCurve(65536,0); - bcurvehist(256); bcurvehistCropped(256); bbeforehist(256); + rCurve(65536,0); + rcurvehist(256); rcurvehistCropped(256); rbeforehist(256); + gCurve(65536,0); + gcurvehist(256); gcurvehistCropped(256); gbeforehist(256); + bCurve(65536,0); + bcurvehist(256); bcurvehistCropped(256); bbeforehist(256); } void ImProcCoordinator::assign (ImageSource* imgsrc) { @@ -156,7 +156,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { imgsrc->HLRecovery_Global( params.hlrecovery ); // this handles Color HLRecovery if (settings->verbose) printf ("Applying white balance, color correction & sRBG conversion...\n"); - currWB = ColorTemp (params.wb.temperature, params.wb.green); + currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.method); if (params.wb.method=="Camera") currWB = imgsrc->getWB (); else if (params.wb.method=="Auto") { @@ -231,15 +231,15 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, \ imgsrc->getGamma(), true, params.toneCurve.curve, \ vhist16, histCropped, hltonecurve, shtonecurve, tonecurve, histToneCurve, scale==1 ? 1 : 1); - - CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, scale==1 ? 1 : 1); - CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, scale==1 ? 1 : 1); - CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale==1 ? 1 : 1); + + CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, scale==1 ? 1 : 1); + CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, scale==1 ? 1 : 1); + CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale==1 ? 1 : 1); // if it's just crop we just need the histogram, no image updates if ( todo!=CROP ) { ipf.rgbProc (oprevi, oprevl, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation, \ - rCurve, gCurve, bCurve); + rCurve, gCurve, bCurve); } // compute L channel histogram @@ -526,7 +526,7 @@ void ImProcCoordinator::getSpotWB (int x, int y, int rect, double& temp, double& if (params.coarse.vflip) tr |= TR_VFLIP; ColorTemp ret = imgsrc->getSpotWB (red, green, blue, tr); - currWB = ColorTemp (params.wb.temperature, params.wb.green); + currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.method); mProcessing.unlock (); if (ret.getTemp() > 0) { @@ -577,7 +577,7 @@ void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) { imgsrc->preprocess( ppar.raw ); imgsrc->demosaic(ppar.raw ); //imgsrc->getImage (imgsrc->getWB(), 0, im, pp, ppar.hlrecovery, ppar.icm, ppar.raw); - ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green); + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.method); if (params.wb.method=="Camera") currWB = imgsrc->getWB (); else if (params.wb.method=="Auto") { diff --git a/rtengine/init.cc b/rtengine/init.cc index b39756a13..977c7b7f1 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -37,6 +37,7 @@ int init (const Settings* s, Glib::ustring baseDir) { iccStore->init (s->iccDirectory, baseDir + "/iccprofiles"); iccStore->findDefaultMonitorProfile(); + ProcParams::init (); CurveFactory::init (); ImProcFunctions::initMunsell(); ImProcFunctions::initCache (); @@ -50,6 +51,7 @@ int init (const Settings* s, Glib::ustring baseDir) { void cleanup () { + ProcParams::cleanup (); ImProcFunctions::cleanupCache (); Thumbnail::cleanupGamma (); } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index cc76b8c72..9d3c71696 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -18,6 +18,7 @@ */ #include #include +#include #include #include #include @@ -37,6 +38,49 @@ namespace procparams { const char *RAWParams::methodstring[RAWParams::numMethods]={"eahd", "hphd", "vng4", "dcb", "amaze", "ahd", "fast" }; const char *RAWParams::ff_BlurTypestring[RAWParams::numFlatFileBlurTypes]={/*"Parametric",*/ "Area Flatfield", "Vertical Flatfield", "Horizontal Flatfield", "V+H Flatfield"}; +std::vector WBParams::wbEntries; + +void WBParams::init() { + // Creation of the different methods and its associated temperature value + wbEntries.push_back(new WBEntry("Camera" ,WBT_CAMERA, M("TP_WBALANCE_CAMERA"), 0)); + wbEntries.push_back(new WBEntry("Auto" ,WBT_AUTO, M("TP_WBALANCE_AUTO"), 0)); + wbEntries.push_back(new WBEntry("Daylight" ,WBT_DAYLIGHT, M("TP_WBALANCE_DAYLIGHT"), 5300)); + wbEntries.push_back(new WBEntry("Cloudy" ,WBT_CLOUDY, M("TP_WBALANCE_CLOUDY"), 6200)); + wbEntries.push_back(new WBEntry("Shade" ,WBT_SHADE, M("TP_WBALANCE_SHADE"), 7600)); + wbEntries.push_back(new WBEntry("Tungsten" ,WBT_TUNGSTEN, M("TP_WBALANCE_TUNGSTEN"), 2856)); + wbEntries.push_back(new WBEntry("Fluo F1" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO1"), 6430)); + wbEntries.push_back(new WBEntry("Fluo F2" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO2"), 4230)); + wbEntries.push_back(new WBEntry("Fluo F3" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO3"), 3450)); + wbEntries.push_back(new WBEntry("Fluo F4" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO4"), 2940)); + wbEntries.push_back(new WBEntry("Fluo F5" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO5"), 6350)); + wbEntries.push_back(new WBEntry("Fluo F6" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO6"), 4150)); + wbEntries.push_back(new WBEntry("Fluo F7" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO7"), 6500)); + wbEntries.push_back(new WBEntry("Fluo F8" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO8"), 5020)); + wbEntries.push_back(new WBEntry("Fluo F9" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO9"), 4330)); + wbEntries.push_back(new WBEntry("Fluo F10" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO10"), 5300)); + wbEntries.push_back(new WBEntry("Fluo F11" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO11"), 4000)); + wbEntries.push_back(new WBEntry("Fluo F12" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO12"), 3000)); + wbEntries.push_back(new WBEntry("HMI Lamp" ,WBT_LAMP, M("TP_WBALANCE_HMI"), 4800)); + wbEntries.push_back(new WBEntry("GTI Lamp" ,WBT_LAMP, M("TP_WBALANCE_GTI"), 5000)); + wbEntries.push_back(new WBEntry("JudgeIII Lamp" ,WBT_LAMP, M("TP_WBALANCE_JUDGEIII"), 5100)); + wbEntries.push_back(new WBEntry("Solux Lamp 3500K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX35"), 3480)); + wbEntries.push_back(new WBEntry("Solux Lamp 4100K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX41"), 3930)); + wbEntries.push_back(new WBEntry("Solux Lamp 4700K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX47"), 4700)); + wbEntries.push_back(new WBEntry("NG Solux Lamp 4700K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX47_NG"), 4480)); + wbEntries.push_back(new WBEntry("LED LSI Lumelex 2040",WBT_LED, M("TP_WBALANCE_LED_LSI"), 3000)); + wbEntries.push_back(new WBEntry("LED CRS SP12 WWMR16" ,WBT_LED, M("TP_WBALANCE_LED_CRS"), 3050)); + wbEntries.push_back(new WBEntry("Flash 5500K" ,WBT_FLASH, M("TP_WBALANCE_FLASH55"), 5500)); + wbEntries.push_back(new WBEntry("Flash 6000K" ,WBT_FLASH, M("TP_WBALANCE_FLASH60"), 6000)); + wbEntries.push_back(new WBEntry("Flash 6500K" ,WBT_FLASH, M("TP_WBALANCE_FLASH65"), 6500)); + // Should remain the last one + wbEntries.push_back(new WBEntry("Custom" ,WBT_CUSTOM, M("TP_WBALANCE_CUSTOM"), 0)); +} + +void WBParams::cleanup() { + for (unsigned int i=0; i wbEntries; Glib::ustring method; int temperature; double green; + + static void init(); + static void cleanup(); }; /** @@ -558,6 +588,9 @@ class ProcParams { * @param pp a pointer to the ProcParams instance to destroy. */ static void destroy (ProcParams* pp); + static void init (); + static void cleanup (); + bool operator== (const ProcParams& other); bool operator!= (const ProcParams& other); diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index a3bc67cb0..9f896a21f 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -130,8 +130,10 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, } } - if (n>0) - ColorTemp::mul2temp (avg_r/n, avg_g/n, avg_b/n, tpp->autowbTemp, tpp->autowbGreen); + if (n>0) { + ColorTemp cTemp; + cTemp.mul2temp (avg_r/n, avg_g/n, avg_b/n, tpp->autowbTemp, tpp->autowbGreen); + } delete img; tpp->init (); @@ -477,7 +479,8 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati double gm = ri->get_rgb_cam(1, 0) * reds + ri->get_rgb_cam(1, 1) * greens + ri->get_rgb_cam(1, 2) * blues; double bm = ri->get_rgb_cam(2, 0) * reds + ri->get_rgb_cam(2, 1) * greens + ri->get_rgb_cam(2, 2) * blues; - ColorTemp::mul2temp(rm, gm, bm, tpp->autowbTemp, tpp->autowbGreen); + ColorTemp cTemp; + cTemp.mul2temp(rm, gm, bm, tpp->autowbTemp, tpp->autowbGreen); if (rotate && ri->get_rotateDegree() > 0) { Image16* rot = tpp->thumbImg->rotate(ri->get_rotateDegree()); @@ -582,7 +585,7 @@ IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rheight, TypeInterpolation interp, std::string camName, double& myscale) { // compute WB multipliers - ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green); + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.method); if (params.wb.method=="Camera") { //recall colorMatrix is rgb_cam double cam_r = colorMatrix[0][0]*camwbRed + colorMatrix[0][1]*camwbGreen + colorMatrix[0][2]*camwbBlue; @@ -591,7 +594,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei currWB = ColorTemp (cam_r, cam_g, cam_b); } else if (params.wb.method=="Auto") - currWB = ColorTemp (autowbTemp, autowbGreen); + currWB = ColorTemp (autowbTemp, autowbGreen, "Custom"); double r, g, b; currWB.getMultipliers (r, g, b); //iColorMatrix is cam_rgb diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 1f283f982..0ac8c4b96 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -94,7 +94,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p ImProcFunctions ipf (¶ms, true); // set the color temperature - ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green); + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.method); if (params.wb.method=="Camera") currWB = imgsrc->getWB (); else if (params.wb.method=="Auto") diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 6e706549f..efc70d0fc 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -21,6 +21,7 @@ #include #include #include +#include "whitebalance.h" RTWindow::RTWindow () :fpanel(NULL) @@ -30,6 +31,7 @@ RTWindow::RTWindow () { cacheMgr->init (); + WhiteBalance::init(); Glib::ustring fName = "rt-logo.png"; Glib::ustring fullPath = RTImage::findIconAbsolutePath(fName); @@ -392,6 +394,8 @@ bool RTWindow::on_delete_event(GdkEventAny* event) { epanel->saveProfile(); cacheMgr->closeCache (); // also makes cleanup if too large + WhiteBalance::cleanup(); + options.firstRun = false; diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index b7743b822..91d16cff0 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -20,9 +20,10 @@ #include #include #include +#include -#define MINTEMP 1200 -#define MAXTEMP 12000 +#define MINTEMP 2000 //1200 +#define MAXTEMP 25000 //12000 #define MINGREEN 0.02 #define MAXGREEN 5.0 @@ -31,18 +32,111 @@ extern Glib::ustring argv0; using namespace rtengine; using namespace rtengine::procparams; +Glib::RefPtr WhiteBalance::wbPixbufs[rtengine::procparams::WBT_CUSTOM+1]; +/* +Glib::RefPtr WhiteBalance::wbCameraPB, WhiteBalance::wbAutoPB, WhiteBalance::wbSunPB, WhiteBalance::wbTungstenPB, + WhiteBalance::wbCloudyPB, WhiteBalance::wbShadePB, WhiteBalance::wbFluorescentPB, WhiteBalance::wbLampPB, + WhiteBalance::wbFlashPB, WhiteBalance::wbLedPB, WhiteBalance::wbCustomPB; +*/ + +void WhiteBalance::init () { + wbPixbufs[WBT_CAMERA] = safe_create_from_file("wb-camera.png"); + wbPixbufs[WBT_AUTO] = safe_create_from_file("wb-auto.png"); + wbPixbufs[WBT_DAYLIGHT] = safe_create_from_file("wb-sun.png"); + wbPixbufs[WBT_CLOUDY] = safe_create_from_file("wb-cloudy.png"); + wbPixbufs[WBT_SHADE] = safe_create_from_file("wb-shade.png"); + wbPixbufs[WBT_TUNGSTEN] = safe_create_from_file("wb-tungsten.png"); + wbPixbufs[WBT_FLUORESCENT] = safe_create_from_file("wb-fluorescent.png"); + wbPixbufs[WBT_LAMP] = safe_create_from_file("wb-lamp.png"); + wbPixbufs[WBT_FLASH] = safe_create_from_file("wb-flash.png"); + wbPixbufs[WBT_LED] = safe_create_from_file("wb-led.png"); + wbPixbufs[WBT_CUSTOM] = safe_create_from_file("wb-custom.png"); +} + +void WhiteBalance::cleanup () { + for (unsigned int i=0; ishow (); Gtk::Label* lab = Gtk::manage (new Gtk::Label (M("TP_WBALANCE_METHOD"))); lab->show (); - method = Gtk::manage (new MyComboBoxText ()); + + // Create the Tree model + refTreeModel = Gtk::TreeStore::create(methodColumns); + // Create the Combobox + method = Gtk::manage (new MyComboBox ()); + // Assign the model to the Combobox + method->set_model(refTreeModel); + + custom_green = new double[WBParams::wbEntries.size()]; + enum WBTypes oldType = WBParams::wbEntries[0]->type; + enum WBTypes currType; + Gtk::TreeModel::Row row, childrow; + for (unsigned int i=0; itype)) { + // New entry type + if (currType == WBT_FLUORESCENT) { + // Creating the Fluorescent subcategory header + row = *(refTreeModel->append()); + row[methodColumns.colIcon] = wbPixbufs[currType]; + row[methodColumns.colLabel] = M("TP_WBALANCE_FLUO_HEADER"); + row[methodColumns.colId] = i+100; + } + if (currType == WBT_LAMP) { + // Creating the Lamp subcategory header + row = *(refTreeModel->append()); + row[methodColumns.colIcon] = wbPixbufs[currType]; + row[methodColumns.colLabel] = M("TP_WBALANCE_LAMP_HEADER"); + row[methodColumns.colId] = i+100; + } + if (currType == WBT_LED) { + // Creating the LED subcategory header + row = *(refTreeModel->append()); + row[methodColumns.colIcon] = wbPixbufs[currType]; + row[methodColumns.colLabel] = M("TP_WBALANCE_LED_HEADER"); + row[methodColumns.colId] = i+100; + } + if (currType == WBT_FLASH) { + // Creating the Flash subcategory header + row = *(refTreeModel->append()); + row[methodColumns.colIcon] = wbPixbufs[currType]; + row[methodColumns.colLabel] = M("TP_WBALANCE_FLASH_HEADER"); + row[methodColumns.colId] = i+100; + } + } + if (currType == WBT_FLUORESCENT + || currType == WBT_LAMP + || currType == WBT_FLASH + || currType == WBT_LED + ) { + childrow = *(refTreeModel->append(row.children())); + childrow[methodColumns.colIcon] = wbPixbufs[currType]; + childrow[methodColumns.colLabel] = WBParams::wbEntries[i]->GUILabel; + childrow[methodColumns.colId] = i; + } + else { + row = *(refTreeModel->append()); + row[methodColumns.colIcon] = wbPixbufs[currType]; + row[methodColumns.colLabel] = WBParams::wbEntries[i]->GUILabel; + row[methodColumns.colId] = i; + } + oldType = currType; + + custom_green[i] = 1.0; + } + + //Add the model columns to the Combo (which is a kind of view), + //rendering them in the default way: + method->pack_start(methodColumns.colIcon, false); + method->pack_start(methodColumns.colLabel, true); + + method->set_active (0); // Camera method->show (); - method->append_text (M("TP_WBALANCE_CAMERA")); - method->append_text (M("TP_WBALANCE_AUTO")); - method->append_text (M("TP_WBALANCE_CUSTOM")); - method->set_active (0); hbox->pack_start (*lab, Gtk::PACK_SHRINK, 4); hbox->pack_start (*method); pack_start (*hbox, Gtk::PACK_SHRINK, 4); @@ -76,7 +170,7 @@ WhiteBalance::WhiteBalance () : Gtk::VBox(), FoldableToolPanel(this), wbp(NULL), pack_start (*spotbox, Gtk::PACK_SHRINK, 4); temp = Gtk::manage (new Adjuster (M("TP_WBALANCE_TEMPERATURE"), MINTEMP, MAXTEMP, 5, 4750)); - green = Gtk::manage (new Adjuster (M("TP_WBALANCE_GREEN"), MINGREEN, MAXGREEN, 0.001, 1.2)); + green = Gtk::manage (new Adjuster (M("TP_WBALANCE_GREEN"), MINGREEN, MAXGREEN, 0.001, 1.0)); temp->show (); green->show (); @@ -91,72 +185,126 @@ WhiteBalance::WhiteBalance () : Gtk::VBox(), FoldableToolPanel(this), wbp(NULL), spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); } +WhiteBalance::~WhiteBalance () { + delete custom_green; +} + void WhiteBalance::adjusterChanged (Adjuster* a, double newval) { - //cache custom WB setting to allow its recall - cache_customWB ((int)temp->getValue(), green->getValue()); + int tVal = (int)temp->getValue(); + double gVal = green->getValue(); - if (method->get_active_row_number()!=2) { - disableListener (); - method->set_active (2); - enableListener (); + Gtk::TreeModel::Row row = getActiveMethod(); + if (row == refTreeModel->children().end()) return; + + Glib::ustring colLabel = row[methodColumns.colLabel]; + WBEntry* ppMethod = findWBEntry (row[methodColumns.colLabel], WBLT_GUI); + WBEntry* wbCustom = findWBEntry ("Custom", WBLT_PP); + + if (!ppMethod || ppMethod->ppLabel != wbCustom->ppLabel) { + if (!ppMethod || a==temp || (ppMethod->type==WBT_CAMERA || ppMethod->type==WBT_AUTO) ) { + methconn.block(true); + opt = setActiveMethod(wbCustom->GUILabel); + methconn.block(false); + } } - + + //cache custom WB setting to allow its recall + if (a==temp) + cache_customTemp (tVal); + else + cache_customGreen (gVal); + if (listener) { - if (a==temp) + if (a==temp) listener->panelChanged (EvWBTemp, Glib::ustring::format ((int)a->getValue())); - else if (a==green) + else if (a==green) listener->panelChanged (EvWBGreen, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue())); } } void WhiteBalance::optChanged () { - if (opt!=method->get_active_row_number()) { - opt = method->get_active_row_number(); - Glib::ustring meth = M("TP_WBALANCE_CUSTOM"); - if (opt==0 && wbp) { - double ctemp; double cgreen; - wbp->getCamWB (ctemp, cgreen); - temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp); - green->setValue (green->getAddMode() ? 0.0 : cgreen); - meth = M("TP_WBALANCE_CAMERA"); - if (batchMode) { - temp->setEditedState (UnEdited); - green->setEditedState (UnEdited); - } - } - else if (opt==1 && wbp) { - double ctemp; double cgreen; - wbp->getAutoWB (ctemp, cgreen); - temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp); - green->setValue (green->getAddMode() ? 0.0 : cgreen); - meth = M("TP_WBALANCE_AUTO"); - if (batchMode) { - temp->setEditedState (UnEdited); - green->setEditedState (UnEdited); - } - } - else if (opt==2 && wbp) { - // recall custom WB settings - if (custom_temp>0){ - temp->setValue (temp->getAddMode() ? 0.0 : custom_temp); - green->setValue (green->getAddMode() ? 0.0 : custom_green); - } - meth = M("TP_WBALANCE_CUSTOM"); - if (batchMode) { - temp->setEditedState (Edited); - green->setEditedState (Edited); - } - } + Gtk::TreeModel::Row row = getActiveMethod(); + if (row == refTreeModel->children().end()) return; + if (row[methodColumns.colId] >= 100) { + // "Header" solutions are trapped ; the combo is then set to the previous value + bool prevState = methconn.block(true); + method->set_active(opt); + methconn.block(prevState); + return; + } - else if (opt==3) { - meth = M("GENERAL_UNCHANGED"); + if (opt != row[methodColumns.colId]) { + + opt = row[methodColumns.colId]; + + if (row[methodColumns.colLabel] == M("GENERAL_UNCHANGED")) { temp->setEditedState (UnEdited); green->setEditedState (UnEdited); } - if (listener) - listener->panelChanged (EvWBMethod, meth); + else { + int methodId = findWBEntryId (row[methodColumns.colLabel], WBLT_GUI); + WBEntry* currMethod = WBParams::wbEntries[methodId]; + + switch (currMethod->type) { + case WBT_CAMERA: + if (wbp) { + double ctemp, cgreen; + wbp->getCamWB (ctemp, cgreen); + temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp); + green->setValue (green->getAddMode() ? 0.0 : cgreen); + if (batchMode) { + temp->setEditedState (UnEdited); + green->setEditedState (UnEdited); + } + } + break; + case WBT_AUTO: + if (wbp) { + double ctemp, cgreen; + wbp->getAutoWB (ctemp, cgreen); + temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp); + green->setValue (green->getAddMode() ? 0.0 : cgreen); + if (batchMode) { + temp->setEditedState (UnEdited); + green->setEditedState (UnEdited); + } + } + break; + case WBT_CUSTOM: + if (custom_temp>0){ + temp->setValue (temp->getAddMode() ? 0.0 : custom_temp); + } + green->setValue (green->getAddMode() ? 0.0 : custom_green[methodId]); + if (batchMode) { + temp->setEditedState (Edited); + green->setEditedState (Edited); + } + break; + /* All other solution are the default cases + case WBT_DAYLIGHT: + case WBT_CLOUDY: + case WBT_SHADE: + case WBT_TUNGSTEN: + case WBT_FLUORESCENT: + case WBT_LAMP: + case WBT_FLASH: + case WBT_LED:*/ + default: + // recall custom WB settings if it exists, set to 1.0 otherwise + temp->setValue (temp->getAddMode() ? 0.0 : (double)(currMethod->temperature)); + green->setValue (green->getAddMode() ? 0.0 : custom_green[methodId]); + if (batchMode) { + temp->setEditedState (Edited); + green->setEditedState (Edited); + } + break; + } + } + + if (listener) + listener->panelChanged (EvWBMethod, row[methodColumns.colLabel]); } } @@ -175,74 +323,105 @@ void WhiteBalance::spotSizeChanged () { void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) { - disableListener (); methconn.block (true); if (pedited) { + // By default, temperature and green are said "UnEdited", but it may change later temp->setEditedState (UnEdited); green->setEditedState (UnEdited); } if (pedited && !pedited->wb.method) { - method->set_active (3); - opt = 3; + opt = setActiveMethod(M("GENERAL_UNCHANGED")); } else { - if (pp->wb.method == "Camera") { - method->set_active (0); - if (wbp) { - double ctemp; double cgreen; - wbp->getCamWB (ctemp, cgreen); - temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp); - green->setValue (green->getAddMode() ? 0.0 : cgreen); - cache_customWB ((int)ctemp, cgreen); // this will be used to set initial Custom WB setting - } - opt = 0; - } - else if (pp->wb.method == "Auto") { - method->set_active (1); - if (wbp) { - double ctemp; double cgreen; - wbp->getAutoWB (ctemp, cgreen); - temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp); - green->setValue (green->getAddMode() ? 0.0 : cgreen); - cache_customWB ((int)ctemp, cgreen); // this will be used to set initial Custom WB setting - } - opt = 1; - } - else if (pp->wb.method == "Custom") { - method->set_active (2); + WBEntry* wbValues = findWBEntry(pp->wb.method, WBLT_PP); + if (!wbValues) + wbValues = findWBEntry("Camera", WBLT_PP); + + opt = setActiveMethod(wbValues->GUILabel); + + // temperature is reset to the associated temperature, or 0.0 if addMode is set. + switch (wbValues->type) { + case WBT_CUSTOM: temp->setValue (pp->wb.temperature); green->setValue (pp->wb.green); - cache_customWB (pp->wb.temperature, pp->wb.green); - - opt = 2; if (pedited) { + // The user may have changed the temperature and green value temp->setEditedState (pedited->wb.temperature ? Edited : UnEdited); green->setEditedState (pedited->wb.green ? Edited : UnEdited); } + //cache_customWB (pp->wb.temperature, pp->wb.green); + break; + case WBT_CAMERA: + if (wbp) { + double ctemp; double cgreen; + wbp->getCamWB (ctemp, cgreen); + + // Set the camera's temperature value, or 0.0 if in ADD mode + temp->setValue (temp->getAddMode() ? 0.0 : ctemp); + // Set the camera's green value, or 0.0 if in ADD mode + green->setValue (green->getAddMode() ? 0.0 : cgreen); + + //cache_customWB ((int)ctemp, cgreen); // this will be used to set initial Custom WB setting + } + break; + case WBT_AUTO: + if (wbp) { + double ctemp; double cgreen; + wbp->getAutoWB (ctemp, cgreen); + + // Set the automatics temperature value, or 0.0 if in ADD mode + temp->setValue (temp->getAddMode() ? 0.0 : ctemp); + // Set the automatics green value, or 0.0 if in ADD mode + green->setValue (green->getAddMode() ? 0.0 : cgreen); + + //cache_customWB ((int)ctemp, cgreen); // this will be used to set initial Custom WB setting + } + break; + /* + All those types are the "default" case: + case WBT_DAYLIGHT: + case WBT_CLOUDY: + case WBT_SHADE: + case WBT_TUNGSTEN: + case WBT_FLUORESCENT: + case WBT_LAMP: + case WBT_FLASH: + case WBT_LED: + */ + default: + // Set the associated temperature, or 0.0 if in ADD mode + temp->setValue(temp->getAddMode() ? 0.0 : (double)wbValues->temperature); + // Set the stored temperature, or 0.0 if in ADD mode + green->setValue(green->getAddMode() ? 0.0 : pp->wb.green); + + // The user may have changed the green value even for predefined WB values + if (pedited) { + green->setEditedState (pedited->wb.green ? Edited : UnEdited); + } + //cache_customGreen (pp->wb.green); + break; } } methconn.block (false); - enableListener (); } void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) { + Gtk::TreeModel::Row row = getActiveMethod(); + if (pedited) { pedited->wb.temperature = temp->getEditedState (); pedited->wb.green = green->getEditedState (); - pedited->wb.method = method->get_active_row_number()!=3; + pedited->wb.method = row[methodColumns.colLabel]!=M("GENERAL_UNCHANGED"); } - if (method->get_active_row_number()==0) - pp->wb.method = "Camera"; - else if (method->get_active_row_number()==1) - pp->wb.method = "Custom"; // "Auto"; // "Auto" is never saved to PP3/XMP. However when reopening images (from RAM) it can lead to crashes because the values are not available yet. - else if (method->get_active_row_number()>=2) - pp->wb.method = "Custom"; - - pp->wb.temperature = (int)temp->getValue (); + WBEntry* ppMethod = findWBEntry (row[methodColumns.colLabel], WBLT_GUI); + + if (ppMethod) + pp->wb.method = ppMethod->ppLabel == "Auto" ? "Custom" : ppMethod->ppLabel; + pp->wb.temperature = temp->getIntValue (); pp->wb.green = green->getValue (); } @@ -261,7 +440,7 @@ void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited* temp->setDefault (temp->getAddMode() ? 0 : (int)ctemp); green->setDefault (green->getAddMode() ? 0 : cgreen); } - else if (defParams->wb.method == "Custom") { + else { temp->setDefault (defParams->wb.temperature); green->setDefault (defParams->wb.green); } @@ -280,7 +459,10 @@ void WhiteBalance::setBatchMode (bool batchMode) { ToolPanel::setBatchMode (batchMode); temp->showEditedCB (); green->showEditedCB (); - method->append_text (M("GENERAL_UNCHANGED")); + Gtk::TreeModel::Row row = *(refTreeModel->append()); + row[methodColumns.colId] = WBParams::wbEntries.size(); + row[methodColumns.colLabel] = M("GENERAL_UNCHANGED"); + } int WhiteBalance::getSize () { @@ -290,18 +472,20 @@ int WhiteBalance::getSize () { void WhiteBalance::setWB (int vtemp, double vgreen) { - disableListener (); + methconn.block(true); + WBEntry *wbValues = findWBEntry("Custom", WBLT_PP); temp->setValue (vtemp); green->setValue (vgreen); + opt = setActiveMethod(wbValues->GUILabel); cache_customWB (vtemp,vgreen); // sequence in which this call is made is important; must be before "method->set_active (2);" - method->set_active (2); temp->setEditedState (Edited); green->setEditedState (Edited); - enableListener (); + methconn.block(false); if (listener) listener->panelChanged (EvWBTemp, Glib::ustring::compose("%1, %2", (int)temp->getValue(), Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), green->getValue()))); } + void WhiteBalance::setAdjusterBehavior (bool tempadd, bool greenadd) { temp->setAddMode(tempadd); @@ -313,3 +497,67 @@ void WhiteBalance::trimValues (rtengine::procparams::ProcParams* pp) { temp->trimValue(pp->wb.temperature); green->trimValue(pp->wb.green); } + +inline void WhiteBalance::cache_customTemp(int temp) { + custom_temp = temp; +} + +void WhiteBalance::cache_customGreen(double green) { + Gtk::TreeModel::Row row = getActiveMethod(); + if (row == refTreeModel->children().end()) return; + + custom_green[row[methodColumns.colId]] = green; + //printf("WhiteBalance::cache_customWB(%d, %f): the \"green\" value of \"%s\" has been set to: %f\n", temp, green, row[methodColumns.colLabel], custom_green[row[methodColumns.colId]]); +} + +void WhiteBalance::cache_customWB(int temp, double green) { + cache_customTemp (temp); + cache_customGreen (green); +} + +int WhiteBalance::findWBEntryId (Glib::ustring label, enum WB_LabelType lblType) { + for (unsigned int i=0; iGUILabel : WBParams::wbEntries[i]->ppLabel)) + return i; + } + return -1; +} + +WBEntry* WhiteBalance::findWBEntry (Glib::ustring label, enum WB_LabelType lblType) { + for (unsigned int i=0; iGUILabel : WBParams::wbEntries[i]->ppLabel)) + return WBParams::wbEntries[i]; + } + return NULL; +} + +int WhiteBalance::_setActiveMethod(Glib::ustring &label, Gtk::TreeModel::Children &children) { + int found = -1; + for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end() && found==-1; ++iter) { + Gtk::TreeModel::Row row = *iter; + if (row[methodColumns.colLabel] == label) { + method->set_active(iter); + found = method->get_active_row_number(); + } + if (found !=-1) + return found; + + Gtk::TreeModel::Children childs = row.children(); + if (childs.size()) { + found = _setActiveMethod(label, childs); + if (found !=-1) + return found; + } + } + // Entry not found + return -1; +} + +int WhiteBalance::setActiveMethod(Glib::ustring label) { + Gtk::TreeModel::Children children = refTreeModel->children(); + return _setActiveMethod(label, children); +} + +inline Gtk::TreeRow WhiteBalance::getActiveMethod () { + return *(method->get_active()); +} diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h index f22790980..c57d1d8c5 100644 --- a/rtgui/whitebalance.h +++ b/rtgui/whitebalance.h @@ -24,6 +24,7 @@ #include #include #include +#include "procparams.h" class SpotWBListener { @@ -33,8 +34,24 @@ class SpotWBListener { class WhiteBalance : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel { + enum WB_LabelType { + WBLT_GUI, + WBLT_PP + }; + protected: - MyComboBoxText* method; + class MethodColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn< Glib::RefPtr > colIcon; + Gtk::TreeModelColumn colLabel; + Gtk::TreeModelColumn colId; + MethodColumns() { add(colIcon); add(colLabel); add(colId); } + }; + + static Glib::RefPtr wbPixbufs[rtengine::procparams::WBT_CUSTOM+1]; + Glib::RefPtr refTreeModel; + MethodColumns methodColumns; + MyComboBox* method; MyComboBoxText* spotsize; Adjuster* temp; Adjuster* green; @@ -46,13 +63,24 @@ class WhiteBalance : public Gtk::VBox, public AdjusterListener, public FoldableT SpotWBListener* wblistener; sigc::connection methconn; int custom_temp; - double custom_green; - void cache_customWB(int temp, double green){custom_temp = temp; custom_green=green;}; //cache custom WB setting to allow its recall + double* custom_green; + void cache_customWB (int temp, double green); //cache custom WB setting to allow its recall + void cache_customTemp (int temp); //cache Temperature only to allow its recall + void cache_customGreen (double green); //cache Green only to allow its recall + int setActiveMethod (Glib::ustring label); + int _setActiveMethod (Glib::ustring &label, Gtk::TreeModel::Children &children); + + Gtk::TreeModel::Row getActiveMethod (); + int findWBEntryId (Glib::ustring label, enum WB_LabelType lblType=WBLT_GUI); + rtengine::procparams::WBEntry* findWBEntry (Glib::ustring label, enum WB_LabelType lblType=WBLT_GUI); public: WhiteBalance (); + ~WhiteBalance (); + static void init (); + static void cleanup (); 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); diff --git a/tools/source_icons/scalable/wb-auto.file b/tools/source_icons/scalable/wb-auto.file new file mode 100644 index 000000000..66d3a295b --- /dev/null +++ b/tools/source_icons/scalable/wb-auto.file @@ -0,0 +1 @@ +wb-auto.png,w22 diff --git a/tools/source_icons/scalable/wb-auto.svg b/tools/source_icons/scalable/wb-auto.svg new file mode 100644 index 000000000..59b8799a2 --- /dev/null +++ b/tools/source_icons/scalable/wb-auto.svg @@ -0,0 +1,638 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-camera.file b/tools/source_icons/scalable/wb-camera.file new file mode 100644 index 000000000..9e9215362 --- /dev/null +++ b/tools/source_icons/scalable/wb-camera.file @@ -0,0 +1 @@ +wb-camera.png,w22 diff --git a/tools/source_icons/scalable/wb-camera.svg b/tools/source_icons/scalable/wb-camera.svg new file mode 100644 index 000000000..119b4a9a6 --- /dev/null +++ b/tools/source_icons/scalable/wb-camera.svg @@ -0,0 +1,650 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-cloudy.file b/tools/source_icons/scalable/wb-cloudy.file new file mode 100644 index 000000000..e67541471 --- /dev/null +++ b/tools/source_icons/scalable/wb-cloudy.file @@ -0,0 +1 @@ +wb-cloudy.png,w22 diff --git a/tools/source_icons/scalable/wb-cloudy.svg b/tools/source_icons/scalable/wb-cloudy.svg new file mode 100644 index 000000000..1929d5c93 --- /dev/null +++ b/tools/source_icons/scalable/wb-cloudy.svg @@ -0,0 +1,640 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-custom.file b/tools/source_icons/scalable/wb-custom.file new file mode 100644 index 000000000..d84fcd118 --- /dev/null +++ b/tools/source_icons/scalable/wb-custom.file @@ -0,0 +1 @@ +wb-custom.png,w22 diff --git a/tools/source_icons/scalable/wb-custom.svg b/tools/source_icons/scalable/wb-custom.svg new file mode 100644 index 000000000..c0334549f --- /dev/null +++ b/tools/source_icons/scalable/wb-custom.svg @@ -0,0 +1,655 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-flash.file b/tools/source_icons/scalable/wb-flash.file new file mode 100644 index 000000000..0da5e23a6 --- /dev/null +++ b/tools/source_icons/scalable/wb-flash.file @@ -0,0 +1 @@ +wb-flash.png,w22 diff --git a/tools/source_icons/scalable/wb-flash.svg b/tools/source_icons/scalable/wb-flash.svg new file mode 100644 index 000000000..b2ee41891 --- /dev/null +++ b/tools/source_icons/scalable/wb-flash.svg @@ -0,0 +1,639 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-fluorescent.file b/tools/source_icons/scalable/wb-fluorescent.file new file mode 100644 index 000000000..9c1926282 --- /dev/null +++ b/tools/source_icons/scalable/wb-fluorescent.file @@ -0,0 +1 @@ +wb-fluorescent.png,w22 diff --git a/tools/source_icons/scalable/wb-fluorescent.svg b/tools/source_icons/scalable/wb-fluorescent.svg new file mode 100644 index 000000000..439fe43be --- /dev/null +++ b/tools/source_icons/scalable/wb-fluorescent.svg @@ -0,0 +1,697 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-lamp.file b/tools/source_icons/scalable/wb-lamp.file new file mode 100644 index 000000000..1e7ba8fa3 --- /dev/null +++ b/tools/source_icons/scalable/wb-lamp.file @@ -0,0 +1 @@ +wb-lamp.png,w22 diff --git a/tools/source_icons/scalable/wb-lamp.svg b/tools/source_icons/scalable/wb-lamp.svg new file mode 100644 index 000000000..bf1e45350 --- /dev/null +++ b/tools/source_icons/scalable/wb-lamp.svg @@ -0,0 +1,1330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-led.file b/tools/source_icons/scalable/wb-led.file new file mode 100644 index 000000000..1327fd240 --- /dev/null +++ b/tools/source_icons/scalable/wb-led.file @@ -0,0 +1 @@ +wb-led.png,w22 diff --git a/tools/source_icons/scalable/wb-led.svg b/tools/source_icons/scalable/wb-led.svg new file mode 100644 index 000000000..a6048bf01 --- /dev/null +++ b/tools/source_icons/scalable/wb-led.svg @@ -0,0 +1,737 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-shade.file b/tools/source_icons/scalable/wb-shade.file new file mode 100644 index 000000000..0f21c85bd --- /dev/null +++ b/tools/source_icons/scalable/wb-shade.file @@ -0,0 +1 @@ +wb-shade.png,w22 diff --git a/tools/source_icons/scalable/wb-shade.svg b/tools/source_icons/scalable/wb-shade.svg new file mode 100644 index 000000000..871321180 --- /dev/null +++ b/tools/source_icons/scalable/wb-shade.svg @@ -0,0 +1,694 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-sun.file b/tools/source_icons/scalable/wb-sun.file new file mode 100644 index 000000000..026bc82f6 --- /dev/null +++ b/tools/source_icons/scalable/wb-sun.file @@ -0,0 +1 @@ +wb-sun.png,w22 diff --git a/tools/source_icons/scalable/wb-sun.svg b/tools/source_icons/scalable/wb-sun.svg new file mode 100644 index 000000000..222177600 --- /dev/null +++ b/tools/source_icons/scalable/wb-sun.svg @@ -0,0 +1,724 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-tungsten.file b/tools/source_icons/scalable/wb-tungsten.file new file mode 100644 index 000000000..a27d226a0 --- /dev/null +++ b/tools/source_icons/scalable/wb-tungsten.file @@ -0,0 +1 @@ +wb-tungsten.png,w22 diff --git a/tools/source_icons/scalable/wb-tungsten.svg b/tools/source_icons/scalable/wb-tungsten.svg new file mode 100644 index 000000000..5d172c203 --- /dev/null +++ b/tools/source_icons/scalable/wb-tungsten.svg @@ -0,0 +1,697 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + +