diff --git a/rawtherapee.astylerc b/rawtherapee.astylerc
index bcea16b96..3d49d821f 100644
--- a/rawtherapee.astylerc
+++ b/rawtherapee.astylerc
@@ -4,5 +4,5 @@ indent-switches
break-blocks
pad-oper
convert-tabs
-pad-first-paren-out
pad-header
+unpad-paren
diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch
index cda1faa42..08da90847 100644
--- a/rtdata/languages/Deutsch
+++ b/rtdata/languages/Deutsch
@@ -45,6 +45,7 @@
#44 21.09.2017 Erweiterung (TooWaBoo) RT 5.2
#45 15.10.2017 Erweiterung (TooWaBoo) RT 5.3
#46 18.10.2017 Erweiterung (TooWaBoo) RT 5.3
+#47 19.11.2017 HDR-Dynamikkompression (TooWaBoo) RT 5.3
ABOUT_TAB_BUILD;Version
ABOUT_TAB_CREDITS;Danksagungen
@@ -2216,10 +2217,10 @@ ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: -
! Untranslated keys follow; remove the ! prefix after an entry is translated.
!!!!!!!!!!!!!!!!!!!!!!!!!
-!HISTORY_MSG_488;HDR Tone Mapping
-!HISTORY_MSG_489;HDR TM - Threshold
-!HISTORY_MSG_490;HDR TM - Amount
-!PARTIALPASTE_TM_FATTAL;HDR Tone mapping
-!TP_TM_FATTAL_AMOUNT;Amount
-!TP_TM_FATTAL_LABEL;HDR Tone Mapping
-!TP_TM_FATTAL_THRESHOLD;Threshold
+HISTORY_MSG_488;(HDR-Dynamikkompression)
+HISTORY_MSG_489;(HDR-Dynamikkompression)\nSchwelle
+HISTORY_MSG_490;(HDR-Dynamikkompression)\nIntensität
+PARTIALPASTE_TM_FATTAL;HDR-Dynamikkompression
+TP_TM_FATTAL_AMOUNT;Intensität
+TP_TM_FATTAL_LABEL;HDR-Dynamikkompression
+TP_TM_FATTAL_THRESHOLD;Schwelle
diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais
index 649f9c5d8..1deea5f07 100644
--- a/rtdata/languages/Francais
+++ b/rtdata/languages/Francais
@@ -34,6 +34,7 @@ CURVEEDITOR_TOOLTIPPASTE;Colle la courbe du presse-papier
CURVEEDITOR_TOOLTIPSAVE;Enregistrer la courbe actuelle
CURVEEDITOR_TYPE;Type:
DIRBROWSER_FOLDERS;Répertoires
+DONT_SHOW_AGAIN;Ne plus montrer ce message.
DYNPROFILEEDITOR_DELETE;Supprimer
DYNPROFILEEDITOR_EDIT;Modifier
DYNPROFILEEDITOR_EDIT_RULE;Modifier une règle de Profil Dynamique
@@ -233,6 +234,7 @@ GENERAL_PORTRAIT;Portrait
GENERAL_SAVE;Enregistrer
GENERAL_UNCHANGED;(Inchangé)
GENERAL_WARNING;Attention
+GIMP_PLUGIN_INFO;Bienvenue dans le plugin RawTherapee de GIMP!\nUne fois l'édition terminée, fermez simplement la fenêtre principale de RawTherapee et l'image sera importée automatiquement dans GIMP.
HISTOGRAM_TOOLTIP_B;Montrer/cacher l'histogramme BLEU
HISTOGRAM_TOOLTIP_BAR;Montrer/Cacher l'indicateur RVB du pixel pointé\nCliquer le bouton droit de la souris sur l'image de prévisualisation pour geler/dégeler
HISTOGRAM_TOOLTIP_CHRO;Montrer/Cacher l'histogramme de Chromaticité
@@ -703,6 +705,18 @@ HISTORY_MSG_472;PS - Adoucir les transitions
HISTORY_MSG_473;PS - Utiliser LMMSE
HISTORY_MSG_474;PS - Égaliser
HISTORY_MSG_475;PS - Égaliser par canal
+HISTORY_MSG_476;CAM02 - Temp sortie
+HISTORY_MSG_477;CAM02 - Vert sortie
+HISTORY_MSG_478;CAM02 - Yb sortie
+HISTORY_MSG_479;CAM02 - adaptation CAT02 sortie
+HISTORY_MSG_480;CAM02 - CAT02 auto sortie
+HISTORY_MSG_481;CAM02 - Temp scène
+HISTORY_MSG_482;CAM02 - Green scène
+HISTORY_MSG_483;CAM02 - Yb scène
+HISTORY_MSG_484;CAM02 - Yb auto scène
+HISTORY_MSG_485;Correction d'Objectif
+HISTORY_MSG_486;Corr. d'Obj. - Appareil
+HISTORY_MSG_487;Corr. d'Obj. - Objectif
HISTORY_MSG_488;Compression tonale HDR
HISTORY_MSG_489;CT HDR - Seuil
HISTORY_MSG_490;CT HDR - Quantité
@@ -752,6 +766,10 @@ IPTCPANEL_TITLE;Titre
IPTCPANEL_TITLEHINT;Enterez un nom court et humainement lisible pour l'image, cela peut être le nom du fichier.
IPTCPANEL_TRANSREFERENCE;ID du travail
IPTCPANEL_TRANSREFERENCEHINT;Enterez un nombre ou identifiant servant au contrôle du flux de travail ou au suivi.
+LENSPROFILE_CORRECTION_AUTOMATCH;Paramètres de correction trouvés automatiquement
+LENSPROFILE_CORRECTION_LCPFILE;Fichier LCP
+LENSPROFILE_CORRECTION_MANUAL;Paramètres de correction manuel
+LENSPROFILE_LENS_WARNING;Attention: la taille du capteur utilisé pour le profilage de l'objectif est plus grand que celui de l'appareil sélectionné, le résultat peut être faux.
MAIN_BUTTON_FULLSCREEN;Plein écran
MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigue à l'image Suivante relativement à l'image ouverte dans l'Éditeur\nRaccourci: Shift-F4\n\nPour naviguer à l'image Suivante relativement à la vignette sélectionnée dans le Navigateur de fichiers\nRaccourci: F4
MAIN_BUTTON_NAVPREV_TOOLTIP;Navigue à l'image Précédente relativement à l'image ouverte dans l'Éditeur\nRaccourci: Shift-F3\n\nPour naviguer à l'image Précédente relativement à la vignette sélectionnée dans le Navigateur de fichiers\nRaccourci: F3
@@ -810,6 +828,7 @@ MAIN_TAB_WAVELET_TOOLTIP;Raccourci: Alt-w
MAIN_TOOLTIP_BACKCOLOR0;Couleur de fond de l'aperçu: Selon le thème\nRaccourci : 9
MAIN_TOOLTIP_BACKCOLOR1;Couleur de fond de l'aperçu: Noir\nRaccourci : 9
MAIN_TOOLTIP_BACKCOLOR2;Couleur de fond de l'aperçu: Blanc\nRaccourci: 9
+MAIN_TOOLTIP_BACKCOLOR3;Couleur de fond de l'aperçu: Gris moyen\nRaccourci : 9
MAIN_TOOLTIP_BEFOREAFTERLOCK;Vérouille / déverouille la vue Avant\n\nVérouille: garde la vue Avant inchangée - \nutile pour évaluer l'effet cumulatif de plusieurs outils.\nDe plus, une comparaison peut être faite à partir de n'importe quelle étape de l'historique\n\nDéverouille: la vue Avant représentera l'étape précédant la vue Après, montrant l'effet qui vient d'être modifié
MAIN_TOOLTIP_HIDEHP;Montrer/cacher le panneau gauche (incluant l'historique)\nRaccourci: l
MAIN_TOOLTIP_INDCLIPPEDH;Indication hautes lumières hors domaine\nRaccourci: <
@@ -907,7 +926,7 @@ PARTIALPASTE_SHADOWSHIGHLIGHTS;Ombres/Hautes lumières
PARTIALPASTE_SHARPENEDGE;Bords
PARTIALPASTE_SHARPENING;Netteté
PARTIALPASTE_SHARPENMICRO;Microcontraste
-PARTIALPASTE_TM_FATTAL;Compression tonale HDR (Fattal02)
+PARTIALPASTE_TM_FATTAL;Compression tonale HDR
PARTIALPASTE_VIBRANCE;Vibrance
PARTIALPASTE_VIGNETTING;Correction du vignettage
PARTIALPASTE_WAVELETGROUP;Niveaux d'ondelette
@@ -920,6 +939,7 @@ PREFERENCES_AUTLISSTD;Haut
PREFERENCES_AUTLISVLOW;Aucun
PREFERENCES_AUTLOW;Bas
PREFERENCES_AUTOMONPROFILE;Utiliser automatiquement le profil de l'écran principal
+PREFERENCES_AUTOSAVE_TP_OPEN;Sauver automatiquement l'état ouvert/fermé\n des outils avant de fermer
PREFERENCES_AUTSTD;Standard
PREFERENCES_BATCH_PROCESSING;Traitement par lot
PREFERENCES_BEHADDALL;Tout à 'Ajoute'
@@ -956,6 +976,7 @@ PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID
PREFERENCES_CUSTPROFBUILDPATH;Chemin de l'exécutable
PREFERENCES_CUTOVERLAYBRUSH;Masque de recadrage
PREFERENCES_D50;5000K
+PREFERENCES_D50_OLD;5000K
PREFERENCES_D55;5500K
PREFERENCES_D60;6000K
PREFERENCES_D65;6500K
@@ -997,6 +1018,7 @@ PREFERENCES_GREY05;Yb=05 CIE L#30
PREFERENCES_GREY10;Yb=10 CIE L#40
PREFERENCES_GREY15;Yb=15 CIE L#45
PREFERENCES_GREY18;Yb=18 CIE L#50
+PREFERENCES_GREY18_OLD;Yb=18 CIE L#50
PREFERENCES_GREY23;Yb=23 CIE L#55
PREFERENCES_GREY30;Yb=30 CIE L#60
PREFERENCES_GREY40;Yb=40 CIE L#70
@@ -1018,6 +1040,7 @@ PREFERENCES_INTENT_PERCEPTUAL;Perceptuel
PREFERENCES_INTENT_RELATIVE;Colorimétrie relative
PREFERENCES_INTENT_SATURATION;Saturation
PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Afficher vignette incluse dans fichier RAW si non édité
+PREFERENCES_LANG;Langage
PREFERENCES_LANGAUTODETECT;Utiliser les paramètres linguistiques de l'OS
PREFERENCES_LEVAUTDN;Niveau de débruitage
PREFERENCES_LEVDN;Taille de la cellule
@@ -1079,6 +1102,7 @@ PREFERENCES_REMEMBERZOOMPAN;Se souvenir de niveau de zoom et de la position de l
PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Retient le niveau de zoom et la position de l'image courante lors de l'ouverture d'une nouvelle image.\n\nCette option ne fonctionne que dans le mode "Éditeur unique" et quand "Méthode de dématriçage utilisé pour l'aperçu à un zoom <100%" is set to "Idem PP3".
PREFERENCES_RGBDTL_LABEL;Nombre maximum d'unités de calcul pour la Réduction du bruit
PREFERENCES_RGBDTL_TOOLTIP;La réduction du bruit nécessite un minimum d'à peu près 128Mo de RAM pour une image de 10MPix ou 512Mo pour une image de 40MPix, ainsi que 128Mo de RAM supplémentaire par unité de calcul. Plus il y aura d'unités de calcul travaillant en parallèle, plus ce sera rapide. Laissez la valeur à "0" pour utiliser automatiquement autant d'unités de calcul que possible.
+PREFERENCES_SAVE_TP_OPEN_NOW;Sauver l'état ouvert/fermé maintenant
PREFERENCES_SELECTFONT;Police principale
PREFERENCES_SELECTFONT_COLPICKER;Police des pipette à couleur
PREFERENCES_SELECTLANG;Choix de la langue
@@ -1109,6 +1133,7 @@ PREFERENCES_TAB_GENERAL;Général
PREFERENCES_TAB_IMPROC;Traitement de l'image
PREFERENCES_TAB_PERFORMANCE;Performance
PREFERENCES_TAB_SOUND;Sons
+PREFERENCES_THEME;Thème
PREFERENCES_TIMAX;Haut
PREFERENCES_TINB;Nombre de tuiles
PREFERENCES_TISTD;Standard
@@ -1311,6 +1336,7 @@ TP_COLORAPP_DATACIE;Histogrammes post CIECAM dans les courbes
TP_COLORAPP_DATACIE_TOOLTIP;Quand activé, les histogrammes de fond des courbes CIECAM02 montrent des valeurs/amplitudes approximatives de J/Q, ou de C:s/M après les ajustements CIECAM.\nCette sélection n'a pas d'incidence sur l'histogramme général.\n\nQuand désactivé, les histogrammes de fond des courbes CIECAM affichent les valeurs Lab avant les ajustements CIECAM
TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Si la case est cochée (recommandé), RT calcule une valeur optimale, qui est utilisée par CAT02, mais aussi pour l'ensemble de CIECAM02.\nVous pouvez décocher la case et changer la valeur du curseur; (les valeurs supérieures à 65 sont recommandées)
TP_COLORAPP_DEGREE_TOOLTIP;Niveau d'adaptation chromatique CIE CAT 2002
+TP_COLORAPP_FREE;Temp libre+vert + CAT02 + [sortie]
TP_COLORAPP_GAMUT;Contrôle du gamut (Lab)
TP_COLORAPP_GAMUT_TOOLTIP;Permet le controle du gamut en mode Lab
TP_COLORAPP_HUE;Teinte (h)
@@ -1323,6 +1349,8 @@ TP_COLORAPP_LIGHT;Luminosité (J)
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;Modèle de Point Blanc\n\nBB [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_NEUTRAL;Résinitialiser
+TP_COLORAPP_NEUTRAL_TIP;Réinitialiser tous les curseurs, cases à cocher et courbes à leurs valeur par défaut
TP_COLORAPP_RSTPRO;Protection des tons chairs et rouges
TP_COLORAPP_RSTPRO_TOOLTIP;Protection des tons chairs et rouges (curseurs et courbes)
TP_COLORAPP_SHARPCIE;Netteté, Contraste par niveau de détails, Microcontraste & Aberration chromatique avec Q/C
@@ -1343,10 +1371,14 @@ 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_TEMP_TOOLTIP;Pour sélectionner un illuminant, toujours régler Teinte=1.\n\nA temp=2856\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504
TP_COLORAPP_TONECIE;Compression Tonale utilisant CIECAM02
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_COLORAPP_YB;Yb% (luminance moyenne)
+TP_COLORAPP_YBSCENE;Yb% (luminance moyenne)
+TP_COLORAPP_YBSCENE_TOOLTIP;si auto activé, Yb est calculé suivant la valeur de luminance moyenne de l'image actuelle
TP_COLORTONING_AB;o C/L
TP_COLORTONING_AUTOSAT;Automatique
TP_COLORTONING_BALANCE;Balance
@@ -1900,7 +1932,7 @@ TP_SPOT_COUNTLABEL;%1 point(s)
TP_SPOT_ENTRYCHANGED;Modification d'un point
TP_SPOT_LABEL;Retrait de taches
TP_TM_FATTAL_AMOUNT;Quantité
-TP_TM_FATTAL_LABEL;Compression Tonale HDR (Fattal02)
+TP_TM_FATTAL_LABEL;Compression Tonale HDR
TP_TM_FATTAL_THRESHOLD;Seuil
TP_VIBRANCE_AVOIDCOLORSHIFT;Éviter les dérives de teinte
TP_VIBRANCE_CURVEEDITOR_SKINTONES;TT
@@ -2145,39 +2177,3 @@ ZOOMPANEL_ZOOMFITSCREEN;Affiche l'image entière\nRaccourci: f
ZOOMPANEL_ZOOMIN;Zoom Avant\nRaccourci: +
ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: -
-!!!!!!!!!!!!!!!!!!!!!!!!!
-! Untranslated keys follow; remove the ! prefix after an entry is translated.
-!!!!!!!!!!!!!!!!!!!!!!!!!
-
-!DONT_SHOW_AGAIN;Don't show this message again.
-!GIMP_PLUGIN_INFO;Welcome to the RawTherapee GIMP plugin!\nOnce you are done editing, simply close the main RawTherapee window and the image will be automatically imported in GIMP.
-!HISTORY_MSG_476;CAM02 - Temp out
-!HISTORY_MSG_477;CAM02 - Green out
-!HISTORY_MSG_478;CAM02 - Yb out
-!HISTORY_MSG_479;CAM02 - CAT02 adaptation out
-!HISTORY_MSG_480;CAM02 - Automatic CAT02 out
-!HISTORY_MSG_481;CAM02 - Temp scene
-!HISTORY_MSG_482;CAM02 - Green scene
-!HISTORY_MSG_483;CAM02 - Yb scene
-!HISTORY_MSG_484;CAM02 - Auto Yb scene
-!HISTORY_MSG_485;Lens Correction
-!HISTORY_MSG_486;Lens Correction - Camera
-!HISTORY_MSG_487;Lens Correction - Lens
-!LENSPROFILE_CORRECTION_AUTOMATCH;Auto-matched correction parameters
-!LENSPROFILE_CORRECTION_LCPFILE;LCP File
-!LENSPROFILE_CORRECTION_MANUAL;Manual correction parameters
-!LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong.
-!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: Middle grey\nShortcut: 9
-!PREFERENCES_AUTOSAVE_TP_OPEN;Automatically save tools collapsed/expanded\nstate before exiting
-!PREFERENCES_D50_OLD;5000K
-!PREFERENCES_GREY18_OLD;Yb=18 CIE L#50
-!PREFERENCES_LANG;Language
-!PREFERENCES_SAVE_TP_OPEN_NOW;Save tools collapsed/expanded state now
-!PREFERENCES_THEME;Theme
-!TP_COLORAPP_FREE;Free temp+green + CAT02 + [output]
-!TP_COLORAPP_NEUTRAL;Reset
-!TP_COLORAPP_NEUTRAL_TIP;Reset all sliders checkbox and curves to their default values
-!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always set Tint=1.\n\nA temp=2856\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504
-!TP_COLORAPP_YB;Yb% (mean luminance)
-!TP_COLORAPP_YBSCENE;Yb% (mean luminance)
-!TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance
diff --git a/rtdata/languages/default b/rtdata/languages/default
index 120be7b4d..eec5268c9 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -1371,14 +1371,14 @@ TP_COLORAPP_TCMODE_LABEL2;Curve mode 2
TP_COLORAPP_TCMODE_LABEL3;Curve chroma mode
TP_COLORAPP_TCMODE_LIGHTNESS;Lightness
TP_COLORAPP_TCMODE_SATUR;Saturation
-TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant always set Tint=1.\n\nA temp=2856\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504
+TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant, always set Tint=1.\n\nA temp=2856\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504
TP_COLORAPP_TONECIE;Tone mapping using CIECAM02
TP_COLORAPP_TONECIE_TOOLTIP;If this option is disabled, tone mapping is done in L*a*b* space.\nIf this option is enabled, tone mapping is done using CIECAM02.\nThe Tone Mapping tool must be enabled for this setting to take effect.
TP_COLORAPP_WBCAM;WB [RT+CAT02] + [output]
TP_COLORAPP_WBRT;WB [RT] + [output]
TP_COLORAPP_YB;Yb% (mean luminance)
TP_COLORAPP_YBSCENE;Yb% (mean luminance)
-TP_COLORAPP_YBSCENE_TOOLTIP;if auto enable, Yb is calculated from the mean value of actual image luminance
+TP_COLORAPP_YBSCENE_TOOLTIP;if auto is enabled, Yb is calculated from the mean value of the actual image's luminance
TP_COLORTONING_AB;o C/L
TP_COLORTONING_AUTOSAT;Automatic
TP_COLORTONING_BALANCE;Balance
diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt
index c8904703d..957304bb8 100644
--- a/rtengine/CMakeLists.txt
+++ b/rtengine/CMakeLists.txt
@@ -107,6 +107,7 @@ set(RTENGINESOURCEFILES
rawimage.cc
rawimagesource.cc
refreshmap.cc
+ rt_algo.cc
rtthumbnail.cc
shmap.cc
simpleprocess.cc
diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc
index 7fef1146f..9ae313530 100644
--- a/rtengine/dcraw.cc
+++ b/rtengine/dcraw.cc
@@ -6410,6 +6410,9 @@ guess_cfa_pc:
}
if (!use_cm)
FORCC pre_mul[c] /= cc[cm_D65][c][c];
+
+ RT_from_adobe_dng_converter = !strncmp(software, "Adobe DNG Converter", 19);
+
return 0;
}
@@ -9690,14 +9693,16 @@ bw: colors = 1;
}
dng_skip:
if ((use_camera_matrix & (use_camera_wb || dng_version))
- && cmatrix[0][0] > 0.125) {
+ && cmatrix[0][0] > 0.125
+ && !RT_from_adobe_dng_converter /* RT -- do not use the embedded
+ * matrices for DNGs coming from the
+ * Adobe DNG Converter, to ensure
+ * consistency of WB values between
+ * DNG-converted and original raw
+ * files. See #4129 */) {
memcpy (rgb_cam, cmatrix, sizeof cmatrix);
raw_color = 0;
- if (dng_version && !use_camera_wb) { // RT
- raw_color = 1;
- }
}
- // RT -- TODO: check if these special cases are still needed!
if(!strncmp(make, "Panasonic", 9) && !strncmp(model, "DMC-LX100",9))
adobe_coeff (make, model);
if(!strncmp(make, "Samsung", 7) && !strncmp(model, "GX20",4))
diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h
index cc1f36484..0a10f9732 100644
--- a/rtengine/dcraw.h
+++ b/rtengine/dcraw.h
@@ -58,6 +58,7 @@ public:
,RT_whitelevel_from_constant(0)
,RT_blacklevel_from_constant(0)
,RT_matrix_from_constant(0)
+ ,RT_from_adobe_dng_converter(false)
,getbithuff(this,ifp,zero_after_ff)
{
memset(&hbd, 0, sizeof(hbd));
@@ -151,6 +152,7 @@ protected:
int RT_whitelevel_from_constant;
int RT_blacklevel_from_constant;
int RT_matrix_from_constant;
+ bool RT_from_adobe_dng_converter;
float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4];
diff --git a/rtengine/rt_algo.cc b/rtengine/rt_algo.cc
new file mode 100644
index 000000000..79508cfb3
--- /dev/null
+++ b/rtengine/rt_algo.cc
@@ -0,0 +1,167 @@
+/*
+ * This file is part of RawTherapee.
+ *
+ * RawTherapee is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * RawTherapee is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RawTherapee. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef _OPENMP
+#include
+#endif
+
+#include "rt_algo.h"
+
+namespace rtengine
+{
+
+void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multithread)
+{
+ // Copyright (c) 2017 Ingo Weyrich
+ // We need to find the (minPrct*size) smallest value and the (maxPrct*size) smallest value in data.
+ // We use a histogram based search for speed and to reduce memory usage.
+ // Memory usage of this method is histoSize * sizeof(uint32_t) * (t + 1) byte,
+ // where t is the number of threads and histoSize is in [1;65536].
+ // Processing time is O(n) where n is size of the input array.
+ // It scales well with multiple threads if the size of the input array is large.
+ // The current implementation is not guaranteed to work correctly if size > 2^32 (4294967296).
+
+ assert(minPrct <= maxPrct);
+
+ if (size == 0) {
+ return;
+ }
+
+ size_t numThreads = 1;
+#ifdef _OPENMP
+ // Because we have an overhead in the critical region of the main loop for each thread
+ // we make a rough calculation to reduce the number of threads for small data size.
+ // This also works fine for the minmax loop.
+ if (multithread) {
+ const size_t maxThreads = omp_get_max_threads();
+ while (size > numThreads * numThreads * 16384 && numThreads < maxThreads) {
+ ++numThreads;
+ }
+ }
+#endif
+
+ // We need min and max value of data to calculate the scale factor for the histogram
+ float minVal = data[0];
+ float maxVal = data[0];
+#ifdef _OPENMP
+ #pragma omp parallel for reduction(min:minVal) reduction(max:maxVal) num_threads(numThreads)
+#endif
+ for (size_t i = 1; i < size; ++i) {
+ minVal = std::min(minVal, data[i]);
+ maxVal = std::max(maxVal, data[i]);
+ }
+
+ if (std::fabs(maxVal - minVal) == 0.f) { // fast exit, also avoids division by zero in calculation of scale factor
+ minOut = maxOut = minVal;
+ return;
+ }
+
+ // Caution: Currently this works correctly only for histoSize in range[1;65536].
+ // For small data size (i.e. thumbnails) we reduce the size of the histogram to the size of data.
+ const unsigned int histoSize = std::min(65536, size);
+
+ // calculate scale factor to use full range of histogram
+ const float scale = (histoSize - 1) / (maxVal - minVal);
+
+ // We need one main histogram
+ std::vector histo(histoSize, 0);
+
+ if (numThreads == 1) {
+ // just one thread => use main histogram
+ for (size_t i = 0; i < size; ++i) {
+ // we have to subtract minVal and multiply with scale to get the data in [0;histosize] range
+ histo[static_cast(scale * (data[i] - minVal))]++;
+ }
+ } else {
+#ifdef _OPENMP
+ #pragma omp parallel num_threads(numThreads)
+#endif
+ {
+ // We need one histogram per thread
+ std::vector histothr(histoSize, 0);
+
+#ifdef _OPENMP
+ #pragma omp for nowait
+#endif
+ for (size_t i = 0; i < size; ++i) {
+ // we have to subtract minVal and multiply with scale to get the data in [0;histosize] range
+ histothr[static_cast(scale * (data[i] - minVal))]++;
+ }
+
+#ifdef _OPENMP
+ #pragma omp critical
+#endif
+ {
+ // add per thread histogram to main histogram
+#ifdef _OPENMP
+ #pragma omp simd
+#endif
+
+ for (size_t i = 0; i < histoSize; ++i) {
+ histo[i] += histothr[i];
+ }
+ }
+ }
+ }
+
+ size_t k = 0;
+ size_t count = 0;
+
+ // find (minPrct*size) smallest value
+ const float threshmin = minPrct * size;
+ while (count < threshmin) {
+ count += histo[k++];
+ }
+
+ if (k > 0) { // interpolate
+ const size_t count_ = count - histo[k - 1];
+ const float c0 = count - threshmin;
+ const float c1 = threshmin - count_;
+ minOut = (c1 * k + c0 * (k - 1)) / (c0 + c1);
+ } else {
+ minOut = k;
+ }
+ // go back to original range
+ minOut /= scale;
+ minOut += minVal;
+
+ // find (maxPrct*size) smallest value
+ const float threshmax = maxPrct * size;
+ while (count < threshmax) {
+ count += histo[k++];
+ }
+
+ if (k > 0) { // interpolate
+ const size_t count_ = count - histo[k - 1];
+ const float c0 = count - threshmax;
+ const float c1 = threshmax - count_;
+ maxOut = (c1 * k + c0 * (k - 1)) / (c0 + c1);
+ } else {
+ maxOut = k;
+ }
+ // go back to original range
+ maxOut /= scale;
+ maxOut += minVal;
+}
+
+}
diff --git a/rtengine/rt_algo.h b/rtengine/rt_algo.h
new file mode 100644
index 000000000..2630bbf41
--- /dev/null
+++ b/rtengine/rt_algo.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2017 Ingo Weyrich
+ *
+ * RawTherapee is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * RawTherapee is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RawTherapee. If not, see .
+ */
+
+#pragma once
+
+#include
+
+namespace rtengine
+{
+
+void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multiThread = true);
+
+}
diff --git a/rtengine/tmo_fattal02.cc b/rtengine/tmo_fattal02.cc
index 0dff22a54..1b301123a 100644
--- a/rtengine/tmo_fattal02.cc
+++ b/rtengine/tmo_fattal02.cc
@@ -73,6 +73,8 @@
#include "StopWatch.h"
#include "sleef.c"
#include "opthelper.h"
+#include "rt_algo.h"
+
namespace rtengine
{
@@ -167,7 +169,7 @@ void downSample (const Array2Df& A, Array2Df& B)
}
}
-void gaussianBlur (const Array2Df& I, Array2Df& L)
+void gaussianBlur (const Array2Df& I, Array2Df& L, bool multithread)
{
const int width = I.getCols();
const int height = I.getRows();
@@ -185,7 +187,7 @@ void gaussianBlur (const Array2Df& I, Array2Df& L)
Array2Df T (width, height);
//--- X blur
- #pragma omp parallel for shared(I, T)
+ #pragma omp parallel for shared(I, T) if(multithread)
for ( int y = 0 ; y < height ; y++ ) {
for ( int x = 1 ; x < width - 1 ; x++ ) {
@@ -200,7 +202,7 @@ void gaussianBlur (const Array2Df& I, Array2Df& L)
}
//--- Y blur
- #pragma omp parallel for
+ #pragma omp parallel for if(multithread)
for ( int x = 0 ; x < width - 7 ; x += 8 ) {
for ( int y = 1 ; y < height - 1 ; y++ ) {
@@ -231,7 +233,7 @@ void gaussianBlur (const Array2Df& I, Array2Df& L)
}
}
-void createGaussianPyramids ( Array2Df* H, Array2Df** pyramids, int nlevels)
+void createGaussianPyramids ( Array2Df* H, Array2Df** pyramids, int nlevels, bool multithread)
{
int width = H->getCols();
int height = H->getRows();
@@ -245,7 +247,7 @@ void createGaussianPyramids ( Array2Df* H, Array2Df** pyramids, int nlevels)
}
Array2Df* L = new Array2Df (width, height);
- gaussianBlur ( *pyramids[0], *L );
+ gaussianBlur ( *pyramids[0], *L, multithread );
for ( int k = 1 ; k < nlevels ; k++ ) {
if (width > 2 && height > 2) {
@@ -267,7 +269,7 @@ void createGaussianPyramids ( Array2Df* H, Array2Df** pyramids, int nlevels)
if (k < nlevels - 1) {
delete L;
L = new Array2Df (width, height);
- gaussianBlur ( *pyramids[k], *L );
+ gaussianBlur ( *pyramids[k], *L, multithread );
}
}
@@ -276,14 +278,14 @@ void createGaussianPyramids ( Array2Df* H, Array2Df** pyramids, int nlevels)
//--------------------------------------------------------------------
-float calculateGradients (Array2Df* H, Array2Df* G, int k)
+float calculateGradients (Array2Df* H, Array2Df* G, int k, bool multithread)
{
const int width = H->getCols();
const int height = H->getRows();
const float divider = pow ( 2.0f, k + 1 );
float avgGrad = 0.0f;
- #pragma omp parallel for reduction(+:avgGrad)
+ #pragma omp parallel for reduction(+:avgGrad) if(multithread)
for ( int y = 0 ; y < height ; y++ ) {
int n = (y == 0 ? 0 : y - 1);
@@ -350,20 +352,17 @@ void upSample (const Array2Df& A, Array2Df& B)
void calculateFiMatrix (Array2Df* FI, Array2Df* gradients[],
float avgGrad[], int nlevels, int detail_level,
- float alfa, float beta, float noise)
+ float alfa, float beta, float noise, bool multithread)
{
- const bool newfattal = true;
int width = gradients[nlevels - 1]->getCols();
int height = gradients[nlevels - 1]->getRows();
Array2Df** fi = new Array2Df*[nlevels];
fi[nlevels - 1] = new Array2Df (width, height);
- if (newfattal) {
- //#pragma omp parallel for shared(fi)
- for ( int k = 0 ; k < width * height ; k++ ) {
- (*fi[nlevels - 1]) (k) = 1.0f;
- }
+ #pragma omp parallel for shared(fi) if(multithread)
+ for ( int k = 0 ; k < width * height ; k++ ) {
+ (*fi[nlevels - 1]) (k) = 1.0f;
}
for ( int k = nlevels - 1; k >= 0 ; k-- ) {
@@ -371,23 +370,16 @@ void calculateFiMatrix (Array2Df* FI, Array2Df* gradients[],
height = gradients[k]->getRows();
// only apply gradients to levels>=detail_level but at least to the coarsest
- if ( k >= detail_level
- || k == nlevels - 1
- || newfattal == false) {
+ if ((k >= detail_level || k == nlevels - 1) && beta != 1.f) {
//DEBUG_STR << "calculateFiMatrix: apply gradient to level " << k << endl;
- #pragma omp parallel for shared(fi,avgGrad)
+ #pragma omp parallel for shared(fi,avgGrad) if(multithread)
for ( int y = 0; y < height; y++ ) {
for ( int x = 0; x < width; x++ ) {
float grad = ((*gradients[k]) (x, y) < 1e-4f) ? 1e-4 : (*gradients[k]) (x, y);
float a = alfa * avgGrad[k];
-
float value = pow ((grad + noise) / a, beta - 1.0f);
- if (newfattal) {
- (*fi[k]) (x, y) *= value;
- } else {
- (*fi[k]) (x, y) = value;
- }
+ (*fi[k]) (x, y) *= value;
}
}
}
@@ -401,9 +393,9 @@ void calculateFiMatrix (Array2Df* FI, Array2Df* gradients[],
fi[0] = FI; // highest level -> result
}
- if ( k > 0 && newfattal ) {
+ if (k > 0) {
upSample (*fi[k], *fi[k - 1]); // upsample to next level
- gaussianBlur (*fi[k - 1], *fi[k - 1]);
+ gaussianBlur (*fi[k - 1], *fi[k - 1], multithread);
}
}
@@ -414,80 +406,6 @@ void calculateFiMatrix (Array2Df* FI, Array2Df* gradients[],
delete[] fi;
}
-inline
-void findMaxMinPercentile (const Array2Df& I,
- float minPrct, float& minLum,
- float maxPrct, float& maxLum)
-{
- assert (minPrct <= maxPrct);
-
- const int size = I.getRows() * I.getCols();
- const float* data = I.data();
-
- // we need to find the (minPrct*size) smallest value and the (maxPrct*size) smallest value in I
- // We use a histogram based search for speed and to reduce memory usage
- // memory usage of this method is 65536 * sizeof(float) * (t + 1) byte, where t is the number of threads
-
- // We need one global histogram
- LUTu histo (65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE);
- histo.clear();
-#ifdef _OPENMP
- #pragma omp parallel
-#endif
- {
- // We need one histogram per thread
- LUTu histothr (65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE);
- histothr.clear();
-
-#ifdef _OPENMP
- #pragma omp for nowait
-#endif
-
- for (int i = 0; i < size; ++i) {
- // values are in [0;1] range, so we have to multiply with 65535 to get the histogram index
- histothr[ (unsigned int) (65535.f * data[i])]++;
- }
-
-#ifdef _OPENMP
- #pragma omp critical
-#endif
- // add per thread histogram to global histogram
- histo += histothr;
- }
-
- int k = 0;
- int count = 0;
-
- // find (minPrct*size) smallest value
- while (count < minPrct * size) {
- count += histo[k++];
- }
-
- if (k > 0) { // interpolate
- int count_ = count - histo[k - 1];
- float c0 = count - minPrct * size;
- float c1 = minPrct * size - count_;
- minLum = (c1 * k + c0 * (k - 1)) / ((c0 + c1) * 65535.f);
- } else {
- minLum = k / 65535.f;
- }
-
- // find (maxPrct*size) smallest value
- while (count < maxPrct * size) {
- count += histo[k++];
- }
-
- if (k > 0) { // interpolate
- int count_ = count - histo[k - 1];
- float c0 = count - maxPrct * size;
- float c1 = maxPrct * size - count_;
- maxLum = (c1 * k + c0 * (k - 1)) / ((c0 + c1) * 65535.f);
- } else {
- maxLum = k / 65535.f;
- }
-
-}
-
void solve_pde_fft (Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread);
void tmo_fattal02 (size_t width,
@@ -543,7 +461,7 @@ void tmo_fattal02 (size_t width,
float minLum = Y (0, 0);
float maxLum = Y (0, 0);
- #pragma omp parallel for reduction(max:maxLum)
+ #pragma omp parallel for reduction(max:maxLum) if(multithread)
for ( int i = 0 ; i < size ; i++ ) {
maxLum = std::max (maxLum, Y (i));
@@ -552,7 +470,7 @@ void tmo_fattal02 (size_t width,
Array2Df* H = new Array2Df (width, height);
float temp = 100.f / maxLum;
float eps = 1e-4f;
- #pragma omp parallel
+ #pragma omp parallel if(multithread)
{
#ifdef __SSE2__
vfloat epsv = F2V (eps);
@@ -627,7 +545,7 @@ void tmo_fattal02 (size_t width,
const int nlevels = 7; // RT -- see above
Array2Df** pyramids = new Array2Df*[nlevels];
- createGaussianPyramids (H, pyramids, nlevels);
+ createGaussianPyramids (H, pyramids, nlevels, multithread);
// ph.setValue(8);
// calculate gradients and its average values on pyramid levels
@@ -636,7 +554,7 @@ void tmo_fattal02 (size_t width,
for ( int k = 0 ; k < nlevels ; k++ ) {
gradients[k] = new Array2Df (pyramids[k]->getCols(), pyramids[k]->getRows());
- avgGrad[k] = calculateGradients (pyramids[k], gradients[k], k);
+ avgGrad[k] = calculateGradients (pyramids[k], gradients[k], k, multithread);
delete pyramids[k];
}
@@ -645,7 +563,7 @@ void tmo_fattal02 (size_t width,
// calculate fi matrix
Array2Df* FI = new Array2Df (width, height);
- calculateFiMatrix (FI, gradients, avgGrad, nlevels, detail_level, alfa, beta, noise);
+ calculateFiMatrix (FI, gradients, avgGrad, nlevels, detail_level, alfa, beta, noise, multithread);
// dumpPFS( "FI.pfs", FI, "Y" );
for ( int i = 0 ; i < nlevels ; i++ ) {
@@ -684,7 +602,7 @@ void tmo_fattal02 (size_t width,
// side accordingly (basically fft solver assumes U(-1) = U(1), whereas zero
// Neumann conditions assume U(-1)=U(0)), see also divergence calculation
// if (fftsolver)
- #pragma omp parallel for
+ #pragma omp parallel for if(multithread)
for ( size_t y = 0 ; y < height ; y++ ) {
// sets index+1 based on the boundary assumption H(N+1)=H(N-1)
@@ -702,7 +620,7 @@ void tmo_fattal02 (size_t width,
delete H;
// calculate divergence
- #pragma omp parallel for
+ #pragma omp parallel for if(multithread)
for ( size_t y = 0; y < height; ++y ) {
for ( size_t x = 0; x < width; ++x ) {
@@ -754,7 +672,7 @@ void tmo_fattal02 (size_t width,
// {
// return;
// }
- #pragma omp parallel
+ #pragma omp parallel if(multithread)
{
#ifdef __SSE2__
vfloat gammav = F2V (gamma);
@@ -783,10 +701,10 @@ void tmo_fattal02 (size_t width,
float cut_min = 0.01f * black_point;
float cut_max = 1.0f - 0.01f * white_point;
assert (cut_min >= 0.0f && (cut_max <= 1.0f) && (cut_min < cut_max));
- findMaxMinPercentile (L, cut_min, minLum, cut_max, maxLum);
+ findMinMaxPercentile (L.data(), L.getRows() * L.getCols(), cut_min, minLum, cut_max, maxLum, multithread);
float dividor = (maxLum - minLum);
- #pragma omp parallel for
+ #pragma omp parallel for if(multithread)
for (size_t i = 0; i < height; ++i) {
for (size_t j = 0; j < width; ++j) {
@@ -869,7 +787,7 @@ void tmo_fattal02 (size_t width,
// returns T = EVy A EVx^tr
// note, modifies input data
-void transform_ev2normal (Array2Df *A, Array2Df *T)
+void transform_ev2normal (Array2Df *A, Array2Df *T, bool multithread)
{
int width = A->getCols();
int height = A->getRows();
@@ -877,7 +795,7 @@ void transform_ev2normal (Array2Df *A, Array2Df *T)
// the discrete cosine transform is not exactly the transform needed
// need to scale input values to get the right transformation
- #pragma omp parallel for
+ #pragma omp parallel for if(multithread)
for (int y = 1 ; y < height - 1 ; y++ )
for (int x = 1 ; x < width - 1 ; x++ ) {
@@ -913,7 +831,7 @@ void transform_ev2normal (Array2Df *A, Array2Df *T)
// returns T = EVy^-1 * A * (EVx^-1)^tr
-void transform_normal2ev (Array2Df *A, Array2Df *T)
+void transform_normal2ev (Array2Df *A, Array2Df *T, bool multithread)
{
int width = A->getCols();
int height = A->getRows();
@@ -928,7 +846,7 @@ void transform_normal2ev (Array2Df *A, Array2Df *T)
// need to scale the output matrix to get the right transform
float factor = (1.0f / ((height - 1) * (width - 1)));
- #pragma omp parallel for
+ #pragma omp parallel for if(multithread)
for (int y = 0 ; y < height ; y++ )
for (int x = 0 ; x < width ; x++ ) {
@@ -1038,7 +956,7 @@ void solve_pde_fft (Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread)/*
// transforms F into eigenvector space: Ftr =
//DEBUG_STR << "solve_pde_fft: transform F to ev space (fft)" << std::endl;
Array2Df* F_tr = buf; //new Array2Df(width,height);
- transform_normal2ev (F, F_tr);
+ transform_normal2ev (F, F_tr, multithread);
// TODO: F no longer needed so could release memory, but as it is an
// input parameter we won't do that
// ph.setValue(50);
@@ -1057,7 +975,7 @@ void solve_pde_fft (Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread)/*
std::vector l1 = get_lambda (height);
std::vector l2 = get_lambda (width);
- #pragma omp parallel for
+ #pragma omp parallel for if(multithread)
for (int y = 0 ; y < height ; y++ ) {
for (int x = 0 ; x < width ; x++ ) {
@@ -1069,7 +987,7 @@ void solve_pde_fft (Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread)/*
// transforms U_tr back to the normal space
//DEBUG_STR << "solve_pde_fft: transform U_tr to normal space (fft)" << std::endl;
- transform_ev2normal (F_tr, U);
+ transform_ev2normal (F_tr, U, multithread);
// delete F_tr; // no longer needed so release memory
// the solution U as calculated will satisfy something like int U = 0
@@ -1079,13 +997,13 @@ void solve_pde_fft (Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread)/*
// (not really needed but good for numerics as we later take exp(U))
//DEBUG_STR << "solve_pde_fft: removing constant from solution" << std::endl;
float max = 0.f;
- #pragma omp parallel for reduction(max:max)
+ #pragma omp parallel for reduction(max:max) if(multithread)
for (int i = 0; i < width * height; i++) {
max = std::max (max, (*U) (i));
}
- #pragma omp parallel for
+ #pragma omp parallel for if(multithread)
for (int i = 0; i < width * height; i++) {
(*U) (i) -= max;
@@ -1335,8 +1253,6 @@ void ImProcFunctions::ToneMapFattal02 (Imagefloat *rgb)
rescale_nearest (Yr, L, multiThread);
tmo_fattal02 (w2, h2, L, L, alpha, beta, noise, detail_level, multiThread);
-// tmo_fattal02(w, h, Yr, L, alpha, beta, noise, detail_level, multiThread);
-
#ifdef _OPENMP
#pragma omp parallel for if(multiThread)
#endif
diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc
index 323900ae6..2fff95904 100644
--- a/rtgui/thumbbrowserentrybase.cc
+++ b/rtgui/thumbbrowserentrybase.cc
@@ -400,7 +400,7 @@ void ThumbBrowserEntryBase::resize (int h)
MYWRITERLOCK(l, lockRW);
height = h;
- int old_preh = preh, old_width = width;
+ int old_preh = preh;
// dimensions of the button set
int bsw = 0, bsh = 0;