diff --git a/.gitignore b/.gitignore index 21ebf986a..fc65c877c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ .project .settings .directory +.vscode CMakeCache.txt CMakeFiles diff --git a/AUTHORS.txt b/AUTHORS.txt index 15e3e13d4..160869776 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -28,6 +28,7 @@ Development contributors, in last name alphabetical order: Adam Reichold Philip Rinn Jan Rinze + Alberto Romei Ben S. Andrey Skvortsov Fabio Suprani diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index 974e51c38..fb5104f95 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -1314,6 +1314,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1851,6 +1853,13 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index 82c8ddfa6..34e87dc1e 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -1361,6 +1361,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1798,6 +1800,13 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 950a33f45..cd62a8f3b 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -2365,3 +2365,13 @@ ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - FILEBROWSER_POPUPREMOVE;Unwiderruflich löschen FILEBROWSER_POPUPREMOVEINCLPROC;Unwiderruflich löschen\n(einschl. aller Dateien der Stabelverarbeitung) FILEBROWSER_SHOWNOTTRASHHINT;Nur Bilder außerhalb des Papierkorbs anzeigen. + +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index 6d1c7c09c..a8639c296 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -838,6 +838,8 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1665,6 +1667,13 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 7f810f71f..19535166e 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -748,6 +748,8 @@ !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1636,6 +1638,13 @@ !TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index 6d44a132f..63eb2bd66 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -1539,6 +1539,8 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1903,6 +1905,13 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index 6286ba63c..20b87789d 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -1248,6 +1248,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1816,6 +1818,13 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index 7317038a3..04a270d49 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -2036,6 +2036,8 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -2230,6 +2232,13 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_EXPOSURE_CLAMPOOG;Clip out-of-gamut colors !TP_EXPOSURE_HISTMATCHING;Auto-Matched Tone Curve !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_ICM_WORKING_TRC;Tone response curve: !TP_ICM_WORKING_TRC_CUSTOM;Custom !TP_ICM_WORKING_TRC_GAMMA;Gamma diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index d1e27f0dc..ad3dc62ee 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -1621,6 +1621,8 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1929,6 +1931,13 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. !TP_EXPOSURE_TCMODE_LUMINANCE;Luminance !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Baseline exposure !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index beffbb9a8..eb9bfe56f 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -2258,6 +2258,8 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. !HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - region offset !HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - region power +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !MAIN_FRAME_PLACES_DEL;Remove !PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PREFERENCES_CACHECLEAR_SAFETY;Only files in the cache are cleared. Processing profiles stored alongside the source images are not touched. @@ -2271,6 +2273,13 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_COLORTONING_LABREGION_OFFSET;Offset !TP_COLORTONING_LABREGION_POWER;Power !TP_CROP_PPI;PPI +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected !TP_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. diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 870895dd7..653f41dce 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -1706,6 +1706,8 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D !HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type @@ -1974,6 +1976,13 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорячая клавиша: - !TP_DISTORTION_AUTO_TIP;Automatically corrects lens distortion in raw files by matching it against the embedded JPEG image if one exists and has had its lens disortion auto-corrected by the camera. !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FLATFIELD_CLIPCONTROL;Clip control !TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index edcf1d2d6..f26e03350 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -1514,6 +1514,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -1902,6 +1904,13 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual !TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points !TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FILMSIMULATION_LABEL;Film Simulation !TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? !TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index 2263584cd..22c1710b5 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -1863,6 +1863,8 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength !HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold !HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values !HISTORY_MSG_HISTMATCHING;Auto-matched tone curve !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -2117,6 +2119,13 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_EXPOSURE_CLAMPOOG;Clip out-of-gamut colors !TP_EXPOSURE_HISTMATCHING;Auto-Matched Tone Curve !TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. +!TP_FILMNEGATIVE_BLUE;Blue ratio +!TP_FILMNEGATIVE_GREEN;Green exponent +!TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +!TP_FILMNEGATIVE_LABEL;Film Negative +!TP_FILMNEGATIVE_PICK;Pick white and black spots +!TP_FILMNEGATIVE_RED;Red ratio +!TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots !TP_FLATFIELD_CLIPCONTROL;Clip control !TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. diff --git a/rtdata/languages/default b/rtdata/languages/default index 31e704d7d..ab85f16e6 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -747,6 +747,8 @@ HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold +HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative +HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values HISTORY_MSG_HISTMATCHING;Auto-matched tone curve HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D @@ -983,6 +985,7 @@ PARTIALPASTE_EVERYTHING;Everything PARTIALPASTE_EXIFCHANGES;Exif PARTIALPASTE_EXPOSURE;Exposure PARTIALPASTE_FILMSIMULATION;Film simulation +PARTIALPASTE_FILMNEGATIVE;Film Negative PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field auto-selection PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field blur radius PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type @@ -1635,6 +1638,13 @@ TP_EXPOSURE_TCMODE_STANDARD;Standard TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +TP_FILMNEGATIVE_BLUE;Blue ratio +TP_FILMNEGATIVE_GREEN;Reference exponent (contrast) +TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. +TP_FILMNEGATIVE_LABEL;Film Negative +TP_FILMNEGATIVE_PICK;Pick white and black spots +TP_FILMNEGATIVE_RED;Red ratio +TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots TP_FILMSIMULATION_LABEL;Film Simulation TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? TP_FILMSIMULATION_STRENGTH;Strength diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index b44413224..c5c8afa82 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -61,6 +61,8 @@ set(RTENGINESOURCEFILES eahd_demosaic.cc fast_demo.cc ffmanager.cc + filmnegativeproc.cc + filmnegativethumb.cc flatcurves.cc gauss.cc green_equil_RT.cc diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 97a14f66e..894414f8a 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2437,6 +2437,11 @@ Camera constants: "pdaf_offset" : 31 }, + { // Quality C, + "make_model": "Sony ILCE-7RM4", + "raw_crop": [ 0, 0, 9568, 0 ] // full raw frame 9600x6376 - 32 rightmost columns are garbage + }, + { // Quality B, color matrix copied from a7rm2 "make_model": "Sony ILCE-9", "dcraw_matrix": [ 6389,-1703,-378,-4562,12265,2587,-670,1489,6550 ], // DNG_v9.12 D65 diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc new file mode 100644 index 000000000..58d87d103 --- /dev/null +++ b/rtengine/filmnegativeproc.cc @@ -0,0 +1,403 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2019 Alberto Romei + * + * 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 + +#ifdef _OPENMP +#include +#endif + +#include "rawimagesource.h" + +#include "mytime.h" +#include "opthelper.h" +#include "procparams.h" +#include "rt_algo.h" +#include "rtengine.h" + +//#define BENCHMARK +#include "StopWatch.h" + +namespace rtengine +{ + +extern const Settings* settings; + +} + +namespace +{ + +bool channelsAvg( + const rtengine::RawImage* ri, + int width, + int height, + const float* cblacksom, + rtengine::Coord spotPos, + int spotSize, + const rtengine::procparams::FilmNegativeParams& params, + std::array& avgs +) +{ + avgs = {}; // Channel averages + + if (ri->getSensorType() != rtengine::ST_BAYER && ri->getSensorType() != rtengine::ST_FUJI_XTRANS) { + return false; + } + + if (rtengine::settings->verbose) { + printf("Spot coord: x=%d y=%d\n", spotPos.x, spotPos.y); + } + + const int half_spot_size = spotSize / 2; + + const int& x1 = spotPos.x - half_spot_size; + const int& x2 = spotPos.x + half_spot_size; + const int& y1 = spotPos.y - half_spot_size; + const int& y2 = spotPos.y + half_spot_size; + + if (x1 < 0 || x2 > width || y1 < 0 || y2 > height) { + return false; // Spot goes outside bounds, bail out. + } + + std::array pxCount = {}; // Per-channel sample counts + for (int c = spotPos.x - spotSize; c < spotPos.x + spotSize; ++c) { + for (int r = spotPos.y - spotSize; r < spotPos.y + spotSize; ++r) { + const int ch = ri->getSensorType() == rtengine::ST_BAYER ? ri->FC(r,c) : ri->XTRANSFC(r,c); + + ++pxCount[ch]; + + // Sample the original unprocessed values from RawImage, subtracting black levels. + // Scaling is irrelevant, as we are only interested in the ratio between two spots. + avgs[ch] += ri->data[r][c] - cblacksom[ch]; + } + } + + for (int ch = 0; ch < 3; ++ch) { + avgs[ch] /= pxCount[ch]; + } + + return true; +} + +} + +bool rtengine::RawImageSource::getFilmNegativeExponents(Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, std::array& newExps) +{ + newExps = { + static_cast(currentParams.redRatio * currentParams.greenExp), + static_cast(currentParams.greenExp), + static_cast(currentParams.blueRatio * currentParams.greenExp) + }; + + constexpr int spotSize = 32; // TODO: Make this configurable? + + Coord spot; + std::array clearVals; + std::array denseVals; + + // Sample first spot + transformPosition(spotA.x, spotA.y, tran, spot.x, spot.y); + if (!channelsAvg(ri, W, H, cblacksom, spot, spotSize, currentParams, clearVals)) { + return false; + } + + // Sample second spot + transformPosition(spotB.x, spotB.y, tran, spot.x, spot.y); + if (!channelsAvg(ri, W, H, cblacksom, spot, spotSize, currentParams, denseVals)) { + return false; + } + + // Detect which one is the dense spot, based on green channel + if (clearVals[1] < denseVals[1]) { + std::swap(clearVals, denseVals); + } + + if (settings->verbose) { + printf("Clear film values: R=%g G=%g B=%g\n", clearVals[0], clearVals[1], clearVals[2]); + printf("Dense film values: R=%g G=%g B=%g\n", denseVals[0], denseVals[1], denseVals[2]); + } + + const float denseGreenRatio = clearVals[1] / denseVals[1]; + + // Calculate logarithms in arbitrary base + const auto logBase = + [](float base, float num) -> float + { + return std::log(num) / std::log(base); + }; + + // Calculate exponents for each channel, based on the ratio between the bright and dark values, + // compared to the ratio in the reference channel (green) + for (int ch = 0; ch < 3; ++ch) { + if (ch == 1) { + newExps[ch] = 1.f; // Green is the reference channel + } else { + newExps[ch] = CLAMP(logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 4.f); + } + } + + if (settings->verbose) { + printf("New exponents: R=%g G=%g B=%g\n", newExps[0], newExps[1], newExps[2]); + } + + return true; +} + +void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams ¶ms) +{ +// BENCHFUNMICRO + + if (!params.enabled) { + return; + } + + // Exponents are expressed as positive in the parameters, so negate them in order + // to get the reciprocals. + const std::array exps = { + static_cast(-params.redRatio * params.greenExp), + static_cast(-params.greenExp), + static_cast(-params.blueRatio * params.greenExp) + }; + + MyTime t1, t2, t3,t4, t5; + + t1.set(); + + // Channel vectors to calculate medians + std::array, 3> cvs; + + // Sample one every 5 pixels, and push the value in the appropriate channel vector. + // Choose an odd step, not a multiple of the CFA size, to get a chance to visit each channel. + if (ri->getSensorType() == ST_BAYER) { + for (int row = 0; row < H; row += 5) { + const int c0 = ri->FC(row, 0); + const int c1 = ri->FC(row, 5); + int col = 0; + for (; col < W - 5; col += 10) { + cvs[c0].push_back(rawData[row][col]); + cvs[c1].push_back(rawData[row][col + 5]); + } + if (col < W) { + cvs[c0].push_back(rawData[row][col]); + } + } + } + else if (ri->getSensorType() == ST_FUJI_XTRANS) { + for (int row = 0; row < H; row += 5) { + const std::array cs = { + ri->XTRANSFC(row, 0), + ri->XTRANSFC(row, 5), + ri->XTRANSFC(row, 10), + ri->XTRANSFC(row, 15), + ri->XTRANSFC(row, 20), + ri->XTRANSFC(row, 25) + }; + int col = 0; + for (; col < W - 25; col += 30) { + for (int c = 0; c < 6; ++c) { + cvs[cs[c]].push_back(rawData[row][col + c * 5]); + } + } + for (int c = 0; col < W; col += 5, ++c) { + cvs[cs[c]].push_back(rawData[row][col]); + } + } + } + + constexpr float MAX_OUT_VALUE = 65000.f; + + t2.set(); + + if (settings->verbose) { + printf("Median vector fill loop time us: %d\n", t2.etime(t1)); + } + + t2.set(); + + std::array medians; // Channel median values + std::array mults = { + 1.f, + 1.f, + 1.f + }; // Channel normalization multipliers + + for (int c = 0; c < 3; ++c) { + // Find median values for each channel + if (!cvs[c].empty()) { + findMinMaxPercentile(cvs[c].data(), cvs[c].size(), 0.5f, medians[c], 0.5f, medians[c], true); + medians[c] = pow_F(rtengine::max(medians[c], 1.f), exps[c]); + // Determine the channel multiplier so that N times the median becomes 65k. This clips away + // the values in the dark border surrounding the negative (due to the film holder, for example), + // the reciprocal of which have blown up to stellar values. + mults[c] = MAX_OUT_VALUE / (medians[c] * 24.f); + } + } + + t3.set(); + + if (settings->verbose) { + printf("Sample count: %zu, %zu, %zu\n", cvs[0].size(), cvs[1].size(), cvs[2].size()); + printf("Medians: %g %g %g\n", medians[0], medians[1], medians[2] ); + printf("Computed multipliers: %g %g %g\n", mults[0], mults[1], mults[2] ); + printf("Median calc time us: %d\n", t3.etime(t2)); + } + + constexpr float CLIP_VAL = 65535.f; + + t3.set(); + + if (ri->getSensorType() == ST_BAYER) { +#ifdef __SSE2__ + const vfloat onev = F2V(1.f); + const vfloat clipv = F2V(CLIP_VAL); +#endif + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int row = 0; row < H; ++row) { + int col = 0; + // Avoid trouble with zeroes, minimum pixel value is 1. + const float exps0 = exps[FC(row, col)]; + const float exps1 = exps[FC(row, col + 1)]; + const float mult0 = mults[FC(row, col)]; + const float mult1 = mults[FC(row, col + 1)]; +#ifdef __SSE2__ + const vfloat expsv = _mm_setr_ps(exps0, exps1, exps0, exps1); + const vfloat multsv = _mm_setr_ps(mult0, mult1, mult0, mult1); + for (; col < W - 3; col += 4) { + STVFU(rawData[row][col], vminf(multsv * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv), clipv)); + } +#endif // __SSE2__ + for (; col < W - 1; col += 2) { + rawData[row][col] = rtengine::min(mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0), CLIP_VAL); + rawData[row][col + 1] = rtengine::min(mult1 * pow_F(rtengine::max(rawData[row][col + 1], 1.f), exps1), CLIP_VAL); + } + if (col < W) { + rawData[row][col] = rtengine::min(mult0 * pow_F(rtengine::max(rawData[row][col], 1.f), exps0), CLIP_VAL); + } + } + } else if (ri->getSensorType() == ST_FUJI_XTRANS) { +#ifdef __SSE2__ + const vfloat onev = F2V(1.f); + const vfloat clipv = F2V(CLIP_VAL); +#endif + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int row = 0; row < H; row ++) { + int col = 0; + // Avoid trouble with zeroes, minimum pixel value is 1. + const std::array expsc = { + exps[ri->XTRANSFC(row, 0)], + exps[ri->XTRANSFC(row, 1)], + exps[ri->XTRANSFC(row, 2)], + exps[ri->XTRANSFC(row, 3)], + exps[ri->XTRANSFC(row, 4)], + exps[ri->XTRANSFC(row, 5)] + }; + const std::array multsc = { + mults[ri->XTRANSFC(row, 0)], + mults[ri->XTRANSFC(row, 1)], + mults[ri->XTRANSFC(row, 2)], + mults[ri->XTRANSFC(row, 3)], + mults[ri->XTRANSFC(row, 4)], + mults[ri->XTRANSFC(row, 5)] + }; +#ifdef __SSE2__ + const vfloat expsv0 = _mm_setr_ps(expsc[0], expsc[1], expsc[2], expsc[3]); + const vfloat expsv1 = _mm_setr_ps(expsc[4], expsc[5], expsc[0], expsc[1]); + const vfloat expsv2 = _mm_setr_ps(expsc[2], expsc[3], expsc[4], expsc[5]); + const vfloat multsv0 = _mm_setr_ps(multsc[0], multsc[1], multsc[2], multsc[3]); + const vfloat multsv1 = _mm_setr_ps(multsc[4], multsc[5], multsc[0], multsc[1]); + const vfloat multsv2 = _mm_setr_ps(multsc[2], multsc[3], multsc[4], multsc[5]); + for (; col < W - 11; col += 12) { + STVFU(rawData[row][col], vminf(multsv0 * pow_F(vmaxf(LVFU(rawData[row][col]), onev), expsv0), clipv)); + STVFU(rawData[row][col + 4], vminf(multsv1 * pow_F(vmaxf(LVFU(rawData[row][col + 4]), onev), expsv1), clipv)); + STVFU(rawData[row][col + 8], vminf(multsv2 * pow_F(vmaxf(LVFU(rawData[row][col + 8]), onev), expsv2), clipv)); + } +#endif // __SSE2__ + for (; col < W - 5; col += 6) { + for (int c = 0; c < 6; ++c) { + rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]), CLIP_VAL); + } + } + for (int c = 0; col < W; col++, c++) { + rawData[row][col + c] = rtengine::min(multsc[c] * pow_F(rtengine::max(rawData[row][col + c], 1.f), expsc[c]), CLIP_VAL); + } + } + } + + t4.set(); + + if (settings->verbose) { + printf("Pow loop time us: %d\n", t4.etime(t3)); + } + + t4.set(); + + PixelsMap bitmapBads(W, H); + + int totBP = 0; // Hold count of bad pixels to correct + + if (ri->getSensorType() == ST_BAYER) { +#ifdef _OPENMP + #pragma omp parallel for reduction(+:totBP) schedule(dynamic,16) +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + if (rawData[i][j] >= MAX_OUT_VALUE) { + bitmapBads.set(j, i); + ++totBP; + } + } + } + + if (totBP > 0) { + interpolateBadPixelsBayer(bitmapBads, rawData); + } + + } + else if (ri->getSensorType() == ST_FUJI_XTRANS) { +#ifdef _OPENMP + #pragma omp parallel for reduction(+:totBP) schedule(dynamic,16) +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + if (rawData[i][j] >= MAX_OUT_VALUE) { + bitmapBads.set(j, i); + totBP++; + } + } + } + + if (totBP > 0) { + interpolateBadPixelsXtrans(bitmapBads); + } + } + + t5.set(); + + if (settings->verbose) { + printf("Bad pixels count: %d\n", totBP); + printf("Bad pixels interpolation time us: %d\n", t5.etime(t4)); + } +} diff --git a/rtengine/filmnegativethumb.cc b/rtengine/filmnegativethumb.cc new file mode 100644 index 000000000..610781872 --- /dev/null +++ b/rtengine/filmnegativethumb.cc @@ -0,0 +1,131 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2019 Alberto Romei + * + * 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 "rtengine.h" +#include "rtthumbnail.h" +#include "opthelper.h" +#include "rt_algo.h" +#include "rtengine.h" +#include "settings.h" +#include "procparams.h" +#define BENCHMARK +#include "StopWatch.h" + +namespace rtengine +{ + +extern const Settings* settings; + +} + +void rtengine::Thumbnail::processFilmNegative( + const procparams::ProcParams ¶ms, + const Imagefloat* baseImg, + const int rwidth, const int rheight, + float &rmi, float &gmi, float &bmi +) { + StopWatch stop1("Thumbnail film negative", true); + + // Channel exponents + const float rexp = -params.filmNegative.redRatio * params.filmNegative.greenExp; + const float gexp = -params.filmNegative.greenExp; + const float bexp = -params.filmNegative.blueRatio * params.filmNegative.greenExp; + + // Need to calculate channel averages, to fake the same conditions + // found in rawimagesource, where get_ColorsCoeff is called with + // forceAutoWB=true. + float rsum = 0.f, gsum = 0.f, bsum = 0.f; + + // Channel vectors to calculate medians + std::vector rv, gv, bv; + + for (int i = 0; i < rheight; i++) { + for (int j = 0; j < rwidth; j++) { + const float r = baseImg->r(i, j); + const float g = baseImg->g(i, j); + const float b = baseImg->b(i, j); + + rsum += r; + gsum += g; + bsum += b; + + rv.push_back(r); + gv.push_back(g); + bv.push_back(b); + } + } + + const float ravg = rsum / (rheight*rwidth); + const float gavg = gsum / (rheight*rwidth); + const float bavg = bsum / (rheight*rwidth); + + // Shifting current WB multipliers, based on channel averages. + rmi /= (gavg/ravg); + // gmi /= (gAvg/gAvg); green chosen as reference channel + bmi /= (gavg/bavg); + + float rmed, gmed, bmed; + findMinMaxPercentile(rv.data(), rv.size(), 0.5f, rmed, 0.5f, rmed, true); + findMinMaxPercentile(gv.data(), gv.size(), 0.5f, gmed, 0.5f, gmed, true); + findMinMaxPercentile(bv.data(), bv.size(), 0.5f, bmed, 0.5f, bmed, true); + + rmed = powf(rmed, rexp); + gmed = powf(gmed, gexp); + bmed = powf(bmed, bexp); + + const float MAX_OUT_VALUE = 65000.f; + const float rmult = (MAX_OUT_VALUE / (rmed * 24)) ; + const float gmult = (MAX_OUT_VALUE / (gmed * 24)) ; + const float bmult = (MAX_OUT_VALUE / (bmed * 24)) ; + + if (settings->verbose) { + printf("Thumbnail channel medians: %g %g %g\n", rmed, gmed, bmed); + printf("Thumbnail computed multipliers: %g %g %g\n", rmult, gmult, bmult); + } + +#ifdef __SSE2__ + const vfloat clipv = F2V(MAXVALF); + const vfloat rexpv = F2V(rexp); + const vfloat gexpv = F2V(gexp); + const vfloat bexpv = F2V(bexp); + const vfloat rmultv = F2V(rmult); + const vfloat gmultv = F2V(gmult); + const vfloat bmultv = F2V(bmult); +#endif + + for (int i = 0; i < rheight; i++) { + float *rline = baseImg->r(i); + float *gline = baseImg->g(i); + float *bline = baseImg->b(i); + int j = 0; +#ifdef __SSE2__ + for (; j < rwidth - 3; j +=4) { + STVFU(rline[j], vminf(rmultv * pow_F(LVFU(rline[j]), rexpv), clipv)); + STVFU(gline[j], vminf(gmultv * pow_F(LVFU(gline[j]), gexpv), clipv)); + STVFU(bline[j], vminf(bmultv * pow_F(LVFU(bline[j]), bexpv), clipv)); + } +#endif + for (; j < rwidth; ++j) { + rline[j] = CLIP(rmult * pow_F(rline[j], rexp)); + gline[j] = CLIP(gmult * pow_F(gline[j], gexp)); + bline[j] = CLIP(bmult * pow_F(bline[j], bexp)); + } + } +} \ No newline at end of file diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 4e38c612a..faa7ad5ed 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -69,36 +69,40 @@ FramesMetaData* FramesMetaData::fromFile (const Glib::ustring& fname, std::uniqu return new FramesData (fname, std::move(rml), firstFrameOnly); } -FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir) - : frameRootDir(frameRootDir_), iptc(nullptr), time(), timeStamp(), iso_speed(0), aperture(0.), focal_len(0.), focal_len35mm(0.), focus_dist(0.f), - shutter(0.), expcomp(0.), make("Unknown"), model("Unknown"), orientation("Unknown"), lens("Unknown"), - sampleFormat(IIOSF_UNKNOWN), isPixelShift(false), isHDR(false) +FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* rootDir, rtexif::TagDirectory* firstRootDir) : + frameRootDir(frameRootDir_), + iptc(nullptr), + time{}, + timeStamp{}, + iso_speed(0), + aperture(0.), + focal_len(0.), + focal_len35mm(0.), + focus_dist(0.f), + shutter(0.), + expcomp(0.), + make("Unknown"), + model("Unknown"), + orientation("Unknown"), + rating(0), + lens("Unknown"), + sampleFormat(IIOSF_UNKNOWN), + isPixelShift(false), + isHDR(false) { - memset (&time, 0, sizeof(time)); - if (!frameRootDir) { return; } - rtexif::Tag* tag; - rtexif::TagDirectory* newFrameRootDir = frameRootDir; - - memset(&time, 0, sizeof(time)); - timeStamp = 0; - iso_speed = 0; - aperture = 0.0; - focal_len = 0.0; - focal_len35mm = 0.0; - focus_dist = 0.0f; - shutter = 0.0; - expcomp = 0.0; make.clear(); model.clear(); serial.clear(); orientation.clear(); lens.clear(); - tag = newFrameRootDir->findTag("Make"); + rtexif::TagDirectory* newFrameRootDir = frameRootDir; + + rtexif::Tag* tag = newFrameRootDir->findTag("Make"); if (!tag) { newFrameRootDir = rootDir; tag = newFrameRootDir->findTag("Make"); @@ -187,6 +191,23 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* orientation = tag->valueToString (); } + // Look for Rating metadata in the following order: + // 1. EXIF + // 2. XMP + // 3. pp3 sidecar file + tag = newFrameRootDir->findTagUpward("Rating"); + if (tag && tag->toInt() != 0) { + rating = tag->toInt(); + } + char sXMPRating[64]; + if (newFrameRootDir->getXMPTagValue("xmp:Rating", sXMPRating)) { + // Guard against out-of-range values (<0, >5) + rating = rtengine::max(0, rtengine::min(5, atoi(sXMPRating))); + // Currently, Rating=-1 is not supported. A value of -1 should mean + // "Rejected" according to the specification. Maybe in the future, Rating=-1 + // sets InTrash=true? + } + tag = newFrameRootDir->findTagUpward("MakerNote"); rtexif::TagDirectory* mnote = nullptr; if (tag) { @@ -876,6 +897,11 @@ std::string FrameData::getOrientation () const return orientation; } +int FrameData::getRating () const +{ + return rating; +} + void FramesData::setDCRawFrameCount (unsigned int frameCount) @@ -1169,10 +1195,20 @@ std::string FramesData::getOrientation(unsigned int frame) const ); } +int FramesData::getRating(unsigned int frame) const +{ + return getFromFrame( + frames, + frame, + [](const FrameData& frame_data) + { + return frame_data.getRating(); + } + ); +} //------inherited functions--------------// - std::string FramesMetaData::apertureToString (double aperture) { diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index c6889e653..d06820296 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -48,6 +48,7 @@ protected: double expcomp; std::string make, model, serial; std::string orientation; + int rating; std::string lens; IIOSampleFormat sampleFormat; @@ -84,6 +85,7 @@ public: std::string getLens () const; std::string getSerialNumber () const; std::string getOrientation () const; + int getRating () const; }; class FramesData : public FramesMetaData { @@ -126,6 +128,7 @@ public: std::string getLens (unsigned int frame = 0) const override; std::string getSerialNumber (unsigned int frame = 0) const; std::string getOrientation (unsigned int frame = 0) const override; + int getRating (unsigned int frame = 0) const override; }; diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index a18cca9d7..bf73b5bb2 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -16,20 +16,22 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _IMAGESOURCE_ -#define _IMAGESOURCE_ +#pragma once + +#include +#include #include -#include -#include "rtengine.h" + #include "colortemp.h" #include "coord2d.h" #include "dcp.h" -#include "LUT.h" -#include "imagedata.h" -#include "image8.h" #include "image16.h" +#include "image8.h" +#include "imagedata.h" #include "imagefloat.h" +#include "LUT.h" +#include "rtengine.h" namespace rtengine { @@ -39,6 +41,7 @@ namespace procparams struct CoarseTransformParams; struct ColorManagementParams; +struct FilmNegativeParams; struct LensProfParams; struct RAWParams; struct RetinexParams; @@ -56,6 +59,7 @@ public: double cam_xyz[3][3] = {}; }; +// TODO: Move implementation to .cc (Flössie) class ImageSource : public InitialImage { @@ -77,6 +81,8 @@ public: ~ImageSource () override {} virtual int load (const Glib::ustring &fname) = 0; virtual void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) {}; + virtual void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) {}; + virtual bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams& currentParams, std::array& newExps) { return false; }; virtual void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold) {}; virtual void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {}; virtual void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; @@ -177,5 +183,5 @@ public: } virtual void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) = 0; }; + } -#endif diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 01f9892bf..6f471eedf 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -277,6 +277,18 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) imgsrc->getRAWHistogram(histRedRaw, histGreenRaw, histBlueRaw); highDetailPreprocessComputed = highDetailNeeded; + + // After preprocess, run film negative processing if enabled + if ( + (todo & M_RAW) + && ( + imgsrc->getSensorType() == ST_BAYER + || imgsrc->getSensorType() == ST_FUJI_XTRANS + ) + && params->filmNegative.enabled + ) { + imgsrc->filmNegativeProcess(params->filmNegative); + } } /* @@ -1250,6 +1262,31 @@ void ImProcCoordinator::getSpotWB(int x, int y, int rect, double& temp, double& } } +bool ImProcCoordinator::getFilmNegativeExponents(int xA, int yA, int xB, int yB, std::array& newExps) +{ + MyMutex::MyLock lock(mProcessing); + + const auto xlate = + [this](int x, int y) -> Coord2D + { + const std::vector points = {Coord2D(x, y)}; + + std::vector red; + std::vector green; + std::vector blue; + ipf.transCoord(fw, fh, points, red, green, blue); + + return green[0]; + }; + + const int tr = getCoarseBitMask(params->coarse); + + const Coord2D p1 = xlate(xA, yA); + const Coord2D p2 = xlate(xB, yB); + + return imgsrc->getFilmNegativeExponents(p1, p2, tr, params->filmNegative, newExps); +} + void ImProcCoordinator::getAutoCrop(double ratio, int &x, int &y, int &w, int &h) { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index c293f0c16..fdf74d297 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -269,6 +269,7 @@ public: bool getAutoWB (double& temp, double& green, double equal, double tempBias) override; void getCamWB (double& temp, double& green) override; void getSpotWB (int x, int y, int rectSize, double& temp, double& green) override; + bool getFilmNegativeExponents(int xA, int yA, int xB, int yB, std::array& newExps) override; void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) override; bool getHighQualComputed() override; void setHighQualComputed() override; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 1c05fbbad..81de080bd 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2734,6 +2734,27 @@ bool MetaDataParams::operator!=(const MetaDataParams &other) const return !(*this == other); } +FilmNegativeParams::FilmNegativeParams() : + enabled(false), + redRatio(1.36), + greenExp(1.5), + blueRatio(0.86) +{ +} + +bool FilmNegativeParams::operator ==(const FilmNegativeParams& other) const +{ + return + enabled == other.enabled + && redRatio == other.redRatio + && greenExp == other.greenExp + && blueRatio == other.blueRatio; +} + +bool FilmNegativeParams::operator !=(const FilmNegativeParams& other) const +{ + return !(*this == other); +} ProcParams::ProcParams() { @@ -2832,7 +2853,10 @@ void ProcParams::setDefaults() exif.clear(); iptc.clear(); - rank = 0; + // -1 means that there's no pp3 data with rank yet. In this case, the + // embedded Rating metadata should take precedence. -1 should never be + // written to pp3 on disk. + rank = -1; colorlabel = 0; inTrash = false; @@ -3566,6 +3590,12 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // MetaData saveToKeyfile(!pedited || pedited->metadata.mode, "MetaData", "Mode", metadata.mode, keyFile); +// Film negative + saveToKeyfile(!pedited || pedited->filmNegative.enabled, "Film Negative", "Enabled", filmNegative.enabled, keyFile); + saveToKeyfile(!pedited || pedited->filmNegative.redRatio, "Film Negative", "RedRatio", filmNegative.redRatio, keyFile); + saveToKeyfile(!pedited || pedited->filmNegative.greenExp, "Film Negative", "GreenExponent", filmNegative.greenExp, keyFile); + saveToKeyfile(!pedited || pedited->filmNegative.blueRatio, "Film Negative", "BlueRatio", filmNegative.blueRatio, keyFile); + // EXIF change list if (!pedited || pedited->exif) { for (ExifPairs::const_iterator i = exif.begin(); i != exif.end(); ++i) { @@ -5109,6 +5139,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackBlue", pedited, raw.xtranssensor.blackblue, pedited->raw.xtranssensor.exBlackBlue); } + if (keyFile.has_group("Film Negative")) { + assignFromKeyfile(keyFile, "Film Negative", "Enabled", pedited, filmNegative.enabled, pedited->filmNegative.enabled); + assignFromKeyfile(keyFile, "Film Negative", "RedRatio", pedited, filmNegative.redRatio, pedited->filmNegative.redRatio); + assignFromKeyfile(keyFile, "Film Negative", "GreenExponent", pedited, filmNegative.greenExp, pedited->filmNegative.greenExp); + assignFromKeyfile(keyFile, "Film Negative", "BlueRatio", pedited, filmNegative.blueRatio, pedited->filmNegative.blueRatio); + } + if (keyFile.has_group("MetaData")) { int mode = int(MetaDataParams::TUNNEL); assignFromKeyfile(keyFile, "MetaData", "Mode", pedited, mode, pedited->metadata.mode); @@ -5231,7 +5268,8 @@ bool ProcParams::operator ==(const ProcParams& other) const && metadata == other.metadata && exif == other.exif && iptc == other.iptc - && dehaze == other.dehaze; + && dehaze == other.dehaze + && filmNegative == other.filmNegative; } bool ProcParams::operator !=(const ProcParams& other) const diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 0982fda48..46eb530bc 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -728,7 +728,6 @@ struct DirPyrDenoiseParams { bool operator !=(const DirPyrDenoiseParams& other) const; void getCurves(NoiseCurve& lCurve, NoiseCurve& cCurve) const; - }; // EPD related parameters. @@ -1056,7 +1055,6 @@ struct ColorManagementParams { bool operator !=(const ColorManagementParams& other) const; }; - /** * Parameters for metadata handling */ @@ -1295,7 +1293,6 @@ struct HSVEqualizerParams { bool operator !=(const HSVEqualizerParams& other) const; }; - /** * Film simualtion params */ @@ -1310,7 +1307,6 @@ struct FilmSimulationParams { bool operator !=(const FilmSimulationParams& other) const; }; - struct SoftLightParams { bool enabled; int strength; @@ -1334,7 +1330,6 @@ struct DehazeParams { bool operator!=(const DehazeParams &other) const; }; - /** * Parameters for RAW demosaicing, common to all sensor type */ @@ -1501,6 +1496,21 @@ struct RAWParams { static Glib::ustring getFlatFieldBlurTypeString(FlatFieldBlurType type); }; +/** + * Parameters of film negative + */ +struct FilmNegativeParams { + bool enabled; + double redRatio; + double greenExp; + double blueRatio; + + FilmNegativeParams(); + + bool operator ==(const FilmNegativeParams& other) const; + bool operator !=(const FilmNegativeParams& other) const; +}; + /** * This class holds all the processing parameters applied on the images */ @@ -1549,6 +1559,7 @@ public: FilmSimulationParams filmSimulation; ///< film simulation parameters SoftLightParams softlight; ///< softlight parameters DehazeParams dehaze; ///< dehaze parameters + FilmNegativeParams filmNegative; ///< Film negative parameters int rank; ///< Custom image quality ranking int colorlabel; ///< Custom color label bool inTrash; ///< Marks deleted image diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 1fa1630ab..0134d4d16 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -67,7 +67,7 @@ RawImage::~RawImage() } } -eSensorType RawImage::getSensorType() +eSensorType RawImage::getSensorType() const { if (isBayer()) { return ST_BAYER; diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index 8e92495a1..ae0bcea84 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -113,7 +113,7 @@ public: return float_raw_image; } - eSensorType getSensorType(); + eSensorType getSensorType() const; void getRgbCam (float rgbcam[3][4]); void getXtransMatrix ( int xtransMatrix[6][6]); diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 64018f354..7c50991c0 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -16,9 +16,9 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RAWIMAGESOURCE_ -#define _RAWIMAGESOURCE_ +#pragma once +#include #include #include @@ -37,7 +37,6 @@ namespace rtengine class RawImageSource : public ImageSource { - private: static DiagonalCurve *phaseOneIccCurve; static DiagonalCurve *phaseOneIccCurveInv; @@ -109,7 +108,6 @@ protected: inline void getRowStartEnd (int x, int &start, int &end); static void getProfilePreprocParams(cmsHPROFILE in, float& gammafac, float& lineFac, float& lineSum); - public: RawImageSource (); ~RawImageSource () override; @@ -117,6 +115,8 @@ public: int load(const Glib::ustring &fname) override { return load(fname, false); } int load(const Glib::ustring &fname, bool firstFrameOnly); void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) override; + void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) override; + bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, std::array& newExps) override; void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold) override; void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) override; void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) override; @@ -307,5 +307,5 @@ protected: void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; }; + } -#endif diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 6264d43ae..f772975b0 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -16,23 +16,29 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _RTENGINE_ -#define _RTENGINE_ +#pragma once -#include "imageformat.h" -#include "rt_math.h" -#include "procevents.h" -#include -#include -#include +#include #include -#include "../rtexif/rtexif.h" -#include "rawmetadatalocation.h" +#include + +#include + +#include + #include "iimage.h" -#include "utils.h" -#include "../rtgui/threadutils.h" -#include "settings.h" +#include "imageformat.h" #include "LUT.h" +#include "procevents.h" +#include "rawmetadatalocation.h" +#include "rt_math.h" +#include "settings.h" +#include "utils.h" + +#include "../rtexif/rtexif.h" + +#include "../rtgui/threadutils.h" + /** * @file * This file contains the main functionality of the RawTherapee engine. @@ -133,6 +139,8 @@ public: virtual std::string getLens (unsigned int frame = 0) const = 0; /** @return the orientation of the image */ virtual std::string getOrientation (unsigned int frame = 0) const = 0; + /** @return the rating of the image */ + virtual int getRating (unsigned int frame = 0) const = 0; /** @return true if the file is a PixelShift shot (Pentax and Sony bodies) */ virtual bool getPixelShift () const = 0; @@ -499,6 +507,7 @@ public: virtual bool getAutoWB (double& temp, double& green, double equal, double tempBias) = 0; virtual void getCamWB (double& temp, double& green) = 0; virtual void getSpotWB (int x, int y, int rectSize, double& temp, double& green) = 0; + virtual bool getFilmNegativeExponents(int xA, int yA, int xB, int yB, std::array& newExps) = 0; virtual void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) = 0; virtual void saveInputICCReference (const Glib::ustring& fname, bool apply_wb) = 0; @@ -612,6 +621,3 @@ void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl); extern MyMutex* lcmsMutex; } - -#endif - diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 0a74cf8c2..2a35176e6 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1167,6 +1167,10 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT Imagefloat* baseImg = resizeTo (rwidth, rheight, interp, thumbImg); + if (isRaw && params.filmNegative.enabled) { + processFilmNegative(params, baseImg, rwidth, rheight, rmi, gmi, bmi); + } + if (params.coarse.rotate) { baseImg->rotate (params.coarse.rotate); rwidth = baseImg->getWidth(); diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index df33b892d..09a0510eb 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -68,6 +68,8 @@ class Thumbnail bool gammaCorrected; double colorMatrix[3][3]; + void processFilmNegative(const procparams::ProcParams& params, const Imagefloat* baseImg, int rwidth, int rheight, float &rmi, float &gmi, float &bmi); + public: bool isRaw; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 8b9bee738..4bdaa6ff1 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -209,6 +209,11 @@ private: imgsrc->setCurrentFrame (params.raw.bayersensor.imageNum); imgsrc->preprocess ( params.raw, params.lensProf, params.coarse, params.dirpyrDenoise.enabled); + // After preprocess, run film negative processing if enabled + if (imgsrc->getSensorType() == ST_BAYER && params.filmNegative.enabled) { + imgsrc->filmNegativeProcess (params.filmNegative); + } + if (pl) { pl->setProgress (0.20); } diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index 571fd4e6b..312cbd1c7 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -3037,6 +3037,12 @@ void ExifManager::parse (bool isRaw, bool skipIgnored) } } + if (!root->getTag ("Rating")) { + Tag *t = new Tag (root, root->getAttrib("Rating")); + t->initInt (0, LONG); + root->addTag (t); + } + // --- detecting image root IFD based on SubFileType, or if not provided, on PhotometricInterpretation bool frameRootDetected = false; diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 3af955be8..bdd166938 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -8,7 +8,7 @@ set(CLISOURCEFILES paramsedited.cc pathutils.cc threadutils.cc - ) +) set(NONCLISOURCEFILES adjuster.cc @@ -43,6 +43,7 @@ set(NONCLISOURCEFILES curveeditorgroup.cc darkframe.cc defringe.cc + dehaze.cc diagonalcurveeditorsubgroup.cc dirbrowser.cc dirpyrdenoise.cc @@ -55,15 +56,18 @@ set(NONCLISOURCEFILES editwidgets.cc editwindow.cc epd.cc + eventmapper.cc exiffiltersettings.cc exifpanel.cc exportpanel.cc extprog.cc + fattaltonemap.cc filebrowser.cc filebrowserentry.cc filecatalog.cc filepanel.cc filethumbnailbuttonset.cc + filmnegative.cc filmsimulation.cc filterpanel.cc flatcurveeditorsubgroup.cc @@ -83,12 +87,15 @@ set(NONCLISOURCEFILES inspector.cc iptcpanel.cc labcurve.cc + labgrid.cc lensgeom.cc lensprofile.cc + localcontrast.cc lockablecolorpicker.cc lwbutton.cc lwbuttonset.cc main.cc + metadatapanel.cc multilangmgr.cc mycurve.cc mydiagonalcurve.cc @@ -122,8 +129,8 @@ set(NONCLISOURCEFILES rgbcurves.cc rotate.cc rtimage.cc - rtsurface.cc rtscalable.cc + rtsurface.cc rtwindow.cc saveasdlg.cc saveformatpanel.cc @@ -134,6 +141,7 @@ set(NONCLISOURCEFILES sharpening.cc sharpenmicro.cc shcselector.cc + softlight.cc soundman.cc splash.cc threadutils.cc @@ -154,14 +162,7 @@ set(NONCLISOURCEFILES xtransprocess.cc xtransrawexposure.cc zoompanel.cc - fattaltonemap.cc - localcontrast.cc - eventmapper.cc - metadatapanel.cc - labgrid.cc - softlight.cc - dehaze.cc - ) +) include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index 35aeb6c91..1756f523b 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -24,12 +24,37 @@ #include "../rtengine/procparams.h" -CacheImageData::CacheImageData () - : md5(""), supported(false), format(FT_Invalid), rankOld(-1), inTrashOld(false), recentlySaved(false), - timeValid(false), year(0), month(0), day(0), hour(0), min(0), sec(0), exifValid(false), frameCount(1), - fnumber(0.0), shutter(0.0), focalLen(0.0), focalLen35mm(0.0), focusDist(0.f), iso(0), isHDR (false), - isPixelShift (false), sensortype(rtengine::ST_NONE), sampleFormat(rtengine::IIOSF_UNKNOWN), - redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0), rotate(0), thumbImgType(0) +CacheImageData::CacheImageData() : + supported(false), + format(FT_Invalid), + rankOld(-1), + inTrashOld(false), + recentlySaved(false), + timeValid(false), + year(0), + month(0), + day(0), + hour(0), + min(0), + sec(0), + exifValid(false), + frameCount(1), + fnumber(0.0), + shutter(0.0), + focalLen(0.0), + focalLen35mm(0.0), + focusDist(0.f), + iso(0), + rating(0), + isHDR (false), + isPixelShift (false), + sensortype(rtengine::ST_NONE), + sampleFormat(rtengine::IIOSF_UNKNOWN), + redAWBMul(-1.0), + greenAWBMul(-1.0), + blueAWBMul(-1.0), + rotate(0), + thumbImgType(0) { } @@ -66,6 +91,10 @@ int CacheImageData::load (const Glib::ustring& fname) rankOld = keyFile.get_integer ("General", "Rank"); } + if (keyFile.has_key ("General", "Rating")) { + rating = keyFile.get_integer ("General", "Rating"); + } + if (keyFile.has_key ("General", "InTrash")) { inTrashOld = keyFile.get_boolean ("General", "InTrash"); } @@ -227,6 +256,7 @@ int CacheImageData::save (const Glib::ustring& fname) keyFile.set_boolean ("General", "Supported", supported); keyFile.set_integer ("General", "Format", format); keyFile.set_boolean ("General", "RecentlySaved", recentlySaved); + keyFile.set_integer ("General", "Rating", rating); // remove the old implementation of Rank and InTrash from cache if (keyFile.has_key ("General", "Rank")) { diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index d3aea803b..9de9d186f 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -54,6 +54,7 @@ public: double focalLen, focalLen35mm; float focusDist; unsigned iso; + int rating; bool isHDR; bool isPixelShift; int sensortype; @@ -108,6 +109,7 @@ public: std::string getModel (unsigned int frame = 0) const override { return camModel; } std::string getLens (unsigned int frame = 0) const override { return lens; } std::string getOrientation (unsigned int frame = 0) const override { return ""; } // TODO + int getRating (unsigned int frame = 0) const override { return rating; } // FIXME-piotr : missing rating bool getPixelShift () const override { return isPixelShift; } bool getHDR (unsigned int frame = 0) const override { return isHDR; } std::string getImageType (unsigned int frame) const override { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc new file mode 100644 index 000000000..598c9463a --- /dev/null +++ b/rtgui/filmnegative.cc @@ -0,0 +1,317 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2019 Alberto Romei + * + * 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 "filmnegative.h" + +#include "editwidgets.h" +#include "eventmapper.h" +#include "options.h" +#include "rtimage.h" + +#include "../rtengine/procparams.h" + +namespace +{ + +Adjuster* createExponentAdjuster(AdjusterListener* listener, const Glib::ustring& label, double minV, double maxV, double defaultVal) +{ + Adjuster* const adj = Gtk::manage(new Adjuster(label, minV, maxV, 0.001, defaultVal)); + adj->setAdjusterListener(listener); + adj->setLogScale(6, 1, true); + + if (adj->delay < options.adjusterMaxDelay) { + adj->delay = options.adjusterMaxDelay; + } + + adj->show(); + return adj; +} + +} + +FilmNegative::FilmNegative() : + FoldableToolPanel(this, "filmnegative", M("TP_FILMNEGATIVE_LABEL"), false, true), + EditSubscriber(ET_OBJECTS), + evFilmNegativeExponents(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_VALUES")), + evFilmNegativeEnabled(ProcEventMapper::getInstance()->newEvent(FIRST, "HISTORY_MSG_FILMNEGATIVE_ENABLED")), + fnp(nullptr), + greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 0.3, 4, 1.5)), // master exponent (green channel) + redRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 0.3, 3, (2.04 / 1.5))), // ratio of red exponent to master exponent + blueRatio(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 0.3, 3, (1.29 / 1.5))), // ratio of blue exponent to master exponent + spotgrid(Gtk::manage(new Gtk::Grid())), + spotbutton(Gtk::manage(new Gtk::ToggleButton(M("TP_FILMNEGATIVE_PICK")))) +{ + spotgrid->get_style_context()->add_class("grid-spacing"); + setExpandAlignProperties(spotgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + setExpandAlignProperties(spotbutton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + spotbutton->get_style_context()->add_class("independent"); + spotbutton->set_tooltip_text(M("TP_FILMNEGATIVE_GUESS_TOOLTIP")); + spotbutton->set_image (*Gtk::manage (new RTImage ("color-picker-small.png"))); + + // TODO make spot size configurable ? + + // Gtk::Label* slab = Gtk::manage (new Gtk::Label (M("TP_WBALANCE_SIZE"))); + // setExpandAlignProperties(slab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + + // Gtk::Grid* wbsizehelper = Gtk::manage(new Gtk::Grid()); + // wbsizehelper->set_name("WB-Size-Helper"); + // setExpandAlignProperties(wbsizehelper, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + + // spotsize = Gtk::manage (new MyComboBoxText ()); + // setExpandAlignProperties(spotsize, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + // spotsize->append ("2"); + // spotsize->set_active(0); + // spotsize->append ("4"); + + spotgrid->attach (*spotbutton, 0, 1, 1, 1); + // spotgrid->attach (*slab, 1, 0, 1, 1); + // spotgrid->attach (*wbsizehelper, 2, 0, 1, 1); + + pack_start(*greenExp, Gtk::PACK_SHRINK, 0); + pack_start(*redRatio, Gtk::PACK_SHRINK, 0); + pack_start(*blueRatio, Gtk::PACK_SHRINK, 0); + pack_start(*spotgrid, Gtk::PACK_SHRINK, 0); + + spotbutton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); + // spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); + + // Editing geometry; create the spot rectangle + Rectangle* const spotRect = new Rectangle(); + spotRect->filled = false; + + visibleGeometry.push_back(spotRect); + + // Stick a dummy rectangle over the whole image in mouseOverGeometry. + // This is to make sure the getCursor() call is fired everywhere. + Rectangle* const imgRect = new Rectangle(); + imgRect->filled = true; + + mouseOverGeometry.push_back(imgRect); +} + +FilmNegative::~FilmNegative() +{ + for (auto geometry : visibleGeometry) { + delete geometry; + } + + for (auto geometry : mouseOverGeometry) { + delete geometry; + } +} + +void FilmNegative::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener(); + + if (pedited) { + redRatio->setEditedState(pedited->filmNegative.redRatio ? Edited : UnEdited); + greenExp->setEditedState(pedited->filmNegative.greenExp ? Edited : UnEdited); + blueRatio->setEditedState(pedited->filmNegative.blueRatio ? Edited : UnEdited); + set_inconsistent(multiImage && !pedited->filmNegative.enabled); + } + + setEnabled(pp->filmNegative.enabled); + redRatio->setValue(pp->filmNegative.redRatio); + greenExp->setValue(pp->filmNegative.greenExp); + blueRatio->setValue(pp->filmNegative.blueRatio); + + enableListener(); +} + +void FilmNegative::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->filmNegative.redRatio = redRatio->getValue(); + pp->filmNegative.greenExp = greenExp->getValue(); + pp->filmNegative.blueRatio = blueRatio->getValue(); + pp->filmNegative.enabled = getEnabled(); + + if (pedited) { + pedited->filmNegative.redRatio = redRatio->getEditedState(); + pedited->filmNegative.greenExp = greenExp->getEditedState(); + pedited->filmNegative.blueRatio = blueRatio->getEditedState(); + pedited->filmNegative.enabled = !get_inconsistent(); + } +} + +void FilmNegative::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + redRatio->setValue(defParams->filmNegative.redRatio); + greenExp->setValue(defParams->filmNegative.greenExp); + blueRatio->setValue(defParams->filmNegative.blueRatio); + + if (pedited) { + redRatio->setDefaultEditedState(pedited->filmNegative.redRatio ? Edited : UnEdited); + greenExp->setDefaultEditedState(pedited->filmNegative.greenExp ? Edited : UnEdited); + blueRatio->setDefaultEditedState(pedited->filmNegative.blueRatio ? Edited : UnEdited); + } else { + redRatio->setDefaultEditedState(Irrelevant); + greenExp->setDefaultEditedState(Irrelevant); + blueRatio->setDefaultEditedState(Irrelevant); + } +} + +void FilmNegative::setBatchMode(bool batchMode) +{ + if (batchMode) { + spotConn.disconnect(); + removeIfThere(this, spotgrid, false); + ToolPanel::setBatchMode(batchMode); + redRatio->showEditedCB(); + greenExp->showEditedCB(); + blueRatio->showEditedCB(); + } +} + +void FilmNegative::adjusterChanged(Adjuster* a, double newval) +{ + if (listener) { + if (a == redRatio || a == greenExp || a == blueRatio) { + if (getEnabled()) { + listener->panelChanged( + evFilmNegativeExponents, + Glib::ustring::compose( + "Ref=%1 ; R=%2 ; B=%3", + greenExp->getValue(), + redRatio->getValue(), + blueRatio->getValue() + ) + ); + } + } + } +} + +void FilmNegative::adjusterAutoToggled(Adjuster* a, bool newval) +{ +} + +void FilmNegative::enabledChanged() +{ + if (listener) { + if (get_inconsistent()) { + listener->panelChanged(evFilmNegativeEnabled, M("GENERAL_UNCHANGED")); + } + else if (getEnabled()) { + listener->panelChanged(evFilmNegativeEnabled, M("GENERAL_ENABLED")); + } + else { + listener->panelChanged(evFilmNegativeEnabled, M("GENERAL_DISABLED")); + } + } +} + +void FilmNegative::setFilmNegProvider(FilmNegProvider* provider) +{ + fnp = provider; +} + +void FilmNegative::setEditProvider(EditDataProvider* provider) +{ + EditSubscriber::setEditProvider(provider); +} + +CursorShape FilmNegative::getCursor(int objectID) const +{ + return CSSpotWB; +} + +bool FilmNegative::mouseOver(int modifierKey) +{ + EditDataProvider* const provider = getEditProvider(); + Rectangle* const spotRect = static_cast(visibleGeometry.at(0)); + spotRect->setXYWH(provider->posImage.x - 16, provider->posImage.y - 16, 32, 32); + + return true; +} + +bool FilmNegative::button1Pressed(int modifierKey) +{ + EditDataProvider* const provider = getEditProvider(); + + EditSubscriber::action = EditSubscriber::Action::NONE; + + if (listener) { + refSpotCoords.push_back(provider->posImage); + + if (refSpotCoords.size() == 2) { + // User has selected 2 reference gray spots. Calculating new exponents + // from channel values and updating parameters. + + std::array newExps; + if (fnp->getFilmNegativeExponents(refSpotCoords[0], refSpotCoords[1], newExps)) { + disableListener(); + // Leaving green exponent unchanged, setting red and blue exponents based on + // the ratios between newly calculated exponents. + redRatio->setValue(newExps[0] / newExps[1]); + blueRatio->setValue(newExps[2] / newExps[1]); + enableListener(); + + if (listener && getEnabled()) { + listener->panelChanged( + evFilmNegativeExponents, + Glib::ustring::compose( + "Ref=%1 ; R=%2 ; B=%3", + greenExp->getValue(), + redRatio->getValue(), + blueRatio->getValue() + ) + ); + } + } + + switchOffEditMode(); + } + } + + return true; +} + +bool FilmNegative::button1Released() +{ + EditSubscriber::action = EditSubscriber::Action::NONE; + return true; +} + +void FilmNegative::switchOffEditMode() +{ + refSpotCoords.clear(); + unsubscribe(); + spotbutton->set_active(false); +} + +void FilmNegative::editToggled() +{ + if (spotbutton->get_active()) { + subscribe(); + + int w, h; + getEditProvider()->getImageSize(w, h); + + // Stick a dummy rectangle over the whole image in mouseOverGeometry. + // This is to make sure the getCursor() call is fired everywhere. + Rectangle* const imgRect = static_cast(mouseOverGeometry.at(0)); + imgRect->setXYWH(0, 0, w, h); + } else { + refSpotCoords.clear(); + unsubscribe(); + } +} diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h new file mode 100644 index 000000000..7de1bd56a --- /dev/null +++ b/rtgui/filmnegative.h @@ -0,0 +1,89 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2019 Alberto Romei + * + * 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 + +#include + +#include "adjuster.h" +#include "editcallbacks.h" +#include "guiutils.h" +#include "toolpanel.h" +#include "wbprovider.h" + +#include "../rtengine/noncopyable.h" + +class FilmNegProvider +{ +public: + virtual ~FilmNegProvider() = default; + + virtual bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, std::array& newExps) = 0; +}; + +class FilmNegative : + public rtengine::NonCopyable, + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel, + public EditSubscriber +{ +public: + FilmNegative(); + ~FilmNegative() override; + + void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; + void write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; + void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; + void setBatchMode(bool batchMode) override; + + void adjusterChanged(Adjuster* a, double newval) override; + void adjusterAutoToggled(Adjuster* a, bool newval) override; + void enabledChanged() override; + + void setFilmNegProvider(FilmNegProvider* provider); + + void setEditProvider(EditDataProvider* provider) override; + + // EditSubscriber interface + CursorShape getCursor(int objectID) const override; + bool mouseOver(int modifierKey) override; + bool button1Pressed(int modifierKey) override; + bool button1Released() override; + void switchOffEditMode() override; + +private: + void editToggled(); + + const rtengine::ProcEvent evFilmNegativeExponents; + const rtengine::ProcEvent evFilmNegativeEnabled; + + std::vector refSpotCoords; + + FilmNegProvider* fnp; + + Adjuster* const greenExp; + Adjuster* const redRatio; + Adjuster* const blueRatio; + + Gtk::Grid* const spotgrid; + Gtk::ToggleButton* const spotbutton; + sigc::connection spotConn; +}; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 2c29b4f5b..952b08161 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -580,6 +580,10 @@ void ParamsEdited::set(bool v) dehaze.showDepthMap = v; dehaze.depth = v; metadata.mode = v; + filmNegative.enabled = v; + filmNegative.redRatio = v; + filmNegative.greenExp = v; + filmNegative.blueRatio = v; exif = v; iptc = v; @@ -1142,6 +1146,10 @@ void ParamsEdited::initFrom(const std::vector& dehaze.showDepthMap = dehaze.showDepthMap && p.dehaze.showDepthMap == other.dehaze.showDepthMap; dehaze.depth = dehaze.depth && p.dehaze.depth == other.dehaze.depth; metadata.mode = metadata.mode && p.metadata.mode == other.metadata.mode; + filmNegative.enabled = filmNegative.enabled && p.filmNegative.enabled == other.filmNegative.enabled; + filmNegative.redRatio = filmNegative.redRatio && p.filmNegative.redRatio == other.filmNegative.redRatio; + filmNegative.greenExp = filmNegative.greenExp && p.filmNegative.greenExp == other.filmNegative.greenExp; + filmNegative.blueRatio = filmNegative.blueRatio && p.filmNegative.blueRatio == other.filmNegative.blueRatio; // How the hell can we handle that??? // exif = exif && p.exif==other.exif @@ -1155,15 +1163,15 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng bool dontforceSet = !forceSet; if (toneCurve.curve) { - toEdit.toneCurve.curve = mods.toneCurve.curve; + toEdit.toneCurve.curve = mods.toneCurve.curve; } if (toneCurve.curve2) { - toEdit.toneCurve.curve2 = mods.toneCurve.curve2; + toEdit.toneCurve.curve2 = mods.toneCurve.curve2; } if (toneCurve.curveMode) { - toEdit.toneCurve.curveMode = mods.toneCurve.curveMode; + toEdit.toneCurve.curveMode = mods.toneCurve.curveMode; } if (toneCurve.curveMode2) { @@ -1175,11 +1183,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (toneCurve.black) { - toEdit.toneCurve.black = dontforceSet && options.baBehav[ADDSET_TC_BLACKLEVEL] ? toEdit.toneCurve.black + mods.toneCurve.black : mods.toneCurve.black; + toEdit.toneCurve.black = dontforceSet && options.baBehav[ADDSET_TC_BLACKLEVEL] ? toEdit.toneCurve.black + mods.toneCurve.black : mods.toneCurve.black; } if (toneCurve.contrast) { - toEdit.toneCurve.contrast = dontforceSet && options.baBehav[ADDSET_TC_CONTRAST] ? toEdit.toneCurve.contrast + mods.toneCurve.contrast : mods.toneCurve.contrast; + toEdit.toneCurve.contrast = dontforceSet && options.baBehav[ADDSET_TC_CONTRAST] ? toEdit.toneCurve.contrast + mods.toneCurve.contrast : mods.toneCurve.contrast; } if (toneCurve.saturation) { @@ -1187,43 +1195,43 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (toneCurve.shcompr) { - toEdit.toneCurve.shcompr = dontforceSet && options.baBehav[ADDSET_TC_SHCOMP] ? toEdit.toneCurve.shcompr + mods.toneCurve.shcompr : mods.toneCurve.shcompr; + toEdit.toneCurve.shcompr = dontforceSet && options.baBehav[ADDSET_TC_SHCOMP] ? toEdit.toneCurve.shcompr + mods.toneCurve.shcompr : mods.toneCurve.shcompr; } if (toneCurve.autoexp) { - toEdit.toneCurve.autoexp = mods.toneCurve.autoexp; + toEdit.toneCurve.autoexp = mods.toneCurve.autoexp; } if (toneCurve.clip) { - toEdit.toneCurve.clip = mods.toneCurve.clip; + toEdit.toneCurve.clip = mods.toneCurve.clip; } if (toneCurve.expcomp) { - toEdit.toneCurve.expcomp = dontforceSet && options.baBehav[ADDSET_TC_EXPCOMP] ? toEdit.toneCurve.expcomp + mods.toneCurve.expcomp : mods.toneCurve.expcomp; + toEdit.toneCurve.expcomp = dontforceSet && options.baBehav[ADDSET_TC_EXPCOMP] ? toEdit.toneCurve.expcomp + mods.toneCurve.expcomp : mods.toneCurve.expcomp; } if (toneCurve.hlcompr) { - toEdit.toneCurve.hlcompr = dontforceSet && options.baBehav[ADDSET_TC_HLCOMPAMOUNT] ? toEdit.toneCurve.hlcompr + mods.toneCurve.hlcompr : mods.toneCurve.hlcompr; + toEdit.toneCurve.hlcompr = dontforceSet && options.baBehav[ADDSET_TC_HLCOMPAMOUNT] ? toEdit.toneCurve.hlcompr + mods.toneCurve.hlcompr : mods.toneCurve.hlcompr; } if (toneCurve.hlcomprthresh) { - toEdit.toneCurve.hlcomprthresh = dontforceSet && options.baBehav[ADDSET_TC_HLCOMPTHRESH] ? toEdit.toneCurve.hlcomprthresh + mods.toneCurve.hlcomprthresh : mods.toneCurve.hlcomprthresh; + toEdit.toneCurve.hlcomprthresh = dontforceSet && options.baBehav[ADDSET_TC_HLCOMPTHRESH] ? toEdit.toneCurve.hlcomprthresh + mods.toneCurve.hlcomprthresh : mods.toneCurve.hlcomprthresh; } if (toneCurve.hrenabled) { - toEdit.toneCurve.hrenabled = mods.toneCurve.hrenabled; + toEdit.toneCurve.hrenabled = mods.toneCurve.hrenabled; } if (toneCurve.method) { - toEdit.toneCurve.method = mods.toneCurve.method; + toEdit.toneCurve.method = mods.toneCurve.method; } if (toneCurve.histmatching) { - toEdit.toneCurve.histmatching = mods.toneCurve.histmatching; + toEdit.toneCurve.histmatching = mods.toneCurve.histmatching; } if (toneCurve.fromHistMatching) { - toEdit.toneCurve.fromHistMatching = mods.toneCurve.fromHistMatching; + toEdit.toneCurve.fromHistMatching = mods.toneCurve.fromHistMatching; } if (toneCurve.clampOOG) { @@ -1231,132 +1239,132 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (retinex.enabled) { - toEdit.retinex.enabled = mods.retinex.enabled; + toEdit.retinex.enabled = mods.retinex.enabled; } if (retinex.cdcurve) { - toEdit.retinex.cdcurve = mods.retinex.cdcurve; + toEdit.retinex.cdcurve = mods.retinex.cdcurve; } if (retinex.mapcurve) { - toEdit.retinex.mapcurve = mods.retinex.mapcurve; + toEdit.retinex.mapcurve = mods.retinex.mapcurve; } if (retinex.cdHcurve) { - toEdit.retinex.cdHcurve = mods.retinex.cdHcurve; + toEdit.retinex.cdHcurve = mods.retinex.cdHcurve; } if (retinex.lhcurve) { - toEdit.retinex.lhcurve = mods.retinex.lhcurve; + toEdit.retinex.lhcurve = mods.retinex.lhcurve; } if (retinex.transmissionCurve) { - toEdit.retinex.transmissionCurve = mods.retinex.transmissionCurve; + toEdit.retinex.transmissionCurve = mods.retinex.transmissionCurve; } if (retinex.gaintransmissionCurve) { - toEdit.retinex.gaintransmissionCurve = mods.retinex.gaintransmissionCurve; + toEdit.retinex.gaintransmissionCurve = mods.retinex.gaintransmissionCurve; } if (retinex.retinexMethod) { - toEdit.retinex.retinexMethod = mods.retinex.retinexMethod; + toEdit.retinex.retinexMethod = mods.retinex.retinexMethod; } if (retinex.mapMethod) { - toEdit.retinex.mapMethod = mods.retinex.mapMethod; + toEdit.retinex.mapMethod = mods.retinex.mapMethod; } if (retinex.viewMethod) { - toEdit.retinex.viewMethod = mods.retinex.viewMethod; + toEdit.retinex.viewMethod = mods.retinex.viewMethod; } if (retinex.retinexcolorspace) { - toEdit.retinex.retinexcolorspace = mods.retinex.retinexcolorspace; + toEdit.retinex.retinexcolorspace = mods.retinex.retinexcolorspace; } if (retinex.gammaretinex) { - toEdit.retinex.gammaretinex = mods.retinex.gammaretinex; + toEdit.retinex.gammaretinex = mods.retinex.gammaretinex; } if (retinex.gam) { - toEdit.retinex.gam = dontforceSet && options.baBehav[ADDSET_RETI_GAM] ? toEdit.retinex.gam + mods.retinex.gam : mods.retinex.gam; + toEdit.retinex.gam = dontforceSet && options.baBehav[ADDSET_RETI_GAM] ? toEdit.retinex.gam + mods.retinex.gam : mods.retinex.gam; } if (retinex.slope) { - toEdit.retinex.slope = dontforceSet && options.baBehav[ADDSET_RETI_SLO] ? toEdit.retinex.slope + mods.retinex.slope : mods.retinex.slope; + toEdit.retinex.slope = dontforceSet && options.baBehav[ADDSET_RETI_SLO] ? toEdit.retinex.slope + mods.retinex.slope : mods.retinex.slope; } if (retinex.str) { - toEdit.retinex.str = dontforceSet && options.baBehav[ADDSET_RETI_STR] ? toEdit.retinex.str + mods.retinex.str : mods.retinex.str; + toEdit.retinex.str = dontforceSet && options.baBehav[ADDSET_RETI_STR] ? toEdit.retinex.str + mods.retinex.str : mods.retinex.str; } if (retinex.scal) { - toEdit.retinex.scal = mods.retinex.scal; + toEdit.retinex.scal = mods.retinex.scal; } if (retinex.iter) { - toEdit.retinex.iter = mods.retinex.iter; + toEdit.retinex.iter = mods.retinex.iter; } if (retinex.grad) { - toEdit.retinex.grad = mods.retinex.grad; + toEdit.retinex.grad = mods.retinex.grad; } if (retinex.grads) { - toEdit.retinex.grads = mods.retinex.grads; + toEdit.retinex.grads = mods.retinex.grads; } // if (retinex.scal) { -// toEdit.retinex.scal = dontforceSet && options.baBehav[ADDSET_RETI_SCAL] ? toEdit.retinex.scal + mods.retinex.scal : mods.retinex.scal; +// toEdit.retinex.scal = dontforceSet && options.baBehav[ADDSET_RETI_SCAL] ? toEdit.retinex.scal + mods.retinex.scal : mods.retinex.scal; // } if (retinex.medianmap) { - toEdit.retinex.medianmap = mods.retinex.medianmap; + toEdit.retinex.medianmap = mods.retinex.medianmap; } if (retinex.neigh) { - toEdit.retinex.neigh = dontforceSet && options.baBehav[ADDSET_RETI_NEIGH] ? toEdit.retinex.neigh + mods.retinex.neigh : mods.retinex.neigh; + toEdit.retinex.neigh = dontforceSet && options.baBehav[ADDSET_RETI_NEIGH] ? toEdit.retinex.neigh + mods.retinex.neigh : mods.retinex.neigh; } if (retinex.limd) { - toEdit.retinex.limd = dontforceSet && options.baBehav[ADDSET_RETI_LIMD] ? toEdit.retinex.limd + mods.retinex.limd : mods.retinex.limd; + toEdit.retinex.limd = dontforceSet && options.baBehav[ADDSET_RETI_LIMD] ? toEdit.retinex.limd + mods.retinex.limd : mods.retinex.limd; } if (retinex.highl) { - toEdit.retinex.highl = mods.retinex.highl; + toEdit.retinex.highl = mods.retinex.highl; } if (retinex.skal) { - toEdit.retinex.skal = mods.retinex.skal; + toEdit.retinex.skal = mods.retinex.skal; } if (retinex.offs) { - toEdit.retinex.offs = dontforceSet && options.baBehav[ADDSET_RETI_OFFS] ? toEdit.retinex.offs + mods.retinex.offs : mods.retinex.offs; + toEdit.retinex.offs = dontforceSet && options.baBehav[ADDSET_RETI_OFFS] ? toEdit.retinex.offs + mods.retinex.offs : mods.retinex.offs; } if (retinex.vart) { - toEdit.retinex.vart = dontforceSet && options.baBehav[ADDSET_RETI_VART] ? toEdit.retinex.vart + mods.retinex.vart : mods.retinex.vart; + toEdit.retinex.vart = dontforceSet && options.baBehav[ADDSET_RETI_VART] ? toEdit.retinex.vart + mods.retinex.vart : mods.retinex.vart; } if (retinex.highlights) { - toEdit.retinex.highlights = mods.retinex.highlights; + toEdit.retinex.highlights = mods.retinex.highlights; } if (retinex.htonalwidth) { - toEdit.retinex.htonalwidth = mods.retinex.htonalwidth; + toEdit.retinex.htonalwidth = mods.retinex.htonalwidth; } if (retinex.shadows) { - toEdit.retinex.shadows = mods.retinex.shadows; + toEdit.retinex.shadows = mods.retinex.shadows; } if (retinex.stonalwidth) { - toEdit.retinex.stonalwidth = mods.retinex.stonalwidth; + toEdit.retinex.stonalwidth = mods.retinex.stonalwidth; } if (retinex.radius) { - toEdit.retinex.radius = mods.retinex.radius; + toEdit.retinex.radius = mods.retinex.radius; } @@ -1365,47 +1373,47 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (labCurve.lcurve) { - toEdit.labCurve.lcurve = mods.labCurve.lcurve; + toEdit.labCurve.lcurve = mods.labCurve.lcurve; } if (labCurve.acurve) { - toEdit.labCurve.acurve = mods.labCurve.acurve; + toEdit.labCurve.acurve = mods.labCurve.acurve; } if (labCurve.bcurve) { - toEdit.labCurve.bcurve = mods.labCurve.bcurve; + toEdit.labCurve.bcurve = mods.labCurve.bcurve; } if (labCurve.cccurve) { - toEdit.labCurve.cccurve = mods.labCurve.cccurve; + toEdit.labCurve.cccurve = mods.labCurve.cccurve; } if (labCurve.chcurve) { - toEdit.labCurve.chcurve = mods.labCurve.chcurve; + toEdit.labCurve.chcurve = mods.labCurve.chcurve; } if (labCurve.lhcurve) { - toEdit.labCurve.lhcurve = mods.labCurve.lhcurve; + toEdit.labCurve.lhcurve = mods.labCurve.lhcurve; } if (labCurve.hhcurve) { - toEdit.labCurve.hhcurve = mods.labCurve.hhcurve; + toEdit.labCurve.hhcurve = mods.labCurve.hhcurve; } if (labCurve.lccurve) { - toEdit.labCurve.lccurve = mods.labCurve.lccurve; + toEdit.labCurve.lccurve = mods.labCurve.lccurve; } if (labCurve.clcurve) { - toEdit.labCurve.clcurve = mods.labCurve.clcurve; + toEdit.labCurve.clcurve = mods.labCurve.clcurve; } if (labCurve.brightness) { - toEdit.labCurve.brightness = dontforceSet && options.baBehav[ADDSET_LC_BRIGHTNESS] ? toEdit.labCurve.brightness + mods.labCurve.brightness : mods.labCurve.brightness; + toEdit.labCurve.brightness = dontforceSet && options.baBehav[ADDSET_LC_BRIGHTNESS] ? toEdit.labCurve.brightness + mods.labCurve.brightness : mods.labCurve.brightness; } if (labCurve.contrast) { - toEdit.labCurve.contrast = dontforceSet && options.baBehav[ADDSET_LC_CONTRAST] ? toEdit.labCurve.contrast + mods.labCurve.contrast : mods.labCurve.contrast; + toEdit.labCurve.contrast = dontforceSet && options.baBehav[ADDSET_LC_CONTRAST] ? toEdit.labCurve.contrast + mods.labCurve.contrast : mods.labCurve.contrast; } if (labCurve.chromaticity) { @@ -1421,7 +1429,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (labCurve.lcredsk) { - toEdit.labCurve.lcredsk = mods.labCurve.lcredsk; + toEdit.labCurve.lcredsk = mods.labCurve.lcredsk; } if (localContrast.enabled) { @@ -1446,23 +1454,23 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (rgbCurves.lumamode) { - toEdit.rgbCurves.lumamode = mods.rgbCurves.lumamode; + toEdit.rgbCurves.lumamode = mods.rgbCurves.lumamode; } if (rgbCurves.rcurve) { - toEdit.rgbCurves.rcurve = mods.rgbCurves.rcurve; + toEdit.rgbCurves.rcurve = mods.rgbCurves.rcurve; } if (rgbCurves.gcurve) { - toEdit.rgbCurves.gcurve = mods.rgbCurves.gcurve; + toEdit.rgbCurves.gcurve = mods.rgbCurves.gcurve; } if (rgbCurves.bcurve) { - toEdit.rgbCurves.bcurve = mods.rgbCurves.bcurve; + toEdit.rgbCurves.bcurve = mods.rgbCurves.bcurve; } if (colorToning.enabled) { - toEdit.colorToning.enabled = mods.colorToning.enabled; + toEdit.colorToning.enabled = mods.colorToning.enabled; } if (colorToning.twocolor) { @@ -1470,7 +1478,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.opacityCurve) { - toEdit.colorToning.opacityCurve = mods.colorToning.opacityCurve; + toEdit.colorToning.opacityCurve = mods.colorToning.opacityCurve; } if (colorToning.colorCurve) { @@ -1478,11 +1486,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.enabled) { - toEdit.colorToning.enabled = mods.colorToning.enabled; + toEdit.colorToning.enabled = mods.colorToning.enabled; } if (colorToning.opacityCurve) { - toEdit.colorToning.opacityCurve = mods.colorToning.opacityCurve; + toEdit.colorToning.opacityCurve = mods.colorToning.opacityCurve; } if (colorToning.satprotectionthreshold) { @@ -1490,7 +1498,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.autosat) { - toEdit.colorToning.autosat = mods.colorToning.autosat; + toEdit.colorToning.autosat = mods.colorToning.autosat; } if (colorToning.saturatedopacity) { @@ -1498,23 +1506,23 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.strength) { - toEdit.colorToning.strength = dontforceSet && options.baBehav[ADDSET_COLORTONING_STRENGTH] ? toEdit.colorToning.strength + mods.colorToning.strength : mods.colorToning.strength; + toEdit.colorToning.strength = dontforceSet && options.baBehav[ADDSET_COLORTONING_STRENGTH] ? toEdit.colorToning.strength + mods.colorToning.strength : mods.colorToning.strength; } if (colorToning.shadowsColSat) { - toEdit.colorToning.shadowsColSat = mods.colorToning.shadowsColSat; + toEdit.colorToning.shadowsColSat = mods.colorToning.shadowsColSat; } if (colorToning.hlColSat) { - toEdit.colorToning.hlColSat = mods.colorToning.hlColSat; + toEdit.colorToning.hlColSat = mods.colorToning.hlColSat; } if (colorToning.balance) { - toEdit.colorToning.balance = dontforceSet && options.baBehav[ADDSET_COLORTONING_BALANCE] ? toEdit.colorToning.balance + mods.colorToning.balance : mods.colorToning.balance; + toEdit.colorToning.balance = dontforceSet && options.baBehav[ADDSET_COLORTONING_BALANCE] ? toEdit.colorToning.balance + mods.colorToning.balance : mods.colorToning.balance; } if (colorToning.clcurve) { - toEdit.colorToning.clcurve = mods.colorToning.clcurve; + toEdit.colorToning.clcurve = mods.colorToning.clcurve; } if (colorToning.method) { @@ -1522,11 +1530,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.cl2curve) { - toEdit.colorToning.cl2curve = mods.colorToning.cl2curve; + toEdit.colorToning.cl2curve = mods.colorToning.cl2curve; } if (colorToning.lumamode) { - toEdit.colorToning.lumamode = mods.colorToning.lumamode; + toEdit.colorToning.lumamode = mods.colorToning.lumamode; } if (colorToning.satlow) { @@ -1534,7 +1542,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.sathigh) { - toEdit.colorToning.sathigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.sathigh + mods.colorToning.sathigh : mods.colorToning.sathigh; + toEdit.colorToning.sathigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.sathigh + mods.colorToning.sathigh : mods.colorToning.sathigh; } if (colorToning.redlow) { @@ -1542,11 +1550,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.greenlow) { - toEdit.colorToning.greenlow = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.greenlow + mods.colorToning.greenlow : mods.colorToning.greenlow; + toEdit.colorToning.greenlow = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.greenlow + mods.colorToning.greenlow : mods.colorToning.greenlow; } if (colorToning.bluelow) { - toEdit.colorToning.bluelow = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluelow + mods.colorToning.bluelow : mods.colorToning.bluelow; + toEdit.colorToning.bluelow = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluelow + mods.colorToning.bluelow : mods.colorToning.bluelow; } if (colorToning.redmed) { @@ -1554,15 +1562,15 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.greenmed) { - toEdit.colorToning.greenmed = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.greenmed + mods.colorToning.greenmed : mods.colorToning.greenmed; + toEdit.colorToning.greenmed = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.greenmed + mods.colorToning.greenmed : mods.colorToning.greenmed; } if (colorToning.bluemed) { - toEdit.colorToning.bluemed = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluemed + mods.colorToning.bluemed : mods.colorToning.bluemed; + toEdit.colorToning.bluemed = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluemed + mods.colorToning.bluemed : mods.colorToning.bluemed; } if (colorToning.redhigh) { - toEdit.colorToning.redhigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.redhigh + mods.colorToning.redhigh : mods.colorToning.redhigh; + toEdit.colorToning.redhigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.redhigh + mods.colorToning.redhigh : mods.colorToning.redhigh; } if (colorToning.greenhigh) { @@ -1570,7 +1578,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorToning.bluehigh) { - toEdit.colorToning.bluehigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluehigh + mods.colorToning.bluehigh : mods.colorToning.bluehigh; + toEdit.colorToning.bluehigh = dontforceSet && options.baBehav[ADDSET_COLORTONING_SPLIT] ? toEdit.colorToning.bluehigh + mods.colorToning.bluehigh : mods.colorToning.bluehigh; } if (colorToning.labgridALow) { @@ -1598,7 +1606,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (sharpenEdge.enabled) { - toEdit.sharpenEdge.enabled = mods.sharpenEdge.enabled; + toEdit.sharpenEdge.enabled = mods.sharpenEdge.enabled; } if (sharpenEdge.passes) { @@ -1610,47 +1618,47 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (sharpenEdge.threechannels) { - toEdit.sharpenEdge.threechannels = mods.sharpenEdge.threechannels; + toEdit.sharpenEdge.threechannels = mods.sharpenEdge.threechannels; } if (sharpenMicro.enabled) { - toEdit.sharpenMicro.enabled = mods.sharpenMicro.enabled; + toEdit.sharpenMicro.enabled = mods.sharpenMicro.enabled; } if (sharpenMicro.matrix) { - toEdit.sharpenMicro.matrix = mods.sharpenMicro.matrix; + toEdit.sharpenMicro.matrix = mods.sharpenMicro.matrix; } if (sharpenMicro.amount) { - toEdit.sharpenMicro.amount = dontforceSet && options.baBehav[ADDSET_SHARPENMICRO_AMOUNT] ? toEdit.sharpenMicro.amount + mods.sharpenMicro.amount : mods.sharpenMicro.amount; + toEdit.sharpenMicro.amount = dontforceSet && options.baBehav[ADDSET_SHARPENMICRO_AMOUNT] ? toEdit.sharpenMicro.amount + mods.sharpenMicro.amount : mods.sharpenMicro.amount; } if (sharpenMicro.contrast) { - toEdit.sharpenMicro.contrast = dontforceSet && options.baBehav[ADDSET_SHARPENMICRO_CONTRAST] ? toEdit.sharpenMicro.contrast + mods.sharpenMicro.contrast : mods.sharpenMicro.contrast; + toEdit.sharpenMicro.contrast = dontforceSet && options.baBehav[ADDSET_SHARPENMICRO_CONTRAST] ? toEdit.sharpenMicro.contrast + mods.sharpenMicro.contrast : mods.sharpenMicro.contrast; } if (sharpenMicro.uniformity) { - toEdit.sharpenMicro.uniformity = dontforceSet && options.baBehav[ADDSET_SHARPENMICRO_UNIFORMITY] ? toEdit.sharpenMicro.uniformity + mods.sharpenMicro.uniformity : mods.sharpenMicro.uniformity; + toEdit.sharpenMicro.uniformity = dontforceSet && options.baBehav[ADDSET_SHARPENMICRO_UNIFORMITY] ? toEdit.sharpenMicro.uniformity + mods.sharpenMicro.uniformity : mods.sharpenMicro.uniformity; } if (sharpening.enabled) { - toEdit.sharpening.enabled = mods.sharpening.enabled; + toEdit.sharpening.enabled = mods.sharpening.enabled; } if (sharpening.contrast) { - toEdit.sharpening.contrast = dontforceSet && options.baBehav[ADDSET_SHARP_CONTRAST] ? toEdit.sharpening.contrast + mods.sharpening.contrast : mods.sharpening.contrast; + toEdit.sharpening.contrast = dontforceSet && options.baBehav[ADDSET_SHARP_CONTRAST] ? toEdit.sharpening.contrast + mods.sharpening.contrast : mods.sharpening.contrast; } if (sharpening.radius) { - toEdit.sharpening.radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.radius + mods.sharpening.radius : mods.sharpening.radius; + toEdit.sharpening.radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.radius + mods.sharpening.radius : mods.sharpening.radius; } if (sharpening.blurradius) { - toEdit.sharpening.blurradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.blurradius + mods.sharpening.blurradius : mods.sharpening.blurradius; + toEdit.sharpening.blurradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.blurradius + mods.sharpening.blurradius : mods.sharpening.blurradius; } if (sharpening.amount) { - toEdit.sharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.amount + mods.sharpening.amount : mods.sharpening.amount; + toEdit.sharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.amount + mods.sharpening.amount : mods.sharpening.amount; } if (sharpening.threshold) { @@ -1658,7 +1666,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (sharpening.edgesonly) { - toEdit.sharpening.edgesonly = mods.sharpening.edgesonly; + toEdit.sharpening.edgesonly = mods.sharpening.edgesonly; } if (sharpening.edges_radius) { @@ -1678,19 +1686,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (sharpening.method) { - toEdit.sharpening.method = mods.sharpening.method; + toEdit.sharpening.method = mods.sharpening.method; } if (sharpening.deconvamount) { - toEdit.sharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.deconvamount + mods.sharpening.deconvamount : mods.sharpening.deconvamount; + toEdit.sharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.deconvamount + mods.sharpening.deconvamount : mods.sharpening.deconvamount; } if (sharpening.deconvradius) { - toEdit.sharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.deconvradius + mods.sharpening.deconvradius : mods.sharpening.deconvradius; + toEdit.sharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.deconvradius + mods.sharpening.deconvradius : mods.sharpening.deconvradius; } if (sharpening.deconviter) { - toEdit.sharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.sharpening.deconviter + mods.sharpening.deconviter : mods.sharpening.deconviter; + toEdit.sharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.sharpening.deconviter + mods.sharpening.deconviter : mods.sharpening.deconviter; } if (sharpening.deconvdamping) { @@ -1698,19 +1706,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (prsharpening.enabled) { - toEdit.prsharpening.enabled = mods.prsharpening.enabled; + toEdit.prsharpening.enabled = mods.prsharpening.enabled; } if (prsharpening.contrast) { - toEdit.prsharpening.contrast = dontforceSet && options.baBehav[ADDSET_SHARP_CONTRAST] ? toEdit.prsharpening.contrast + mods.prsharpening.contrast : mods.prsharpening.contrast; + toEdit.prsharpening.contrast = dontforceSet && options.baBehav[ADDSET_SHARP_CONTRAST] ? toEdit.prsharpening.contrast + mods.prsharpening.contrast : mods.prsharpening.contrast; } if (prsharpening.radius) { - toEdit.prsharpening.radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.radius + mods.prsharpening.radius : mods.prsharpening.radius; + toEdit.prsharpening.radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.radius + mods.prsharpening.radius : mods.prsharpening.radius; } if (prsharpening.amount) { - toEdit.prsharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.prsharpening.amount + mods.prsharpening.amount : mods.prsharpening.amount; + toEdit.prsharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.prsharpening.amount + mods.prsharpening.amount : mods.prsharpening.amount; } if (prsharpening.threshold) { @@ -1718,11 +1726,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (prsharpening.edgesonly) { - toEdit.prsharpening.edgesonly = mods.prsharpening.edgesonly; + toEdit.prsharpening.edgesonly = mods.prsharpening.edgesonly; } if (prsharpening.edges_radius) { - toEdit.prsharpening.edges_radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.edges_radius + mods.prsharpening.edges_radius : mods.prsharpening.edges_radius; + toEdit.prsharpening.edges_radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.edges_radius + mods.prsharpening.edges_radius : mods.prsharpening.edges_radius; } if (prsharpening.edges_tolerance) { @@ -1730,7 +1738,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (prsharpening.halocontrol) { - toEdit.prsharpening.halocontrol = mods.prsharpening.halocontrol; + toEdit.prsharpening.halocontrol = mods.prsharpening.halocontrol; } if (prsharpening.halocontrol_amount) { @@ -1738,19 +1746,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (prsharpening.method) { - toEdit.prsharpening.method = mods.prsharpening.method; + toEdit.prsharpening.method = mods.prsharpening.method; } if (prsharpening.deconvamount) { - toEdit.prsharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.prsharpening.deconvamount + mods.prsharpening.deconvamount : mods.prsharpening.deconvamount; + toEdit.prsharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.prsharpening.deconvamount + mods.prsharpening.deconvamount : mods.prsharpening.deconvamount; } if (prsharpening.deconvradius) { - toEdit.prsharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.deconvradius + mods.prsharpening.deconvradius : mods.prsharpening.deconvradius; + toEdit.prsharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.prsharpening.deconvradius + mods.prsharpening.deconvradius : mods.prsharpening.deconvradius; } if (prsharpening.deconviter) { - toEdit.prsharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.prsharpening.deconviter + mods.prsharpening.deconviter : mods.prsharpening.deconviter; + toEdit.prsharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.prsharpening.deconviter + mods.prsharpening.deconviter : mods.prsharpening.deconviter; } if (prsharpening.deconvdamping) { @@ -1758,79 +1766,79 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (vibrance.enabled) { - toEdit.vibrance.enabled = mods.vibrance.enabled; + toEdit.vibrance.enabled = mods.vibrance.enabled; } if (vibrance.pastels) { - toEdit.vibrance.pastels = dontforceSet && options.baBehav[ADDSET_VIBRANCE_PASTELS] ? toEdit.vibrance.pastels + mods.vibrance.pastels : mods.vibrance.pastels; + toEdit.vibrance.pastels = dontforceSet && options.baBehav[ADDSET_VIBRANCE_PASTELS] ? toEdit.vibrance.pastels + mods.vibrance.pastels : mods.vibrance.pastels; } if (vibrance.saturated) { - toEdit.vibrance.saturated = dontforceSet && options.baBehav[ADDSET_VIBRANCE_SATURATED] ? toEdit.vibrance.saturated + mods.vibrance.saturated : mods.vibrance.saturated; + toEdit.vibrance.saturated = dontforceSet && options.baBehav[ADDSET_VIBRANCE_SATURATED] ? toEdit.vibrance.saturated + mods.vibrance.saturated : mods.vibrance.saturated; } if (vibrance.psthreshold) { - toEdit.vibrance.psthreshold = mods.vibrance.psthreshold; + toEdit.vibrance.psthreshold = mods.vibrance.psthreshold; } if (vibrance.protectskins) { - toEdit.vibrance.protectskins = mods.vibrance.protectskins; + toEdit.vibrance.protectskins = mods.vibrance.protectskins; } if (vibrance.avoidcolorshift) { - toEdit.vibrance.avoidcolorshift = mods.vibrance.avoidcolorshift; + toEdit.vibrance.avoidcolorshift = mods.vibrance.avoidcolorshift; } if (vibrance.pastsattog) { - toEdit.vibrance.pastsattog = mods.vibrance.pastsattog; + toEdit.vibrance.pastsattog = mods.vibrance.pastsattog; } if (vibrance.skintonescurve) { - toEdit.vibrance.skintonescurve = mods.vibrance.skintonescurve; + toEdit.vibrance.skintonescurve = mods.vibrance.skintonescurve; } - //if (colorBoost.amount) toEdit.colorBoost.amount = dontforceSet && options.baBehav[ADDSET_CBOOST_AMOUNT] ? toEdit.colorBoost.amount + mods.colorBoost.amount : mods.colorBoost.amount; - //if (colorBoost.avoidclip) toEdit.colorBoost.avoidclip = mods.colorBoost.avoidclip; - //if (colorBoost.enable_saturationlimiter)toEdit.colorBoost.enable_saturationlimiter = mods.colorBoost.enable_saturationlimiter; - //if (colorBoost.saturationlimit) toEdit.colorBoost.saturationlimit = mods.colorBoost.saturationlimit; + //if (colorBoost.amount) toEdit.colorBoost.amount = dontforceSet && options.baBehav[ADDSET_CBOOST_AMOUNT] ? toEdit.colorBoost.amount + mods.colorBoost.amount : mods.colorBoost.amount; + //if (colorBoost.avoidclip) toEdit.colorBoost.avoidclip = mods.colorBoost.avoidclip; + //if (colorBoost.enable_saturationlimiter)toEdit.colorBoost.enable_saturationlimiter = mods.colorBoost.enable_saturationlimiter; + //if (colorBoost.saturationlimit) toEdit.colorBoost.saturationlimit = mods.colorBoost.saturationlimit; if (wb.enabled) { toEdit.wb.enabled = mods.wb.enabled; } if (wb.method) { - toEdit.wb.method = mods.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; + toEdit.wb.equal = dontforceSet && options.baBehav[ADDSET_WB_EQUAL] ? toEdit.wb.equal + mods.wb.equal : mods.wb.equal; } if (wb.tempBias) { - toEdit.wb.tempBias = dontforceSet && options.baBehav[ADDSET_WB_TEMPBIAS] ? toEdit.wb.tempBias + mods.wb.tempBias : mods.wb.tempBias; + toEdit.wb.tempBias = dontforceSet && options.baBehav[ADDSET_WB_TEMPBIAS] ? toEdit.wb.tempBias + mods.wb.tempBias : mods.wb.tempBias; } if (wb.green) { - toEdit.wb.green = dontforceSet && options.baBehav[ADDSET_WB_GREEN] ? toEdit.wb.green + mods.wb.green : mods.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; + 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; - //if (colorShift.b) toEdit.colorShift.b = dontforceSet && options.baBehav[ADDSET_CS_GREENMAGENTA] ? toEdit.colorShift.b + mods.colorShift.b : mods.colorShift.b; - //if (lumaDenoise.enabled) toEdit.lumaDenoise.enabled = mods.lumaDenoise.enabled; - //if (lumaDenoise.radius) toEdit.lumaDenoise.radius = mods.lumaDenoise.radius; - //if (lumaDenoise.edgetolerance) toEdit.lumaDenoise.edgetolerance = dontforceSet && options.baBehav[ADDSET_LD_EDGETOLERANCE] ? toEdit.lumaDenoise.edgetolerance + mods.lumaDenoise.edgetolerance : mods.lumaDenoise.edgetolerance; - //if (colorDenoise.enabled) toEdit.colorDenoise.enabled = mods.colorDenoise.enabled; - //if (colorDenoise.amount) toEdit.colorDenoise.amount = mods.colorDenoise.amount; + //if (colorShift.a) toEdit.colorShift.a = dontforceSet && options.baBehav[ADDSET_CS_BLUEYELLOW] ? toEdit.colorShift.a + mods.colorShift.a : mods.colorShift.a; + //if (colorShift.b) toEdit.colorShift.b = dontforceSet && options.baBehav[ADDSET_CS_GREENMAGENTA] ? toEdit.colorShift.b + mods.colorShift.b : mods.colorShift.b; + //if (lumaDenoise.enabled) toEdit.lumaDenoise.enabled = mods.lumaDenoise.enabled; + //if (lumaDenoise.radius) toEdit.lumaDenoise.radius = mods.lumaDenoise.radius; + //if (lumaDenoise.edgetolerance) toEdit.lumaDenoise.edgetolerance = dontforceSet && options.baBehav[ADDSET_LD_EDGETOLERANCE] ? toEdit.lumaDenoise.edgetolerance + mods.lumaDenoise.edgetolerance : mods.lumaDenoise.edgetolerance; + //if (colorDenoise.enabled) toEdit.colorDenoise.enabled = mods.colorDenoise.enabled; + //if (colorDenoise.amount) toEdit.colorDenoise.amount = mods.colorDenoise.amount; if (defringe.enabled) { - toEdit.defringe.enabled = mods.defringe.enabled; + toEdit.defringe.enabled = mods.defringe.enabled; } if (defringe.radius) { - toEdit.defringe.radius = mods.defringe.radius; + toEdit.defringe.radius = mods.defringe.radius; } if (defringe.threshold) { @@ -1838,23 +1846,23 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (defringe.huecurve) { - toEdit.defringe.huecurve = mods.defringe.huecurve; + toEdit.defringe.huecurve = mods.defringe.huecurve; } if (colorappearance.curve) { - toEdit.colorappearance.curve = mods.colorappearance.curve; + toEdit.colorappearance.curve = mods.colorappearance.curve; } if (colorappearance.curve2) { - toEdit.colorappearance.curve2 = mods.colorappearance.curve2; + toEdit.colorappearance.curve2 = mods.colorappearance.curve2; } if (colorappearance.curve3) { - toEdit.colorappearance.curve3 = mods.colorappearance.curve3; + toEdit.colorappearance.curve3 = mods.colorappearance.curve3; } if (colorappearance.curveMode) { - toEdit.colorappearance.curveMode = mods.colorappearance.curveMode; + toEdit.colorappearance.curveMode = mods.colorappearance.curveMode; } if (colorappearance.curveMode2) { @@ -1866,11 +1874,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorappearance.enabled) { - toEdit.colorappearance.enabled = mods.colorappearance.enabled; + toEdit.colorappearance.enabled = mods.colorappearance.enabled; } if (colorappearance.degree) { - toEdit.colorappearance.degree = dontforceSet && options.baBehav[ADDSET_CAT_DEGREE] ? toEdit.colorappearance.degree + mods.colorappearance.degree : mods.colorappearance.degree; + toEdit.colorappearance.degree = dontforceSet && options.baBehav[ADDSET_CAT_DEGREE] ? toEdit.colorappearance.degree + mods.colorappearance.degree : mods.colorappearance.degree; } if (colorappearance.autodegree) { @@ -1878,7 +1886,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorappearance.degreeout) { - toEdit.colorappearance.degreeout = mods.colorappearance.degreeout; + toEdit.colorappearance.degreeout = mods.colorappearance.degreeout; } if (colorappearance.autodegreeout) { @@ -1886,95 +1894,95 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (colorappearance.surround) { - toEdit.colorappearance.surround = mods.colorappearance.surround; + toEdit.colorappearance.surround = mods.colorappearance.surround; } if (colorappearance.surrsrc) { - toEdit.colorappearance.surrsrc = mods.colorappearance.surrsrc; + toEdit.colorappearance.surrsrc = mods.colorappearance.surrsrc; } if (colorappearance.autoadapscen) { - toEdit.colorappearance.autoadapscen = mods.colorappearance.autoadapscen; + toEdit.colorappearance.autoadapscen = mods.colorappearance.autoadapscen; } if (colorappearance.adapscen) { - toEdit.colorappearance.adapscen = dontforceSet && options.baBehav[ADDSET_CAT_ADAPTSCENE] ? toEdit.colorappearance.adapscen + mods.colorappearance.adapscen : mods.colorappearance.adapscen; + toEdit.colorappearance.adapscen = dontforceSet && options.baBehav[ADDSET_CAT_ADAPTSCENE] ? toEdit.colorappearance.adapscen + mods.colorappearance.adapscen : mods.colorappearance.adapscen; } if (colorappearance.autoybscen) { - toEdit.colorappearance.autoybscen = mods.colorappearance.autoybscen; + toEdit.colorappearance.autoybscen = mods.colorappearance.autoybscen; } if (colorappearance.ybscen) { - toEdit.colorappearance.ybscen = mods.colorappearance.ybscen; + toEdit.colorappearance.ybscen = mods.colorappearance.ybscen; } if (colorappearance.adaplum) { - toEdit.colorappearance.adaplum = dontforceSet && options.baBehav[ADDSET_CAT_ADAPTVIEWING] ? toEdit.colorappearance.adaplum + mods.colorappearance.adaplum : mods.colorappearance.adaplum; + toEdit.colorappearance.adaplum = dontforceSet && options.baBehav[ADDSET_CAT_ADAPTVIEWING] ? toEdit.colorappearance.adaplum + mods.colorappearance.adaplum : mods.colorappearance.adaplum; } if (colorappearance.badpixsl) { - toEdit.colorappearance.badpixsl = dontforceSet && options.baBehav[ADDSET_CAT_BADPIX] ? toEdit.colorappearance.badpixsl + mods.colorappearance.badpixsl : mods.colorappearance.badpixsl; + toEdit.colorappearance.badpixsl = dontforceSet && options.baBehav[ADDSET_CAT_BADPIX] ? toEdit.colorappearance.badpixsl + mods.colorappearance.badpixsl : mods.colorappearance.badpixsl; } if (colorappearance.wbmodel) { - toEdit.colorappearance.wbmodel = mods.colorappearance.wbmodel; + toEdit.colorappearance.wbmodel = mods.colorappearance.wbmodel; } if (colorappearance.algo) { - toEdit.colorappearance.algo = mods.colorappearance.algo; + toEdit.colorappearance.algo = mods.colorappearance.algo; } if (colorappearance.tempout) { - toEdit.colorappearance.tempout = mods.colorappearance.tempout; + toEdit.colorappearance.tempout = mods.colorappearance.tempout; } if (colorappearance.greenout) { - toEdit.colorappearance.greenout = mods.colorappearance.greenout; + toEdit.colorappearance.greenout = mods.colorappearance.greenout; } if (colorappearance.tempsc) { - toEdit.colorappearance.tempsc = mods.colorappearance.tempsc; + toEdit.colorappearance.tempsc = mods.colorappearance.tempsc; } if (colorappearance.greensc) { - toEdit.colorappearance.greensc = mods.colorappearance.greensc; + toEdit.colorappearance.greensc = mods.colorappearance.greensc; } if (colorappearance.ybout) { - toEdit.colorappearance.ybout = mods.colorappearance.ybout; + toEdit.colorappearance.ybout = mods.colorappearance.ybout; } if (colorappearance.jlight) { - toEdit.colorappearance.jlight = dontforceSet && options.baBehav[ADDSET_CAT_LIGHT] ? toEdit.colorappearance.jlight + mods.colorappearance.jlight : mods.colorappearance.jlight; + toEdit.colorappearance.jlight = dontforceSet && options.baBehav[ADDSET_CAT_LIGHT] ? toEdit.colorappearance.jlight + mods.colorappearance.jlight : mods.colorappearance.jlight; } if (colorappearance.qbright) { - toEdit.colorappearance.qbright = dontforceSet && options.baBehav[ADDSET_CAT_BRIGHT] ? toEdit.colorappearance.qbright + mods.colorappearance.qbright : mods.colorappearance.qbright; + toEdit.colorappearance.qbright = dontforceSet && options.baBehav[ADDSET_CAT_BRIGHT] ? toEdit.colorappearance.qbright + mods.colorappearance.qbright : mods.colorappearance.qbright; } if (colorappearance.chroma) { - toEdit.colorappearance.chroma = dontforceSet && options.baBehav[ADDSET_CAT_CHROMA] ? toEdit.colorappearance.chroma + mods.colorappearance.chroma : mods.colorappearance.chroma; + toEdit.colorappearance.chroma = dontforceSet && options.baBehav[ADDSET_CAT_CHROMA] ? toEdit.colorappearance.chroma + mods.colorappearance.chroma : mods.colorappearance.chroma; } if (colorappearance.schroma) { - toEdit.colorappearance.schroma = dontforceSet && options.baBehav[ADDSET_CAT_CHROMA_S] ? toEdit.colorappearance.schroma + mods.colorappearance.schroma : mods.colorappearance.schroma; + toEdit.colorappearance.schroma = dontforceSet && options.baBehav[ADDSET_CAT_CHROMA_S] ? toEdit.colorappearance.schroma + mods.colorappearance.schroma : mods.colorappearance.schroma; } if (colorappearance.mchroma) { - toEdit.colorappearance.mchroma = dontforceSet && options.baBehav[ADDSET_CAT_CHROMA_M] ? toEdit.colorappearance.mchroma + mods.colorappearance.mchroma : mods.colorappearance.mchroma; + toEdit.colorappearance.mchroma = dontforceSet && options.baBehav[ADDSET_CAT_CHROMA_M] ? toEdit.colorappearance.mchroma + mods.colorappearance.mchroma : mods.colorappearance.mchroma; } if (colorappearance.contrast) { - toEdit.colorappearance.contrast = dontforceSet && options.baBehav[ADDSET_CAT_CONTRAST] ? toEdit.colorappearance.contrast + mods.colorappearance.contrast : mods.colorappearance.contrast; + toEdit.colorappearance.contrast = dontforceSet && options.baBehav[ADDSET_CAT_CONTRAST] ? toEdit.colorappearance.contrast + mods.colorappearance.contrast : mods.colorappearance.contrast; } if (colorappearance.qcontrast) { - toEdit.colorappearance.qcontrast = dontforceSet && options.baBehav[ADDSET_CAT_CONTRAST_Q] ? toEdit.colorappearance.qcontrast + mods.colorappearance.qcontrast : mods.colorappearance.qcontrast; + toEdit.colorappearance.qcontrast = dontforceSet && options.baBehav[ADDSET_CAT_CONTRAST_Q] ? toEdit.colorappearance.qcontrast + mods.colorappearance.qcontrast : mods.colorappearance.qcontrast; } if (colorappearance.colorh) { - toEdit.colorappearance.colorh = dontforceSet && options.baBehav[ADDSET_CAT_HUE] ? toEdit.colorappearance.colorh + mods.colorappearance.colorh : mods.colorappearance.colorh; + toEdit.colorappearance.colorh = dontforceSet && options.baBehav[ADDSET_CAT_HUE] ? toEdit.colorappearance.colorh + mods.colorappearance.colorh : mods.colorappearance.colorh; } if (colorappearance.rstprotection) { @@ -2000,47 +2008,47 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng // if (colorappearance.sharpcie) toEdit.colorappearance.sharpcie = mods.colorappearance.sharpcie; if (impulseDenoise.enabled) { - toEdit.impulseDenoise.enabled = mods.impulseDenoise.enabled; + toEdit.impulseDenoise.enabled = mods.impulseDenoise.enabled; } if (impulseDenoise.thresh) { - toEdit.impulseDenoise.thresh = mods.impulseDenoise.thresh; + toEdit.impulseDenoise.thresh = mods.impulseDenoise.thresh; } if (dirpyrDenoise.enabled) { - toEdit.dirpyrDenoise.enabled = mods.dirpyrDenoise.enabled; + toEdit.dirpyrDenoise.enabled = mods.dirpyrDenoise.enabled; } if (dirpyrDenoise.enhance) { - toEdit.dirpyrDenoise.enhance = mods.dirpyrDenoise.enhance; + toEdit.dirpyrDenoise.enhance = mods.dirpyrDenoise.enhance; } if (dirpyrDenoise.median) { - toEdit.dirpyrDenoise.median = mods.dirpyrDenoise.median; + toEdit.dirpyrDenoise.median = mods.dirpyrDenoise.median; } if (dirpyrDenoise.luma) { - toEdit.dirpyrDenoise.luma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_LUMA] ? toEdit.dirpyrDenoise.luma + mods.dirpyrDenoise.luma : mods.dirpyrDenoise.luma; + toEdit.dirpyrDenoise.luma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_LUMA] ? toEdit.dirpyrDenoise.luma + mods.dirpyrDenoise.luma : mods.dirpyrDenoise.luma; } if (dirpyrDenoise.lcurve) { - toEdit.dirpyrDenoise.lcurve = mods.dirpyrDenoise.lcurve; + toEdit.dirpyrDenoise.lcurve = mods.dirpyrDenoise.lcurve; } if (dirpyrDenoise.cccurve) { - toEdit.dirpyrDenoise.cccurve = mods.dirpyrDenoise.cccurve; + toEdit.dirpyrDenoise.cccurve = mods.dirpyrDenoise.cccurve; } if (dirpyrDenoise.Ldetail) { - toEdit.dirpyrDenoise.Ldetail = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_LUMDET] ? toEdit.dirpyrDenoise.Ldetail + mods.dirpyrDenoise.Ldetail : mods.dirpyrDenoise.Ldetail; + toEdit.dirpyrDenoise.Ldetail = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_LUMDET] ? toEdit.dirpyrDenoise.Ldetail + mods.dirpyrDenoise.Ldetail : mods.dirpyrDenoise.Ldetail; } if (dirpyrDenoise.chroma) { - toEdit.dirpyrDenoise.chroma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMA] ? toEdit.dirpyrDenoise.chroma + mods.dirpyrDenoise.chroma : mods.dirpyrDenoise.chroma; + toEdit.dirpyrDenoise.chroma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMA] ? toEdit.dirpyrDenoise.chroma + mods.dirpyrDenoise.chroma : mods.dirpyrDenoise.chroma; } if (dirpyrDenoise.redchro) { - toEdit.dirpyrDenoise.redchro = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMARED] ? toEdit.dirpyrDenoise.redchro + mods.dirpyrDenoise.redchro : mods.dirpyrDenoise.redchro; + toEdit.dirpyrDenoise.redchro = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMARED] ? toEdit.dirpyrDenoise.redchro + mods.dirpyrDenoise.redchro : mods.dirpyrDenoise.redchro; } if (dirpyrDenoise.bluechro) { @@ -2048,68 +2056,68 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (dirpyrDenoise.gamma) { - toEdit.dirpyrDenoise.gamma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_GAMMA] ? toEdit.dirpyrDenoise.gamma + mods.dirpyrDenoise.gamma : mods.dirpyrDenoise.gamma; + toEdit.dirpyrDenoise.gamma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_GAMMA] ? toEdit.dirpyrDenoise.gamma + mods.dirpyrDenoise.gamma : mods.dirpyrDenoise.gamma; } if (dirpyrDenoise.passes) { - toEdit.dirpyrDenoise.passes = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_PASSES] ? toEdit.dirpyrDenoise.passes + mods.dirpyrDenoise.passes : mods.dirpyrDenoise.passes; + toEdit.dirpyrDenoise.passes = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_PASSES] ? toEdit.dirpyrDenoise.passes + mods.dirpyrDenoise.passes : mods.dirpyrDenoise.passes; } -// if (dirpyrDenoise.perform) toEdit.dirpyrDenoise.perform = mods.dirpyrDenoise.perform; +// if (dirpyrDenoise.perform) toEdit.dirpyrDenoise.perform = mods.dirpyrDenoise.perform; if (dirpyrDenoise.dmethod) { - toEdit.dirpyrDenoise.dmethod = mods.dirpyrDenoise.dmethod; + toEdit.dirpyrDenoise.dmethod = mods.dirpyrDenoise.dmethod; } if (dirpyrDenoise.Lmethod) { - toEdit.dirpyrDenoise.Lmethod = mods.dirpyrDenoise.Lmethod; + toEdit.dirpyrDenoise.Lmethod = mods.dirpyrDenoise.Lmethod; } if (dirpyrDenoise.Cmethod) { - toEdit.dirpyrDenoise.Cmethod = mods.dirpyrDenoise.Cmethod; + toEdit.dirpyrDenoise.Cmethod = mods.dirpyrDenoise.Cmethod; } if (dirpyrDenoise.C2method) { - toEdit.dirpyrDenoise.C2method = mods.dirpyrDenoise.C2method; + toEdit.dirpyrDenoise.C2method = mods.dirpyrDenoise.C2method; } if (dirpyrDenoise.smethod) { - toEdit.dirpyrDenoise.smethod = mods.dirpyrDenoise.smethod; + toEdit.dirpyrDenoise.smethod = mods.dirpyrDenoise.smethod; } if (dirpyrDenoise.medmethod) { - toEdit.dirpyrDenoise.medmethod = mods.dirpyrDenoise.medmethod; + toEdit.dirpyrDenoise.medmethod = mods.dirpyrDenoise.medmethod; } if (dirpyrDenoise.methodmed) { - toEdit.dirpyrDenoise.methodmed = mods.dirpyrDenoise.methodmed; + toEdit.dirpyrDenoise.methodmed = mods.dirpyrDenoise.methodmed; } if (dirpyrDenoise.rgbmethod) { - toEdit.dirpyrDenoise.rgbmethod = mods.dirpyrDenoise.rgbmethod; + toEdit.dirpyrDenoise.rgbmethod = mods.dirpyrDenoise.rgbmethod; } if (epd.enabled) { - toEdit.epd.enabled = mods.epd.enabled; + toEdit.epd.enabled = mods.epd.enabled; } if (epd.strength) { - toEdit.epd.strength = mods.epd.strength; + toEdit.epd.strength = mods.epd.strength; } if (epd.gamma) { - toEdit.epd.gamma = mods.epd.gamma; + toEdit.epd.gamma = mods.epd.gamma; } if (epd.edgeStopping) { - toEdit.epd.edgeStopping = mods.epd.edgeStopping; + toEdit.epd.edgeStopping = mods.epd.edgeStopping; } if (epd.scale) { - toEdit.epd.scale = mods.epd.scale; + toEdit.epd.scale = mods.epd.scale; } if (epd.reweightingIterates) { - toEdit.epd.reweightingIterates = mods.epd.reweightingIterates; + toEdit.epd.reweightingIterates = mods.epd.reweightingIterates; } if (fattal.enabled) { @@ -2129,31 +2137,31 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (sh.enabled) { - toEdit.sh.enabled = mods.sh.enabled; + toEdit.sh.enabled = mods.sh.enabled; } if (sh.highlights) { - toEdit.sh.highlights = dontforceSet && options.baBehav[ADDSET_SH_HIGHLIGHTS] ? toEdit.sh.highlights + mods.sh.highlights : mods.sh.highlights; + toEdit.sh.highlights = dontforceSet && options.baBehav[ADDSET_SH_HIGHLIGHTS] ? toEdit.sh.highlights + mods.sh.highlights : mods.sh.highlights; } if (sh.htonalwidth) { - toEdit.sh.htonalwidth = mods.sh.htonalwidth; + toEdit.sh.htonalwidth = mods.sh.htonalwidth; } if (sh.shadows) { - toEdit.sh.shadows = dontforceSet && options.baBehav[ADDSET_SH_SHADOWS] ? toEdit.sh.shadows + mods.sh.shadows : mods.sh.shadows; + toEdit.sh.shadows = dontforceSet && options.baBehav[ADDSET_SH_SHADOWS] ? toEdit.sh.shadows + mods.sh.shadows : mods.sh.shadows; } if (sh.stonalwidth) { - toEdit.sh.stonalwidth = mods.sh.stonalwidth; + toEdit.sh.stonalwidth = mods.sh.stonalwidth; } if (sh.radius) { - toEdit.sh.radius = mods.sh.radius; + toEdit.sh.radius = mods.sh.radius; } if (sh.lab) { - toEdit.sh.lab = mods.sh.lab; + toEdit.sh.lab = mods.sh.lab; } if (crop.enabled) { @@ -2161,27 +2169,27 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (crop.x) { - toEdit.crop.x = mods.crop.x; + toEdit.crop.x = mods.crop.x; } if (crop.y) { - toEdit.crop.y = mods.crop.y; + toEdit.crop.y = mods.crop.y; } if (crop.w) { - toEdit.crop.w = mods.crop.w; + toEdit.crop.w = mods.crop.w; } if (crop.h) { - toEdit.crop.h = mods.crop.h; + toEdit.crop.h = mods.crop.h; } if (crop.fixratio) { - toEdit.crop.fixratio = mods.crop.fixratio; + toEdit.crop.fixratio = mods.crop.fixratio; } if (crop.ratio) { - toEdit.crop.ratio = mods.crop.ratio; + toEdit.crop.ratio = mods.crop.ratio; } if (crop.orientation) { @@ -2189,51 +2197,51 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (crop.guide) { - toEdit.crop.guide = mods.crop.guide; + toEdit.crop.guide = mods.crop.guide; } if (coarse.rotate) { - toEdit.coarse.rotate = mods.coarse.rotate; + toEdit.coarse.rotate = mods.coarse.rotate; } if (coarse.hflip) { - toEdit.coarse.hflip = mods.coarse.hflip; + toEdit.coarse.hflip = mods.coarse.hflip; } if (coarse.vflip) { - toEdit.coarse.vflip = mods.coarse.vflip; + toEdit.coarse.vflip = mods.coarse.vflip; } if (commonTrans.autofill) { - toEdit.commonTrans.autofill = mods.commonTrans.autofill; + toEdit.commonTrans.autofill = mods.commonTrans.autofill; } if (rotate.degree) { - toEdit.rotate.degree = dontforceSet && options.baBehav[ADDSET_ROTATE_DEGREE] ? toEdit.rotate.degree + mods.rotate.degree : mods.rotate.degree; + toEdit.rotate.degree = dontforceSet && options.baBehav[ADDSET_ROTATE_DEGREE] ? toEdit.rotate.degree + mods.rotate.degree : mods.rotate.degree; } if (distortion.amount) { - toEdit.distortion.amount = dontforceSet && options.baBehav[ADDSET_DIST_AMOUNT] ? toEdit.distortion.amount + mods.distortion.amount : mods.distortion.amount; + toEdit.distortion.amount = dontforceSet && options.baBehav[ADDSET_DIST_AMOUNT] ? toEdit.distortion.amount + mods.distortion.amount : mods.distortion.amount; } if (lensProf.lcMode) { - toEdit.lensProf.lcMode = mods.lensProf.lcMode; + toEdit.lensProf.lcMode = mods.lensProf.lcMode; } if (lensProf.lcpFile) { - toEdit.lensProf.lcpFile = mods.lensProf.lcpFile; + toEdit.lensProf.lcpFile = mods.lensProf.lcpFile; } if (lensProf.useDist) { - toEdit.lensProf.useDist = mods.lensProf.useDist; + toEdit.lensProf.useDist = mods.lensProf.useDist; } if (lensProf.useVign) { - toEdit.lensProf.useVign = mods.lensProf.useVign; + toEdit.lensProf.useVign = mods.lensProf.useVign; } if (lensProf.useCA) { - toEdit.lensProf.useCA = mods.lensProf.useCA; + toEdit.lensProf.useCA = mods.lensProf.useCA; } if (lensProf.lfCameraMake) { @@ -2249,47 +2257,47 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (perspective.horizontal) { - toEdit.perspective.horizontal = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.horizontal + mods.perspective.horizontal : mods.perspective.horizontal; + toEdit.perspective.horizontal = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.horizontal + mods.perspective.horizontal : mods.perspective.horizontal; } if (perspective.vertical) { - toEdit.perspective.vertical = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.vertical + mods.perspective.vertical : mods.perspective.vertical; + toEdit.perspective.vertical = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.vertical + mods.perspective.vertical : mods.perspective.vertical; } if (gradient.enabled) { - toEdit.gradient.enabled = mods.gradient.enabled; + toEdit.gradient.enabled = mods.gradient.enabled; } if (gradient.degree) { - toEdit.gradient.degree = dontforceSet && options.baBehav[ADDSET_GRADIENT_DEGREE] ? toEdit.gradient.degree + mods.gradient.degree : mods.gradient.degree; + toEdit.gradient.degree = dontforceSet && options.baBehav[ADDSET_GRADIENT_DEGREE] ? toEdit.gradient.degree + mods.gradient.degree : mods.gradient.degree; } if (gradient.feather) { - toEdit.gradient.feather = dontforceSet && options.baBehav[ADDSET_GRADIENT_FEATHER] ? toEdit.gradient.feather + mods.gradient.feather : mods.gradient.feather; + toEdit.gradient.feather = dontforceSet && options.baBehav[ADDSET_GRADIENT_FEATHER] ? toEdit.gradient.feather + mods.gradient.feather : mods.gradient.feather; } if (gradient.strength) { - toEdit.gradient.strength = dontforceSet && options.baBehav[ADDSET_GRADIENT_STRENGTH] ? toEdit.gradient.strength + mods.gradient.strength : mods.gradient.strength; + toEdit.gradient.strength = dontforceSet && options.baBehav[ADDSET_GRADIENT_STRENGTH] ? toEdit.gradient.strength + mods.gradient.strength : mods.gradient.strength; } if (gradient.centerX) { - toEdit.gradient.centerX = dontforceSet && options.baBehav[ADDSET_GRADIENT_CENTER] ? toEdit.gradient.centerX + mods.gradient.centerX : mods.gradient.centerX; + toEdit.gradient.centerX = dontforceSet && options.baBehav[ADDSET_GRADIENT_CENTER] ? toEdit.gradient.centerX + mods.gradient.centerX : mods.gradient.centerX; } if (gradient.centerY) { - toEdit.gradient.centerY = dontforceSet && options.baBehav[ADDSET_GRADIENT_CENTER] ? toEdit.gradient.centerY + mods.gradient.centerY : mods.gradient.centerY; + toEdit.gradient.centerY = dontforceSet && options.baBehav[ADDSET_GRADIENT_CENTER] ? toEdit.gradient.centerY + mods.gradient.centerY : mods.gradient.centerY; } if (pcvignette.enabled) { - toEdit.pcvignette.enabled = mods.pcvignette.enabled; + toEdit.pcvignette.enabled = mods.pcvignette.enabled; } if (pcvignette.strength) { - toEdit.pcvignette.strength = dontforceSet && options.baBehav[ADDSET_PCVIGNETTE_STRENGTH] ? toEdit.pcvignette.strength + mods.pcvignette.strength : mods.pcvignette.strength; + toEdit.pcvignette.strength = dontforceSet && options.baBehav[ADDSET_PCVIGNETTE_STRENGTH] ? toEdit.pcvignette.strength + mods.pcvignette.strength : mods.pcvignette.strength; } if (pcvignette.feather) { - toEdit.pcvignette.feather = dontforceSet && options.baBehav[ADDSET_PCVIGNETTE_FEATHER] ? toEdit.pcvignette.feather + mods.pcvignette.feather : mods.pcvignette.feather; + toEdit.pcvignette.feather = dontforceSet && options.baBehav[ADDSET_PCVIGNETTE_FEATHER] ? toEdit.pcvignette.feather + mods.pcvignette.feather : mods.pcvignette.feather; } if (pcvignette.roundness) { @@ -2297,19 +2305,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (cacorrection.red) { - toEdit.cacorrection.red = dontforceSet && options.baBehav[ADDSET_CA] ? toEdit.cacorrection.red + mods.cacorrection.red : mods.cacorrection.red; + toEdit.cacorrection.red = dontforceSet && options.baBehav[ADDSET_CA] ? toEdit.cacorrection.red + mods.cacorrection.red : mods.cacorrection.red; } if (cacorrection.blue) { - toEdit.cacorrection.blue = dontforceSet && options.baBehav[ADDSET_CA] ? toEdit.cacorrection.blue + mods.cacorrection.blue : mods.cacorrection.blue; + toEdit.cacorrection.blue = dontforceSet && options.baBehav[ADDSET_CA] ? toEdit.cacorrection.blue + mods.cacorrection.blue : mods.cacorrection.blue; } if (vignetting.amount) { - toEdit.vignetting.amount = dontforceSet && options.baBehav[ADDSET_VIGN_AMOUNT] ? toEdit.vignetting.amount + mods.vignetting.amount : mods.vignetting.amount; + toEdit.vignetting.amount = dontforceSet && options.baBehav[ADDSET_VIGN_AMOUNT] ? toEdit.vignetting.amount + mods.vignetting.amount : mods.vignetting.amount; } if (vignetting.radius) { - toEdit.vignetting.radius = dontforceSet && options.baBehav[ADDSET_VIGN_RADIUS] ? toEdit.vignetting.radius + mods.vignetting.radius : mods.vignetting.radius; + toEdit.vignetting.radius = dontforceSet && options.baBehav[ADDSET_VIGN_RADIUS] ? toEdit.vignetting.radius + mods.vignetting.radius : mods.vignetting.radius; } if (vignetting.strength) { @@ -2330,92 +2338,92 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng for (int i = 0; i < 3; i++) { if (chmixer.red[i]) { - toEdit.chmixer.red[i] = dontforceSet && options.baBehav[ADDSET_CHMIXER] ? toEdit.chmixer.red[i] + mods.chmixer.red[i] : mods.chmixer.red[i]; + toEdit.chmixer.red[i] = dontforceSet && options.baBehav[ADDSET_CHMIXER] ? toEdit.chmixer.red[i] + mods.chmixer.red[i] : mods.chmixer.red[i]; } if (chmixer.green[i]) { - toEdit.chmixer.green[i] = dontforceSet && options.baBehav[ADDSET_CHMIXER] ? toEdit.chmixer.green[i] + mods.chmixer.green[i] : mods.chmixer.green[i]; + toEdit.chmixer.green[i] = dontforceSet && options.baBehav[ADDSET_CHMIXER] ? toEdit.chmixer.green[i] + mods.chmixer.green[i] : mods.chmixer.green[i]; } if (chmixer.blue[i]) { - toEdit.chmixer.blue[i] = dontforceSet && options.baBehav[ADDSET_CHMIXER] ? toEdit.chmixer.blue[i] + mods.chmixer.blue[i] : mods.chmixer.blue[i]; + toEdit.chmixer.blue[i] = dontforceSet && options.baBehav[ADDSET_CHMIXER] ? toEdit.chmixer.blue[i] + mods.chmixer.blue[i] : mods.chmixer.blue[i]; } } if (blackwhite.enabled) { - toEdit.blackwhite.enabled = mods.blackwhite.enabled; + toEdit.blackwhite.enabled = mods.blackwhite.enabled; } if (blackwhite.method) { - toEdit.blackwhite.method = mods.blackwhite.method; + toEdit.blackwhite.method = mods.blackwhite.method; } if (blackwhite.luminanceCurve) { - toEdit.blackwhite.luminanceCurve = mods.blackwhite.luminanceCurve; + toEdit.blackwhite.luminanceCurve = mods.blackwhite.luminanceCurve; } if (blackwhite.autoc) { - toEdit.blackwhite.autoc = mods.blackwhite.autoc; + toEdit.blackwhite.autoc = mods.blackwhite.autoc; } if (blackwhite.setting) { - toEdit.blackwhite.setting = mods.blackwhite.setting; + toEdit.blackwhite.setting = mods.blackwhite.setting; } if (blackwhite.enabledcc) { - toEdit.blackwhite.enabledcc = mods.blackwhite.enabledcc; + toEdit.blackwhite.enabledcc = mods.blackwhite.enabledcc; } if (blackwhite.filter) { - toEdit.blackwhite.filter = mods.blackwhite.filter; + toEdit.blackwhite.filter = mods.blackwhite.filter; } if (blackwhite.mixerRed) { - toEdit.blackwhite.mixerRed = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerRed + mods.blackwhite.mixerRed : mods.blackwhite.mixerRed; + toEdit.blackwhite.mixerRed = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerRed + mods.blackwhite.mixerRed : mods.blackwhite.mixerRed; } if (blackwhite.mixerOrange) { - toEdit.blackwhite.mixerOrange = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerOrange + mods.blackwhite.mixerOrange : mods.blackwhite.mixerOrange; + toEdit.blackwhite.mixerOrange = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerOrange + mods.blackwhite.mixerOrange : mods.blackwhite.mixerOrange; } if (blackwhite.mixerYellow) { - toEdit.blackwhite.mixerYellow = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerYellow + mods.blackwhite.mixerYellow : mods.blackwhite.mixerYellow; + toEdit.blackwhite.mixerYellow = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerYellow + mods.blackwhite.mixerYellow : mods.blackwhite.mixerYellow; } if (blackwhite.mixerGreen) { - toEdit.blackwhite.mixerGreen = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerGreen + mods.blackwhite.mixerGreen : mods.blackwhite.mixerGreen; + toEdit.blackwhite.mixerGreen = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerGreen + mods.blackwhite.mixerGreen : mods.blackwhite.mixerGreen; } if (blackwhite.mixerCyan) { - toEdit.blackwhite.mixerCyan = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerCyan + mods.blackwhite.mixerCyan : mods.blackwhite.mixerCyan; + toEdit.blackwhite.mixerCyan = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerCyan + mods.blackwhite.mixerCyan : mods.blackwhite.mixerCyan; } if (blackwhite.mixerBlue) { - toEdit.blackwhite.mixerBlue = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerBlue + mods.blackwhite.mixerBlue : mods.blackwhite.mixerBlue; + toEdit.blackwhite.mixerBlue = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerBlue + mods.blackwhite.mixerBlue : mods.blackwhite.mixerBlue; } if (blackwhite.mixerMagenta) { - toEdit.blackwhite.mixerMagenta = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerMagenta + mods.blackwhite.mixerMagenta : mods.blackwhite.mixerMagenta; + toEdit.blackwhite.mixerMagenta = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerMagenta + mods.blackwhite.mixerMagenta : mods.blackwhite.mixerMagenta; } if (blackwhite.mixerPurple) { - toEdit.blackwhite.mixerPurple = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerPurple + mods.blackwhite.mixerPurple : mods.blackwhite.mixerPurple; + toEdit.blackwhite.mixerPurple = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_HUES] ? toEdit.blackwhite.mixerPurple + mods.blackwhite.mixerPurple : mods.blackwhite.mixerPurple; } if (blackwhite.gammaRed) { - toEdit.blackwhite.gammaRed = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_GAMMA] ? toEdit.blackwhite.gammaRed + mods.blackwhite.gammaRed : mods.blackwhite.gammaRed; + toEdit.blackwhite.gammaRed = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_GAMMA] ? toEdit.blackwhite.gammaRed + mods.blackwhite.gammaRed : mods.blackwhite.gammaRed; } if (blackwhite.gammaGreen) { - toEdit.blackwhite.gammaGreen = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_GAMMA] ? toEdit.blackwhite.gammaGreen + mods.blackwhite.gammaGreen : mods.blackwhite.gammaGreen; + toEdit.blackwhite.gammaGreen = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_GAMMA] ? toEdit.blackwhite.gammaGreen + mods.blackwhite.gammaGreen : mods.blackwhite.gammaGreen; } if (blackwhite.gammaBlue) { - toEdit.blackwhite.gammaBlue = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_GAMMA] ? toEdit.blackwhite.gammaBlue + mods.blackwhite.gammaBlue : mods.blackwhite.gammaBlue; + toEdit.blackwhite.gammaBlue = dontforceSet && options.baBehav[ADDSET_BLACKWHITE_GAMMA] ? toEdit.blackwhite.gammaBlue + mods.blackwhite.gammaBlue : mods.blackwhite.gammaBlue; } if (blackwhite.beforeCurve) { - toEdit.blackwhite.beforeCurve = mods.blackwhite.beforeCurve; + toEdit.blackwhite.beforeCurve = mods.blackwhite.beforeCurve; } if (blackwhite.beforeCurveMode) { @@ -2423,19 +2431,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (blackwhite.afterCurve) { - toEdit.blackwhite.afterCurve = mods.blackwhite.afterCurve; + toEdit.blackwhite.afterCurve = mods.blackwhite.afterCurve; } if (blackwhite.afterCurveMode) { - toEdit.blackwhite.afterCurveMode = mods.blackwhite.afterCurveMode; + toEdit.blackwhite.afterCurveMode = mods.blackwhite.afterCurveMode; } if (blackwhite.algo) { - toEdit.blackwhite.algo = mods.blackwhite.algo; + toEdit.blackwhite.algo = mods.blackwhite.algo; } if (resize.scale) { - toEdit.resize.scale = dontforceSet && options.baBehav[ADDSET_RESIZE_SCALE] ? toEdit.resize.scale + mods.resize.scale : mods.resize.scale; + toEdit.resize.scale = dontforceSet && options.baBehav[ADDSET_RESIZE_SCALE] ? toEdit.resize.scale + mods.resize.scale : mods.resize.scale; } if (resize.appliesTo) { @@ -2443,23 +2451,23 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (resize.method) { - toEdit.resize.method = mods.resize.method; + toEdit.resize.method = mods.resize.method; } if (resize.dataspec) { - toEdit.resize.dataspec = mods.resize.dataspec; + toEdit.resize.dataspec = mods.resize.dataspec; } if (resize.width) { - toEdit.resize.width = mods.resize.width; + toEdit.resize.width = mods.resize.width; } if (resize.height) { - toEdit.resize.height = mods.resize.height; + toEdit.resize.height = mods.resize.height; } if (resize.enabled) { - toEdit.resize.enabled = mods.resize.enabled; + toEdit.resize.enabled = mods.resize.enabled; } if (resize.allowUpscaling) { @@ -2519,47 +2527,47 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (raw.bayersensor.method) { - toEdit.raw.bayersensor.method = mods.raw.bayersensor.method; + toEdit.raw.bayersensor.method = mods.raw.bayersensor.method; } if (raw.bayersensor.border) { - toEdit.raw.bayersensor.border = mods.raw.bayersensor.border; + toEdit.raw.bayersensor.border = mods.raw.bayersensor.border; } if (raw.bayersensor.imageNum) { - toEdit.raw.bayersensor.imageNum = mods.raw.bayersensor.imageNum; + toEdit.raw.bayersensor.imageNum = mods.raw.bayersensor.imageNum; } if (raw.bayersensor.ccSteps) { - toEdit.raw.bayersensor.ccSteps = mods.raw.bayersensor.ccSteps; + toEdit.raw.bayersensor.ccSteps = mods.raw.bayersensor.ccSteps; } if (raw.bayersensor.exBlack0) { - toEdit.raw.bayersensor.black0 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black0 + mods.raw.bayersensor.black0 : mods.raw.bayersensor.black0; + toEdit.raw.bayersensor.black0 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black0 + mods.raw.bayersensor.black0 : mods.raw.bayersensor.black0; } if (raw.bayersensor.exBlack1) { - toEdit.raw.bayersensor.black1 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black1 + mods.raw.bayersensor.black1 : mods.raw.bayersensor.black1; + toEdit.raw.bayersensor.black1 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black1 + mods.raw.bayersensor.black1 : mods.raw.bayersensor.black1; } if (raw.bayersensor.exBlack2) { - toEdit.raw.bayersensor.black2 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black2 + mods.raw.bayersensor.black2 : mods.raw.bayersensor.black2; + toEdit.raw.bayersensor.black2 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black2 + mods.raw.bayersensor.black2 : mods.raw.bayersensor.black2; } if (raw.bayersensor.exBlack3) { - toEdit.raw.bayersensor.black3 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black3 + mods.raw.bayersensor.black3 : mods.raw.bayersensor.black3; + toEdit.raw.bayersensor.black3 = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.bayersensor.black3 + mods.raw.bayersensor.black3 : mods.raw.bayersensor.black3; } if (raw.bayersensor.exTwoGreen) { - toEdit.raw.bayersensor.twogreen = mods.raw.bayersensor.twogreen; + toEdit.raw.bayersensor.twogreen = mods.raw.bayersensor.twogreen; } if (raw.bayersensor.dcbIterations) { - toEdit.raw.bayersensor.dcb_iterations = mods.raw.bayersensor.dcb_iterations; + toEdit.raw.bayersensor.dcb_iterations = mods.raw.bayersensor.dcb_iterations; } if (raw.bayersensor.dcbEnhance) { - toEdit.raw.bayersensor.dcb_enhance = mods.raw.bayersensor.dcb_enhance; + toEdit.raw.bayersensor.dcb_enhance = mods.raw.bayersensor.dcb_enhance; } if (raw.bayersensor.lmmseIterations) { @@ -2631,11 +2639,11 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (raw.bayersensor.greenEq) { - toEdit.raw.bayersensor.greenthresh = dontforceSet && options.baBehav[ADDSET_PREPROCESS_GREENEQUIL] ? toEdit.raw.bayersensor.greenthresh + mods.raw.bayersensor.greenthresh : mods.raw.bayersensor.greenthresh; + toEdit.raw.bayersensor.greenthresh = dontforceSet && options.baBehav[ADDSET_PREPROCESS_GREENEQUIL] ? toEdit.raw.bayersensor.greenthresh + mods.raw.bayersensor.greenthresh : mods.raw.bayersensor.greenthresh; } if (raw.bayersensor.linenoise) { - toEdit.raw.bayersensor.linenoise = dontforceSet && options.baBehav[ADDSET_PREPROCESS_LINEDENOISE] ? toEdit.raw.bayersensor.linenoise + mods.raw.bayersensor.linenoise : mods.raw.bayersensor.linenoise; + toEdit.raw.bayersensor.linenoise = dontforceSet && options.baBehav[ADDSET_PREPROCESS_LINEDENOISE] ? toEdit.raw.bayersensor.linenoise + mods.raw.bayersensor.linenoise : mods.raw.bayersensor.linenoise; } if (raw.bayersensor.linenoiseDirection) { @@ -2647,67 +2655,67 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (raw.xtranssensor.method) { - toEdit.raw.xtranssensor.method = mods.raw.xtranssensor.method; + toEdit.raw.xtranssensor.method = mods.raw.xtranssensor.method; } if (raw.xtranssensor.dualDemosaicAutoContrast) { - toEdit.raw.xtranssensor.dualDemosaicAutoContrast = mods.raw.xtranssensor.dualDemosaicAutoContrast; + toEdit.raw.xtranssensor.dualDemosaicAutoContrast = mods.raw.xtranssensor.dualDemosaicAutoContrast; } if (raw.xtranssensor.dualDemosaicContrast) { - toEdit.raw.xtranssensor.dualDemosaicContrast = mods.raw.xtranssensor.dualDemosaicContrast; + toEdit.raw.xtranssensor.dualDemosaicContrast = mods.raw.xtranssensor.dualDemosaicContrast; } if (raw.xtranssensor.ccSteps) { - toEdit.raw.xtranssensor.ccSteps = mods.raw.xtranssensor.ccSteps; + toEdit.raw.xtranssensor.ccSteps = mods.raw.xtranssensor.ccSteps; } if (raw.xtranssensor.border) { - toEdit.raw.xtranssensor.border = mods.raw.xtranssensor.border; + toEdit.raw.xtranssensor.border = mods.raw.xtranssensor.border; } if (raw.xtranssensor.exBlackRed) { - toEdit.raw.xtranssensor.blackred = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackred + mods.raw.xtranssensor.blackred : mods.raw.xtranssensor.blackred; + toEdit.raw.xtranssensor.blackred = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackred + mods.raw.xtranssensor.blackred : mods.raw.xtranssensor.blackred; } if (raw.xtranssensor.exBlackGreen) { - toEdit.raw.xtranssensor.blackgreen = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackgreen + mods.raw.xtranssensor.blackgreen : mods.raw.xtranssensor.blackgreen; + toEdit.raw.xtranssensor.blackgreen = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackgreen + mods.raw.xtranssensor.blackgreen : mods.raw.xtranssensor.blackgreen; } if (raw.xtranssensor.exBlackBlue) { - toEdit.raw.xtranssensor.blackblue = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackblue + mods.raw.xtranssensor.blackblue : mods.raw.xtranssensor.blackblue; + toEdit.raw.xtranssensor.blackblue = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackblue + mods.raw.xtranssensor.blackblue : mods.raw.xtranssensor.blackblue; } if (raw.ca_autocorrect) { - toEdit.raw.ca_autocorrect = mods.raw.ca_autocorrect; + toEdit.raw.ca_autocorrect = mods.raw.ca_autocorrect; } if (raw.ca_avoidcolourshift) { - toEdit.raw.ca_avoidcolourshift = mods.raw.ca_avoidcolourshift; + toEdit.raw.ca_avoidcolourshift = mods.raw.ca_avoidcolourshift; } if (raw.caautoiterations) { - toEdit.raw.caautoiterations = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.caautoiterations + mods.raw.caautoiterations : mods.raw.caautoiterations; + toEdit.raw.caautoiterations = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.caautoiterations + mods.raw.caautoiterations : mods.raw.caautoiterations; } if (raw.cared) { - toEdit.raw.cared = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.cared + mods.raw.cared : mods.raw.cared; + toEdit.raw.cared = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.cared + mods.raw.cared : mods.raw.cared; } if (raw.cablue) { - toEdit.raw.cablue = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.cablue + mods.raw.cablue : mods.raw.cablue; + toEdit.raw.cablue = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.cablue + mods.raw.cablue : mods.raw.cablue; } if (raw.exPos) { - toEdit.raw.expos = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_LINEAR] ? toEdit.raw.expos + mods.raw.expos : mods.raw.expos; + toEdit.raw.expos = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_LINEAR] ? toEdit.raw.expos + mods.raw.expos : mods.raw.expos; } if (raw.hotPixelFilter) { - toEdit.raw.hotPixelFilter = mods.raw.hotPixelFilter; + toEdit.raw.hotPixelFilter = mods.raw.hotPixelFilter; } if (raw.deadPixelFilter) { - toEdit.raw.deadPixelFilter = mods.raw.deadPixelFilter; + toEdit.raw.deadPixelFilter = mods.raw.deadPixelFilter; } if (raw.hotdeadpix_thresh) { @@ -2715,27 +2723,27 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (raw.darkFrame) { - toEdit.raw.dark_frame = mods.raw.dark_frame; + toEdit.raw.dark_frame = mods.raw.dark_frame; } if (raw.df_autoselect) { - toEdit.raw.df_autoselect = mods.raw.df_autoselect; + toEdit.raw.df_autoselect = mods.raw.df_autoselect; } if (raw.ff_file) { - toEdit.raw.ff_file = mods.raw.ff_file; + toEdit.raw.ff_file = mods.raw.ff_file; } if (raw.ff_AutoSelect) { - toEdit.raw.ff_AutoSelect = mods.raw.ff_AutoSelect; + toEdit.raw.ff_AutoSelect = mods.raw.ff_AutoSelect; } if (raw.ff_BlurRadius) { - toEdit.raw.ff_BlurRadius = mods.raw.ff_BlurRadius; + toEdit.raw.ff_BlurRadius = mods.raw.ff_BlurRadius; } if (raw.ff_BlurType) { - toEdit.raw.ff_BlurType = mods.raw.ff_BlurType; + toEdit.raw.ff_BlurType = mods.raw.ff_BlurType; } if (raw.ff_AutoClipControl) { @@ -2743,135 +2751,135 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (raw.ff_clipControl) { - toEdit.raw.ff_clipControl = dontforceSet && options.baBehav[ADDSET_RAWFFCLIPCONTROL] ? toEdit.raw.ff_clipControl + mods.raw.ff_clipControl : mods.raw.ff_clipControl; + toEdit.raw.ff_clipControl = dontforceSet && options.baBehav[ADDSET_RAWFFCLIPCONTROL] ? toEdit.raw.ff_clipControl + mods.raw.ff_clipControl : mods.raw.ff_clipControl; } if (wavelet.enabled) { - toEdit.wavelet.enabled = mods.wavelet.enabled; + toEdit.wavelet.enabled = mods.wavelet.enabled; } if (wavelet.strength) { - toEdit.wavelet.strength = mods.wavelet.strength; + toEdit.wavelet.strength = mods.wavelet.strength; } if (wavelet.balance) { - toEdit.wavelet.balance = mods.wavelet.balance; + toEdit.wavelet.balance = mods.wavelet.balance; } if (wavelet.iter) { - toEdit.wavelet.iter = mods.wavelet.iter; + toEdit.wavelet.iter = mods.wavelet.iter; } if (wavelet.median) { - toEdit.wavelet.median = mods.wavelet.median; + toEdit.wavelet.median = mods.wavelet.median; } if (wavelet.medianlev) { - toEdit.wavelet.medianlev = mods.wavelet.medianlev; + toEdit.wavelet.medianlev = mods.wavelet.medianlev; } if (wavelet.linkedg) { - toEdit.wavelet.linkedg = mods.wavelet.linkedg; + toEdit.wavelet.linkedg = mods.wavelet.linkedg; } if (wavelet.cbenab) { - toEdit.wavelet.cbenab = mods.wavelet.cbenab; + toEdit.wavelet.cbenab = mods.wavelet.cbenab; } if (wavelet.greenhigh) { - toEdit.wavelet.greenhigh = mods.wavelet.greenhigh; + toEdit.wavelet.greenhigh = mods.wavelet.greenhigh; } if (wavelet.bluehigh) { - toEdit.wavelet.bluehigh = mods.wavelet.bluehigh; + toEdit.wavelet.bluehigh = mods.wavelet.bluehigh; } if (wavelet.greenmed) { - toEdit.wavelet.greenmed = mods.wavelet.greenmed; + toEdit.wavelet.greenmed = mods.wavelet.greenmed; } if (wavelet.bluemed) { - toEdit.wavelet.bluemed = mods.wavelet.bluemed; + toEdit.wavelet.bluemed = mods.wavelet.bluemed; } if (wavelet.greenlow) { - toEdit.wavelet.greenlow = mods.wavelet.greenlow; + toEdit.wavelet.greenlow = mods.wavelet.greenlow; } if (wavelet.bluelow) { - toEdit.wavelet.bluelow = mods.wavelet.bluelow; + toEdit.wavelet.bluelow = mods.wavelet.bluelow; } if (wavelet.lipst) { - toEdit.wavelet.lipst = mods.wavelet.lipst; + toEdit.wavelet.lipst = mods.wavelet.lipst; } if (wavelet.Medgreinf) { - toEdit.wavelet.Medgreinf = mods.wavelet.Medgreinf; + toEdit.wavelet.Medgreinf = mods.wavelet.Medgreinf; } if (wavelet.avoid) { - toEdit.wavelet.avoid = mods.wavelet.avoid; + toEdit.wavelet.avoid = mods.wavelet.avoid; } if (wavelet.tmr) { - toEdit.wavelet.tmr = mods.wavelet.tmr; + toEdit.wavelet.tmr = mods.wavelet.tmr; } if (wavelet.Lmethod) { - toEdit.wavelet.Lmethod = mods.wavelet.Lmethod; + toEdit.wavelet.Lmethod = mods.wavelet.Lmethod; } if (wavelet.CLmethod) { - toEdit.wavelet.CLmethod = mods.wavelet.CLmethod; + toEdit.wavelet.CLmethod = mods.wavelet.CLmethod; } if (wavelet.Backmethod) { - toEdit.wavelet.Backmethod = mods.wavelet.Backmethod; + toEdit.wavelet.Backmethod = mods.wavelet.Backmethod; } if (wavelet.Tilesmethod) { - toEdit.wavelet.Tilesmethod = mods.wavelet.Tilesmethod; + toEdit.wavelet.Tilesmethod = mods.wavelet.Tilesmethod; } if (wavelet.daubcoeffmethod) { - toEdit.wavelet.daubcoeffmethod = mods.wavelet.daubcoeffmethod; + toEdit.wavelet.daubcoeffmethod = mods.wavelet.daubcoeffmethod; } if (wavelet.CHmethod) { - toEdit.wavelet.CHmethod = mods.wavelet.CHmethod; + toEdit.wavelet.CHmethod = mods.wavelet.CHmethod; } if (wavelet.CHSLmethod) { - toEdit.wavelet.CHSLmethod = mods.wavelet.CHSLmethod; + toEdit.wavelet.CHSLmethod = mods.wavelet.CHSLmethod; } if (wavelet.EDmethod) { - toEdit.wavelet.EDmethod = mods.wavelet.EDmethod; + toEdit.wavelet.EDmethod = mods.wavelet.EDmethod; } if (wavelet.NPmethod) { - toEdit.wavelet.NPmethod = mods.wavelet.NPmethod; + toEdit.wavelet.NPmethod = mods.wavelet.NPmethod; } if (wavelet.BAmethod) { - toEdit.wavelet.BAmethod = mods.wavelet.BAmethod; + toEdit.wavelet.BAmethod = mods.wavelet.BAmethod; } if (wavelet.TMmethod) { - toEdit.wavelet.TMmethod = mods.wavelet.TMmethod; + toEdit.wavelet.TMmethod = mods.wavelet.TMmethod; } if (wavelet.HSmethod) { - toEdit.wavelet.HSmethod = mods.wavelet.HSmethod; + toEdit.wavelet.HSmethod = mods.wavelet.HSmethod; } if (wavelet.Dirmethod) { - toEdit.wavelet.Dirmethod = mods.wavelet.Dirmethod; + toEdit.wavelet.Dirmethod = mods.wavelet.Dirmethod; } if (wavelet.edgthresh) { - toEdit.wavelet.edgthresh = mods.wavelet.edgthresh; + toEdit.wavelet.edgthresh = mods.wavelet.edgthresh; } if (wavelet.sky) { @@ -2887,39 +2895,39 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (wavelet.sup) { - toEdit.wavelet.sup = mods.wavelet.sup; + toEdit.wavelet.sup = mods.wavelet.sup; } if (wavelet.hllev) { - toEdit.wavelet.hllev = mods.wavelet.hllev; + toEdit.wavelet.hllev = mods.wavelet.hllev; } if (wavelet.bllev) { - toEdit.wavelet.bllev = mods.wavelet.bllev; + toEdit.wavelet.bllev = mods.wavelet.bllev; } if (wavelet.edgcont) { - toEdit.wavelet.edgcont = mods.wavelet.edgcont; + toEdit.wavelet.edgcont = mods.wavelet.edgcont; } if (wavelet.level0noise) { - toEdit.wavelet.level0noise = mods.wavelet.level0noise; + toEdit.wavelet.level0noise = mods.wavelet.level0noise; } if (wavelet.level1noise) { - toEdit.wavelet.level1noise = mods.wavelet.level1noise; + toEdit.wavelet.level1noise = mods.wavelet.level1noise; } if (wavelet.level2noise) { - toEdit.wavelet.level2noise = mods.wavelet.level2noise; + toEdit.wavelet.level2noise = mods.wavelet.level2noise; } if (wavelet.level3noise) { - toEdit.wavelet.level3noise = mods.wavelet.level3noise; + toEdit.wavelet.level3noise = mods.wavelet.level3noise; } if (wavelet.pastlev) { - toEdit.wavelet.pastlev = mods.wavelet.pastlev; + toEdit.wavelet.pastlev = mods.wavelet.pastlev; } if (wavelet.satlev) { @@ -2927,7 +2935,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (wavelet.ccwcurve) { - toEdit.wavelet.ccwcurve = mods.wavelet.ccwcurve; + toEdit.wavelet.ccwcurve = mods.wavelet.ccwcurve; } if (wavelet.opacityCurveRG) { @@ -2939,7 +2947,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (wavelet.opacityCurveW) { - toEdit.wavelet.opacityCurveW = mods.wavelet.opacityCurveW; + toEdit.wavelet.opacityCurveW = mods.wavelet.opacityCurveW; } if (wavelet.opacityCurveWL) { @@ -2947,44 +2955,44 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (wavelet.hhcurve) { - toEdit.wavelet.hhcurve = mods.wavelet.hhcurve; + toEdit.wavelet.hhcurve = mods.wavelet.hhcurve; } if (wavelet.Chcurve) { - toEdit.wavelet.Chcurve = mods.wavelet.Chcurve; + toEdit.wavelet.Chcurve = mods.wavelet.Chcurve; } if (wavelet.wavclCurve) { toEdit.wavelet.wavclCurve = mods.wavelet.wavclCurve; } - //if (wavelet.enacont) toEdit.wavelet.enacont = mods.wavelet.enacont; + //if (wavelet.enacont) toEdit.wavelet.enacont = mods.wavelet.enacont; if (wavelet.expcontrast) { - toEdit.wavelet.expcontrast = mods.wavelet.expcontrast; + toEdit.wavelet.expcontrast = mods.wavelet.expcontrast; } if (wavelet.expchroma) { - toEdit.wavelet.expchroma = mods.wavelet.expchroma; + toEdit.wavelet.expchroma = mods.wavelet.expchroma; } if (wavelet.expedge) { - toEdit.wavelet.expedge = mods.wavelet.expedge; + toEdit.wavelet.expedge = mods.wavelet.expedge; } if (wavelet.expresid) { - toEdit.wavelet.expresid = mods.wavelet.expresid; + toEdit.wavelet.expresid = mods.wavelet.expresid; } if (wavelet.expfinal) { - toEdit.wavelet.expfinal = mods.wavelet.expfinal; + toEdit.wavelet.expfinal = mods.wavelet.expfinal; } if (wavelet.exptoning) { - toEdit.wavelet.exptoning = mods.wavelet.exptoning; + toEdit.wavelet.exptoning = mods.wavelet.exptoning; } if (wavelet.expnoise) { - toEdit.wavelet.expnoise = mods.wavelet.expnoise; + toEdit.wavelet.expnoise = mods.wavelet.expnoise; } for (int i = 0; i < 9; i++) { @@ -3004,19 +3012,19 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (wavelet.hueskin) { - toEdit.wavelet.hueskin = mods.wavelet.hueskin; + toEdit.wavelet.hueskin = mods.wavelet.hueskin; } if (wavelet.hueskin2) { - toEdit.wavelet.hueskin2 = mods.wavelet.hueskin2; + toEdit.wavelet.hueskin2 = mods.wavelet.hueskin2; } if (wavelet.edgesensi) { - toEdit.wavelet.edgesensi = mods.wavelet.edgesensi; + toEdit.wavelet.edgesensi = mods.wavelet.edgesensi; } if (wavelet.edgeampli) { - toEdit.wavelet.edgeampli = mods.wavelet.edgeampli; + toEdit.wavelet.edgeampli = mods.wavelet.edgeampli; } if (wavelet.resconH) { @@ -3089,20 +3097,20 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng if (dirpyrequalizer.enabled) { - toEdit.dirpyrequalizer.enabled = mods.dirpyrequalizer.enabled; + toEdit.dirpyrequalizer.enabled = mods.dirpyrequalizer.enabled; } if (dirpyrequalizer.gamutlab) { - toEdit.dirpyrequalizer.gamutlab = mods.dirpyrequalizer.gamutlab; + toEdit.dirpyrequalizer.gamutlab = mods.dirpyrequalizer.gamutlab; } if (dirpyrequalizer.cbdlMethod) { - toEdit.dirpyrequalizer.cbdlMethod = mods.dirpyrequalizer.cbdlMethod; + toEdit.dirpyrequalizer.cbdlMethod = mods.dirpyrequalizer.cbdlMethod; } for (int i = 0; i < 6; i++) { if (dirpyrequalizer.mult[i]) { - toEdit.dirpyrequalizer.mult[i] = dontforceSet && options.baBehav[ADDSET_DIRPYREQ] ? toEdit.dirpyrequalizer.mult[i] + mods.dirpyrequalizer.mult[i] : mods.dirpyrequalizer.mult[i]; + toEdit.dirpyrequalizer.mult[i] = dontforceSet && options.baBehav[ADDSET_DIRPYREQ] ? toEdit.dirpyrequalizer.mult[i] + mods.dirpyrequalizer.mult[i] : mods.dirpyrequalizer.mult[i]; } } @@ -3115,77 +3123,95 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng } if (dirpyrequalizer.hueskin) { - toEdit.dirpyrequalizer.hueskin = mods.dirpyrequalizer.hueskin; + toEdit.dirpyrequalizer.hueskin = mods.dirpyrequalizer.hueskin; } -// if (dirpyrequalizer.algo) toEdit.dirpyrequalizer.algo = mods.dirpyrequalizer.algo; +// if (dirpyrequalizer.algo) toEdit.dirpyrequalizer.algo = mods.dirpyrequalizer.algo; if (hsvequalizer.enabled) { toEdit.hsvequalizer.enabled = mods.hsvequalizer.enabled; } if (hsvequalizer.hcurve) { - toEdit.hsvequalizer.hcurve = mods.hsvequalizer.hcurve; + toEdit.hsvequalizer.hcurve = mods.hsvequalizer.hcurve; } if (hsvequalizer.scurve) { - toEdit.hsvequalizer.scurve = mods.hsvequalizer.scurve; + toEdit.hsvequalizer.scurve = mods.hsvequalizer.scurve; } if (hsvequalizer.vcurve) { - toEdit.hsvequalizer.vcurve = mods.hsvequalizer.vcurve; + toEdit.hsvequalizer.vcurve = mods.hsvequalizer.vcurve; } if (filmSimulation.enabled) { - toEdit.filmSimulation.enabled = mods.filmSimulation.enabled; + toEdit.filmSimulation.enabled = mods.filmSimulation.enabled; } if (filmSimulation.clutFilename) { - toEdit.filmSimulation.clutFilename = mods.filmSimulation.clutFilename; + toEdit.filmSimulation.clutFilename = mods.filmSimulation.clutFilename; } if (filmSimulation.strength) { - toEdit.filmSimulation.strength = dontforceSet && options.baBehav[ADDSET_FILMSIMULATION_STRENGTH] ? toEdit.filmSimulation.strength + mods.filmSimulation.strength : mods.filmSimulation.strength; + toEdit.filmSimulation.strength = dontforceSet && options.baBehav[ADDSET_FILMSIMULATION_STRENGTH] ? toEdit.filmSimulation.strength + mods.filmSimulation.strength : mods.filmSimulation.strength; } if (softlight.enabled) { - toEdit.softlight.enabled = mods.softlight.enabled; + toEdit.softlight.enabled = mods.softlight.enabled; } if (softlight.strength) { - toEdit.softlight.strength = dontforceSet && options.baBehav[ADDSET_SOFTLIGHT_STRENGTH] ? toEdit.softlight.strength + mods.softlight.strength : mods.softlight.strength; + toEdit.softlight.strength = dontforceSet && options.baBehav[ADDSET_SOFTLIGHT_STRENGTH] ? toEdit.softlight.strength + mods.softlight.strength : mods.softlight.strength; } if (dehaze.enabled) { - toEdit.dehaze.enabled = mods.dehaze.enabled; + toEdit.dehaze.enabled = mods.dehaze.enabled; } if (dehaze.strength) { - toEdit.dehaze.strength = dontforceSet && options.baBehav[ADDSET_DEHAZE_STRENGTH] ? toEdit.dehaze.strength + mods.dehaze.strength : mods.dehaze.strength; + toEdit.dehaze.strength = dontforceSet && options.baBehav[ADDSET_DEHAZE_STRENGTH] ? toEdit.dehaze.strength + mods.dehaze.strength : mods.dehaze.strength; } if (dehaze.depth) { - toEdit.dehaze.depth = mods.dehaze.depth; + toEdit.dehaze.depth = mods.dehaze.depth; } if (dehaze.showDepthMap) { - toEdit.dehaze.showDepthMap = mods.dehaze.showDepthMap; + toEdit.dehaze.showDepthMap = mods.dehaze.showDepthMap; } if (metadata.mode) { - toEdit.metadata.mode = mods.metadata.mode; + toEdit.metadata.mode = mods.metadata.mode; + } + + if (filmNegative.enabled) { + toEdit.filmNegative.enabled = mods.filmNegative.enabled; + } + + if (filmNegative.redRatio) { + toEdit.filmNegative.redRatio = mods.filmNegative.redRatio; + } + + if (filmNegative.greenExp) { + toEdit.filmNegative.greenExp = mods.filmNegative.greenExp; + } + + if (filmNegative.blueRatio) { + toEdit.filmNegative.blueRatio = mods.filmNegative.blueRatio; } // Exif changes are added to the existing ones - if (exif) + if (exif) { for (procparams::ExifPairs::const_iterator i = mods.exif.begin(); i != mods.exif.end(); ++i) { toEdit.exif[i->first] = i->second; } + } // IPTC changes are added to the existing ones - if (iptc) + if (iptc) { for (procparams::IPTCPairs::const_iterator i = mods.iptc.begin(); i != mods.iptc.end(); ++i) { toEdit.iptc[i->first] = i->second; } + } } bool RAWParamsEdited::BayerSensor::isUnchanged() const @@ -3216,3 +3242,8 @@ bool RetinexParamsEdited::isUnchanged() const { return enabled && retinexcolorspace && gammaretinex && gam && slope; } + +bool FilmNegativeParamsEdited::isUnchanged() const +{ + return enabled && redRatio && greenExp && blueRatio; +} diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 95701e01a..08a41fc7a 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -666,6 +666,15 @@ struct MetaDataParamsEdited { bool mode; }; +struct FilmNegativeParamsEdited { + bool enabled; + bool redRatio; + bool greenExp; + bool blueRatio; + + bool isUnchanged() const; +}; + struct ParamsEdited { GeneralParamsEdited general; ToneCurveParamsEdited toneCurve; @@ -710,6 +719,7 @@ struct ParamsEdited { SoftLightParamsEdited softlight; DehazeParamsEdited dehaze; MetaDataParamsEdited metadata; + FilmNegativeParamsEdited filmNegative; bool exif; bool iptc; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index 734f7c29b..52adcfbf7 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -134,6 +134,8 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren raw_ca_autocorrect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_AUTO"))); raw_caredblue = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CAREDBLUE"))); raw_ca_avoid_colourshift = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_AVOIDCOLORSHIFT"))); + //--- + filmNegative = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FILMNEGATIVE")) ); Gtk::VBox* vboxes[8]; Gtk::HSeparator* hseps[8]; @@ -249,6 +251,8 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren vboxes[7]->pack_start (*raw_ca_autocorrect, Gtk::PACK_SHRINK, 2); vboxes[7]->pack_start (*raw_caredblue, Gtk::PACK_SHRINK, 2); vboxes[7]->pack_start (*raw_ca_avoid_colourshift, Gtk::PACK_SHRINK, 2); + vboxes[7]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); + vboxes[7]->pack_start (*filmNegative, Gtk::PACK_SHRINK, 2); Gtk::VBox* vbCol1 = Gtk::manage (new Gtk::VBox ()); Gtk::VBox* vbCol2 = Gtk::manage (new Gtk::VBox ()); @@ -396,6 +400,8 @@ PartialPasteDlg::PartialPasteDlg (const Glib::ustring &title, Gtk::Window* paren raw_ca_autocorrectConn = raw_ca_autocorrect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_caredblueConn = raw_caredblue->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); raw_ca_avoid_colourshiftconn = raw_ca_avoid_colourshift->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + //--- + filmNegativeConn = filmNegative->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); add_button (M("GENERAL_OK"), Gtk::RESPONSE_OK); add_button (M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL); @@ -467,6 +473,7 @@ void PartialPasteDlg::rawToggled () ConnectionBlocker raw_ca_autocorrectBlocker(raw_ca_autocorrectConn); ConnectionBlocker raw_caredblueBlocker(raw_caredblueConn); ConnectionBlocker raw_ca_avoid_colourshiftBlocker(raw_ca_avoid_colourshiftconn); + ConnectionBlocker filmNegativeBlocker(filmNegativeConn); raw->set_inconsistent (false); @@ -495,6 +502,7 @@ void PartialPasteDlg::rawToggled () raw_ca_autocorrect->set_active (raw->get_active ()); raw_caredblue->set_active (raw->get_active ()); raw_ca_avoid_colourshift->set_active (raw->get_active ()); + filmNegative->set_active (raw->get_active()); } void PartialPasteDlg::basicToggled () @@ -966,6 +974,13 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.raw.ff_AutoClipControl = falsePE.raw.ff_AutoClipControl; } + if (!filmNegative->get_active ()) { + filterPE.filmNegative.enabled = falsePE.filmNegative.enabled; + filterPE.filmNegative.redRatio = falsePE.filmNegative.redRatio; + filterPE.filmNegative.greenExp = falsePE.filmNegative.greenExp; + filterPE.filmNegative.blueRatio = falsePE.filmNegative.blueRatio; + } + if (dstPE) { *dstPE = filterPE; } @@ -973,4 +988,3 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param // Apply the filter! filterPE.combine(*dstPP, *srcPP, true); } - diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index 0325fa063..b5b93b11a 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -130,6 +130,8 @@ public: Gtk::CheckButton* ff_BlurType; Gtk::CheckButton* ff_ClipControl; + Gtk::CheckButton* filmNegative; + sigc::connection everythingConn, basicConn, detailConn, colorConn, lensConn, compositionConn, metaConn, rawConn, advancedConn; sigc::connection wbConn, exposureConn, localcontrastConn, shConn, pcvignetteConn, gradientConn, labcurveConn, colorappearanceConn; @@ -140,6 +142,7 @@ public: sigc::connection metadataConn, exifchConn, iptcConn, icmConn; sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn; sigc::connection raw_caredblueConn, raw_ca_autocorrectConn, raw_ca_avoid_colourshiftconn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_pdaf_lines_filterConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_borderConn, raw_imagenumConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_pixelshiftConn, raw_dcb_enhanceConn, raw_exposConn, raw_blackConn; + sigc::connection filmNegativeConn; public: PartialPasteDlg (const Glib::ustring &title, Gtk::Window* parent); diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 757708002..39f4ca093 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -813,6 +813,7 @@ int Thumbnail::infoFromImage (const Glib::ustring& fname, std::unique_ptrgetLens(); cfs.camMake = idata->getMake(); cfs.camModel = idata->getModel(); + cfs.rating = idata->getRating(); if (idata->getOrientation() == "Rotate 90 CW") { deg = 90; @@ -1005,15 +1006,22 @@ void Thumbnail::setFileName (const Glib::ustring &fn) int Thumbnail::getRank () const { - return pparams->rank; + // prefer the user-set rank over the embedded Rating + // pparams->rank == -1 means that there is no saved rank yet, so we should + // next look for the embedded Rating metadata. + if (pparams->rank != -1) { + return pparams->rank; + } else { + return cfs.rating; + } } void Thumbnail::setRank (int rank) { if (pparams->rank != rank) { pparams->rank = rank; - pparamsValid = true; } + pparamsValid = true; } int Thumbnail::getColorLabel () const diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 41e25387e..f7e2991e1 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -92,6 +92,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit bayerrawexposure = Gtk::manage (new BayerRAWExposure ()); xtransrawexposure = Gtk::manage (new XTransRAWExposure ()); fattal = Gtk::manage (new FattalToneMapping ()); + filmNegative = Gtk::manage (new FilmNegative ()); // So Demosaic, Line noise filter, Green Equilibration, Ca-Correction (garder le nom de section identique!) and Black-Level will be moved in a "Bayer sensor" tool, // and a separate Demosaic and Black Level tool will be created in an "X-Trans sensor" tool @@ -154,6 +155,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit addfavoritePanel (rawPanel, preprocess); addfavoritePanel (rawPanel, darkframe); addfavoritePanel (rawPanel, flatfield); + addfavoritePanel (rawPanel, filmNegative); int favoriteCount = 0; for(auto it = favorites.begin(); it != favorites.end(); ++it) { @@ -255,6 +257,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit distortion->setLensGeomListener (this); crop->setCropPanelListener (this); icm->setICMPanelListener (this); + filmNegative->setFilmNegProvider (this); toolBar = new ToolBar (); toolBar->setToolBarListener (this); @@ -305,6 +308,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt sensorbayer->FoldableToolPanel::show(); preprocess->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show(); + filmNegative->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -320,6 +324,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt sensorbayer->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show(); + filmNegative->FoldableToolPanel::show(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -335,6 +340,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt sensorxtrans->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::show(); + filmNegative->FoldableToolPanel::hide(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -349,6 +355,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt sensorxtrans->FoldableToolPanel::hide(); preprocess->FoldableToolPanel::hide(); flatfield->FoldableToolPanel::hide(); + filmNegative->FoldableToolPanel::hide(); retinex->FoldableToolPanel::setGrayedOut(false); return false; @@ -360,6 +367,7 @@ void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXt [this]() -> bool { rawPanelSW->set_sensitive(false); + filmNegative->FoldableToolPanel::hide(); retinex->FoldableToolPanel::setGrayedOut(true); return false; @@ -476,7 +484,7 @@ void ToolPanelCoordinator::profileChange( lParams[1] = *mergedParams; pe.initFrom (lParams); - filterRawRefresh = pe.raw.isUnchanged() && pe.lensProf.isUnchanged() && pe.retinex.isUnchanged(); + filterRawRefresh = pe.raw.isUnchanged() && pe.lensProf.isUnchanged() && pe.retinex.isUnchanged() && pe.filmNegative.isUnchanged(); } *params = *mergedParams; @@ -1014,3 +1022,8 @@ void ToolPanelCoordinator::setEditProvider (EditDataProvider *provider) toolPanels.at (i)->setEditProvider (provider); } } + +bool ToolPanelCoordinator::getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, std::array& newExps) +{ + return ipc && ipc->getFilmNegativeExponents(spotA.x, spotA.y, spotB.x, spotB.y, newExps); +} diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 1ac74871a..5569861ae 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -82,6 +82,7 @@ #include "softlight.h" #include "dehaze.h" #include "guiutils.h" +#include "filmnegative.h" class ImageEditorCoordinator; @@ -97,7 +98,8 @@ class ToolPanelCoordinator : public CropPanelListener, public ICMPanelListener, public ImageAreaToolListener, - public rtengine::ImageTypeListener + public rtengine::ImageTypeListener, + public FilmNegProvider { protected: WhiteBalance* whitebalance; @@ -152,6 +154,7 @@ protected: XTransRAWExposure* xtransrawexposure; FattalToneMapping *fattal; MetaDataPanel* metadata; + FilmNegative* filmNegative; std::vector paramcListeners; @@ -288,6 +291,9 @@ public: rtengine::RawImage* getFF() override; Glib::ustring GetCurrentImageFilePath() override; + // FilmNegProvider interface + bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, std::array& newExps) override; + // rotatelistener interface void straightenRequested () override; void autoCropRequested () override;