diff --git a/rtdata/images/Dark/actions/wb-water.png b/rtdata/images/Dark/actions/wb-water.png
new file mode 100644
index 000000000..196869abf
Binary files /dev/null and b/rtdata/images/Dark/actions/wb-water.png differ
diff --git a/rtdata/images/Light/actions/wb-water.png b/rtdata/images/Light/actions/wb-water.png
new file mode 100644
index 000000000..a1ae414af
Binary files /dev/null and b/rtdata/images/Light/actions/wb-water.png differ
diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais
index 94a3b199a..50f65572b 100644
--- a/rtdata/languages/Francais
+++ b/rtdata/languages/Francais
@@ -443,6 +443,7 @@ HISTORY_MSG_204;Niveau d'amélioration LMMSE
HISTORY_MSG_205;CAM02 pixels chauds/morts
HISTORY_MSG_206;CAT02 - Adapt. auto à la scène
HISTORY_MSG_207;A.C. - Teinte
+HISTORY_MSG_208;Égaliseur Bleu/Rouge
HISTORY_NEWSNAPSHOTAS;Sous...
HISTORY_NEWSNAPSHOT;Ajouter
HISTORY_NEWSNAPSHOT_TOOLTIP;Raccourci: Alt-s
@@ -554,7 +555,7 @@ MAIN_TAB_DETAIL;Détail
MAIN_TAB_DETAIL_TOOLTIP;Alt-d
MAIN_TAB_DEVELOP; Développer
MAIN_TAB_EXIF;EXIF
-MAIN_TAB_EXPORT; Exporter
+MAIN_TAB_EXPORT;Export Rapide
MAIN_TAB_EXPOSURE;Exposition
MAIN_TAB_EXPOSURE_TOOLTIP;Alt-e
MAIN_TAB_FILTER; Filtrer
@@ -787,8 +788,8 @@ PREFERENCES_MULTITABDUALMON;Éditeurs multiple, si possible sur un second monite
PREFERENCES_MULTITAB;Éditeurs multiple
PREFERENCES_OUTDIRFOLDERHINT;Place les images traitées dans le dossier selectionné
PREFERENCES_OUTDIRFOLDER;Dossier de sauvegarde
-PREFERENCES_OUTDIRHINT;Vous pouvez utiliser les paramètres de chaîne formatées suivants:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nCes paramètres de chaînes formatées se réfèrent aux dossiers et sous-chemins du chemin du fichier RAW.\n\nPar exemple, si /home/tom/image/02-09-2006/dsc0012.nefa été ouvert, la signification des paramètres est:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nSi vous voulez enregistrer l'image de sortie là où se trouve l'originale, écrivez:\n%p1/%f\n\nSi vous voulez enregistrer l'image de sortie dans un dossier 'convertis' situé dans le dossier de l'originale, écrivez:\n%p1/convertis/%f\n\nSi vous voulez enregistrer l'image de sortie dans le dossier '/home/tom/convertis' en conservant le même sous-dossier de dates, écrivez:\n%p2/convertis/%d1/%f
-PREFERENCES_OUTDIRTEMPLATEHINT;Vous pouvez utiliser les paramètres de chaîne formatées suivants:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nCes paramètres de chaînes formatées se réfèrent aux dossiers et sous-chemins du chemin du fichier RAW.\n\nPar exemple, si /home/tom/image/02-09-2006/dsc0012.nefa été ouvert, la signification des paramètres est:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nSi vous voulez enregistrer l'image de sortie là où se trouve l'originale, écrivez:\n%p1/%f\n\nSi vous voulez enregistrer l'image de sortie dans un dossier 'convertis' situé dans le dossier de l'originale, écrivez:\n%p1/convertis/%f\n\nSi vous voulez enregistrer l'image de sortie dans le dossier '/home/tom/convertis' en conservant le même sous-dossier de dates, écrivez:\n%p2/convertis/%d1/%f
+PREFERENCES_OUTDIRHINT;Vous pouvez utiliser les paramètres de chaîne formatées suivants:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nCes chaînes de formattage se réfèrent aux différentes parties du chemin de la photo ou certains de ses attributs.\n\nPar exemple, si la photo en cours de traitement a le chemin suivant:\n/home/tom/image/02-09-2006/dsc0012.nef\nla signification des chaînes de formattage est:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/tom/photos/\n%p3 = /home/tom/\n%p4 = /home/\n\n%r sera remplacé par le rang de la photo. Si la photo n'a pas de rang, %r sera remplacé par '0'. Si la photo est dans la corbeille de RawTherapee, %r sera remplacé par 'x'.\n\nSi vous voulez enregistrer l'image de sortie là où se trouve l'originale, écrivez:\n%p1/%f\n\nSi vous voulez enregistrer l'image de sortie dans un dossier nommé "convertis" situé dans le dossier de l'originale, écrivez:\n%p1/convertis/%f\n\nSi vous voulez enregistrer l'image de sortie dans un dossier nommé "/home/tom/photos/convertis/2010-10-31", écrivez:\n%p2/convertis/%d1/%f
+PREFERENCES_OUTDIRTEMPLATEHINT;Vous pouvez utiliser les paramètres de chaîne formatées suivants:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nCes chaînes de formattage se réfèrent aux différentes parties du chemin de la photo, certains de ses attributs ou un numéro de séquence arbitraire dans le traitement par lot.\n\nPar exemple, si la photo en cours de traitement a le chemin suivant:\n/home/tom/image/02-09-2006/dsc0012.nef\nla signification des chaînes de formattage est:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/tom/photos/\n%p3 = /home/tom/\n%p4 = /home/\n\n%r sera remplacé par le rang de la photo. Si la photo n'a pas de rang, %r sera remplacé par '0'. Si la photo est dans la corbeille de RawTherapee, %r sera remplacé par 'x'.\n\n%s1, %s2, etc. sera remplacé par un index de séquence constitué de 1 à 9 chiffre. L'index de la séquence commencera à 1 à chaque fois que le file de traitement est démarrée, et est incrémenté de 1 pour chaque image traitée.\n\nSi vous voulez enregistrer l'image de sortie là où se trouve l'originale, écrivez:\n%p1/%f\n\nSi vous voulez enregistrer l'image de sortie dans un dossier nommé "convertis" situé dans le dossier de l'originale, écrivez:\n%p1/convertis/%f\n\nSi vous voulez enregistrer l'image de sortie dans un dossier nommé "/home/tom/photos/convertis/2010-10-31", écrivez:\n%p2/convertis/%d1/%f
PREFERENCES_OUTDIRTEMPLATE;Utiliser le modèle
PREFERENCES_OUTDIR;Dossier de sortie
PREFERENCES_OVERLAY_FILENAMES;Superposer les noms de fichier sur les vignettes
@@ -979,11 +980,11 @@ TP_COLORAPP_GAMUT_TOOLTIP;Permet le controle du gamut en mode Lab
TP_COLORAPP_HUE;Teinte (h)
TP_COLORAPP_HUE_TOOLTIP;Teinte (h) - angle entre 0° et 360°
TP_COLORAPP_LABEL;Apparence de la Couleur (CIECAM02)
-TP_COLORAPP_LABEL_CAM02;Édition de l'image avec CIECAM
+TP_COLORAPP_LABEL_CAM02;Édition de l'image avec CIE-CAM 2002
TP_COLORAPP_LABEL_SCENE;Conditions de la scène
TP_COLORAPP_LABEL_VIEWING;Conditions de visionnage
TP_COLORAPP_LIGHT;Luminosité (J)
-TP_COLORAPP_LIGHT_TOOLTIP;Luminosité dans CIECAM02 est différent de Lab et RVB
+TP_COLORAPP_LIGHT_TOOLTIP;Luminosité dans CIECAM02 est différent de celui de Lab et RVB
TP_COLORAPP_MODEL;Modèle de Point Blanc
TP_COLORAPP_MODEL_TOOLTIP;BB [RT] + [sortie]:\nLa BB de RT est utilisée pour la scène, CIECAM est réglé sur D50, le blanc du périphérique de sortie utilise la valeur réglée dans Préférences\n\nBB [RT+CAT02] + [sortie]:\nLes réglages de BB de RT sont utilisés par CAT02 et le blanc du périphérique de sortie utilise la valeur réglée dans Préférences
TP_COLORAPP_RSTPRO;Protection des tons chairs et rouges
@@ -1006,8 +1007,8 @@ TP_COLORAPP_TCMODE_LABEL2;Courbe mode 2
TP_COLORAPP_TCMODE_LABEL3;Courbe chroma mode
TP_COLORAPP_TCMODE_LIGHTNESS;Luminosité
TP_COLORAPP_TCMODE_SATUR;Saturation
-TP_COLORAPP_TONECIE;Compression tonale avec brillance Q CIECAM
-TP_COLORAPP_TONECIE_TOOLTIP;Si vous choisissez cette option, tous les réglages "compression tonale" (si activé) seront utilisés par CIECAM
+TP_COLORAPP_TONECIE;Compression Tonale utilisant la Brillance CIECAM02 (Q)
+TP_COLORAPP_TONECIE_TOOLTIP;Si cette option est désactivée, la compression tonale est faite dans l'espace Lab.\nSi cette options est activée, la compression tonale est faite en utilisant CIECAM02.\nL'outil Compression Tonale doit être activé pour que ce réglage prenne effet
TP_COLORAPP_WBCAM;BB [RT+CAT02] + [sortie]
TP_COLORAPP_WBRT;BB [RT] + [sortie]
TP_CROP_FIXRATIO;Ratio fixe:
@@ -1317,10 +1318,14 @@ TP_VIGNETTING_LABEL;Correction vignettage
TP_VIGNETTING_RADIUS;Rayon
TP_VIGNETTING_STRENGTH;Force
TP_WBALANCE_AUTO;Auto
+TP_WBALANCE_EQBLUERED;Égaliseur Bleu/Rouge
+TP_WBALANCE_EQBLUERED_TOOLTIP;Permet de dévier du comportement normal de la "balance des blancs" en modulant la balance bleu/rouge.\nCeci peut être utile lorsque les conditions de prise de vue:\na) sont loins de l'illuminant strandard (ex: sous-marin)\nb) sont loins des conditions où a été réalisé le calibrage\nc) où les matrices ou les profiles ICC sont incorrect
TP_WBALANCE_CAMERA;Appareil photo
TP_WBALANCE_CLOUDY;Nuageux
TP_WBALANCE_CUSTOM;Personnalisé
TP_WBALANCE_DAYLIGHT;Lumière du jour (ensoleillé)
+TP_WBALANCE_WATER1;Sous-marin 1
+TP_WBALANCE_WATER2;Sous-marin 2
TP_WBALANCE_FLASH55;Leica
TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus
TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta
@@ -1338,6 +1343,7 @@ 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_WATER_HEADER;Sous-marin
TP_WBALANCE_GREEN;Teinte
TP_WBALANCE_GTI;GTI
TP_WBALANCE_HMI;HMI
diff --git a/rtdata/languages/default b/rtdata/languages/default
index 867e7b31d..fd385517e 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -442,6 +442,7 @@ HISTORY_MSG_204;LMMSE Enhancement Steps
HISTORY_MSG_205;CAM02 hot/bad pixels
HISTORY_MSG_206;CAT02 - Adapt scene auto
HISTORY_MSG_207;Defringing Hue curve
+HISTORY_MSG_208;Blue/Red Equalizer
HISTORY_NEWSNAPSHOTAS;As...
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
@@ -1297,10 +1298,14 @@ TP_VIGNETTING_LABEL;Vignetting Correction
TP_VIGNETTING_RADIUS;Radius
TP_VIGNETTING_STRENGTH;Strength
TP_WBALANCE_AUTO;Auto
+TP_WBALANCE_EQBLUERED;Blue/Red Equalizer
+TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater)\nb) are far from conditions where calibrations were performed\nc) where the matrices or ICC profiles are unsuitable
TP_WBALANCE_CAMERA;Camera
TP_WBALANCE_CLOUDY;Cloudy
TP_WBALANCE_CUSTOM;Custom
TP_WBALANCE_DAYLIGHT;Daylight (sunny)
+TP_WBALANCE_WATER1;UnderWater 1
+TP_WBALANCE_WATER2;UnderWater 2
TP_WBALANCE_FLASH55;Leica
TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus
TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta
@@ -1318,6 +1323,7 @@ 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_WATER_HEADER;UnderWater
TP_WBALANCE_GREEN;Tint
TP_WBALANCE_GTI;GTI
TP_WBALANCE_HMI;HMI
diff --git a/rtdata/profiles/BW 1.pp3 b/rtdata/profiles/BW 1.pp3
index 35b98a56e..d3cd5b2e3 100644
--- a/rtdata/profiles/BW 1.pp3
+++ b/rtdata/profiles/BW 1.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=true
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/BW 2.pp3 b/rtdata/profiles/BW 2.pp3
index e5776e196..20c2a77aa 100644
--- a/rtdata/profiles/BW 2.pp3
+++ b/rtdata/profiles/BW 2.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=true
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/BW 3.pp3 b/rtdata/profiles/BW 3.pp3
index 57056f116..247d259ca 100644
--- a/rtdata/profiles/BW 3.pp3
+++ b/rtdata/profiles/BW 3.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=true
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/BW 4.pp3 b/rtdata/profiles/BW 4.pp3
index 3622735f0..fa5e85770 100644
--- a/rtdata/profiles/BW 4.pp3
+++ b/rtdata/profiles/BW 4.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=true
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/Default ISO High.pp3 b/rtdata/profiles/Default ISO High.pp3
index e444007d3..64a7eb1f2 100644
--- a/rtdata/profiles/Default ISO High.pp3
+++ b/rtdata/profiles/Default ISO High.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=true
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/Default ISO Medium.pp3 b/rtdata/profiles/Default ISO Medium.pp3
index 087152360..6e0e14b7e 100644
--- a/rtdata/profiles/Default ISO Medium.pp3
+++ b/rtdata/profiles/Default ISO Medium.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=true
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/Default.pp3 b/rtdata/profiles/Default.pp3
index afa142023..a0f9c70f0 100644
--- a/rtdata/profiles/Default.pp3
+++ b/rtdata/profiles/Default.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=true
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/High-Key.pp3 b/rtdata/profiles/High-Key.pp3
index 994216d6a..8027d2b3a 100644
--- a/rtdata/profiles/High-Key.pp3
+++ b/rtdata/profiles/High-Key.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=true
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/Natural 1.pp3 b/rtdata/profiles/Natural 1.pp3
index 547335365..59bdab717 100644
--- a/rtdata/profiles/Natural 1.pp3
+++ b/rtdata/profiles/Natural 1.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=true
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/Natural 2.pp3 b/rtdata/profiles/Natural 2.pp3
index 403f2adf8..97aa4d4f5 100644
--- a/rtdata/profiles/Natural 2.pp3
+++ b/rtdata/profiles/Natural 2.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=true
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/Neutral.pp3 b/rtdata/profiles/Neutral.pp3
index 36028335c..014cee165 100644
--- a/rtdata/profiles/Neutral.pp3
+++ b/rtdata/profiles/Neutral.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=false
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/Pop 1.pp3 b/rtdata/profiles/Pop 1.pp3
index 340e8f0da..af57d5f21 100644
--- a/rtdata/profiles/Pop 1.pp3
+++ b/rtdata/profiles/Pop 1.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=false
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5325
Green=1.162
+Equal=1.0
[Color appearance]
Enabled=true
diff --git a/rtdata/profiles/Pop 2 L.pp3 b/rtdata/profiles/Pop 2 L.pp3
index d2e68f3b3..1c1aa8309 100644
--- a/rtdata/profiles/Pop 2 L.pp3
+++ b/rtdata/profiles/Pop 2 L.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=false
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5325
Green=1.162
+Equal=1.0
[Color appearance]
Enabled=true
diff --git a/rtdata/profiles/Pop 3 Skin.pp3 b/rtdata/profiles/Pop 3 Skin.pp3
index 91690b431..c6b6afcde 100644
--- a/rtdata/profiles/Pop 3 Skin.pp3
+++ b/rtdata/profiles/Pop 3 Skin.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=false
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5388
Green=1.101
+Equal=1.0
[Color appearance]
Enabled=true
diff --git a/rtdata/profiles/Pop 4 BW.pp3 b/rtdata/profiles/Pop 4 BW.pp3
index e1d8e45f7..b1d97dfb3 100644
--- a/rtdata/profiles/Pop 4 BW.pp3
+++ b/rtdata/profiles/Pop 4 BW.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=false
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=7922
Green=1.159
+Equal=1.0
[Color appearance]
Enabled=true
diff --git a/rtdata/profiles/Portrait Smooth.pp3 b/rtdata/profiles/Portrait Smooth.pp3
index d4180284c..8a02bc209 100644
--- a/rtdata/profiles/Portrait Smooth.pp3
+++ b/rtdata/profiles/Portrait Smooth.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=false
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=7922
Green=1.159
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/Punchy 1.pp3 b/rtdata/profiles/Punchy 1.pp3
index 4cd2437eb..a560e2ae5 100644
--- a/rtdata/profiles/Punchy 1.pp3
+++ b/rtdata/profiles/Punchy 1.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=true
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/Punchy 2.pp3 b/rtdata/profiles/Punchy 2.pp3
index 880d5dd93..322a8adb9 100644
--- a/rtdata/profiles/Punchy 2.pp3
+++ b/rtdata/profiles/Punchy 2.pp3
@@ -1,6 +1,6 @@
[Version]
-AppVersion=4.0.11.0
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=true
@@ -80,6 +80,7 @@ Uniformity=50
Setting=Camera
Temperature=5745
Green=1.0
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtdata/profiles/Skintones - Natural TM.pp3 b/rtdata/profiles/Skintones - Natural TM.pp3
index b6b964ead..25ca695c7 100644
--- a/rtdata/profiles/Skintones - Natural TM.pp3
+++ b/rtdata/profiles/Skintones - Natural TM.pp3
@@ -1,7 +1,7 @@
[Version]
-AppVersion=4.0.11
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=false
@@ -81,6 +81,7 @@ Uniformity=50
Setting=Camera
Temperature=4500
Green=1.073
+Equal=1.0
[Color appearance]
Enabled=true
diff --git a/rtdata/profiles/Skintones - Natural.pp3 b/rtdata/profiles/Skintones - Natural.pp3
index 5af0e7d94..4bf701556 100644
--- a/rtdata/profiles/Skintones - Natural.pp3
+++ b/rtdata/profiles/Skintones - Natural.pp3
@@ -1,7 +1,7 @@
[Version]
-AppVersion=4.0.11
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=false
@@ -81,6 +81,7 @@ Uniformity=50
Setting=Camera
Temperature=4500
Green=1.073
+Equal=1.0
[Color appearance]
Enabled=true
diff --git a/rtdata/profiles/Skintones - Pale TM Bright.pp3 b/rtdata/profiles/Skintones - Pale TM Bright.pp3
index b7e0d227e..5f45b9f3e 100644
--- a/rtdata/profiles/Skintones - Pale TM Bright.pp3
+++ b/rtdata/profiles/Skintones - Pale TM Bright.pp3
@@ -1,7 +1,7 @@
[Version]
-AppVersion=4.0.11
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=false
@@ -81,6 +81,7 @@ Uniformity=50
Setting=Camera
Temperature=4500
Green=1.073
+Equal=1.0
[Color appearance]
Enabled=true
diff --git a/rtdata/profiles/Skintones - Pale TM.pp3 b/rtdata/profiles/Skintones - Pale TM.pp3
index e6dda592f..666f50210 100644
--- a/rtdata/profiles/Skintones - Pale TM.pp3
+++ b/rtdata/profiles/Skintones - Pale TM.pp3
@@ -1,7 +1,7 @@
[Version]
-AppVersion=4.0.11
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=false
@@ -80,7 +80,8 @@ Uniformity=50
[White Balance]
Setting=Camera
Temperature=5699
-Green=1.0329999999999999
+Green=1.033
+Equal=1.0
[Color appearance]
Enabled=true
diff --git a/rtdata/profiles/Skintones - Pale.pp3 b/rtdata/profiles/Skintones - Pale.pp3
index 9eb5d535a..a83f71a95 100644
--- a/rtdata/profiles/Skintones - Pale.pp3
+++ b/rtdata/profiles/Skintones - Pale.pp3
@@ -1,7 +1,7 @@
[Version]
-AppVersion=4.0.11
-Version=308
+AppVersion=4.0.11.20
+Version=309
[Exposure]
Auto=false
@@ -80,7 +80,8 @@ Uniformity=50
[White Balance]
Setting=Camera
Temperature=4670
-Green=1.1000000000000001
+Green=1.1
+Equal=1.0
[Color appearance]
Enabled=false
diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc
index d5ac4c9c7..6bd46de32 100644
--- a/rtengine/colortemp.cc
+++ b/rtengine/colortemp.cc
@@ -26,6 +26,8 @@
#include
#include "mytime.h"
#include "sleef.c"
+#include "../rtgui/options.h"
+
#undef CLIPD
#define CLIPD(a) ((a)>0.0?((a)<1.0?(a):1.0):0.0)
#define CLIPQQ(a) ((a)>0?((a)<250?(a):250):0)
@@ -34,7 +36,7 @@
namespace rtengine {
using namespace procparams;
-extern const Settings* settings;
+ extern const Settings* settings;
static const double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desmis observer 2°
{0.0000000,0.000000,0.000000}, {0.0000000,0.000000,0.000000}, {0.0001299,0.0003917,0.0006061},
@@ -72,9 +74,9 @@ extern const Settings* settings;
{0.000001251141,0.00000045181,0.000000}
};
-ColorTemp::ColorTemp (double t, double g, Glib::ustring m) : temp(t), green(g), method(m) {
+ColorTemp::ColorTemp (double t, double g, double e, Glib::ustring m) : temp(t), green(g), equal(e), method(m) {
- clip (temp, green);
+ clip (temp, green, equal);
}
void ColorTemp::clip (double &temp, double &green) {
@@ -83,26 +85,44 @@ void ColorTemp::clip (double &temp, double &green) {
temp = MINTEMP;
else if (temp > MAXTEMP)
temp = MAXTEMP;
-
+
if (green < MINGREEN)
green = MINGREEN;
else if (green > MAXGREEN)
green = MAXGREEN;
}
-ColorTemp::ColorTemp (double mulr, double mulg, double mulb) {
- method = "Custom";
- mul2temp (mulr, mulg, mulb, temp, green);
+void ColorTemp::clip (double &temp, double &green, double &equal) {
+
+ if (temp < MINTEMP)
+ temp = MINTEMP;
+ else if (temp > MAXTEMP)
+ temp = MAXTEMP;
+
+ if (green < MINGREEN)
+ green = MINGREEN;
+ else if (green > MAXGREEN)
+ green = MAXGREEN;
+
+ if(equal < MINEQUAL)
+ equal = MINEQUAL;
+ else if(equal > MAXEQUAL)
+ equal = MAXEQUAL;
}
-void ColorTemp::mul2temp (double rmul, double gmul, double bmul, double& temp, double& green) {
+ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e) : equal(e) {
+ method = "Custom";
+ mul2temp (mulr, mulg, mulb, equal, temp, green);
+}
- double maxtemp=(double)MAXTEMP, mintemp=(double)MINTEMP;
+void ColorTemp::mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green) {
+
+ 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);
+ temp2mul (temp, 1.0, equal, tmpr, tmpg, tmpb);
if (tmpb/tmpr > bmul/rmul)
maxtemp = temp;
else
@@ -114,7 +134,7 @@ void ColorTemp::mul2temp (double rmul, double gmul, double bmul, double& temp, d
}
-// spectral data for Daylight direct Sun: I have choose 5300K beacuse Nikon=5200K, Olympus=5300K, Panasonic=5500K, Leica=5400K, Minolta=5100K
+// spectral data for Daylight direct Sun: I have choose 5300K because Nikon=5200K, Olympus=5300K, Panasonic=5500K, Leica=5400K, Minolta=5100K
const double ColorTemp::Daylight5300_spect[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,
@@ -122,7 +142,7 @@ const double ColorTemp::Daylight5300_spect[97] = {
63.88,67.13,68.85,70.57
};
-//spectral data for Daylight Cloudy: I have choose 6200K beacuse Nikon=6000K, Olympus=6000K, Panasonic=6200K, Leica=6400K, Minolta=6500K
+//spectral data for Daylight Cloudy: I have choose 6200K because Nikon=6000K, Olympus=6000K, Panasonic=6200K, Leica=6400K, Minolta=6500K
const double ColorTemp::Cloudy6200_spect[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,
@@ -130,7 +150,7 @@ const double ColorTemp::Cloudy6200_spect[97] = {
53.63,56.47,59.31,60.80,62.29
};
-//spectral data for Daylight Shade: I have choose 7600K beacuse Nikon=8000K, Olympus=7500K, Panasonic=7500K, Leica=7500K, Minolta=7500K
+//spectral data for Daylight Shade: I have choose 7600K because Nikon=8000K, Olympus=7500K, Panasonic=7500K, Leica=7500K, Minolta=7500K
const double ColorTemp::Shade7600_spect[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,
@@ -1229,8 +1249,10 @@ void ColorTemp::temp2mulxyz (double tem, double gree, Glib::ustring method ,doub
double m1, m2;
if (tem<=7000)
x_D = -4.6070e9/(tem*tem*tem) + 2.9678e6/(tem*tem) + 0.09911e3/tem + 0.244063;
- else
- x_D = -2.0064e9/(tem*tem*tem) + 1.9018e6/(tem*tem) + 0.24748e3/tem + 0.237040;
+ else if (tem <=25000)
+ x_D = -2.0064e9/(tem*tem*tem) + 1.9018e6/(tem*tem) + 0.24748e3/tem + 0.237040;
+ else if (tem >25000)
+ x_D = -2.0064e9/(tem*tem*tem) + 1.9018e6/(tem*tem) + 0.24748e3/tem + 0.237040 - ((tem-25000)/25000)*0.025;//Jacques empirical adjustemnt for very high temp (underwater !)
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
@@ -1253,9 +1275,12 @@ void ColorTemp::temp2mulxyz (double tem, double gree, Glib::ustring method ,doub
//printf("Xxyz=%f Zxyz=%f\n",Xxyz,Zxyz);
}
-void ColorTemp::temp2mul (double temp, double green, double& rmul, double& gmul, double& bmul) {
+void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul) {
+
+ clip (temp, green, equal);
+
+ //printf("temp=%d green=%.3f equal=%.3f\n", (int)temp, (float) green, (float) equal);
- clip (temp, green);
//variables for CRI and display Lab, and palette
bool CRI_type=false;
double xD, yD, x_D, y_D, interm;
@@ -1281,10 +1306,6 @@ void ColorTemp::temp2mul (double temp, double green, double& rmul, double& gmul,
double Lbb[50],abb[50],bbb[50];
double Lpal[50],apal[50],bpal[50];
- float DeltaE[50], DeltaEs[8];
- float quadCRI=0.0f,quadCRIs=0.0f;
- float CRI_RT=0.0, CRI[50];
- float CRI_RTs=0.0, CRIs[8];
int palet=-1;
bool palette=true;
// double tempalet; // correlated temperature
@@ -1330,10 +1351,12 @@ void ColorTemp::temp2mul (double temp, double green, double& rmul, double& gmul,
palet=29;
if (temp<=7000)
x_D = -4.6070e9/(temp*temp*temp) + 2.9678e6/(temp*temp) + 0.09911e3/temp + 0.244063;
- else
+ else if (temp <=25000)
x_D = -2.0064e9/(temp*temp*temp) + 1.9018e6/(temp*temp) + 0.24748e3/temp + 0.237040;
+ else if (temp >25000) // above 25000 it's unknown..then I have modified to adjust for underwater
+ x_D = -2.0064e9/(temp*temp*temp) + 1.9018e6/(temp*temp) + 0.24748e3/temp + 0.237040 - ((temp-25000)/25000)*0.025;//Jacques empirical adjustemnt for very high temp (underwater !)
- y_D = -3.0*x_D*x_D + 2.87*x_D - 0.275;
+ y_D = (-3.0*x_D*x_D + 2.87*x_D - 0.275);//modify blue / red action
//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);
@@ -1345,6 +1368,11 @@ void ColorTemp::temp2mul (double temp, double green, double& rmul, double& gmul,
}
xD=x; yD=y;
+ float adj=1.f;
+ if(equal < 0.9999 || equal > 1.0001 ){
+ adj=(100.f+( 1000.f-(1000.f*(float)equal) )/20.f)/100.f;
+ }
+ //printf("adj=%f\n",adj);
double Xwb = xD/yD;
double Ywb = 1.0;
double Zwb = (1.0-xD-yD)/yD;
@@ -1365,12 +1393,12 @@ void ColorTemp::temp2mul (double temp, double green, double& rmul, double& gmul,
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]*Xwb + sRGBd65_xyz[0][1]*Ywb + sRGBd65_xyz[0][2]*Zwb;
- gmul = sRGBd65_xyz[1][0]*Xwb + sRGBd65_xyz[1][1]*Ywb + sRGBd65_xyz[1][2]*Zwb;
- bmul = sRGBd65_xyz[2][0]*Xwb + sRGBd65_xyz[2][1]*Ywb + sRGBd65_xyz[2][2]*Zwb;
+ rmul = sRGBd65_xyz[0][0]*Xwb*adj + sRGBd65_xyz[0][1]*Ywb + sRGBd65_xyz[0][2]*Zwb/adj; // Jacques' empirical modification 5/2013
+ gmul = sRGBd65_xyz[1][0]*Xwb + sRGBd65_xyz[1][1]*Ywb + sRGBd65_xyz[1][2]*Zwb;
+ bmul = sRGBd65_xyz[2][0]*Xwb*adj + sRGBd65_xyz[2][1]*Ywb + sRGBd65_xyz[2][2]*Zwb/adj;
//};
gmul /= green;
-
+ //printf("rmul=%f gmul=%f bmul=%f\n",rmul, gmul, bmul);
double max = rmul;
if (gmul>max) max = gmul;
if (bmul>max) max = bmul;
@@ -1526,6 +1554,11 @@ void ColorTemp::temp2mul (double temp, double green, double& rmul, double& gmul,
else {CRI_type=false;}
if (CRI_type) {
+ float DeltaE[50], DeltaEs[8];
+ float quadCRI=0.0f,quadCRIs=0.0f;
+ float CRI_RT=0.0, CRI[50];
+ float CRI_RTs=0.0, CRIs[8];
+
for(int i=0;i
#include
@@ -28,35 +29,47 @@
namespace rtengine {
+using namespace procparams;
-#define MINTEMP 2000
-#define MAXTEMP 25000
+
+#define MINTEMP 1500
+#define MAXTEMP 60000
#define MINGREEN 0.02
#define MAXGREEN 5.0
+#define MINEQUAL 0.8
+#define MAXEQUAL 1.5
+
#define INITIALBLACKBODY 4000
+
class ColorTemp {
private:
double temp;
double green;
+ double equal;
Glib::ustring method;
-
static void clip (double &temp, double &green);
+ static void clip (double &temp, double &green, double &equal);
public:
+
+ ColorTemp () : temp(-1.), green(-1.), equal (1.), method("Custom") {}
+ ColorTemp (double e) : temp(-1.), green(-1.), equal (e), method("Custom") {}
+ ColorTemp (double t, double g, double e, Glib::ustring m);
+ ColorTemp (double mulr, double mulg, double mulb, double e);
- ColorTemp () : temp(-1), green(-1), method("Custom") {}
- ColorTemp (double t, double g, Glib::ustring m);
- ColorTemp (double mulr, double mulg, double mulb);
+ void update (const double rmul, const double gmul, const double bmul, const double equal) { this->equal = equal; mul2temp (rmul, gmul, bmul, this->equal, temp, green); }
+ void useDefaults (const double equal) { temp = 6504; green = 1.0; this->equal = equal; } // Values copied from procparams.cc
inline double getTemp () { return temp; }
inline double getGreen () { return green; }
+ inline double getEqual () { return equal; }
- void getMultipliers (double &mulr, double &mulg, double &mulb) { temp2mul (temp, green, mulr, mulg, mulb); }
+ void getMultipliers (double &mulr, double &mulg, double &mulb) { temp2mul (temp, green, equal, mulr, mulg, mulb); }
- 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 mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green);
+ void temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul);
static void temp2mulxyz (double tem, double gree, Glib::ustring method, double &Xxyz, double &Zxyz);
int XYZtoCorColorTemp(double x0,double y0 ,double z0, double &temp);
diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc
index a39b54294..13b10efde 100644
--- a/rtengine/dcraw.cc
+++ b/rtengine/dcraw.cc
@@ -6880,7 +6880,8 @@ void CLASS adobe_coeff (const char *make, const char *model)
{ "Panasonic DMC-GH1", 15, 0xf92, /* RT - Colin Walker */
{ 6360,-1557,-375,-4201,11504,3086,-1378,2518,5843 } },
{ "Panasonic DMC-GH2", 15, 0xf95, /* RT - Colin Walker */
- { 6855,-1765,-456,-4223,11600,2996,-1450,2602,5761 } },
+// { 6855,-1765,-456,-4223,11600,2996,-1450,2602,5761 } },
+ { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
{ "Panasonic DMC-GH3", 144, 0,
{ 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
{ "Panasonic DMC-GX1", 143, 0,
diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch
index 054f43b69..f3fb96e3c 100644
--- a/rtengine/dcraw.patch
+++ b/rtengine/dcraw.patch
@@ -1066,8 +1066,6 @@
- { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } },
+ { "Panasonic DMC-GH1", 15, 0xf92, /* RT - Colin Walker */
+ { 6360,-1557,-375,-4201,11504,3086,-1378,2518,5843 } },
-+ { "Panasonic DMC-GH2", 15, 0xf95, /* RT - Colin Walker */
-+ { 6855,-1765,-456,-4223,11600,2996,-1450,2602,5761 } },
{ "Panasonic DMC-GH3", 144, 0,
{ 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } },
{ "Panasonic DMC-GX1", 143, 0,
diff --git a/rtengine/iimage.h b/rtengine/iimage.h
index 4d01b9eb9..b975688c9 100644
--- a/rtengine/iimage.h
+++ b/rtengine/iimage.h
@@ -84,7 +84,7 @@ namespace rtengine {
virtual void getSpotWBData (double &reds, double &greens, double &blues, int &rn, int &gn, int &bn,
std::vector &red, std::vector &green, std::vector &blue,
int tran) {}
- virtual ColorTemp getAutoWB () { return ColorTemp(); }
+ virtual void getAutoWBMultipliers (double &rm, double &gm, double &bm) { rm=1.0; bm=1.0; gm=1.0; }
virtual const char* getType () const { return "unknown"; }
};
@@ -476,7 +476,7 @@ namespace rtengine {
}
}
- ColorTemp getAutoWB () {
+ void getAutoWBMultipliers (double &rm, double &gm, double &bm) {
double avg_r = 0.;
double avg_g = 0.;
@@ -500,8 +500,9 @@ namespace rtengine {
avg_b += intpow( (double)b(i, j), p);*/
n++;
}
- return ColorTemp (avg_r/double(n), avg_g/double(n), avg_b/double(n));
- //return ColorTemp (pow(avg_r/n, 1.0/p), pow(avg_g/n, 1.0/p), pow(avg_b/n, 1.0/p));
+ rm = avg_r/double(n);
+ gm = avg_g/double(n);
+ bm = avg_b/double(n);
}
void transformPixel (int x, int y, int tran, int& tx, int& ty) {
@@ -905,7 +906,7 @@ namespace rtengine {
}
}
- ColorTemp getAutoWB () {
+ void getAutoWBMultipliers (double &rm, double &gm, double &bm) {
double avg_r = 0.;
double avg_g = 0.;
@@ -929,8 +930,9 @@ namespace rtengine {
avg_b += intpow( (double)b(i, j), p);*/
n++;
}
- return ColorTemp (avg_r/double(n), avg_g/double(n), avg_b/double(n));
- //return ColorTemp (pow(avg_r/n, 1.0/p), pow(avg_g/n, 1.0/p), pow(avg_b/n, 1.0/p));
+ rm = avg_r/double(n);
+ gm = avg_g/double(n);
+ bm = avg_b/double(n);
}
void transformPixel (int x, int y, int tran, int& tx, int& ty) {
diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h
index 8add1a032..8f540677a 100644
--- a/rtengine/imagesource.h
+++ b/rtengine/imagesource.h
@@ -50,6 +50,7 @@ class ImageSource : public InitialImage {
int references;
protected:
+ double redAWBMul, greenAWBMul, blueAWBMul; // local copy of the multipliers, to avoid recomputing the values
cmsHPROFILE embProfile;
Glib::ustring fileName;
ImageData* idata;
@@ -57,7 +58,8 @@ class ImageSource : public InitialImage {
double dirpyrdenoiseExpComp;
public:
- ImageSource () : references (1), embProfile(NULL), idata(NULL), dirpyrdenoiseExpComp(INFINITY) {}
+ ImageSource () : references (1), redAWBMul(-1.), greenAWBMul(-1.), blueAWBMul(-1.),
+ embProfile(NULL), idata(NULL), dirpyrdenoiseExpComp(INFINITY) {}
virtual ~ImageSource () {}
virtual int load (Glib::ustring fname, bool batch = false) =0;
@@ -75,10 +77,10 @@ class ImageSource : public InitialImage {
// true is ready to provide the AutoWB, i.e. when the image has been demosaiced for RawImageSource
virtual bool isWBProviderReady () =0;
- virtual void convertColorSpace(Imagefloat* image, ColorManagementParams cmp, RAWParams raw) =0;// DIRTY HACK: this method is derived in rawimagesource and strimagesource, but (...,RAWParams raw) will be used ONLY for raw images
+ virtual void convertColorSpace (Imagefloat* image, ColorManagementParams cmp, RAWParams raw) =0;// DIRTY HACK: this method is derived in rawimagesource and strimagesource, but (...,RAWParams raw) will be used ONLY for raw images
+ virtual void getAutoWBMultipliers (double &rm, double &bm, double &gm) =0;
virtual ColorTemp getWB () =0;
- virtual ColorTemp getAutoWB () =0;
- virtual ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran) =0;
+ virtual ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) =0;
virtual double getDefGain () { return 1.0; }
diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc
index 43d530e12..0d91c392e 100644
--- a/rtengine/improccoordinator.cc
+++ b/rtengine/improccoordinator.cc
@@ -29,7 +29,7 @@ namespace rtengine {
extern const Settings* settings;
ImProcCoordinator::ImProcCoordinator ()
- : workimg(NULL), awbComputed(false), ipf(¶ms, true), scale(10), highDetailPreprocessComputed(false),
+ : workimg(NULL), lastAwbEqual(0.), ipf(¶ms, true), scale(10), highDetailPreprocessComputed(false),
highDetailRawComputed(false), allocated(false),
hltonecurve(65536,0),
@@ -182,13 +182,23 @@ 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, params.wb.method);
+ currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method);
if (params.wb.method=="Camera")
currWB = imgsrc->getWB ();
else if (params.wb.method=="Auto") {
- if (!awbComputed) {
- autoWB = imgsrc->getAutoWB ();
- awbComputed = true;
+ if (lastAwbEqual != params.wb.equal) {
+ double rm, gm, bm;
+ imgsrc->getAutoWBMultipliers(rm, gm, bm);
+ if (rm != -1.) {
+ autoWB.update(rm, bm, gm, params.wb.equal);
+ lastAwbEqual = params.wb.equal;
+ }
+ else {
+ lastAwbEqual = -1.;
+ autoWB.useDefaults(params.wb.equal);
+ }
+ //double rr,gg,bb;
+ //autoWB.getMultipliers(rr,gg,bb);
}
currWB = autoWB;
}
@@ -609,20 +619,28 @@ void ImProcCoordinator::progress (Glib::ustring str, int pr) {
}*/
}
-bool ImProcCoordinator::getAutoWB (double& temp, double& green) {
+bool ImProcCoordinator::getAutoWB (double& temp, double& green, double equal) {
- if (imgsrc && imgsrc->isWBProviderReady()) {
- if (!awbComputed) {
- minit.lock ();
- autoWB = imgsrc->getAutoWB ();
- minit.unlock ();
- awbComputed = true;
+ if (imgsrc) {
+ if (lastAwbEqual != equal) {
+ Glib::Mutex::Lock lock(minit); // Also used in crop window
+ double rm, gm, bm;
+ imgsrc->getAutoWBMultipliers(rm, gm, bm);
+ if (rm != -1) {
+ autoWB.update(rm, bm, gm, equal);
+ lastAwbEqual = equal;
+ }
+ else {
+ lastAwbEqual = -1.;
+ autoWB.useDefaults(equal);
+ }
}
temp = autoWB.getTemp ();
green = autoWB.getGreen ();
return true;
}
else {
+ //temp = autoWB.getTemp();
temp = -1.0;
green = -1.0;
return false;
@@ -652,9 +670,11 @@ void ImProcCoordinator::getSpotWB (int x, int y, int rect, double& temp, double&
if (params.coarse.rotate==270) tr |= TR_R270;
if (params.coarse.hflip) tr |= TR_HFLIP;
if (params.coarse.vflip) tr |= TR_VFLIP;
-
- ColorTemp ret = imgsrc->getSpotWB (red, green, blue, tr);
- currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.method);
+ ColorTemp ret = imgsrc->getSpotWB (red, green, blue, tr, params.wb.equal);
+ currWB = ColorTemp (params.wb.temperature, params.wb.green,params.wb.equal, params.wb.method);
+ //double rr,gg,bb;
+ //currWB.getMultipliers(rr,gg,bb);
+
mProcessing.unlock ();
if (ret.getTemp() > 0) {
@@ -711,13 +731,21 @@ void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) {
imgsrc->preprocess( ppar.raw, ppar.lensProf, ppar.coarse );
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, params.wb.method);
+ ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method);
if (params.wb.method=="Camera")
currWB = imgsrc->getWB ();
else if (params.wb.method=="Auto") {
- if (!awbComputed) {
- autoWB = imgsrc->getAutoWB ();
- awbComputed = true;
+ if (lastAwbEqual != params.wb.equal) {
+ double rm, gm, bm;
+ imgsrc->getAutoWBMultipliers(rm, gm, bm);
+ if (rm != -1.) {
+ autoWB.update(rm, bm, gm, params.wb.equal);
+ lastAwbEqual = params.wb.equal;
+ }
+ else {
+ lastAwbEqual = -1.;
+ autoWB.useDefaults(params.wb.equal);
+ }
}
currWB = autoWB;
}
diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h
index 4d1f4ed0d..481319a8e 100644
--- a/rtengine/improccoordinator.h
+++ b/rtengine/improccoordinator.h
@@ -56,7 +56,7 @@ class ImProcCoordinator : public StagedImageProcessor {
ColorTemp currWB;
ColorTemp autoWB;
- bool awbComputed;
+ double lastAwbEqual;
ImProcFunctions ipf;
@@ -174,7 +174,7 @@ class ImProcCoordinator : public StagedImageProcessor {
DetailedCrop* createCrop ();
- bool getAutoWB (double& temp, double& green);
+ bool getAutoWB (double& temp, double& green, double equal);
void getCamWB (double& temp, double& green);
void getSpotWB (int x, int y, int rectSize, double& temp, double& green);
void getAutoCrop (double ratio, int &x, int &y, int &w, int &h);
diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc
index 40ee4b847..a8ba6f052 100644
--- a/rtengine/improcfun.cc
+++ b/rtengine/improcfun.cc
@@ -3286,7 +3286,7 @@ fclose(f);*/
if (thumb == NULL)
return 0.0;
- Thumbnail* raw = rtengine::Thumbnail::loadFromRaw (fname, ri, w_raw, h_raw, 1, FALSE);
+ Thumbnail* raw = rtengine::Thumbnail::loadFromRaw (fname, ri, w_raw, h_raw, 1, 1.0, FALSE);
if (raw == NULL) {
delete thumb;
return 0.0;
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index 501e9a4e8..20e8dac38 100644
--- a/rtengine/procevents.h
+++ b/rtengine/procevents.h
@@ -230,7 +230,9 @@ enum ProcEvent {
EvCATbadpix=204,
EvCATAutoAdap=205,
EvPFCurve=206,
- NUMOFEVENTS=207
+ EvWBequal=207,
+ EvWBequalbo=208,
+ NUMOFEVENTS=209
};
}
#endif
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index c467a029b..bc2aea4d8 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -49,38 +49,40 @@ 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"), 2970));
- 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));
+ wbEntries.push_back(new WBEntry("Camera" ,WBT_CAMERA, M("TP_WBALANCE_CAMERA"), 0, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Auto" ,WBT_AUTO, M("TP_WBALANCE_AUTO"), 0, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Daylight" ,WBT_DAYLIGHT, M("TP_WBALANCE_DAYLIGHT"), 5300, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Cloudy" ,WBT_CLOUDY, M("TP_WBALANCE_CLOUDY"), 6200, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Shade" ,WBT_SHADE, M("TP_WBALANCE_SHADE"), 7600, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Water 1" ,WBT_WATER, M("TP_WBALANCE_WATER1"), 35000, 0.3f, 1.1f));
+ wbEntries.push_back(new WBEntry("Water 2" ,WBT_WATER, M("TP_WBALANCE_WATER2"), 48000, 0.63f, 1.38f));
+ wbEntries.push_back(new WBEntry("Tungsten" ,WBT_TUNGSTEN, M("TP_WBALANCE_TUNGSTEN"), 2856, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Fluo F1" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO1"), 6430, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Fluo F2" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO2"), 4230, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Fluo F3" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO3"), 3450, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Fluo F4" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO4"), 2940, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Fluo F5" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO5"), 6350, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Fluo F6" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO6"), 4150, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Fluo F7" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO7"), 6500, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Fluo F8" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO8"), 5020, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Fluo F9" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO9"), 4330, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Fluo F10" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO10"), 5300, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Fluo F11" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO11"), 4000, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Fluo F12" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO12"), 3000, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("HMI Lamp" ,WBT_LAMP, M("TP_WBALANCE_HMI"), 4800, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("GTI Lamp" ,WBT_LAMP, M("TP_WBALANCE_GTI"), 5000, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("JudgeIII Lamp" ,WBT_LAMP, M("TP_WBALANCE_JUDGEIII"), 5100, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Solux Lamp 3500K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX35"), 3480, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Solux Lamp 4100K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX41"), 3930, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Solux Lamp 4700K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX47"), 4700, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("NG Solux Lamp 4700K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX47_NG"), 4480, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("LED LSI Lumelex 2040",WBT_LED, M("TP_WBALANCE_LED_LSI"), 2970, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("LED CRS SP12 WWMR16" ,WBT_LED, M("TP_WBALANCE_LED_CRS"), 3050, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Flash 5500K" ,WBT_FLASH, M("TP_WBALANCE_FLASH55"), 5500, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Flash 6000K" ,WBT_FLASH, M("TP_WBALANCE_FLASH60"), 6000, 1.f, 1.f));
+ wbEntries.push_back(new WBEntry("Flash 6500K" ,WBT_FLASH, M("TP_WBALANCE_FLASH65"), 6500, 1.f, 1.f));
// Should remain the last one
- wbEntries.push_back(new WBEntry("Custom" ,WBT_CUSTOM, M("TP_WBALANCE_CUSTOM"), 0));
+ wbEntries.push_back(new WBEntry("Custom" ,WBT_CUSTOM, M("TP_WBALANCE_CUSTOM"), 0, 1.f, 1.f));
}
void WBParams::cleanup() {
@@ -212,7 +214,7 @@ void ProcParams::setDefaults () {
wb.method = "Camera";
wb.temperature = 6504;
wb.green = 1.0;
-
+ wb.equal = 1.0;
colorappearance.enabled = false;
colorappearance.degree = 90;
colorappearance.autodegree = true;
@@ -601,6 +603,7 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, ParamsEdited* p
if (!pedited || pedited->wb.method) keyFile.set_string ("White Balance", "Setting", wb.method);
if (!pedited || pedited->wb.temperature) keyFile.set_integer ("White Balance", "Temperature", wb.temperature);
if (!pedited || pedited->wb.green) keyFile.set_double ("White Balance", "Green", wb.green);
+ if (!pedited || pedited->wb.equal) keyFile.set_double ("White Balance", "Equal", wb.equal);
/*
// save colorShift
@@ -1135,6 +1138,7 @@ if (keyFile.has_group ("White Balance")) {
if (keyFile.has_key ("White Balance", "Setting")) { wb.method = keyFile.get_string ("White Balance", "Setting"); if (pedited) pedited->wb.method = true; }
if (keyFile.has_key ("White Balance", "Temperature")) { wb.temperature = keyFile.get_integer ("White Balance", "Temperature"); if (pedited) pedited->wb.temperature = true; }
if (keyFile.has_key ("White Balance", "Green")) { wb.green = keyFile.get_double ("White Balance", "Green"); if (pedited) pedited->wb.green = true; }
+ if (keyFile.has_key ("White Balance", "Equal")) { wb.equal = keyFile.get_double ("White Balance", "Equal"); if (pedited) pedited->wb.equal = true; }
}
// load colorShift
@@ -1572,6 +1576,7 @@ bool ProcParams::operator== (const ProcParams& other) {
&& wb.method == other.wb.method
&& wb.green == other.wb.green
&& wb.temperature == other.wb.temperature
+ && wb.equal == other.wb.equal
//&& colorShift.a == other.colorShift.a
//&& colorShift.b == other.colorShift.b
&& colorappearance.enabled == other.colorappearance.enabled
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 1e9a38ae7..dbb700458 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -315,6 +315,7 @@ enum WBTypes {
WBT_DAYLIGHT,
WBT_CLOUDY,
WBT_SHADE,
+ WBT_WATER,
WBT_TUNGSTEN,
WBT_FLUORESCENT,
WBT_LAMP,
@@ -330,8 +331,10 @@ public:
enum WBTypes type;
Glib::ustring GUILabel;
int temperature;
+ double green;
+ double equal;
- WBEntry(Glib::ustring p, enum WBTypes t, Glib::ustring l, int temp) : ppLabel(p), type(t), GUILabel(l), temperature(temp) {};
+ WBEntry(Glib::ustring p, enum WBTypes t, Glib::ustring l, int temp, double green, double equal) : ppLabel(p), type(t), GUILabel(l), temperature(temp), green(green), equal(equal) {};
};
class WBParams {
@@ -341,6 +344,7 @@ class WBParams {
Glib::ustring method;
int temperature;
double green;
+ double equal;
static void init();
static void cleanup();
diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc
index 2f3e3da00..597ac2a7c 100644
--- a/rtengine/rawimagesource.cc
+++ b/rtengine/rawimagesource.cc
@@ -891,7 +891,7 @@ int RawImageSource::load (Glib::ustring fname, bool batch) {
double cam_g = imatrices.rgb_cam[1][0]*camwb_red + imatrices.rgb_cam[1][1]*camwb_green + imatrices.rgb_cam[1][2]*camwb_blue;
double cam_b = imatrices.rgb_cam[2][0]*camwb_red + imatrices.rgb_cam[2][1]*camwb_green + imatrices.rgb_cam[2][2]*camwb_blue;
- wb = ColorTemp (cam_r, cam_g, cam_b);
+ wb = ColorTemp (cam_r, cam_g, cam_b, 1.);
ri->set_prefilters();
@@ -2265,8 +2265,22 @@ void RawImageSource::getRowStartEnd (int x, int &start, int &end) {
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- ColorTemp RawImageSource::getAutoWB () {
-
+ void RawImageSource::getAutoWBMultipliers (double &rm, double &bm, double &gm) {
+
+ if (redAWBMul != -1.) {
+ rm = redAWBMul;
+ gm = greenAWBMul;
+ bm = blueAWBMul;
+ return;
+ }
+
+ if (!isWBProviderReady()) {
+ rm = -1.0;
+ gm = -1.0;
+ bm = -1.0;
+ return;
+ }
+
double avg_r = 0;
double avg_g = 0;
double avg_b = 0;
@@ -2369,17 +2383,15 @@ void RawImageSource::getRowStartEnd (int x, int &start, int &end) {
double greens = avg_g/gn * camwb_green;
double blues = avg_b/bn * camwb_blue;
- double rm = imatrices.rgb_cam[0][0]*reds + imatrices.rgb_cam[0][1]*greens + imatrices.rgb_cam[0][2]*blues;
- double gm = imatrices.rgb_cam[1][0]*reds + imatrices.rgb_cam[1][1]*greens + imatrices.rgb_cam[1][2]*blues;
- double bm = imatrices.rgb_cam[2][0]*reds + imatrices.rgb_cam[2][1]*greens + imatrices.rgb_cam[2][2]*blues;
-
- return ColorTemp (rm, gm, bm);
+ redAWBMul = rm = imatrices.rgb_cam[0][0]*reds + imatrices.rgb_cam[0][1]*greens + imatrices.rgb_cam[0][2]*blues;
+ greenAWBMul = gm = imatrices.rgb_cam[1][0]*reds + imatrices.rgb_cam[1][1]*greens + imatrices.rgb_cam[1][2]*blues;
+ blueAWBMul = bm = imatrices.rgb_cam[2][0]*reds + imatrices.rgb_cam[2][1]*greens + imatrices.rgb_cam[2][2]*blues;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- ColorTemp RawImageSource::getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran) {
+ ColorTemp RawImageSource::getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) {
int x; int y;
double reds = 0, greens = 0, blues = 0;
@@ -2410,7 +2422,8 @@ void RawImageSource::getRowStartEnd (int x, int &start, int &end) {
} else {
int d[9][2] = {{0,0}, {-1,-1}, {-1,0}, {-1,1}, {0,-1}, {0,1}, {1,-1}, {1,0}, {1,1}};
- int rloc, gloc, bloc, rnbrs, gnbrs, bnbrs;
+ double rloc, gloc, bloc;
+ int rnbrs, gnbrs, bnbrs;
for (size_t i=0; i=0 && yv>=0 && xv=0 && yv>=0 && xv=0 && yv>=0 && xv=0 && yv>=0 && xv &red, std::vector &green, std::vector &blue, int tran);
+ void getAutoWBMultipliers (double &rm, double &bm, double &gm);
+ ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal);
bool isWBProviderReady () { return rawData; }
double getDefGain () { return defGain; }
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index 85099a9ea..e39d9da85 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -198,35 +198,37 @@ LUMINANCECURVE, // EvCATDegree
LUMINANCECURVE, // EvCATMethodsur
LUMINANCECURVE, // EvCATAdapscen
LUMINANCECURVE, // EvCATAdapLum
-LUMINANCECURVE, // EvCATMethodWB
+LUMINANCECURVE, // EvCATMethodWB
LUMINANCECURVE, // EvCATJLight
LUMINANCECURVE, // EvCATChroma
-LUMINANCECURVE, // EvCATAutoDegree
-LUMINANCECURVE, // EvCATContrast
-LUMINANCECURVE, // EvCATSurr
-LUMINANCECURVE, // EvCATgamut
-LUMINANCECURVE, // EvCATmethodalg
-LUMINANCECURVE, // EvCATRstpro
-LUMINANCECURVE, // EvCATQbright
-LUMINANCECURVE, // EvCATQContrast
-LUMINANCECURVE, // EvCATSChroma
-LUMINANCECURVE, // EvCATMchroma
-LUMINANCECURVE, // EvCAThue
-LUMINANCECURVE, // EvCATcurve1
-LUMINANCECURVE, // EvCATcurve2
-LUMINANCECURVE, // EvCATcurvemode1
-LUMINANCECURVE, // EvCATcurvemode2
-LUMINANCECURVE, // EvCATcurve3
-LUMINANCECURVE, // EvCATcurvemode3
-LUMINANCECURVE, // EvCATdatacie
-LUMINANCECURVE, // EvCATtonecie
+LUMINANCECURVE, // EvCATAutoDegree
+LUMINANCECURVE, // EvCATContrast
+LUMINANCECURVE, // EvCATSurr
+LUMINANCECURVE, // EvCATgamut
+LUMINANCECURVE, // EvCATmethodalg
+LUMINANCECURVE, // EvCATRstpro
+LUMINANCECURVE, // EvCATQbright
+LUMINANCECURVE, // EvCATQContrast
+LUMINANCECURVE, // EvCATSChroma
+LUMINANCECURVE, // EvCATMchroma
+LUMINANCECURVE, // EvCAThue
+LUMINANCECURVE, // EvCATcurve1
+LUMINANCECURVE, // EvCATcurve2
+LUMINANCECURVE, // EvCATcurvemode1
+LUMINANCECURVE, // EvCATcurvemode2
+LUMINANCECURVE, // EvCATcurve3
+LUMINANCECURVE, // EvCATcurvemode3
+LUMINANCECURVE, // EvCATdatacie
+LUMINANCECURVE, // EvCATtonecie
ALLNORAW, // EvDPDNbluechro
ALLNORAW, // EvDPDNperform
-ALLNORAW, //EvDPDNmet
+ALLNORAW, // EvDPDNmet
DEMOSAIC, // EvDemosaicLMMSEIter
-LUMINANCECURVE, // EvCATbadpix
-LUMINANCECURVE, // EvCATAutoadap
-DEFRINGE // EvPFCurve,
+LUMINANCECURVE, // EvCATbadpix
+LUMINANCECURVE, // EvCATAutoadap
+DEFRINGE, // EvPFCurve,
+WHITEBALANCE, // EvWBequal,
+WHITEBALANCE // EvWBequalbo,
//LUMINANCECURVE // EvCATsharpcie
diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h
index 13d09a8c5..329ad408e 100644
--- a/rtengine/rtengine.h
+++ b/rtengine/rtengine.h
@@ -321,7 +321,7 @@ namespace rtengine {
/** Creates and returns a Crop instance that acts as a window on the image */
virtual DetailedCrop* createCrop () =0;
- virtual bool getAutoWB (double& temp, double& green) =0;
+ virtual bool getAutoWB (double& temp, double& green, double equal) =0;
virtual void getCamWB (double& temp, double& green) =0;
virtual void getSpotWB (int x, int y, int rectSize, double& temp, double& green) =0;
virtual void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) =0;
diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc
index fd0d25008..642126108 100644
--- a/rtengine/rtthumbnail.cc
+++ b/rtengine/rtthumbnail.cc
@@ -40,7 +40,7 @@
namespace rtengine {
-Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh) {
+Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq) {
StdImageSource imgSrc;
if (imgSrc.load(fname)) {
@@ -51,26 +51,13 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h,
Thumbnail* tpp = new Thumbnail ();
- tpp->camwbRed = 1.0;
- tpp->camwbGreen = 1.0;
- tpp->camwbBlue = 1.0;
-
- tpp->embProfileLength = 0;
unsigned char* data;
img->getEmbeddedProfileData (tpp->embProfileLength, data);
if (data && tpp->embProfileLength) {
tpp->embProfileData = new unsigned char [tpp->embProfileLength];
memcpy (tpp->embProfileData, data, tpp->embProfileLength);
}
- else {
- tpp->embProfileLength = 0;
- tpp->embProfileData = NULL;
- }
- tpp->redMultiplier = 1.0;
- tpp->greenMultiplier = 1.0;
- tpp->blueMultiplier = 1.0;
-
tpp->scaleForSave = 8192;
tpp->defGain = 1.0;
tpp->gammaCorrected = false;
@@ -120,7 +107,13 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h,
if (n>0) {
ColorTemp cTemp;
- cTemp.mul2temp (avg_r/double(n), avg_g/double(n), avg_b/double(n), tpp->autowbTemp, tpp->autowbGreen);
+
+ tpp->redAWBMul = avg_r/double(n);
+ tpp->greenAWBMul = avg_g/double(n);
+ tpp->blueAWBMul = avg_b/double(n);
+ tpp->wbEqual = wbEq;
+
+ cTemp.mul2temp (tpp->redAWBMul, tpp->greenAWBMul, tpp->blueAWBMul, tpp->wbEqual, tpp->autoWBTemp, tpp->autoWBGreen);
}
tpp->init ();
@@ -174,21 +167,6 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
Thumbnail* tpp = new Thumbnail ();
- tpp->camwbRed = 1.0;
- tpp->camwbGreen = 1.0;
- tpp->camwbBlue = 1.0;
-
- tpp->embProfileLength = 0;
- tpp->embProfile = NULL;
- tpp->embProfileData = NULL;
-
- tpp->redMultiplier = 1.0;
- tpp->greenMultiplier = 1.0;
- tpp->blueMultiplier = 1.0;
-
- tpp->scaleForSave = 8192;
- tpp->defGain = 1.0;
- tpp->gammaCorrected = false;
tpp->isRaw = 1;
memset (tpp->colorMatrix, 0, sizeof(tpp->colorMatrix));
tpp->colorMatrix[0][0] = 1.0;
@@ -208,9 +186,6 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
tpp->thumbImg = resizeTo(w, h, TI_Nearest, img);
delete img;
- tpp->autowbTemp=2700;
- tpp->autowbGreen=1.0;
-
if (rotate && ri->get_rotateDegree() > 0) {
// Leaf .mos, Mamiya .mef and Phase One files have thumbnails already rotated.
if (ri->get_maker() != "Leaf" && ri->get_maker() != "Mamiya" && ri->get_maker() != "Phase One") {
@@ -231,7 +206,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
#define FISBLUE(filter,row,col) \
((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==2 || !filter)
-Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, bool rotate)
+Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, double wbEq, bool rotate)
{
RawImage *ri= new RawImage (fname);
int r = ri->loadRaw(1,0);
@@ -459,12 +434,13 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
double greens = avg_g / gn * tpp->camwbGreen;
double blues = avg_b / bn * tpp->camwbBlue;
- double rm = ri->get_rgb_cam(0, 0) * reds + ri->get_rgb_cam(0, 1) * greens + ri->get_rgb_cam(0, 2) * blues;
- 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;
+ tpp->redAWBMul = ri->get_rgb_cam(0, 0) * reds + ri->get_rgb_cam(0, 1) * greens + ri->get_rgb_cam(0, 2) * blues;
+ tpp->greenAWBMul = ri->get_rgb_cam(1, 0) * reds + ri->get_rgb_cam(1, 1) * greens + ri->get_rgb_cam(1, 2) * blues;
+ tpp->blueAWBMul = ri->get_rgb_cam(2, 0) * reds + ri->get_rgb_cam(2, 1) * greens + ri->get_rgb_cam(2, 2) * blues;
+ tpp->wbEqual = wbEq;
ColorTemp cTemp;
- cTemp.mul2temp(rm, gm, bm, tpp->autowbTemp, tpp->autowbGreen);
+ cTemp.mul2temp(tpp->redAWBMul, tpp->greenAWBMul, tpp->blueAWBMul, tpp->wbEqual, tpp->autoWBTemp, tpp->autoWBGreen);
if (rotate && ri->get_rotateDegree() > 0) {
tpp->thumbImg->rotate(ri->get_rotateDegree());
@@ -513,7 +489,15 @@ void Thumbnail::init () {
}
Thumbnail::Thumbnail () :
- camProfile(NULL), thumbImg(NULL), embProfileData(NULL), embProfile(NULL) {
+ camProfile(NULL), thumbImg(NULL),
+ camwbRed(1.0), camwbGreen(1.0), camwbBlue(1.0),
+ redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0),
+ autoWBTemp(2700), autoWBGreen(1.0), wbEqual(-1.0),
+ embProfileLength(0), embProfileData(NULL), embProfile(NULL),
+ redMultiplier(1.0), greenMultiplier(1.0), blueMultiplier(1.0),
+ defGain(1.0),
+ scaleForSave(8192),
+ gammaCorrected(false) {
}
Thumbnail::~Thumbnail () {
@@ -555,17 +539,25 @@ IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int
IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rheight, TypeInterpolation interp, std::string camName,
double focalLen, double focalLen35mm, float focusDist, float shutter, float fnumber, float iso,std::string expcomp_, double& myscale) {
+ // check if the WB's equalizer value has changed
+ if (wbEqual < (params.wb.equal-5e-4) || wbEqual > (params.wb.equal+5e-4)) {
+ wbEqual = params.wb.equal;
+ // recompute the autoWB
+ ColorTemp cTemp;
+ cTemp.mul2temp (redAWBMul, greenAWBMul, blueAWBMul, wbEqual, autoWBTemp, autoWBGreen);
+ }
+
// compute WB multipliers
- ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.method);
+ ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal,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;
double cam_g = colorMatrix[1][0]*camwbRed + colorMatrix[1][1]*camwbGreen + colorMatrix[1][2]*camwbBlue;
double cam_b = colorMatrix[2][0]*camwbRed + colorMatrix[2][1]*camwbGreen + colorMatrix[2][2]*camwbBlue;
- currWB = ColorTemp (cam_r, cam_g, cam_b);
+ currWB = ColorTemp (cam_r, cam_g, cam_b, params.wb.equal);
}
else if (params.wb.method=="Auto")
- currWB = ColorTemp (autowbTemp, autowbGreen, "Custom");
+ currWB = ColorTemp (autoWBTemp, autoWBGreen, wbEqual, "Custom");
double r, g, b;
currWB.getMultipliers (r, g, b);
//iColorMatrix is cam_rgb
@@ -884,15 +876,28 @@ void Thumbnail::getCamWB (double& temp, double& green) {
double cam_r = colorMatrix[0][0]*camwbRed + colorMatrix[0][1]*camwbGreen + colorMatrix[0][2]*camwbBlue;
double cam_g = colorMatrix[1][0]*camwbRed + colorMatrix[1][1]*camwbGreen + colorMatrix[1][2]*camwbBlue;
double cam_b = colorMatrix[2][0]*camwbRed + colorMatrix[2][1]*camwbGreen + colorMatrix[2][2]*camwbBlue;
- ColorTemp currWB = ColorTemp (cam_r, cam_g, cam_b);
+ ColorTemp currWB = ColorTemp (cam_r, cam_g, cam_b, 1.0); // we do not take the equalizer into account here, because we want camera's WB
temp = currWB.getTemp ();
green = currWB.getGreen ();
}
-void Thumbnail::getAutoWB (double& temp, double& green) {
-
- temp = autowbTemp;
- green = autowbGreen;
+void Thumbnail::getAutoWB (double& temp, double& green, double equal) {
+
+ if (equal != wbEqual) {
+ // compute the values depending on equal
+ ColorTemp cTemp;
+ wbEqual = equal;
+ // compute autoWBTemp and autoWBGreen
+ cTemp.mul2temp(redAWBMul, greenAWBMul, blueAWBMul, wbEqual, autoWBTemp, autoWBGreen);
+ }
+ temp = autoWBTemp;
+ green = autoWBGreen;
+}
+
+void Thumbnail::getAutoWBMultipliers (double& rm, double& gm, double& bm) {
+ rm = redAWBMul;
+ gm = greenAWBMul;
+ bm = blueAWBMul;
}
void Thumbnail::applyAutoExp (procparams::ProcParams& params) {
@@ -937,7 +942,7 @@ void Thumbnail::getSpotWB (const procparams::ProcParams& params, int xp, int yp,
double gm = colorMatrix[1][0]*reds + colorMatrix[1][1]*greens + colorMatrix[1][2]*blues;
double bm = colorMatrix[2][0]*reds + colorMatrix[2][1]*greens + colorMatrix[2][2]*blues;
- ColorTemp ct (rm, gm, bm);
+ ColorTemp ct (rm, gm, bm, params.wb.equal);
rtemp = ct.getTemp ();
rgreen = ct.getGreen ();
}
@@ -1283,8 +1288,9 @@ bool Thumbnail::readData (const Glib::ustring& fname) {
if (keyFile.has_key ("LiveThumbData", "CamWBRed")) camwbRed = keyFile.get_double ("LiveThumbData", "CamWBRed");
if (keyFile.has_key ("LiveThumbData", "CamWBGreen")) camwbGreen = keyFile.get_double ("LiveThumbData", "CamWBGreen");
if (keyFile.has_key ("LiveThumbData", "CamWBBlue")) camwbBlue = keyFile.get_double ("LiveThumbData", "CamWBBlue");
- if (keyFile.has_key ("LiveThumbData", "AutoWBTemp")) autowbTemp = keyFile.get_double ("LiveThumbData", "AutoWBTemp");
- if (keyFile.has_key ("LiveThumbData", "AutoWBGreen")) autowbGreen = keyFile.get_double ("LiveThumbData", "AutoWBGreen");
+ if (keyFile.has_key ("LiveThumbData", "RedAWBMul")) redAWBMul = keyFile.get_double ("LiveThumbData", "RedAWBMul");
+ if (keyFile.has_key ("LiveThumbData", "GreenAWBMul")) greenAWBMul = keyFile.get_double ("LiveThumbData", "GreenAWBMul");
+ if (keyFile.has_key ("LiveThumbData", "BlueAWBMul")) blueAWBMul = keyFile.get_double ("LiveThumbData", "BlueAWBMul");
if (keyFile.has_key ("LiveThumbData", "AEHistCompression")) aeHistCompression = keyFile.get_integer ("LiveThumbData", "AEHistCompression");
if (keyFile.has_key ("LiveThumbData", "RedMultiplier")) redMultiplier = keyFile.get_double ("LiveThumbData", "RedMultiplier");
if (keyFile.has_key ("LiveThumbData", "GreenMultiplier")) greenMultiplier = keyFile.get_double ("LiveThumbData", "GreenMultiplier");
@@ -1301,12 +1307,11 @@ bool Thumbnail::readData (const Glib::ustring& fname) {
colorMatrix[i][j] = cm[ix++];
}
}
+ return true;
}
- catch (Glib::Error &err) {
- return false;
- }
+ catch (Glib::Error &err) {}
- return true;
+ return false;
}
bool Thumbnail::writeData (const Glib::ustring& fname) {
@@ -1323,8 +1328,9 @@ bool Thumbnail::writeData (const Glib::ustring& fname) {
keyFile.set_double ("LiveThumbData", "CamWBRed", camwbRed);
keyFile.set_double ("LiveThumbData", "CamWBGreen", camwbGreen);
keyFile.set_double ("LiveThumbData", "CamWBBlue", camwbBlue);
- keyFile.set_double ("LiveThumbData", "AutoWBTemp", autowbTemp);
- keyFile.set_double ("LiveThumbData", "AutoWBGreen", autowbGreen);
+ keyFile.set_double ("LiveThumbData", "RedAWBMul", redAWBMul);
+ keyFile.set_double ("LiveThumbData", "GreenAWBMul", greenAWBMul);
+ keyFile.set_double ("LiveThumbData", "BlueAWBMul", blueAWBMul);
keyFile.set_integer ("LiveThumbData", "AEHistCompression", aeHistCompression);
keyFile.set_double ("LiveThumbData", "RedMultiplier", redMultiplier);
keyFile.set_double ("LiveThumbData", "GreenMultiplier", greenMultiplier);
diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h
index 46ecfbd15..f7037cf9d 100644
--- a/rtengine/rtthumbnail.h
+++ b/rtengine/rtthumbnail.h
@@ -46,8 +46,8 @@ namespace rtengine {
double camwbRed;
double camwbGreen;
double camwbBlue;
- double autowbTemp;
- double autowbGreen;
+ double redAWBMul, greenAWBMul, blueAWBMul; // multipliers for auto WB
+ double autoWBTemp, autoWBGreen, wbEqual; // autoWBTemp and autoWBGreen are updated each time autoWB is requested and if wbEqual has been modified
LUTu aeHistogram;
int aeHistCompression;
int embProfileLength;
@@ -80,11 +80,12 @@ namespace rtengine {
void getDimensions (int& w, int& h, double& scaleFac);
static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int &w, int &h, int fixwh, bool rotate);
- static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, bool rotate);
- static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh);
+ static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, double wbEq, bool rotate);
+ static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq);
void getCamWB (double& temp, double& green);
- void getAutoWB (double& temp, double& green);
+ void getAutoWB (double& temp, double& green, double equal);
+ void getAutoWBMultipliers (double& rm, double& gm, double& bm);
void getSpotWB (const procparams::ProcParams& params, int x, int y, int rect, double& temp, double& green);
void applyAutoExp (procparams::ProcParams& pparams);
diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc
index d302d6b95..d3e70d47d 100644
--- a/rtengine/simpleprocess.cc
+++ b/rtengine/simpleprocess.cc
@@ -105,11 +105,14 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
imgsrc->HLRecovery_Global( params.hlrecovery );
if (pl) pl->setProgress (0.40);
// set the color temperature
- ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.method);
+ ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method);
if (params.wb.method=="Camera")
currWB = imgsrc->getWB ();
- else if (params.wb.method=="Auto")
- currWB = imgsrc->getAutoWB ();
+ else if (params.wb.method=="Auto") {
+ double rm, bm, gm;
+ imgsrc->getAutoWBMultipliers(rm, bm, gm);
+ currWB.update(rm, bm, gm, params.wb.equal);
+ }
Imagefloat* baseImg = new Imagefloat (fw, fh);
imgsrc->getImage (currWB, tr, baseImg, pp, params.hlrecovery, params.icm, params.raw);
if (pl) pl->setProgress (0.45);
diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc
index 090d8abe7..379ad5ce8 100644
--- a/rtengine/stdimagesource.cc
+++ b/rtengine/stdimagesource.cc
@@ -188,7 +188,7 @@ int StdImageSource::load (Glib::ustring fname, bool batch) {
plistener->setProgress (1.0);
}
- wb = ColorTemp (1.0,1.0,1.0);
+ wb = ColorTemp (1.0,1.0,1.0,1.0);
//this is probably a mistake if embedded profile is not D65
return 0;
@@ -292,11 +292,22 @@ void StdImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) {
}
}
-ColorTemp StdImageSource::getAutoWB () {
- return img->getAutoWB();
+void StdImageSource::getAutoWBMultipliers (double &rm, double &bm, double &gm) {
+ if (redAWBMul != -1.) {
+ rm = redAWBMul;
+ gm = greenAWBMul;
+ bm = blueAWBMul;
+ return;
+ }
+
+ img->getAutoWBMultipliers(rm, gm, bm);
+
+ redAWBMul = rm;
+ greenAWBMul = gm;
+ blueAWBMul = bm;
}
-ColorTemp StdImageSource::getSpotWB (std::vector &red, std::vector &green, std::vector& blue, int tran) {
+ColorTemp StdImageSource::getSpotWB (std::vector &red, std::vector &green, std::vector& blue, int tran, double equal) {
int rn, gn, bn;
double reds, greens, blues;
img->getSpotWBData(reds, greens, blues, rn, gn, bn, red, green, blue, tran);
@@ -305,7 +316,7 @@ ColorTemp StdImageSource::getSpotWB (std::vector &red, std::vectorverbose )
printf ("AVG: %g %g %g\n", reds/rn, greens/gn, blues/bn);
- return ColorTemp (reds/rn*img_r, greens/gn*img_g, blues/bn*img_b);
+ return ColorTemp (reds/rn*img_r, greens/gn*img_g, blues/bn*img_b, equal);
}
}
diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h
index 304ec8929..a052c07c8 100644
--- a/rtengine/stdimagesource.h
+++ b/rtengine/stdimagesource.h
@@ -45,8 +45,8 @@ class StdImageSource : public ImageSource {
int load (Glib::ustring fname, bool batch = false);
void getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp, RAWParams raw);
ColorTemp getWB () { return wb; }
- ColorTemp getAutoWB ();
- ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran);
+ void getAutoWBMultipliers (double &rm, double &bm, double &gm);
+ ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal);
bool isWBProviderReady () { return true; };
diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h
index aca5edbd9..004f49c9d 100644
--- a/rtgui/addsetids.h
+++ b/rtgui/addsetids.h
@@ -65,8 +65,9 @@
#define ADDSET_CAT_CHROMA_M 57
#define ADDSET_CAT_HUE 58
#define ADDSET_CAT_BADPIX 59
+#define ADDSET_WB_EQUAL 60
// When adding items, make sure to update ADDSET_PARAM_NUM
-#define ADDSET_PARAM_NUM 60 // THIS IS USED AS A DELIMITER!!
+#define ADDSET_PARAM_NUM 61 // THIS IS USED AS A DELIMITER!!
#endif
diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc
index 8b60fa569..311d52efb 100644
--- a/rtgui/batchtoolpanelcoord.cc
+++ b/rtgui/batchtoolpanelcoord.cc
@@ -126,7 +126,7 @@ void BatchToolPanelCoordinator::initSession () {
toneCurve->setAdjusterBehavior (false, false, false, false, false, false, false, false);
lcurve->setAdjusterBehavior (false, false, false);
- whitebalance->setAdjusterBehavior (false, false);
+ whitebalance->setAdjusterBehavior (false, false, false);
vibrance->setAdjusterBehavior (false, false, false);
vignetting->setAdjusterBehavior (false, false, false, false);
colorappearance->setAdjusterBehavior (false, false, false, false, false, false, false, false, false, false, false, false, false);
@@ -154,7 +154,7 @@ void BatchToolPanelCoordinator::initSession () {
toneCurve->setAdjusterBehavior (options.baBehav[ADDSET_TC_EXPCOMP], options.baBehav[ADDSET_TC_HLCOMPAMOUNT],options.baBehav[ADDSET_TC_HLCOMPTHRESH], options.baBehav[ADDSET_TC_BRIGHTNESS], options.baBehav[ADDSET_TC_BLACKLEVEL],options.baBehav[ADDSET_TC_SHCOMP], options.baBehav[ADDSET_TC_CONTRAST], options.baBehav[ADDSET_TC_SATURATION]);
lcurve->setAdjusterBehavior (options.baBehav[ADDSET_LC_BRIGHTNESS], options.baBehav[ADDSET_LC_CONTRAST], options.baBehav[ADDSET_LC_CHROMATICITY]);
- whitebalance->setAdjusterBehavior (options.baBehav[ADDSET_WB_TEMPERATURE], options.baBehav[ADDSET_WB_GREEN]);
+ whitebalance->setAdjusterBehavior (options.baBehav[ADDSET_WB_TEMPERATURE], options.baBehav[ADDSET_WB_GREEN], options.baBehav[ADDSET_WB_EQUAL]);
vignetting->setAdjusterBehavior (options.baBehav[ADDSET_VIGN_AMOUNT], options.baBehav[ADDSET_VIGN_RADIUS], options.baBehav[ADDSET_VIGN_STRENGTH], options.baBehav[ADDSET_VIGN_CENTER]);
colorappearance->setAdjusterBehavior (options.baBehav[ADDSET_CAT_DEGREE], options.baBehav[ADDSET_CAT_ADAPTSCENE], options.baBehav[ADDSET_CAT_ADAPTVIEWING],options.baBehav[ADDSET_CAT_BADPIX], options.baBehav[ADDSET_CAT_LIGHT], options.baBehav[ADDSET_CAT_CHROMA],options.baBehav[ADDSET_CAT_CONTRAST],options.baBehav[ADDSET_CAT_RSTPRO],options.baBehav[ADDSET_CAT_BRIGHT],options.baBehav[ADDSET_CAT_CONTRAST_Q],options.baBehav[ADDSET_CAT_CHROMA_S],options.baBehav[ADDSET_CAT_CHROMA_M],options.baBehav[ADDSET_CAT_HUE]);
rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]);
@@ -201,6 +201,7 @@ void BatchToolPanelCoordinator::initSession () {
if (options.baBehav[ADDSET_WB_TEMPERATURE]) pparams.wb.temperature = 0;
if (options.baBehav[ADDSET_WB_GREEN]) pparams.wb.green = 0;
+ if (options.baBehav[ADDSET_WB_EQUAL]) pparams.wb.equal = 0;
if (options.baBehav[ADDSET_VIBRANCE_PASTELS]) pparams.vibrance.pastels = 0;
if (options.baBehav[ADDSET_VIBRANCE_SATURATED]) pparams.vibrance.saturated = 0;
@@ -314,10 +315,10 @@ void BatchToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const G
paramcListeners[i]->procParamsChanged (&pparams, event, descr, &pparamsEdited);
}
-void BatchToolPanelCoordinator::getAutoWB (double& temp, double& green) {
+void BatchToolPanelCoordinator::getAutoWB (double& temp, double& green, double equal) {
if (!selected.empty())
- selected[0]->getAutoWB (temp, green);
+ selected[0]->getAutoWB (temp, green, equal);
}
void BatchToolPanelCoordinator::getCamWB (double& temp, double& green) {
diff --git a/rtgui/batchtoolpanelcoord.h b/rtgui/batchtoolpanelcoord.h
index b1db46294..8cdd12c64 100644
--- a/rtgui/batchtoolpanelcoord.h
+++ b/rtgui/batchtoolpanelcoord.h
@@ -60,7 +60,7 @@ class BatchToolPanelCoordinator :
void profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited=NULL);
// wbprovider interface
- void getAutoWB (double& temp, double& green);
+ void getAutoWB (double& temp, double& green, double equal);
void getCamWB (double& temp, double& green);
// thumbnaillistener interface
diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc
index 0846ebcb4..61da6cf5e 100644
--- a/rtgui/cacheimagedata.cc
+++ b/rtgui/cacheimagedata.cc
@@ -25,9 +25,12 @@
CacheImageData::CacheImageData ()
: md5(""), supported(false), format(FT_Invalid), rankOld(-1), inTrashOld(false), recentlySaved(false),
- timeValid(false), exifValid(false), thumbImgType(0) {
+ timeValid(false), exifValid(false), redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0), thumbImgType(0) {
}
+/*
+ * Load the General, DateTime, ExifInfo, File info and ExtraRawInfo sections of the image data file
+ */
int CacheImageData::load (const Glib::ustring& fname) {
rtengine::SafeKeyFile keyFile;
@@ -104,6 +107,9 @@ int CacheImageData::load (const Glib::ustring& fname) {
return 1;
}
+/*
+ * Save the General, DateTime, ExifInfo, File info and ExtraRawInfo sections of the image data file
+ */
int CacheImageData::save (const Glib::ustring& fname) {
rtengine::SafeKeyFile keyFile;
diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h
index 4786ff513..39e81b9a1 100644
--- a/rtgui/cacheimagedata.h
+++ b/rtgui/cacheimagedata.h
@@ -56,6 +56,11 @@ class CacheImageData {
Glib::ustring filetype;
Glib::ustring expcomp;
+ // store a copy of the autoWB's multipliers computed in Thumbnail::_generateThumbnailImage
+ // they are not stored in the cache file by this class, but by rtengine::Thumbnail
+ // -1 = Unknown
+ double redAWBMul, greenAWBMul, blueAWBMul;
+
// additional info on raw images
int rotate;
int thumbImgType;
diff --git a/rtgui/options.cc b/rtgui/options.cc
index 5613517b3..ae64f0fb6 100644
--- a/rtgui/options.cc
+++ b/rtgui/options.cc
@@ -423,6 +423,7 @@ void Options::setDefaults () {
0, // ADDSET_CAT_JLIGHT
0, // ADDSET_CAT_CHROMA
0, // ADDSET_CAT_CONTRAST
+ 0, // ADDSET_WB_EQUAL
};
baBehav = std::vector (babehav, babehav+ADDSET_PARAM_NUM);
@@ -679,7 +680,6 @@ if (keyFile.has_group ("Color Management")) {
if (keyFile.has_key ("Color Management", "MonitorProfile")) rtSettings.monitorProfile = keyFile.get_string ("Color Management", "MonitorProfile");
if (keyFile.has_key ("Color Management", "AutoMonitorProfile")) rtSettings.autoMonitorProfile = keyFile.get_boolean ("Color Management", "AutoMonitorProfile");
if (keyFile.has_key ("Color Management", "Autocielab")) rtSettings.autocielab = keyFile.get_boolean ("Color Management", "Autocielab");
- if (keyFile.has_key ("Color Management", "Ciencamfloat")) rtSettings.ciecamfloat = keyFile.get_boolean ("Color Management", "Ciecamfloat");
if (keyFile.has_key ("Color Management", "RGBcurvesLumamode_Gamut")) rtSettings.rgbcurveslumamode_gamut = keyFile.get_boolean ("Color Management", "RGBcurvesLumamode_Gamut");
if (keyFile.has_key ("Color Management", "Intent")) rtSettings.colorimetricIntent = keyFile.get_integer("Color Management", "Intent");
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index 261a61fcd..6606f51b9 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -133,6 +133,7 @@ void ParamsEdited::set (bool v) {
wb.method = v;
wb.green = v;
wb.temperature = v;
+ wb.equal = v;
//colorShift.a = v;
//colorShift.b = v;
//lumaDenoise.enabled = v;
@@ -375,6 +376,7 @@ void ParamsEdited::initFrom (const std::vector
//colorBoost.saturationlimit = colorBoost.saturationlimit && p.colorBoost.saturationlimit == other.colorBoost.saturationlimit;
wb.method = wb.method && p.wb.method == other.wb.method;
wb.green = wb.green && p.wb.green == other.wb.green;
+ wb.equal = wb.equal && p.wb.equal == other.wb.equal;
wb.temperature = wb.temperature && p.wb.temperature == other.wb.temperature;
//colorShift.a = colorShift.a && p.colorShift.a == other.colorShift.a;
//colorShift.b = colorShift.b && p.colorShift.b == other.colorShift.b;
@@ -593,6 +595,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
//if (colorBoost.enable_saturationlimiter)toEdit.colorBoost.enable_saturationlimiter = mods.colorBoost.enable_saturationlimiter;
//if (colorBoost.saturationlimit) toEdit.colorBoost.saturationlimit = mods.colorBoost.saturationlimit;
if (wb.method) toEdit.wb.method = mods.wb.method;
+ if (wb.equal) toEdit.wb.equal = dontforceSet && options.baBehav[ADDSET_WB_EQUAL] ? toEdit.wb.equal + mods.wb.equal : mods.wb.equal;
if (wb.green) toEdit.wb.green = dontforceSet && options.baBehav[ADDSET_WB_GREEN] ? toEdit.wb.green + mods.wb.green : mods.wb.green;
if (wb.temperature) toEdit.wb.temperature = dontforceSet && options.baBehav[ADDSET_WB_TEMPERATURE] ? toEdit.wb.temperature + mods.wb.temperature : mods.wb.temperature;
//if (colorShift.a) toEdit.colorShift.a = dontforceSet && options.baBehav[ADDSET_CS_BLUEYELLOW] ? toEdit.colorShift.a + mods.colorShift.a : mods.colorShift.a;
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index 5c2514877..2897a51e3 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -143,6 +143,7 @@ class WBParamsEdited {
bool method;
bool temperature;
bool green;
+ bool equal;
};
/*class ColorShiftParamsEdited {
diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h
index 737016de3..a2547b7f4 100644
--- a/rtgui/ppversion.h
+++ b/rtgui/ppversion.h
@@ -2,7 +2,7 @@
#define _PPVERSION_
// This number have to be incremented whenever the PP3 file format is modified
-#define PPVERSION 308
+#define PPVERSION 309
#define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified
/* Log of version changes
diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc
index e75a15823..4a18f086d 100644
--- a/rtgui/preferences.cc
+++ b/rtgui/preferences.cc
@@ -201,6 +201,7 @@ Gtk::Widget* Preferences::getBatchProcPanel () {
mi->set_value (behavColumns.label, M("TP_WBALANCE_LABEL"));
appendBehavList (mi, M("TP_WBALANCE_TEMPERATURE"), ADDSET_WB_TEMPERATURE, true);
appendBehavList (mi, M("TP_WBALANCE_GREEN"), ADDSET_WB_GREEN, true);
+ appendBehavList (mi, M("TP_WBALANCE_EQREDBLUE"), ADDSET_WB_EQUAL, true);
mi = behModel->append ();
mi->set_value (behavColumns.label, M("TP_COLORAPP_LABEL"));
diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc
index dae668cdc..9ae058d1f 100644
--- a/rtgui/thumbnail.cc
+++ b/rtgui/thumbnail.cc
@@ -72,13 +72,13 @@ Thumbnail::Thumbnail (CacheManager* cm, const Glib::ustring& fname, const std::s
cfs.md5 = md5;
- _generateThumbnailImage ();
if (pparams) {
this->pparams = *pparams;
pparamsValid = true;
}
else
loadProcParams ();
+ _generateThumbnailImage ();
cfs.recentlySaved = false;
initial_ = false;
@@ -107,17 +107,17 @@ void Thumbnail::_generateThumbnailImage () {
cfs.timeValid = false;
if (ext.lowercase()=="jpg" || ext.lowercase()=="jpeg") {
- tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1);
+ tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, pparams.wb.equal);
if (tpp)
cfs.format = FT_Jpeg;
}
else if (ext.lowercase()=="png") {
- tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1);
+ tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, pparams.wb.equal);
if (tpp)
cfs.format = FT_Png;
}
else if (ext.lowercase()=="tif" || ext.lowercase()=="tiff") {
- tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1);
+ tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, pparams.wb.equal);
if (tpp)
cfs.format = FT_Tiff;
}
@@ -136,7 +136,7 @@ void Thumbnail::_generateThumbnailImage () {
if ( tpp == NULL )
{
quick = false;
- tpp = rtengine::Thumbnail::loadFromRaw (fname, ri, tw, th, 1, TRUE);
+ tpp = rtengine::Thumbnail::loadFromRaw (fname, ri, tw, th, 1, pparams.wb.equal, TRUE);
}
if (tpp) {
cfs.format = FT_Raw;
@@ -146,7 +146,8 @@ void Thumbnail::_generateThumbnailImage () {
}
if (tpp)
- {
+ {
+ tpp->getAutoWBMultipliers(cfs.redAWBMul, cfs.greenAWBMul, cfs.blueAWBMul);
_saveThumbnail ();
cfs.supported = true;
needsReProcessing = true;
@@ -178,7 +179,7 @@ const ProcParams& Thumbnail::getProcParams () {
}
else if (pparams.wb.method=="Auto") {
double ct;
- getAutoWB (ct, pparams.wb.green);
+ getAutoWB (ct, pparams.wb.green, pparams.wb.equal);
pparams.wb.temperature = ct;
}
}
@@ -558,6 +559,17 @@ const Glib::ustring& Thumbnail::getDateTimeString () {
return dateTimeString;
}
+void Thumbnail::getAutoWB (double& temp, double& green, double equal) {
+ if (cfs.redAWBMul != -1.0) {
+ rtengine::ColorTemp ct(cfs.redAWBMul, cfs.greenAWBMul, cfs.blueAWBMul, equal);
+ temp = ct.getTemp();
+ green = ct.getGreen();
+ }
+ else
+ temp = green = -1.0;
+}
+
+
ThFileType Thumbnail::getType () {
return (ThFileType) cfs.format;
@@ -615,6 +627,14 @@ int Thumbnail::infoFromImage (const Glib::ustring& fname, rtengine::RawMetaDataL
return deg;
}
+/*
+ * Read all thumbnail's data from the cache; build and save them if doesn't exist - NON PROTECTED
+ * This includes:
+ * - image's bitmap (*.rtti)
+ * - auto exposure's histogram (full thumbnail only)
+ * - embedded profile (full thumbnail only)
+ * - LiveThumbData section of the data file
+ */
void Thumbnail::_loadThumbnail(bool firstTrial) {
needsReProcessing = true;
@@ -626,7 +646,10 @@ void Thumbnail::_loadThumbnail(bool firstTrial) {
// load supplementary data
bool succ = tpp->readData (getCacheFileName ("data")+".txt");
-
+
+ if (succ)
+ tpp->getAutoWBMultipliers(cfs.redAWBMul, cfs.greenAWBMul, cfs.blueAWBMul);
+
// thumbnail image
succ = succ && tpp->readImage (getCacheFileName ("images"));
@@ -656,11 +679,27 @@ void Thumbnail::_loadThumbnail(bool firstTrial) {
if (!initial_ && tpp) tw = tpp->getImageWidth (getProcParams(), th, imgRatio); // this might return 0 if image was just building
}
+/*
+ * Read all thumbnail's data from the cache; build and save them if doesn't exist - MUTEX PROTECTED
+ * This includes:
+ * - image's bitmap (*.rtti)
+ * - auto exposure's histogram (full thumbnail only)
+ * - embedded profile (full thumbnail only)
+ * - LiveThumbData section of the data file
+ */
void Thumbnail::loadThumbnail (bool firstTrial) {
Glib::Mutex::Lock lock(mutex);
_loadThumbnail(firstTrial);
}
+/*
+ * Save thumbnail's data to the cache - NON PROTECTED
+ * This includes:
+ * - image's bitmap (*.rtti)
+ * - auto exposure's histogram (full thumbnail only)
+ * - embedded profile (full thumbnail only)
+ * - LiveThumbData section of the data file
+ */
void Thumbnail::_saveThumbnail () {
if (!tpp)
@@ -686,12 +725,26 @@ void Thumbnail::_saveThumbnail () {
tpp->writeData (getCacheFileName ("data")+".txt");
}
+/*
+ * Save thumbnail's data to the cache - MUTEX PROTECTED
+ * This includes:
+ * - image's bitmap (*.rtti)
+ * - auto exposure's histogram (full thumbnail only)
+ * - embedded profile (full thumbnail only)
+ * - LiveThumbData section of the data file
+ */
void Thumbnail::saveThumbnail ()
{
Glib::Mutex::Lock lock(mutex);
_saveThumbnail();
}
+/*
+ * Update the cached files
+ * - updatePParams==true (default) : write the procparams file (sidecar or cache, depending on the options)
+ * - updateCacheImageData==true (default) : write the CacheImageData values in the cache folder,
+ * i.e. some General, DateTime, ExifInfo, File info and ExtraRawInfo,
+ */
void Thumbnail::updateCache (bool updatePParams, bool updateCacheImageData) {
if (updatePParams && pparamsValid) {
diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h
index 37286306a..cc7fbbe5c 100644
--- a/rtgui/thumbnail.h
+++ b/rtgui/thumbnail.h
@@ -109,7 +109,7 @@ class Thumbnail {
const Glib::ustring& getExifString ();
const Glib::ustring& getDateTimeString ();
void getCamWB (double& temp, double& green) { if (tpp) tpp->getCamWB (temp, green); else temp = green = -1.0; }
- void getAutoWB (double& temp, double& green) { if (tpp) tpp->getAutoWB (temp, green); else temp = green = -1.0; }
+ void getAutoWB (double& temp, double& green, double equal);
void getSpotWB (int x, int y, int rect, double& temp, double& green) { if (tpp) tpp->getSpotWB (getProcParams(), x, y, rect, temp, green); else temp = green = -1.0; }
void applyAutoExp (rtengine::procparams::ProcParams& pparams) { if (tpp) tpp->applyAutoExp (pparams); }
diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h
index 5e54a4995..cef0c6574 100644
--- a/rtgui/toolpanelcoord.h
+++ b/rtgui/toolpanelcoord.h
@@ -179,7 +179,7 @@ class ToolPanelCoordinator : public ToolPanelListener,
virtual ~ToolPanelCoordinator ();
bool getChangedState () { return hasChanged; }
- void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve,LUTu & histCCurve, LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma);
+ void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve,LUTu & histCCurve, LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma);
void foldAllButOne (Gtk::Box* parent, FoldableToolPanel* openedSection);
// multiple listeners can be added that are notified on changes (typical: profile panel and the history)
@@ -195,16 +195,19 @@ class ToolPanelCoordinator : public ToolPanelListener,
// to support the GUI:
CropGUIListener* getCropGUIListener (); // through the CropGUIListener the editor area can notify the "crop" ToolPanel when the crop selection changes
- // init the toolpanelcoordinator with an image & close it
+ // init the toolpanelcoordinator with an image & close it
void initImage (rtengine::StagedImageProcessor* ipc_, bool israw);
void closeImage ();
// read/write the "expanded" state of the expanders & read/write the crop panel settings (ratio, guide type, etc.)
void readOptions ();
- void writeOptions ();
+ void writeOptions ();
// wbprovider interface
- void getAutoWB (double& temp, double& green) { if (ipc) ipc->getAutoWB (temp, green); }
+ void getAutoWB (double& temp, double& green, double equal) {
+ if (ipc)
+ ipc->getAutoWB (temp, green, equal);
+ }
void getCamWB (double& temp, double& green) { if (ipc) ipc->getCamWB (temp, green); }
//DFProvider interface
diff --git a/rtgui/wbprovider.h b/rtgui/wbprovider.h
index 928c8f3cb..e92013c2b 100644
--- a/rtgui/wbprovider.h
+++ b/rtgui/wbprovider.h
@@ -23,7 +23,8 @@
class WBProvider {
public:
- virtual void getAutoWB (double& temp, double& green) {}
+ virtual ~WBProvider() {}
+ virtual void getAutoWB (double& temp, double& green, double equal) {}
virtual void getCamWB (double& temp, double& green) {}
virtual void spotWBRequested (int size) {}
};
diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc
index 64e8fa61a..f7c5cac16 100644
--- a/rtgui/whitebalance.cc
+++ b/rtgui/whitebalance.cc
@@ -22,12 +22,12 @@
#include "options.h"
#include "../rtengine/safegtk.h"
-#define MINTEMP 2000 //1200
-#define MAXTEMP 25000 //12000
+#define MINTEMP 1500 //1200
+#define MAXTEMP 60000 //12000
#define MINGREEN 0.02
#define MAXGREEN 5.0
-
-extern Glib::ustring argv0;
+#define MINEQUAL 0.8
+#define MAXEQUAL 1.5
using namespace rtengine;
using namespace rtengine::procparams;
@@ -45,6 +45,8 @@ void WhiteBalance::init () {
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_WATER] = safe_create_from_file("wb-water.png");
+// wbPixbufs[WBT_WATER2] = safe_create_from_file("wb-water.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");
@@ -75,7 +77,6 @@ WhiteBalance::WhiteBalance () : Gtk::VBox(), FoldableToolPanel(this), wbp(NULL),
// 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;
@@ -89,6 +90,13 @@ WhiteBalance::WhiteBalance () : Gtk::VBox(), FoldableToolPanel(this), wbp(NULL),
row[methodColumns.colLabel] = M("TP_WBALANCE_FLUO_HEADER");
row[methodColumns.colId] = i+100;
}
+ if (currType == WBT_WATER) {
+ // Creating the under water subcategory header
+ row = *(refTreeModel->append());
+ row[methodColumns.colIcon] = wbPixbufs[currType];
+ row[methodColumns.colLabel] = M("TP_WBALANCE_WATER_HEADER");
+ row[methodColumns.colId] = i+100;
+ }
if (currType == WBT_LAMP) {
// Creating the Lamp subcategory header
row = *(refTreeModel->append());
@@ -113,6 +121,7 @@ WhiteBalance::WhiteBalance () : Gtk::VBox(), FoldableToolPanel(this), wbp(NULL),
}
if (currType == WBT_FLUORESCENT
|| currType == WBT_LAMP
+ || currType == WBT_WATER
|| currType == WBT_FLASH
|| currType == WBT_LED
) {
@@ -129,7 +138,8 @@ WhiteBalance::WhiteBalance () : Gtk::VBox(), FoldableToolPanel(this), wbp(NULL),
}
oldType = currType;
- custom_green[i] = 1.0;
+ custom_green = 1.0;
+ custom_equal = 1.0;
}
//Add the model columns to the Combo (which is a kind of view),
@@ -173,29 +183,30 @@ WhiteBalance::WhiteBalance () : Gtk::VBox(), FoldableToolPanel(this), wbp(NULL),
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.0));
+ equal = Gtk::manage (new Adjuster (M("TP_WBALANCE_EQBLUERED"), MINEQUAL, MAXEQUAL, 0.001, 1.0));
+ equal->set_tooltip_markup (M("TP_WBALANCE_EQBLUERED_TOOLTIP"));
temp->show ();
green->show ();
+ equal->show ();
pack_start (*temp);
pack_start (*green);
+ pack_start (*equal);
temp->setAdjusterListener (this);
green->setAdjusterListener (this);
+ equal->setAdjusterListener (this);
spotbutton->signal_pressed().connect( sigc::mem_fun(*this, &WhiteBalance::spotPressed) );
methconn = method->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::optChanged) );
spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) );
}
-WhiteBalance::~WhiteBalance () {
- delete[] custom_green;
-}
-
void WhiteBalance::adjusterChanged (Adjuster* a, double newval) {
int tVal = (int)temp->getValue();
double gVal = green->getValue();
-
+ double eVal = equal->getValue();
Gtk::TreeModel::Row row = getActiveMethod();
if (row == refTreeModel->children().end()) return;
@@ -203,25 +214,42 @@ void WhiteBalance::adjusterChanged (Adjuster* a, double newval) {
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);
- }
+ if (!ppMethod || (ppMethod->ppLabel!=wbCustom->ppLabel && !(a==equal && ppMethod->type==WBT_AUTO)) ) {
+ methconn.block(true);
+ opt = setActiveMethod(wbCustom->GUILabel);
+ cache_customWB (tVal, gVal);
+ cache_customEqual(eVal);
+ methconn.block(false);
}
//cache custom WB setting to allow its recall
if (a==temp)
cache_customTemp (tVal);
- else
+ else if (a==green)
cache_customGreen (gVal);
+ else if (a==equal) {
+ cache_customEqual (eVal);
+ // Recomputing AutoWB if it's the current method
+ if (wbp && ppMethod->type==WBT_AUTO) {
+ double ctemp=-1.0; double cgreen=-1.0;
+ wbp->getAutoWB (ctemp, cgreen, eVal);
+
+ if (ctemp != -1.0) {
+ // Set the automatics temperature value only if in SET mode
+ if (temp->getEditedState() && !temp->getAddMode() ) temp->setValue (ctemp);
+ // Set the automatics green value only if in SET mode
+ if (green->getEditedState() && !green->getAddMode()) green->setValue (cgreen);
+ }
+ }
+ }
if (listener) {
if (a==temp)
listener->panelChanged (EvWBTemp, Glib::ustring::format ((int)a->getValue()));
else if (a==green)
listener->panelChanged (EvWBGreen, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue()));
+ else if (a==equal)
+ listener->panelChanged (EvWBequal, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue()));
}
}
@@ -244,6 +272,7 @@ void WhiteBalance::optChanged () {
if (row[methodColumns.colLabel] == M("GENERAL_UNCHANGED")) {
temp->setEditedState (UnEdited);
green->setEditedState (UnEdited);
+ equal->setEditedState (UnEdited);
}
else {
int methodId = findWBEntryId (row[methodColumns.colLabel], WBLT_GUI);
@@ -256,23 +285,28 @@ void WhiteBalance::optChanged () {
wbp->getCamWB (ctemp, cgreen);
temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp);
green->setValue (green->getAddMode() ? 0.0 : cgreen);
+ equal->setValue (equal->getAddMode() ? 0.0 : 1.0);
if (batchMode) {
temp->setEditedState (UnEdited);
green->setEditedState (UnEdited);
+ equal->setEditedState (UnEdited);
}
}
break;
case WBT_AUTO:
if (wbp) {
- double ctemp, cgreen;
- wbp->getAutoWB (ctemp, cgreen);
- if (ctemp != -1.0) {
- temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp);
- green->setValue (green->getAddMode() ? 0.0 : cgreen);
- }
if (batchMode) {
temp->setEditedState (UnEdited);
green->setEditedState (UnEdited);
+ // equal remain as is
+ }
+ if (!batchMode || equal->getEditedState()) {
+ double ctemp, cgreen;
+ wbp->getAutoWB (ctemp, cgreen, equal->getValue());
+ if (ctemp != -1.0) {
+ temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp);
+ green->setValue (green->getAddMode() ? 0.0 : cgreen);
+ }
}
}
break;
@@ -280,10 +314,12 @@ void WhiteBalance::optChanged () {
if (custom_temp>0){
temp->setValue (temp->getAddMode() ? 0.0 : custom_temp);
}
- green->setValue (green->getAddMode() ? 0.0 : custom_green[methodId]);
+ green->setValue (green->getAddMode() ? 0.0 : custom_green);
+ equal->setValue (equal->getAddMode() ? 0.0 : custom_equal);
if (batchMode) {
temp->setEditedState (Edited);
green->setEditedState (Edited);
+ equal->setEditedState (Edited);
}
break;
/* All other solution are the default cases
@@ -297,11 +333,13 @@ void WhiteBalance::optChanged () {
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]);
+ temp->setValue ( temp->getAddMode() ? 0.0 : (double)(currMethod->temperature));
+ green->setValue (green->getAddMode() ? 0.0 : (double)(currMethod->green));
+ equal->setValue (equal->getAddMode() ? 0.0 : (double)(currMethod->equal));
if (batchMode) {
temp->setEditedState (Edited);
green->setEditedState (Edited);
+ equal->setEditedState (Edited);
}
break;
}
@@ -326,13 +364,16 @@ void WhiteBalance::spotSizeChanged () {
}
void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) {
+ disableListener ();
methconn.block (true);
+ equal->setValue (pp->wb.equal);
if (pedited) {
// By default, temperature and green are said "UnEdited", but it may change later
temp->setEditedState (UnEdited);
green->setEditedState (UnEdited);
+ equal->setEditedState (pedited->wb.equal ? Edited : UnEdited);
}
if (pedited && !pedited->wb.method) {
@@ -350,12 +391,12 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) {
case WBT_CUSTOM:
temp->setValue (pp->wb.temperature);
green->setValue (pp->wb.green);
- if (pedited) {
+ equal->setValue (pp->wb.equal);
+ 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) {
@@ -366,23 +407,34 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) {
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
+ equal->setValue (equal->getAddMode() ? 0.0 : 1.);
}
break;
case WBT_AUTO:
+ // the equalizer's value is restored for the AutoWB
+ equal->setValue (equal->getAddMode() ? 0.0 : pp->wb.equal);
+
+ // set default values first if in ADD mode, otherwise keep the current ones
+ if (temp->getAddMode() ) temp->setValue (0.0);
+ if (green->getAddMode()) green->setValue (0.0);
+
+ // then check for the correct ones, if possible
if (wbp) {
- double ctemp; double cgreen;
- wbp->getAutoWB (ctemp, cgreen);
+ double ctemp=-1.0; double cgreen=-1.0;
+ wbp->getAutoWB (ctemp, cgreen, pp->wb.equal);
if (ctemp != -1.0) {
- // 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);
+ // Set the automatics temperature if in SET mode
+ if (!pedited || (pedited->wb.temperature && !temp->getAddMode()) ) {
+ temp->setValue (ctemp);
+ if (pedited) temp->setEditedState (Edited);
+ }
+ // Set the automatics green value if in SET mode
+ if (!pedited || (pedited->wb.green && !green->getAddMode())) {
+ green->setValue (cgreen);
+ if (pedited) green->setEditedState (Edited);
+ }
}
-
- //cache_customWB ((int)ctemp, cgreen); // this will be used to set initial Custom WB setting
}
break;
/*
@@ -401,16 +453,19 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) {
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);
+ equal->setValue(equal->getAddMode() ? 0.0 : pp->wb.equal);
// The user may have changed the green value even for predefined WB values
if (pedited) {
green->setEditedState (pedited->wb.green ? Edited : UnEdited);
+ equal->setEditedState (pedited->wb.equal ? Edited : UnEdited);
}
//cache_customGreen (pp->wb.green);
break;
}
}
methconn.block (false);
+ enableListener ();
}
void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) {
@@ -420,6 +475,7 @@ void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) {
if (pedited) {
pedited->wb.temperature = temp->getEditedState ();
pedited->wb.green = green->getEditedState ();
+ pedited->wb.equal = equal->getEditedState ();
pedited->wb.method = row[methodColumns.colLabel]!=M("GENERAL_UNCHANGED");
}
@@ -429,10 +485,11 @@ void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) {
pp->wb.method = ppMethod->ppLabel;
pp->wb.temperature = temp->getIntValue ();
pp->wb.green = green->getValue ();
-
+ pp->wb.equal = equal->getValue ();
}
void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
+ equal->setDefault (defParams->wb.equal);
if (wbp && defParams->wb.method == "Camera") {
double ctemp; double cgreen;
@@ -444,7 +501,7 @@ void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited*
// this setDefaults method is called too early ; the wbp has been set,
// but wbp is not ready to provide!
double ctemp; double cgreen;
- wbp->getAutoWB (ctemp, cgreen);
+ wbp->getAutoWB (ctemp, cgreen, defParams->wb.equal);
if (ctemp != -1.0) {
temp->setDefault (temp->getAddMode() ? 0 : (int)ctemp);
green->setDefault (green->getAddMode() ? 0 : cgreen);
@@ -462,10 +519,12 @@ void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited*
if (pedited) {
temp->setDefaultEditedState (pedited->wb.temperature ? Edited : UnEdited);
green->setDefaultEditedState (pedited->wb.green ? Edited : UnEdited);
+ equal->setDefaultEditedState (pedited->wb.equal ? Edited : UnEdited);
}
else {
temp->setDefaultEditedState (Irrelevant);
green->setDefaultEditedState (Irrelevant);
+ equal->setDefaultEditedState (Irrelevant);
}
}
@@ -474,6 +533,7 @@ void WhiteBalance::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
temp->showEditedCB ();
green->showEditedCB ();
+ equal->showEditedCB ();
Gtk::TreeModel::Row row = *(refTreeModel->append());
row[methodColumns.colId] = WBParams::wbEntries.size();
row[methodColumns.colLabel] = M("GENERAL_UNCHANGED");
@@ -493,6 +553,7 @@ void WhiteBalance::setWB (int vtemp, double vgreen) {
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);"
+ cache_customEqual(equal->getValue());
temp->setEditedState (Edited);
green->setEditedState (Edited);
methconn.block(false);
@@ -501,16 +562,18 @@ void WhiteBalance::setWB (int vtemp, double vgreen) {
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) {
+void WhiteBalance::setAdjusterBehavior (bool tempadd, bool greenadd, bool equaladd) {
temp->setAddMode(tempadd);
green->setAddMode(greenadd);
+ equal->setAddMode(equaladd);
}
void WhiteBalance::trimValues (rtengine::procparams::ProcParams* pp) {
temp->trimValue(pp->wb.temperature);
green->trimValue(pp->wb.green);
+ equal->trimValue(pp->wb.equal);
}
inline void WhiteBalance::cache_customTemp(int temp) {
@@ -518,11 +581,10 @@ inline void WhiteBalance::cache_customTemp(int 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]]);
+ custom_green = green;
+}
+void WhiteBalance::cache_customEqual(double equal) {
+ custom_equal = equal;
}
void WhiteBalance::cache_customWB(int temp, double green) {
diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h
index 1da7012f3..5e932fe25 100644
--- a/rtgui/whitebalance.h
+++ b/rtgui/whitebalance.h
@@ -55,18 +55,23 @@ class WhiteBalance : public Gtk::VBox, public AdjusterListener, public FoldableT
MyComboBoxText* spotsize;
Adjuster* temp;
Adjuster* green;
+ Adjuster* equal;
+
Gtk::Button* spotbutton;
int opt;
double nextTemp;
double nextGreen;
- WBProvider *wbp;
+ WBProvider *wbp; // pointer to a ToolPanelCoordinator object, or its subclass BatchToolPanelCoordinator
SpotWBListener* wblistener;
sigc::connection methconn;
int custom_temp;
- double* custom_green;
+ double custom_green;
+ double custom_equal;
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
+ void cache_customEqual (double equal); //cache Equal only to allow its recall
+
int setActiveMethod (Glib::ustring label);
int _setActiveMethod (Glib::ustring &label, Gtk::TreeModel::Children &children);
@@ -77,7 +82,7 @@ class WhiteBalance : public Gtk::VBox, public AdjusterListener, public FoldableT
public:
WhiteBalance ();
- ~WhiteBalance ();
+ ~WhiteBalance () {};
static void init ();
static void cleanup ();
@@ -86,7 +91,6 @@ class WhiteBalance : public Gtk::VBox, public AdjusterListener, public FoldableT
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode);
-
void optChanged ();
void spotPressed ();
void spotSizeChanged ();
@@ -96,7 +100,7 @@ class WhiteBalance : public Gtk::VBox, public AdjusterListener, public FoldableT
void setSpotWBListener (SpotWBListener* l) { wblistener = l; }
void setWB (int temp, double green);
- void setAdjusterBehavior (bool tempadd, bool greenadd);
+ void setAdjusterBehavior (bool tempadd, bool greenadd, bool equaladd);
void trimValues (rtengine::procparams::ProcParams* pp);
};
diff --git a/tools/source_icons/scalable/wb-water.file b/tools/source_icons/scalable/wb-water.file
new file mode 100644
index 000000000..14ce25494
--- /dev/null
+++ b/tools/source_icons/scalable/wb-water.file
@@ -0,0 +1 @@
+wb-water.png,w22,actions
diff --git a/tools/source_icons/scalable/wb-water.svg b/tools/source_icons/scalable/wb-water.svg
new file mode 100644
index 000000000..d3e2ecde7
--- /dev/null
+++ b/tools/source_icons/scalable/wb-water.svg
@@ -0,0 +1,642 @@
+
+
+
+