Merge branch 'dev' into hidpi-icons

This commit is contained in:
Hombre 2018-10-25 20:43:41 +02:00
commit 785a0e6a46
216 changed files with 2636 additions and 1327 deletions

Binary file not shown.

Binary file not shown.

View File

@ -70,6 +70,7 @@
#69 25.07.2018 Erweiterung (TooWaBoo) RT 5.4
#70 25.07.2018 Korrekturen (TooWaBoo) RT 5.4
#71 28.09.2018 Korrekturen (TooWaBoo) RT 5.5
#72 05.10.2018 Korrekturen (TooWaBoo) RT 5.5
ABOUT_TAB_BUILD;Version
ABOUT_TAB_CREDITS;Danksagungen
@ -181,7 +182,7 @@ FILEBROWSER_APPLYPROFILE;Profil anwenden
FILEBROWSER_APPLYPROFILE_PARTIAL;Profil selektiv anwenden
FILEBROWSER_AUTODARKFRAME;Automatisches Dunkelbild
FILEBROWSER_AUTOFLATFIELD;Automatisches Weißbild
FILEBROWSER_BROWSEPATHBUTTONHINT;Ausgewählter Pfad öffnen
FILEBROWSER_BROWSEPATHBUTTONHINT;Ausgewählten Pfad öffnen.
FILEBROWSER_BROWSEPATHHINT;Einen Pfad eingeben:\nTaste:\n<b>Strg</b> + <b>o</b> Setzt den Cursor in das Eingabefeld\n<b>Enter</b> Öffnet den Pfad\n<b>Esc</b> Änderungen verwerfen\n<b>Umschalt</b> + <b>Esc</b> Eingabefeld verlassen\n\nSchnellnavigation:\nTaste:\n<b>~</b> “Home“-Verzeichnis des Benutzers\n<b>!</b> Bilder-Verzeichnis des Benutzers
FILEBROWSER_CACHE;Festplatten-Cache
FILEBROWSER_CACHECLEARFROMFULL;Aus dem Festplatten-Cache entfernen (vollständig)
@ -236,7 +237,7 @@ FILEBROWSER_POPUPSELECTALL;Alle auswählen
FILEBROWSER_POPUPTRASH;In den Papierkorb verschieben
FILEBROWSER_POPUPUNRANK;Bewertung entfernen
FILEBROWSER_POPUPUNTRASH;Aus dem Papierkorb wiederherstellen
FILEBROWSER_QUERYBUTTONHINT;Suchfilter zurücksetzen
FILEBROWSER_QUERYBUTTONHINT;Suchfilter zurücksetzen.
FILEBROWSER_QUERYHINT;Nur Dateien anzeigen, deren Namen die angegebene Zeichenkette beinhalten.\n\nTaste:\n<b>Strg</b> + <b>f</b> Setzt den Cursor in das Suchfeld\n<b>Enter</b> Suche starten\n<b>Esc</b> Suchfeld löschen\n<b>Umschalt</b> + <b>Esc</b> Suchfeldfeld verlassen
FILEBROWSER_QUERYLABEL; Suche:
FILEBROWSER_RANK1_TOOLTIP;Bewertung 1 *\nTaste: <b>Umschalt</b> + <b>1</b>
@ -248,31 +249,31 @@ FILEBROWSER_RENAMEDLGLABEL;Datei umbenennen
FILEBROWSER_RESETDEFAULTPROFILE;Profil auf Vorgabe zurücksetzen
FILEBROWSER_SELECTDARKFRAME;Dunkelbild wählen...
FILEBROWSER_SELECTFLATFIELD;Weißbild wählen...
FILEBROWSER_SHOWCOLORLABEL1HINT;Nur rot markierte Bilder anzeigen\nTaste: <b>Alt</b> + <b>1</b>
FILEBROWSER_SHOWCOLORLABEL2HINT;Nur gelb markierte Bilder anzeigen\nTaste: <b>Alt</b> + <b>2</b>
FILEBROWSER_SHOWCOLORLABEL3HINT;Nur grün markierte Bilder anzeigen\nTaste: <b>Alt</b> + <b>3</b>
FILEBROWSER_SHOWCOLORLABEL4HINT;Nur blau markierte Bilder anzeigen\nTaste: <b>Alt</b> + <b>4</b>
FILEBROWSER_SHOWCOLORLABEL5HINT;Nur violett markierte Bilder anzeigen\nTaste: <b>Alt</b> + <b>5</b>
FILEBROWSER_SHOWDIRHINT;Alle Filter zurücksetzen\nTaste: <b>d</b>
FILEBROWSER_SHOWEDITEDHINT;Nur bearbeitete Bilder anzeigen\nTaste: <b>7</b>
FILEBROWSER_SHOWEDITEDNOTHINT;Nur unbearbeitete Bilder anzeigen\nTaste: <b>6</b>
FILEBROWSER_SHOWCOLORLABEL1HINT;Nur rot markierte Bilder anzeigen.\nTaste: <b>Alt</b> + <b>1</b>
FILEBROWSER_SHOWCOLORLABEL2HINT;Nur gelb markierte Bilder anzeigen.\nTaste: <b>Alt</b> + <b>2</b>
FILEBROWSER_SHOWCOLORLABEL3HINT;Nur grün markierte Bilder anzeigen.\nTaste: <b>Alt</b> + <b>3</b>
FILEBROWSER_SHOWCOLORLABEL4HINT;Nur blau markierte Bilder anzeigen.\nTaste: <b>Alt</b> + <b>4</b>
FILEBROWSER_SHOWCOLORLABEL5HINT;Nur violett markierte Bilder anzeigen.\nTaste: <b>Alt</b> + <b>5</b>
FILEBROWSER_SHOWDIRHINT;Alle Filter zurücksetzen.\nTaste: <b>d</b>
FILEBROWSER_SHOWEDITEDHINT;Nur bearbeitete Bilder anzeigen.\nTaste: <b>7</b>
FILEBROWSER_SHOWEDITEDNOTHINT;Nur unbearbeitete Bilder anzeigen.\nTaste: <b>6</b>
FILEBROWSER_SHOWEXIFINFO;Bildinformationen ein-/ausblenden.\n\nIm Multi-Reitermodus:\nTaste: <b>i</b>\nIm Ein-Reitermodus:\nTaste: <b>Alt</b> + <b>i</b>
FILEBROWSER_SHOWNOTTRASHHINT;Nur nicht gelöschte Bilder anzeigen
FILEBROWSER_SHOWNOTTRASHHINT;Nur nicht gelöschte Bilder anzeigen.
FILEBROWSER_SHOWORIGINALHINT;Zeige nur das Originalbild.\n\nWenn mehrere Bilder mit dem gleichen Dateinamen und unterschiedlichen Dateitypen existieren, ist das Originalbild das Bild, welches in der Liste "Dateitypen anzeigen" unter Einstellungen > Dateiverwaltung als erstes gefunden wird.
FILEBROWSER_SHOWRANK1HINT;Nur mit 1 Stern bewertete Bilder anzeigen\nTaste: <b>1</b>
FILEBROWSER_SHOWRANK2HINT;Nur mit 2 Sternen bewertete Bilder anzeigen\nTaste: <b>2</b>
FILEBROWSER_SHOWRANK3HINT;Nur mit 3 Sternen bewertete Bilder anzeigen\nTaste: <b>3</b>
FILEBROWSER_SHOWRANK4HINT;Nur mit 4 Sternen bewertete Bilder anzeigen\nTaste: <b>4</b>
FILEBROWSER_SHOWRANK5HINT;Nur mit 5 Sternen bewertete Bilder anzeigen\nTaste: <b>5</b>
FILEBROWSER_SHOWRECENTLYSAVEDHINT;Nur gespeicherte Bilder anzeigen\nTaste: <b>Alt</b> + <b>7</b>
FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Nur nicht gespeicherte Bilder anzeigen\nTaste: <b>Alt</b> + <b>6</b>
FILEBROWSER_SHOWTRASHHINT;Inhalt des Papierkorbs anzeigen\nTaste: <b>Strg</b> + <b>t</b>
FILEBROWSER_SHOWUNCOLORHINT;Nur unmarkierte Bilder anzeigen\nTaste: <b>Alt</b> + <b>0</b>
FILEBROWSER_SHOWUNRANKHINT;Nur unbewertete Bilder anzeigen\nTaste: <b>0</b>
FILEBROWSER_SHOWRANK1HINT;Nur mit 1 Stern bewertete Bilder anzeigen.\nTaste: <b>1</b>
FILEBROWSER_SHOWRANK2HINT;Nur mit 2 Sternen bewertete Bilder anzeigen.\nTaste: <b>2</b>
FILEBROWSER_SHOWRANK3HINT;Nur mit 3 Sternen bewertete Bilder anzeigen.\nTaste: <b>3</b>
FILEBROWSER_SHOWRANK4HINT;Nur mit 4 Sternen bewertete Bilder anzeigen.\nTaste: <b>4</b>
FILEBROWSER_SHOWRANK5HINT;Nur mit 5 Sternen bewertete Bilder anzeigen.\nTaste: <b>5</b>
FILEBROWSER_SHOWRECENTLYSAVEDHINT;Nur gespeicherte Bilder anzeigen.\nTaste: <b>Alt</b> + <b>7</b>
FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Nur nicht gespeicherte Bilder anzeigen.\nTaste: <b>Alt</b> + <b>6</b>
FILEBROWSER_SHOWTRASHHINT;Inhalt des Papierkorbs anzeigen.\nTaste: <b>Strg</b> + <b>t</b>
FILEBROWSER_SHOWUNCOLORHINT;Nur unmarkierte Bilder anzeigen.\nTaste: <b>Alt</b> + <b>0</b>
FILEBROWSER_SHOWUNRANKHINT;Nur unbewertete Bilder anzeigen.\nTaste: <b>0</b>
FILEBROWSER_THUMBSIZE;Miniaturbildgröße
FILEBROWSER_UNRANK_TOOLTIP;Bewertung entfernen\nTaste: <b>Umschalt</b> + <b>0</b>
FILEBROWSER_ZOOMINHINT;Miniaturbilder vergrößern\n\nIm Multi-Reitermodus:\nTaste: <b>+</b>\nIm Ein-Reitermodus:\nTaste: <b>Alt</b> <b>+</b>
FILEBROWSER_ZOOMOUTHINT;Miniaturbilder verkleinern\n\nIm Multi-Reitermodus:\nTaste: <b>-</b>\nIm Ein-Reitermodus:\nTaste: <b>Alt</b> <b>-</b>
FILEBROWSER_UNRANK_TOOLTIP;Bewertung entfernen.\nTaste: <b>Umschalt</b> + <b>0</b>
FILEBROWSER_ZOOMINHINT;Miniaturbilder vergrößern.\n\nIm Multi-Reitermodus:\nTaste: <b>+</b>\nIm Ein-Reitermodus:\nTaste: <b>Alt</b> <b>+</b>
FILEBROWSER_ZOOMOUTHINT;Miniaturbilder verkleinern.\n\nIm Multi-Reitermodus:\nTaste: <b>-</b>\nIm Ein-Reitermodus:\nTaste: <b>Alt</b> <b>-</b>
FILECHOOSER_FILTER_ANY;Alle Dateien
FILECHOOSER_FILTER_COLPROF;Farbprofile
FILECHOOSER_FILTER_CURVE;Kurvendateien
@ -917,14 +918,14 @@ LENSPROFILE_CORRECTION_LCPFILE;LCP-Datei
LENSPROFILE_CORRECTION_MANUAL;Benutzerdefiniert (Lensfun)
LENSPROFILE_LENS_WARNING;Warnung: Der Cropfaktor des Profils entspricht nicht dem des Objektivs.\nDies kann zu einem fehlerhaften Ergebnis führen.
MAIN_BUTTON_FULLSCREEN;Vollbild\nTaste: <b>F11</b>
MAIN_BUTTON_ICCPROFCREATOR;ICC-Profil erstellen
MAIN_BUTTON_ICCPROFCREATOR;ICC-Profil erstellen.
MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigiert zum nächsten Miniaturbild in der\nDateiverwaltung oder Filmstreifen bezogen\nauf das ausgewählte Miniaturbild.\nTaste: <b>F4</b>\n\nNavigiert zum nächsten Miniaturbild in der\nDateiverwaltung oder Filmstreifen bezogen\nauf auf das im Editor geöffnete Bild.\nTaste: <b>Umschalt</b> + <b>F4 </b>
MAIN_BUTTON_NAVPREV_TOOLTIP;Navigiert zum vorherigen Miniaturbild in der\nDateiverwaltung oder Filmstreifen bezogen\nauf das ausgewählte Miniaturbild.\nTaste: <b>F3</b>\n\nNavigiert zum vorherigen Miniaturbild in der\nDateiverwaltung oder Filmstreifen bezogen\nauf auf das im Editor geöffnete Bild.\nTaste: <b>Umschalt</b> + <b>F3 </b>
MAIN_BUTTON_NAVSYNC_TOOLTIP;Selektiert das Miniaturbild des aktuell geöffneten\nBildes in der Dateiverwaltung und des Filmstreifens.\nEs werden alle aktiven Filter gelöscht.\nTaste: <b>x</b>\n\nWie oben, jedoch ohne Löschung aktiver Filter. Das\nMiniaturbild des geöffneten Bildes wird nicht angezeigt,\nwenn es herausgefiltert wurde.\nTaste: <b>y</b>
MAIN_BUTTON_PREFERENCES;Einstellungen
MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Bild zur Warteschlange hinzufügen.\nTaste: <b>Strg</b> + <b>b</b>
MAIN_BUTTON_SAVE_TOOLTIP;Bild speichern.\nTaste: <b>Strg</b> + <b>s</b>\nProfil (.pp3) speichern.\nTaste: <b>Strg</b> + <b>Umschalt</b> + <b>s</b>
MAIN_BUTTON_SENDTOEDITOR;Bild im externen Editor öffnen
MAIN_BUTTON_SENDTOEDITOR;Bild im externen Editor öffnen.
MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Bild im externen Editor öffnen.\nTaste: <b>Strg</b> + <b>e</b>
MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Alle seitlichen Bedienfelder ein-/ausblenden.\nTaste: <b>m</b>
MAIN_BUTTON_UNFULLSCREEN;Vollbild beenden.\nTaste: <b>F11</b>
@ -939,8 +940,8 @@ MAIN_FRAME_PLACES_ADD;Hinzufügen
MAIN_FRAME_PLACES_DEL;Entfernen
MAIN_FRAME_RECENT;Verzeichnishistorie
MAIN_MSG_ALREADYEXISTS;Diese Datei existiert bereits.
MAIN_MSG_CANNOTLOAD;Bild kann nicht geladen werden
MAIN_MSG_CANNOTSAVE;Fehler beim Speichern
MAIN_MSG_CANNOTLOAD;Bild kann nicht geladen werden.
MAIN_MSG_CANNOTSAVE;Fehler beim Speichern.
MAIN_MSG_CANNOTSTARTEDITOR;Der externe Editor kann nicht gestartet werden.
MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Setzen Sie bitte den richtigen Pfad in den Einstellungen.
MAIN_MSG_EMPTYFILENAME;Dateiname fehlt!
@ -1182,7 +1183,7 @@ PREFERENCES_GREYSC18;Yb = 18 CIE L#49
PREFERENCES_GREYSCA;Automatisch
PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogramm linksseitig
PREFERENCES_HISTOGRAMWORKING;Das Arbeitsprofil zur Darstellung des Haupthistogramms verwenden
PREFERENCES_HISTOGRAM_TOOLTIP;Wenn aktiviert wird das Arbeitsprofil für die Darstellung\ndes Haupthistogramms verwendet, andernfalls das des\ngammakorrigierten Ausgangsprofil.
PREFERENCES_HISTOGRAM_TOOLTIP;Wenn aktiviert, wird das Arbeitsprofil für die Darstellung\ndes Haupthistogramms verwendet, andernfalls das des\ngammakorrigierten Ausgangsprofils.
PREFERENCES_HLTHRESHOLD;Lichter - Schwelle
PREFERENCES_ICCDIR;ICC-Profile-Verzeichnis
PREFERENCES_IMG_RELOAD_NEEDED;Änderungen werden nur auf neu geöffnete Bilder angewendet
@ -1214,7 +1215,7 @@ PREFERENCES_MULTITABDUALMON;Multi-Reitermodus (auf zweitem Monitor, wenn verfüg
PREFERENCES_NAVGUIDEBRUSH;Farbe der Navigationshilfe
PREFERENCES_NAVIGATIONFRAME;Navigation
PREFERENCES_OUTDIR;Ausgabeverzeichnis
PREFERENCES_OUTDIRFOLDER;In dieses Verzeichnis speichern.
PREFERENCES_OUTDIRFOLDER;In dieses Verzeichnis speichern
PREFERENCES_OUTDIRFOLDERHINT;Alle Dateien im ausgewählten Verzeichnis speichern.
PREFERENCES_OUTDIRTEMPLATE;Dynamisches Verzeichnis verwenden
PREFERENCES_OUTDIRTEMPLATEHINT;Die folgenden Variablen können verwendet werden:\n<b>%f</b>, <b>%d1</b>, <b>%d2</b>, ..., <b>%p1</b>, <b>%p2</b>, ..., <b>%r</b>, <b>%s1</b>, <b>%s2</b>, ...\n\nDiese Variablen beinhalten bestimmte Teile des Verzeichnispfades, in welchem sich das Bild befindet, oder Attribute des Bildes.\n\nWenn zum Beispiel <b><i>/home/tom/photos/2010-10-31/dsc0042.nef</i></b> geöffnet wurde, dann haben die Variablen den folgenden Inhalt:\n<b>%d4</b> = <i>home</i>\n<b>%d3</b> = <i>tom</i>\n<b>%d2</b> = <i>photos</i>\n<b>%d1</b> = <i>2010-10-31</i>\n<b>%f</b> = <i>dsc0042</i>\n<b>%p1</b> = <i>/home/tom/photos/2010-10-31</i>\n<b>%p2</b> = <i>/home/tom/photos</i>\n<b>%p3</b> = <i>/home/tom</i>\n<b>%p4</b> = <i>/home</i>\n\nWenn Sie die Ausgabedatei in dasselbe Verzeichnis wie das Originalbild speichern wollen, dann wählen Sie:\n<b>%p1/%f</b>\n\nWenn Sie die Ausgabedatei in ein Unterverzeichnis mit dem Namen "<i>converted</i>" schreiben wollen, dann wählen Sie:\n<b>%p1/converted/%f</b>\n\nWenn Sie die Ausgabedatei im Verzeichnispfad "<i>/home/tom/photos/converted</i>" speichern wollen, dort jedoch in einem mit dem Namen des Ursprungsverzeichnisses betitelten Unterverzeichnis, dann wählen Sie:\n<b>%p2/converted/%d1/%f</b>\n\nDie Variable <b>%r</b> enthält die Bewertung des Bildes.
@ -1251,10 +1252,10 @@ PREFERENCES_PSPATH;Adobe Photoshop Installationsverzeichnis
PREFERENCES_REMEMBERZOOMPAN;Zoom und Bildposition merken
PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Öffnen eines neuen Bildes mit den Zoom- und Positionswerten\ndes vorangegangenen Bildes.\n\nFunktioniert nur unter folgenden Bedingungen:\nEin-Reitermodus aktiv\n“Demosaikmethode für 100%-Ansicht“ muss auf “Wie im Bild-\nverarbeitungsprofil vorgegeben“ eingestellt sein.
PREFERENCES_SAVE_TP_OPEN_NOW;Werkzeugstatus jetzt speichern
PREFERENCES_SELECTFONT;Schriftart
PREFERENCES_SELECTFONT_COLPICKER;Schriftart für die Farbwähler
PREFERENCES_SELECTFONT;Schriftart:
PREFERENCES_SELECTFONT_COLPICKER;Schriftart Farbwähler
PREFERENCES_SELECTLANG;Sprache
PREFERENCES_SELECTTHEME;Oberflächendesign (erfordert Neustart)
PREFERENCES_SELECTTHEME;Oberflächendesign
PREFERENCES_SERIALIZE_TIFF_READ;TIFF-Bilder
PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialisiertes Lesen von TIFF-Bildern verwenden
PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Beim Arbeiten mit Ordnern voll unkomprimierter TIFF-Bilder, kann diese Einstellung das Generieren von Miniaturbildern deutlich beschleunigen.
@ -1278,7 +1279,7 @@ PREFERENCES_TAB_GENERAL;Allgemein
PREFERENCES_TAB_IMPROC;Bildbearbeitung
PREFERENCES_TAB_PERFORMANCE;Performance
PREFERENCES_TAB_SOUND;Klänge
PREFERENCES_THEME;Oberflächendesign
PREFERENCES_THEME;Oberflächendesign (erfordert Neustart)
PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Eingebundenes JPEG
PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Bildanzeige
PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutrales RAW-Bild
@ -1541,7 +1542,7 @@ TP_COLORTONING_METHOD;Methode
TP_COLORTONING_METHOD_TOOLTIP;L*a*b*-Überlagerung, RGB-Regler und RGB-Kurven\nverwenden eine interpolierte Farbüberlagerung.\n\nFarbausgleich (Schatten/Mitten/Lichter) und Sättigung\n(2-Farben) verwenden direkte Farben.
TP_COLORTONING_MIDTONES;Mitten
TP_COLORTONING_NEUTRAL;Regler zurücksetzen
TP_COLORTONING_NEUTRAL_TIP;Alle Werte auf Standard zurücksetzen\n(Schatten, Mitten, Lichter)
TP_COLORTONING_NEUTRAL_TIP;Alle Werte auf Standard zurücksetzen.\n(Schatten, Mitten, Lichter)
TP_COLORTONING_OPACITY;Deckkraft
TP_COLORTONING_RGBCURVES;RGB-Kurven
TP_COLORTONING_RGBSLIDERS;RGB-Regler
@ -1573,7 +1574,7 @@ TP_CROP_GUIDETYPE;Hilfslinien:
TP_CROP_H;Höhe
TP_CROP_LABEL;Ausschnitt
TP_CROP_PPI;PPI=
TP_CROP_SELECTCROP;Ausschnitt wählen.
TP_CROP_SELECTCROP;Ausschnitt wählen
TP_CROP_W;Breite
TP_CROP_X;x
TP_CROP_Y;y
@ -2073,7 +2074,7 @@ TP_RGBCURVES_LUMAMODE_TOOLTIP;Der <b>Helligkeitsmodus</b> ändert die Helligkeit
TP_RGBCURVES_RED;R
TP_ROTATE_DEGREE;Winkel
TP_ROTATE_LABEL;Drehen
TP_ROTATE_SELECTLINE;Leitlinie wählen.
TP_ROTATE_SELECTLINE;Leitlinie wählen
TP_SAVEDIALOG_OK_TIP;Taste: <b>Strg</b> + <b>Enter</b>
TP_SHADOWSHLIGHTS_HIGHLIGHTS;Lichter
TP_SHADOWSHLIGHTS_HLTONALW;Tonwertbreite Lichter
@ -2350,10 +2351,9 @@ TP_WBALANCE_WATER1;Unterwasser 1
TP_WBALANCE_WATER2;Unterwasser 2
TP_WBALANCE_WATER_HEADER;Unterwasser
ZOOMPANEL_100;(100%)
ZOOMPANEL_NEWCROPWINDOW;Neues Detailfenster öffnen
ZOOMPANEL_NEWCROPWINDOW;Neues Detailfenster öffnen.
ZOOMPANEL_ZOOM100;Zoom 100%\nTaste: <b>z</b>
ZOOMPANEL_ZOOMFITCROPSCREEN;Ausschnitt an Bildschirm anpassen\nTaste: <b>f</b>
ZOOMPANEL_ZOOMFITSCREEN;An Bildschirm anpassen\nTaste: <b>Alt</b> + <b>f</b>
ZOOMPANEL_ZOOMFITCROPSCREEN;Ausschnitt an Bildschirm anpassen.\nTaste: <b>f</b>
ZOOMPANEL_ZOOMFITSCREEN;An Bildschirm anpassen.\nTaste: <b>Alt</b> + <b>f</b>
ZOOMPANEL_ZOOMIN;Hineinzoomen\nTaste: <b>+</b>
ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: <b>-</b>

View File

@ -728,7 +728,8 @@ HISTORY_MSG_492;RGB Curves
HISTORY_MSG_493;L*a*b* Adjustments
HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors
HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction
HISTORY_MSG_DUALDEMOSAIC_CONTRAST;AMaZE+VNG4 - Contrast threshold
HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold
HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold
HISTORY_MSG_HISTMATCHING;Auto-matched tone curve
HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries
HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D
@ -751,6 +752,7 @@ HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correction - Iterations
HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correction - Avoid color shift
HISTORY_MSG_RAW_BORDER;Raw border
HISTORY_MSG_RESIZE_ALLOWUPSCALING;Resize - Allow upscaling
HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace
HISTORY_MSG_SHARPENING_CONTRAST;Sharpening - Contrast threshold
HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light
HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength
@ -1815,6 +1817,8 @@ TP_RAW_DMETHOD;Method
TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing...
TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement...
TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look.\nPixel Shift is for Pentax/Sony Pixel Shift files. It falls back to AMaZE for non-Pixel Shift files.
TP_RAW_DUALDEMOSAICAUTOCONTRAST;Auto threshold
TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value based on flat regions in the image.\nIf there is no flat region in the image or the image is too noisy, the value will be set to 0.\nTo set the value manually, uncheck the check-box first (reasonable values depend on the image).
TP_RAW_DUALDEMOSAICCONTRAST;Contrast threshold
TP_RAW_EAHD;EAHD
TP_RAW_FALSECOLOR;False color suppression steps

View File

@ -36,6 +36,18 @@ scrollbar:not(.overlay-indicator):hover {
min-width: 1px;
}
/* Toolbar stuck workaround */
.scrollableToolbar > scrollbar:not(.dummy),
.scrollableToolbar > scrollbar:not(.dummy) > contents:not(.dummy),
.scrollableToolbar > scrollbar:not(.dummy) > contents:not(.dummy) > trough:not(.dummy),
.scrollableToolbar > scrollbar:not(.dummy) > contents:not(.dummy) > trough:not(.dummy) > slider:not(.dummy) {
padding: 0;
margin: 0;
min-height: 0;
min-width: 0;
border: none;
}
.view:selected:not(check):not(radio) {
color: #262626;
background-color: #AAAAAA

View File

@ -2,7 +2,7 @@
This file is part of RawTherapee.
Copyright (c) 2016-2018 TooWaBoo
Version 2.80
Version 2.82
RawTherapee is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -80,7 +80,6 @@
min-height: 0;
padding: 0;
margin: 0;
opacity: 1;
border: none;
box-shadow: none;
}
@ -145,6 +144,10 @@ arrow {
min-width: 1.333333333333333333em;
min-height: 1.333333333333333333em;
}
/* combobox cellview to high for font size 8@96dpi*/
cellview {
margin: -1px 0;
}
text {
background-color: @bg-dark-grey;
@ -290,7 +293,7 @@ textview:selected, treeview:selected {
}
#Snapshots > border {
min-height: calc(6.5em + 36px);
min-height: calc(6em + 36px);
}
#Snapshots > label {
margin-bottom: -4px;
@ -315,6 +318,7 @@ textview:selected, treeview:selected {
border: 0.083333333333333333em solid @bg-dark-grey;
border-radius: 0;
box-shadow: none;
min-height: 2em;
}
#Snapshots button:hover,
@ -326,8 +330,9 @@ background-color: @bg-list-hover;
background-color: shade(@bg-list-hover, 1.15);
}
fontchooser scrolledwindow,
#PlacesPaned scrolledwindow,
#HistoryPanel > border,
#HistoryPanel scrolledwindow,
#Snapshots scrolledwindow {
background-color: @bg-dark-grey;
border: 0.083333333333333333em solid @bg-dark-grey;
@ -686,7 +691,18 @@ scrollbar.hovering slider:hover {
scrollbar:not(.overlay-indicator):hover {
min-width: 1px;
}
/**/
/* Toolbar stuck workaround */
.scrollableToolbar > scrollbar:not(.dummy),
.scrollableToolbar > scrollbar:not(.dummy) > contents:not(.dummy),
.scrollableToolbar > scrollbar:not(.dummy) > contents:not(.dummy) > trough:not(.dummy),
.scrollableToolbar > scrollbar:not(.dummy) > contents:not(.dummy) > trough:not(.dummy) > slider:not(.dummy) {
padding: 0;
margin: 0;
min-height: 0;
min-width: 0;
border: none;
}
/*** end ***************************************************************************************/
@ -1477,6 +1493,10 @@ button.text-button label {
margin: 0 0.5em;/* x */
}
button image + label {
margin-left: 0.25em;
}
#PrefNotebook > stack > :nth-child(5) combobox {
/* margin: 0.166666666666666666em 0; */
margin: 2px 0;
@ -1583,12 +1603,9 @@ button.MiddleH {
margin-left: -2px;
}
#PlacesPaned button.Left,
#PlacesPaned button.Right {
margin-top: 3px;
}
#PlacesPaned combobox {
margin-bottom: -3px;
margin-bottom: -8px;
padding-bottom: 0.416666666666666666em;
}
/**/
@ -1699,8 +1716,16 @@ buttonbox:not(.dialog-action-area) button{
button.color {
min-height: 1.166666666666666666em;
min-width: 2.75em;
padding: 0.25em;
}
button.color colorswatch,
colorchooser colorswatch {
border: 1px solid @bg-button-border;
}
colorchooser colorswatch#add-color-button:first-child {
border-radius: 5.5px 0 0 5.5px;
}
/* Save, Cancel, OK ... buttons */
.dialog-action-area button {
@ -2132,21 +2157,10 @@ headerbar .title:backdrop {
color: alpha(@winTitle,.60);
}
/*** end ***************************************************************************************/
/* Toolbar stuck workaround */
/* .scrollableToolbar scrollbar:not(.overlay-indicator) slider:not(.dummy) {
padding: 0;
margin: 0;
min-height: 0;
min-width: 0;
border: none;
} */
/* .view:not(check):not(radio), image:not(check):not(radio), spinbutton button, cellview {
-gtk-icon-transform: scale(1.5);
}
* {-gtk-dpi: 144;} */
-gtk-icon-transform: scale(calc(( 96 / 96 ) * ( 8 / 9 )));
} */
/* * {-gtk-dpi: 144;} */

View File

@ -33,7 +33,7 @@
@define-color bg-image rgb(120,120,120); /*** Image area & File Browser background * Default: rgb(70,70,70) ***/
@define-color accent-color2 rgb(49,132,220); /*** Scale, Progressbar, Scrollbar, Tabs * Default: rgb(35,99,166) ***/
@define-color accent-color2 rgb(175,175,175); /*** Scale, Progressbar, Scrollbar, Tabs * Default: rgb(35,99,166) ***/
@define-color accent-color4 rgb(155,155,155); /*** Slider knob * Default: rgb(115,115,115) ***/
@define-color accent-color3 rgb(85,85,85); /*** Selected thumbnail background color * Default: rgb(35,99,166) ***/
@ -43,10 +43,10 @@
@define-color bg-light-grey rgb(135,135,135);
@define-color bg-grey rgb(120,120,120);
@define-color bg-dark-grey rgb(85,85,85);
@define-color bg-dark-grey rgb(90,90,90);
@define-color bg-button-hover rgba(0,0,0,.15);
@define-color bg-button-active rgba(0,0,0,.5);
@define-color bg-button-hover rgba(40,40,40,.16);
@define-color bg-button-active rgba(40,40,40,.4);
@define-color winHeaderbar rgb(75,75,75);
@define-color winTitle rgb(210,210,210);
@ -55,7 +55,7 @@
@define-color border-tooltip rgb(50,50,50);
@define-color text-tooltip rgb(50,50,50);
/***********************************************/
@define-color text-color rgb(230,230,230);
@define-color text-color rgb(220,220,220);
@define-color text-tbEntry rgb(245,245,245);
@define-color border-color rgba(255,255,255,.35);
@define-color bg-list-hover rgb(95,95,95);

View File

@ -127,6 +127,7 @@ set(RTENGINESOURCEFILES
xtrans_demosaic.cc
vng4_demosaic_RT.cc
ipsoftlight.cc
guidedfilter.cc
)
if(LENSFUN_HAS_LOAD_DIRECTORY)

View File

@ -805,8 +805,15 @@ BENCHFUN
}
#endif
float *LbloxArray[denoiseNestedLevels * numthreads] = {};
float *fLbloxArray[denoiseNestedLevels * numthreads] = {};
const std::size_t blox_array_size = denoiseNestedLevels * numthreads;
float *LbloxArray[blox_array_size];
float *fLbloxArray[blox_array_size];
for (std::size_t i = 0; i < blox_array_size; ++i) {
LbloxArray[i] = nullptr;
fLbloxArray[i] = nullptr;
}
if (numtiles > 1 && denoiseLuminance) {
for (int i = 0; i < denoiseNestedLevels * numthreads; ++i) {

View File

@ -89,8 +89,7 @@ using LUTd = LUT<double>;
using LUTuc = LUT<uint8_t>;
template<typename T>
class LUT :
public rtengine::NonCopyable
class LUT
{
protected:
// list of variables ordered to improve cache speed
@ -198,6 +197,8 @@ public:
}
}
explicit LUT(const LUT&) = delete;
void setClip(int flags)
{
clip = flags;
@ -225,7 +226,7 @@ public:
return size > 0 ? upperBound : 0;
}
LUT<T> & operator=(LUT<T> &rhs)
LUT<T> & operator=(const LUT<T>& rhs)
{
if (this != &rhs) {
if (rhs.size > this->size) {
@ -257,7 +258,7 @@ public:
// handy to sum up per thread histograms. #pragma omp simd speeds up the loop by about factor 3 for LUTu (uint32_t).
template<typename U = T, typename = typename std::enable_if<std::is_same<U, std::uint32_t>::value>::type>
LUT<T> & operator+=(LUT<T> &rhs)
LUT<T> & operator+=(const LUT<T>& rhs)
{
if (rhs.size == this->size) {
#ifdef _OPENMP

View File

@ -267,11 +267,11 @@ public:
ar_realloc(w, h);
memcpy(data, copy, w * h * sizeof(T));
}
int width()
int width() const
{
return x;
}
int height()
int height() const
{
return y;
}

View File

@ -35,6 +35,8 @@ namespace rtengine
template<class T, class A> void boxblur (T** src, A** dst, int radx, int rady, int W, int H)
{
//box blur image; box range = (radx,rady)
assert(2*radx+1 < W);
assert(2*rady+1 < H);
AlignedBuffer<float>* buffer = new AlignedBuffer<float> (W * H);
float* temp = buffer->data;

View File

@ -1225,6 +1225,11 @@ Camera constants:
}
},
{ // Quality C
"make_model": "DJI FC6310",
"ranges": { "white": 64886 }
},
{ // Quality B
"make_model": "FUJIFILM GFX 50S",
"dcraw_matrix": [ 11756,-4754,-874,-3056,11045,2305,-381,1457,6006 ], // DNGv9.9 D65
@ -1338,13 +1343,13 @@ Camera constants:
"make_model": "LG mobile LG-H815",
"dcraw_matrix": [ 5859,547,-1250,-6484,15547,547,-2422,5625,3906 ], // DNG D65
//"dcraw_matrix": [ 11563,-2891,-3203,-5313,15625,625,-781,2813,5625 ], // DNG A
"ranges": { "white_max": 1000 }
"ranges": { "white": 1000 }
},
{ // Quality C
"make_model": "LG mobile LG-H850",
//"dcraw_matrix": [ 10000,-2188,-2813,-5156,15469,625,-703,2734,5078 ], // DNG A
"dcraw_matrix": [ 5313,1016,-1172,-6250,15391,547,-2344,5547,3359 ], // DNG D65
"ranges": { "white_max": 1000 }
"ranges": { "white": 1000 }
},
{ // Quality A
@ -1578,6 +1583,13 @@ Camera constants:
"ranges": { "white": 3980 } // 12-bit files.
},
{ // Quality C, only colour matrix and PDAF lines info
"make_model" : "Nikon Z 7",
"dcraw_matrix" : [10405,-3755,-1270,-5461,13787,1793,-1040,2015,6785], // Adobe DNG Converter 11.0 ColorMatrix2
"pdaf_pattern" : [0, 12],
"pdaf_offset" : 29
},
{ // Quality B, 16Mp and 64Mp raw frames
"make_model": "OLYMPUS E-M5MarkII",
"dcraw_matrix": [ 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 ], // DNG_v8.8 D65

View File

@ -6462,17 +6462,20 @@ guess_cfa_pc:
unsigned oldOrder = order;
order = 0x4d4d; // always big endian per definition in https://www.adobe.com/content/dam/acom/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf chapter 7
unsigned ntags = get4(); // read the number of opcodes
while (ntags--) {
unsigned opcode = get4();
fseek (ifp, 8, SEEK_CUR); // skip 8 bytes as they don't interest us currently
if (opcode == 4) { // FixBadPixelsConstant
fseek (ifp, 4, SEEK_CUR); // skip 4 bytes as we know that the opcode 4 takes 4 byte
if(get4() == 0) { // if raw 0 values should be treated as bad pixels, set zero_is_bad to true (1). That's the only value currently supported by rt
zero_is_bad = 1;
if (ntags < ifp->size / 12) { // rough check for wrong value (happens for example with DNG files from DJI FC6310)
while (ntags-- && !ifp->eof) {
unsigned opcode = get4();
fseek (ifp, 8, SEEK_CUR); // skip 8 bytes as they don't interest us currently
if (opcode == 4) { // FixBadPixelsConstant
fseek (ifp, 4, SEEK_CUR); // skip 4 bytes as we know that the opcode 4 takes 4 byte
if(get4() == 0) { // if raw 0 values should be treated as bad pixels, set zero_is_bad to true (1). That's the only value currently supported by rt
zero_is_bad = 1;
}
} else {
fseek (ifp, get4(), SEEK_CUR);
}
}
} else {
fseek (ifp, get4(), SEEK_CUR);
}
}
order = oldOrder;
break;
@ -10062,6 +10065,10 @@ dng_skip:
adobe_coeff (make, model);
if((!strncmp(make, "XIAOYI", 6) || !strncmp(make, "YI", 2)) && !strncmp(model, "M1",2))
adobe_coeff (make, model);
if(!strncmp(make, "DJI", 3) && !strncmp(model, "FC6310", 6)) // DNG files from this camera have wrong (too high) white level
adobe_coeff (make, model);
if (!strncmp(make, "LG", 2) && (!strncmp(model, "LG-H850",7) || !strncmp(model, "LG-H815",7)))
adobe_coeff (make, model);
if (raw_color) adobe_coeff (make, model);
if (load_raw == &CLASS kodak_radc_load_raw)
if (raw_color) adobe_coeff ("Apple","Quicktake");

View File

@ -139,10 +139,10 @@ void Crop::update(int todo)
// give possibility to the listener to modify crop window (as the full image dimensions are already known at this point)
int wx, wy, ww, wh, ws;
bool overrideWindow = false;
const bool overrideWindow = cropImageListener;
if (cropImageListener) {
overrideWindow = cropImageListener->getWindow(wx, wy, ww, wh, ws);
if (overrideWindow) {
cropImageListener->getWindow(wx, wy, ww, wh, ws);
}
// re-allocate sub-images and arrays if their dimensions changed

View File

@ -37,7 +37,7 @@
#include "sleef.c"
#include "opthelper.h"
#include "median.h"
#define BENCHMARK
//#define BENCHMARK
#include "StopWatch.h"
#ifdef _OPENMP
#include <omp.h>

View File

@ -36,11 +36,11 @@ using namespace std;
namespace rtengine
{
void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast, int autoX, int autoY)
void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast)
{
BENCHFUN
if (contrast == 0.0 && !autoContrast) {
if (contrast == 0.f && !autoContrast) {
// contrast == 0.0 means only first demosaicer will be used
if(isBayer) {
if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) ) {
@ -91,24 +91,6 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int wi
{ 0.019334, 0.119193, 0.950227 }
};
if (autoContrast && autoX >= 0 && autoY >= 0) {
constexpr int rectSize = 40;
const int autoWidth = min(rectSize, winw - autoX);
const int autoHeight = min(rectSize, winh - autoY);
if (std::min(autoWidth, autoHeight) > 20) {
array2D<float> autoL(autoWidth, autoHeight);
for(int i = 0; i < autoHeight; ++i) {
Color::RGB2L(red[i + autoY] + autoX, green[i + autoY] + autoX, blue[i + autoY] + autoX, autoL[i], xyz_rgb, autoWidth);
}
// calculate contrast based blend factors to use vng4 in regions with low contrast
JaggedArray<float> blend(autoWidth - 2, autoHeight - 2);
int c = calcContrastThreshold(autoL, blend, autoWidth, autoHeight);
if(c < 100) {
contrast = c; // alternative : contrast = c - 1
}
}
}
#pragma omp parallel
{
#pragma omp for
@ -118,7 +100,10 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int wi
}
// calculate contrast based blend factors to use vng4 in regions with low contrast
JaggedArray<float> blend(winw, winh);
buildBlendMask(L, blend, winw, winh, contrast / 100.f);
float contrastf = contrast / 100.f;
buildBlendMask(L, blend, winw, winh, contrastf, 1.f, autoContrast);
contrast = contrastf * 100.f;
// the following is split into 3 loops intentionally to avoid cache conflicts on CPUs with only 4-way cache
#pragma omp parallel for

View File

@ -21,11 +21,11 @@
//#include <giomm.h>
#include <helpers.h>
class PListener : public rtengine::ProgressListener
class PListener :
public rtengine::ProgressListener
{
public:
void setProgressStr (Glib::ustring str)
void setProgressStr(const Glib::ustring& str)
{
std::cout << str << std::endl;
}
@ -33,11 +33,16 @@ public:
{
std::cout << p << std::endl;
}
void setProgressState(bool inProcessing)
{
}
void error(const Glib::ustring& descr)
{
}
};
int main (int argc, char* argv[])
{
if (argc < 4) {
std::cout << "Usage: rtcmd <infile> <paramfile> <outfile>" << std::endl;
exit(1);

195
rtengine/guidedfilter.cc Normal file
View File

@ -0,0 +1,195 @@
/* -*- C++ -*-
*
* This file is part of RawTherapee.
*
* Copyright (c) 2018 Alberto Griggio <alberto.griggio@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* This is a Fast Guided Filter implementation, derived directly from the
* pseudo-code of the paper:
*
* Fast Guided Filter
* by Kaiming He, Jian Sun
*
* available at https://arxiv.org/abs/1505.00996
*/
#include "guidedfilter.h"
#include "boxblur.h"
#include "rescale.h"
#include "imagefloat.h"
namespace rtengine {
#if 0
# define DEBUG_DUMP(arr) \
do { \
Imagefloat im(arr.width(), arr.height()); \
const char *out = "/tmp/" #arr ".tif"; \
for (int y = 0; y < im.getHeight(); ++y) { \
for (int x = 0; x < im.getWidth(); ++x) { \
im.r(y, x) = im.g(y, x) = im.b(y, x) = arr[y][x] * 65535.f; \
} \
} \
im.saveTIFF(out, 16); \
} while (false)
#else
# define DEBUG_DUMP(arr)
#endif
void guidedFilter(const array2D<float> &guide, const array2D<float> &src, array2D<float> &dst, int r, float epsilon, bool multithread, int subsampling)
{
const int W = src.width();
const int H = src.height();
enum Op { MUL, DIVEPSILON, ADD, SUB, ADDMUL, SUBMUL };
const auto apply =
[=](Op op, array2D<float> &res, const array2D<float> &a, const array2D<float> &b, const array2D<float> &c=array2D<float>()) -> void
{
const int w = res.width();
const int h = res.height();
#ifdef _OPENMP
#pragma omp parallel for if (multithread)
#endif
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; ++x) {
float r;
float aa = a[y][x];
float bb = b[y][x];
switch (op) {
case MUL:
r = aa * bb;
break;
case DIVEPSILON:
r = aa / (bb + epsilon);
break;
case ADD:
r = aa + bb;
break;
case SUB:
r = aa - bb;
break;
case ADDMUL:
r = aa * bb + c[y][x];
break;
case SUBMUL:
r = c[y][x] - (aa * bb);
break;
default:
assert(false);
r = 0;
break;
}
res[y][x] = r;
}
}
};
// use the terminology of the paper (Algorithm 2)
const array2D<float> &I = guide;
const array2D<float> &p = src;
array2D<float> &q = dst;
const auto f_mean =
[](array2D<float> &d, array2D<float> &s, int rad) -> void
{
rad = LIM(rad, 0, (min(s.width(), s.height()) - 1) / 2 - 1);
boxblur<float, float>(s, d, rad, rad, s.width(), s.height());
};
const auto f_subsample =
[=](array2D<float> &d, const array2D<float> &s) -> void
{
rescaleBilinear(s, d, multithread);
};
const auto f_upsample = f_subsample;
const int w = W / subsampling;
const int h = H / subsampling;
array2D<float> I1(w, h);
array2D<float> p1(w, h);
f_subsample(I1, I);
f_subsample(p1, p);
DEBUG_DUMP(I);
DEBUG_DUMP(p);
DEBUG_DUMP(I1);
DEBUG_DUMP(p1);
float r1 = float(r) / subsampling;
array2D<float> meanI(w, h);
f_mean(meanI, I1, r1);
DEBUG_DUMP(meanI);
array2D<float> meanp(w, h);
f_mean(meanp, p1, r1);
DEBUG_DUMP(meanp);
array2D<float> &corrIp = p1;
apply(MUL, corrIp, I1, p1);
f_mean(corrIp, corrIp, r1);
DEBUG_DUMP(corrIp);
array2D<float> &corrI = I1;
apply(MUL, corrI, I1, I1);
f_mean(corrI, corrI, r1);
DEBUG_DUMP(corrI);
array2D<float> &varI = corrI;
apply(SUBMUL, varI, meanI, meanI, corrI);
DEBUG_DUMP(varI);
array2D<float> &covIp = corrIp;
apply(SUBMUL, covIp, meanI, meanp, corrIp);
DEBUG_DUMP(covIp);
array2D<float> &a = varI;
apply(DIVEPSILON, a, covIp, varI);
DEBUG_DUMP(a);
array2D<float> &b = covIp;
apply(SUBMUL, b, a, meanI, meanp);
DEBUG_DUMP(b);
array2D<float> &meana = a;
f_mean(meana, a, r1);
DEBUG_DUMP(meana);
array2D<float> &meanb = b;
f_mean(meanb, b, r1);
DEBUG_DUMP(meanb);
array2D<float> meanA(W, H);
f_upsample(meanA, meana);
DEBUG_DUMP(meanA);
array2D<float> &meanB = q;
f_upsample(meanB, meanb);
DEBUG_DUMP(meanB);
apply(ADDMUL, q, meanA, I, meanB);
DEBUG_DUMP(q);
}
} // namespace rtengine

View File

@ -1,7 +1,8 @@
/*
/* -*- C++ -*-
*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
* Copyright (c) 2018 Alberto Griggio <alberto.griggio@gmail.com>
*
* RawTherapee is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,16 +17,13 @@
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MOUNTSELECTIONLISTENER_
#define _MOUNTSELECTIONLISTENER_
#include <glibmm.h>
#pragma once
class MountSelectionListener
{
#include "array2D.h"
public:
virtual void mountSelectionChanged (Glib::ustring mountRoot) {}
};
namespace rtengine {
#endif
void guidedFilter(const array2D<float> &guide, const array2D<float> &src, array2D<float> &dst, int r, float epsilon, bool multithread, int subsampling=4);
} // namespace rtengine

View File

@ -29,7 +29,6 @@ typedef enum IIO_Sample_Format {
//IIOSF_SIGNED_INT , // Not yet supported
IIOSF_UNSIGNED_CHAR = 1 << 0,
IIOSF_UNSIGNED_SHORT = 1 << 1,
//IIOSF_HALF , // OpenEXR & NVidia's Half Float, not yet supported
IIOSF_LOGLUV24 = 1 << 2,
IIOSF_LOGLUV32 = 1 << 3,
IIOSF_FLOAT16 = 1 << 4,

View File

@ -704,7 +704,7 @@ int ImageIO::getTIFFSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat,
sFormat = IIOSF_UNSIGNED_SHORT;
return IMIO_SUCCESS;
}
} else if (samplesperpixel == 3 && sampleformat == SAMPLEFORMAT_IEEEFP) {
} else if ((samplesperpixel == 3 || samplesperpixel == 4) && sampleformat == SAMPLEFORMAT_IEEEFP) {
if (bitspersample==16) {
sFormat = IIOSF_FLOAT16;
return IMIO_SUCCESS;
@ -718,7 +718,7 @@ int ImageIO::getTIFFSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat,
return IMIO_SUCCESS;
}
}
} else if (samplesperpixel == 3 && photometric == PHOTOMETRIC_LOGLUV) {
} else if ((samplesperpixel == 3 || samplesperpixel == 4) && photometric == PHOTOMETRIC_LOGLUV) {
if (compression == COMPRESSION_SGILOG24) {
sFormat = IIOSF_LOGLUV24;
return IMIO_SUCCESS;

View File

@ -83,6 +83,7 @@ public:
virtual void setBorder (unsigned int border) {}
virtual void setCurrentFrame (unsigned int frameNum) = 0;
virtual int getFrameCount () = 0;
virtual int getFlatFieldAutoClipValue () = 0;
// use right after demosaicing image, add coarse transformation and put the result in the provided Imagefloat*

View File

@ -93,7 +93,7 @@ ImProcCoordinator::ImProcCoordinator()
fw(0), fh(0), tr(0),
fullw(1), fullh(1),
pW(-1), pH(-1),
plistener(nullptr), imageListener(nullptr), aeListener(nullptr), acListener(nullptr), abwListener(nullptr), awbListener(nullptr), frameCountListener(nullptr), imageTypeListener(nullptr), actListener(nullptr), adnListener(nullptr), awavListener(nullptr), dehaListener(nullptr), hListener(nullptr),
plistener(nullptr), imageListener(nullptr), aeListener(nullptr), acListener(nullptr), abwListener(nullptr), awbListener(nullptr), flatFieldAutoClipListener(nullptr), bayerAutoContrastListener(nullptr), xtransAutoContrastListener(nullptr), frameCountListener(nullptr), imageTypeListener(nullptr), actListener(nullptr), adnListener(nullptr), awavListener(nullptr), dehaListener(nullptr), hListener(nullptr),
resultValid(false), lastOutputProfile("BADFOOD"), lastOutputIntent(RI__COUNT), lastOutputBPC(false), thread(nullptr), changeSinceLast(0), updaterRunning(false), destroying(false), utili(false), autili(false),
butili(false), ccutili(false), cclutili(false), clcutili(false), opautili(false), wavcontlutili(false), colourToningSatLimit(0.f), colourToningSatLimitOpacity(0.f), highQualityComputed(false)
{}
@ -160,7 +160,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
}
}
if (((todo & ALL) == ALL) || panningRelatedChange || (highDetailNeeded && options.prevdemo != PD_Sidecar)) {
if (((todo & ALL) == ALL) || (todo & M_MONITOR) || panningRelatedChange || (highDetailNeeded && options.prevdemo != PD_Sidecar)) {
bwAutoR = bwAutoG = bwAutoB = -9000.f;
if (todo == CROP && ipf.needsPCVignetting()) {
@ -199,6 +199,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
imgsrc->setCurrentFrame(params.raw.bayersensor.imageNum);
imgsrc->preprocess(rp, params.lensProf, params.coarse);
if (flatFieldAutoClipListener && rp.ff_AutoClipControl) {
flatFieldAutoClipListener->flatFieldAutoClipValueChanged(imgsrc->getFlatFieldAutoClipValue());
}
imgsrc->getRAWHistogram(histRedRaw, histGreenRaw, histBlueRaw);
highDetailPreprocessComputed = highDetailNeeded;
@ -239,10 +242,17 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
imgsrc->setBorder(std::max(params.raw.bayersensor.border, 2));
}
}
bool autoContrast = false;
double contrastThreshold = 0.f;
bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicAutoContrast : params.raw.xtranssensor.dualDemosaicAutoContrast;
double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicContrast : params.raw.xtranssensor.dualDemosaicContrast;
imgsrc->demosaic(rp, autoContrast, contrastThreshold); //enabled demosaic
if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener && autoContrast) {
bayerAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0);
}
if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener && autoContrast) {
xtransAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0);
}
// if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag
todo |= M_INIT;
@ -896,11 +906,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
// process crop, if needed
for (size_t i = 0; i < crops.size(); i++)
if (crops[i]->hasListener() && (panningRelatedChange || crops[i]->get_skip() == 1)) {
if (crops[i]->hasListener() && (panningRelatedChange || (highDetailNeeded && options.prevdemo != PD_Sidecar) || (todo & (M_MONITOR | M_RGBCURVE | M_LUMACURVE)) || crops[i]->get_skip() == 1)) {
crops[i]->update(todo); // may call ourselves
}
if (panningRelatedChange) {
if (panningRelatedChange || (todo & M_MONITOR)) {
progress("Conversion to RGB...", 100 * readyphase / numofphases);
if ((todo != CROP && todo != MINUPDATE) || (todo & M_MONITOR)) {
@ -1441,6 +1451,7 @@ void ImProcCoordinator::process()
|| params.softlight != nextParams.softlight
|| params.raw != nextParams.raw
|| params.retinex != nextParams.retinex
|| params.wavelet != nextParams.wavelet
|| params.dirpyrequalizer != nextParams.dirpyrequalizer;
params = nextParams;

View File

@ -158,6 +158,9 @@ protected:
AutoCamListener* acListener;
AutoBWListener* abwListener;
AutoWBListener* awbListener;
FlatFieldAutoClipListener *flatFieldAutoClipListener;
AutoContrastListener *bayerAutoContrastListener;
AutoContrastListener *xtransAutoContrastListener;
FrameCountListener *frameCountListener;
ImageTypeListener *imageTypeListener;
@ -344,6 +347,20 @@ public:
frameCountListener = fcl;
}
void setFlatFieldAutoClipListener (FlatFieldAutoClipListener* ffacl)
{
flatFieldAutoClipListener = ffacl;
}
void setBayerAutoContrastListener (AutoContrastListener* acl)
{
bayerAutoContrastListener = acl;
}
void setXtransAutoContrastListener (AutoContrastListener* acl)
{
xtransAutoContrastListener = acl;
}
void setImageTypeListener (ImageTypeListener* itl)
{
imageTypeListener = itl;

View File

@ -22,6 +22,7 @@
#include "gauss.h"
#include "sleef.c"
#include "opthelper.h"
#include "guidedfilter.h"
namespace rtengine {
@ -33,11 +34,32 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab)
const int width = lab->W;
const int height = lab->H;
const bool lab_mode = params->sh.lab;
array2D<float> mask(width, height);
const float sigma = params->sh.radius * 5.f / scale;
LUTf f(32768);
array2D<float> L(width, height);
const float radius = float(params->sh.radius) * 10 / scale;
LUTf f(lab_mode ? 32768 : 65536);
TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile);
TMatrix iws = ICCStore::getInstance()->workingSpaceInverseMatrix(params->icm.workingProfile);
const auto rgb2lab =
[&](float R, float G, float B, float &l, float &a, float &b) -> void
{
float x, y, z;
Color::rgbxyz(R, G, B, x, y, z, ws);
Color::XYZ2Lab(x, y, z, l, a, b);
};
const auto lab2rgb =
[&](float l, float a, float b, float &R, float &G, float &B) -> void
{
float x, y, z;
Color::Lab2XYZ(l, a, b, x, y, z);
Color::xyz2rgb(x, y, z, R, G, B, iws);
};
const auto apply =
[&](int amount, int tonalwidth, bool hl) -> void
{
@ -45,27 +67,24 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab)
const float scale = hl ? (thresh > 0.f ? 0.9f / thresh : 1.f) : thresh * 0.9f;
#ifdef _OPENMP
#pragma omp parallel if (multiThread)
#pragma omp parallel for if (multiThread)
#endif
{
#ifdef _OPENMP
#pragma omp for
#endif
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
float l = lab->L[y][x];
if (hl) {
mask[y][x] = (l > thresh) ? 1.f : pow4(l * scale);
} else {
mask[y][x] = l <= thresh ? 1.f : pow4(scale / l);
}
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
float l = lab->L[y][x];
float l1 = l / 32768.f;
if (hl) {
mask[y][x] = (l > thresh) ? 1.f : pow4(l * scale);
L[y][x] = 1.f - l1;
} else {
mask[y][x] = l <= thresh ? 1.f : pow4(scale / l);
L[y][x] = l1;
}
}
gaussianBlur(mask, mask, width, height, sigma);
}
guidedFilter(L, mask, mask, radius, 0.075, multiThread, 4);
const float base = std::pow(4.f, float(amount)/100.f);
const float gamma = hl ? base : 1.f / base;
@ -80,35 +99,55 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab)
});
if(!hl) {
if (lab_mode) {
#ifdef _OPENMP
#pragma omp parallel for if (multiThread)
#pragma omp parallel for if (multiThread)
#endif
for (int l = 0; l < 32768; ++l) {
auto base = pow_F(l / 32768.f, gamma);
// get a bit more contrast in the shadows
base = sh_contrast.getVal(base);
f[l] = base * 32768.f;
for (int l = 0; l < 32768; ++l) {
auto base = pow_F(l / 32768.f, gamma);
// get a bit more contrast in the shadows
base = sh_contrast.getVal(base);
f[l] = base * 32768.f;
}
} else {
#ifdef _OPENMP
#pragma omp parallel for if (multiThread)
#endif
for (int c = 0; c < 65536; ++c) {
float l, a, b;
float R = c, G = c, B = c;
rgb2lab(R, G, B, l, a, b);
auto base = pow_F(l / 32768.f, gamma);
// get a bit more contrast in the shadows
base = sh_contrast.getVal(base);
l = base * 32768.f;
lab2rgb(l, a, b, R, G, B);
f[c] = G;
}
}
} else {
#ifdef __SSE2__
vfloat c32768v = F2V(32768.f);
vfloat lv = _mm_setr_ps(0,1,2,3);
vfloat fourv = F2V(4.f);
vfloat gammav = F2V(gamma);
for (int l = 0; l < 32768; l += 4) {
vfloat basev = pow_F(lv / c32768v, gammav);
STVFU(f[l], basev * c32768v);
lv += fourv;
}
#else
if (lab_mode) {
#ifdef _OPENMP
#pragma omp parallel for if (multiThread)
#pragma omp parallel for if (multiThread)
#endif
for (int l = 0; l < 32768; ++l) {
auto base = pow_F(l / 32768.f, gamma);
f[l] = base * 32768.f;
for (int l = 0; l < 32768; ++l) {
auto base = pow_F(l / 32768.f, gamma);
f[l] = base * 32768.f;
}
} else {
#ifdef _OPENMP
#pragma omp parallel for if (multiThread)
#endif
for (int c = 0; c < 65536; ++c) {
float l, a, b;
float R = c, G = c, B = c;
rgb2lab(R, G, B, l, a, b);
auto base = pow_F(l / 32768.f, gamma);
l = base * 32768.f;
lab2rgb(l, a, b, R, G, B);
f[c] = G;
}
}
#endif
}
#ifdef _OPENMP
@ -117,17 +156,26 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab)
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
float l = lab->L[y][x];
float blend = mask[y][x];
float blend = LIM01(mask[y][x]);
float orig = 1.f - blend;
if (l >= 0.f && l < 32768.f) {
lab->L[y][x] = f[l] * blend + l * orig;
if (!hl && l > 1.f) {
// when pushing shadows, scale also the chromaticity
float s = max(lab->L[y][x] / l * 0.5f, 1.f) * blend;
float a = lab->a[y][x];
float b = lab->b[y][x];
lab->a[y][x] = a * s + a * orig;
lab->b[y][x] = b * s + b * orig;
if (lab_mode) {
lab->L[y][x] = f[l] * blend + l * orig;
if (!hl && l > 1.f) {
// when pushing shadows, scale also the chromaticity
float s = max(lab->L[y][x] / l * 0.5f, 1.f) * blend;
float a = lab->a[y][x];
float b = lab->b[y][x];
lab->a[y][x] = a * s + a * orig;
lab->b[y][x] = b * s + b * orig;
}
} else {
float rgb[3];
lab2rgb(l, lab->a[y][x], lab->b[y][x], rgb[0], rgb[1], rgb[2]);
for (int i = 0; i < 3; ++i) {
rgb[i] = f[rgb[i]] * blend + rgb[i] * orig;
}
rgb2lab(rgb[0], rgb[1], rgb[2], lab->L[y][x], lab->a[y][x], lab->b[y][x]);
}
}
}
@ -135,11 +183,11 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab)
};
if (params->sh.highlights > 0) {
apply(params->sh.highlights, params->sh.htonalwidth, true);
apply(params->sh.highlights * 0.7, params->sh.htonalwidth, true);
}
if (params->sh.shadows > 0) {
apply(params->sh.shadows, params->sh.stonalwidth, false);
apply(params->sh.shadows * 0.6, params->sh.stonalwidth, false);
}
}

View File

@ -176,7 +176,8 @@ BENCHFUN
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
JaggedArray<float> blend(W, H);
buildBlendMask(luminance, blend, W, H, sharpenParam.contrast / 100.f, sharpenParam.deconvamount / 100.0);
float contrast = sharpenParam.contrast / 100.f;
buildBlendMask(luminance, blend, W, H, contrast, sharpenParam.deconvamount / 100.f);
const float damping = sharpenParam.deconvdamping / 5.0;
const bool needdamp = sharpenParam.deconvdamping > 0;
@ -222,7 +223,8 @@ void ImProcFunctions::sharpening (LabImage* lab, const SharpeningParams &sharpen
if(showMask) {
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
JaggedArray<float> blend(W, H);
buildBlendMask(lab->L, blend, W, H, sharpenParam.contrast / 100.f, sharpenParam.method == "rld" ? sharpenParam.deconvamount / 100.0 : 1.f);
float contrast = sharpenParam.contrast / 100.f;
buildBlendMask(lab->L, blend, W, H, contrast, sharpenParam.method == "rld" ? sharpenParam.deconvamount / 100.f : 1.f);
#ifdef _OPENMP
#pragma omp parallel for
#endif
@ -256,7 +258,8 @@ BENCHFUN
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
JaggedArray<float> blend(W, H);
buildBlendMask(lab->L, blend, W, H, sharpenParam.contrast / 100.f);
float contrast = sharpenParam.contrast / 100.f;
buildBlendMask(lab->L, blend, W, H, contrast);
#ifdef _OPENMP
#pragma omp parallel
@ -610,7 +613,8 @@ BENCHFUN
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
JaggedArray<float> blend(W, H);
buildBlendMask(luminance, blend, W, H, params->sharpenMicro.contrast / 100.f);
float contrast = params->sharpenMicro.contrast / 100.f;
buildBlendMask(luminance, blend, W, H, contrast);
#ifdef _OPENMP
#pragma omp parallel
@ -819,7 +823,8 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2, bool showMask)
if(showMask) {
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
JaggedArray<float> blend(W, H);
buildBlendMask(ncie->sh_p, blend, W, H, params->sharpening.contrast / 100.f);
float contrast = params->sharpening.contrast / 100.f;
buildBlendMask(ncie->sh_p, blend, W, H, contrast);
#ifdef _OPENMP
#pragma omp parallel for
#endif
@ -852,7 +857,8 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2, bool showMask)
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
JaggedArray<float> blend(W, H);
buildBlendMask(ncie->sh_p, blend, W, H, params->sharpening.contrast / 100.f);
float contrast = params->sharpening.contrast / 100.f;
buildBlendMask(ncie->sh_p, blend, W, H, contrast);
#ifdef _OPENMP
#pragma omp parallel

View File

@ -1501,7 +1501,8 @@ SHParams::SHParams() :
htonalwidth(70),
shadows(0),
stonalwidth(30),
radius(40)
radius(40),
lab(false)
{
}
@ -1513,7 +1514,8 @@ bool SHParams::operator ==(const SHParams& other) const
&& htonalwidth == other.htonalwidth
&& shadows == other.shadows
&& stonalwidth == other.stonalwidth
&& radius == other.radius;
&& radius == other.radius
&& lab == other.lab;
}
bool SHParams::operator !=(const SHParams& other) const
@ -2388,6 +2390,7 @@ RAWParams::BayerSensor::BayerSensor() :
greenthresh(0),
dcb_iterations(2),
lmmse_iterations(2),
dualDemosaicAutoContrast(true),
dualDemosaicContrast(20),
pixelShiftMotionCorrectionMethod(PSMotionCorrectionMethod::AUTO),
pixelShiftEperIso(0.0),
@ -2425,6 +2428,7 @@ bool RAWParams::BayerSensor::operator ==(const BayerSensor& other) const
&& greenthresh == other.greenthresh
&& dcb_iterations == other.dcb_iterations
&& lmmse_iterations == other.lmmse_iterations
&& dualDemosaicAutoContrast == other.dualDemosaicAutoContrast
&& dualDemosaicContrast == other.dualDemosaicContrast
&& pixelShiftMotionCorrectionMethod == other.pixelShiftMotionCorrectionMethod
&& pixelShiftEperIso == other.pixelShiftEperIso
@ -2512,6 +2516,7 @@ Glib::ustring RAWParams::BayerSensor::getPSDemosaicMethodString(PSDemosaicMethod
RAWParams::XTransSensor::XTransSensor() :
method(getMethodString(Method::THREE_PASS)),
dualDemosaicAutoContrast(true),
dualDemosaicContrast(20),
ccSteps(0),
blackred(0.0),
@ -2524,6 +2529,7 @@ bool RAWParams::XTransSensor::operator ==(const XTransSensor& other) const
{
return
method == other.method
&& dualDemosaicAutoContrast == other.dualDemosaicAutoContrast
&& dualDemosaicContrast == other.dualDemosaicContrast
&& ccSteps == other.ccSteps
&& blackred == other.blackred
@ -3090,6 +3096,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->sh.shadows, "Shadows & Highlights", "Shadows", sh.shadows, keyFile);
saveToKeyfile(!pedited || pedited->sh.stonalwidth, "Shadows & Highlights", "ShadowTonalWidth", sh.stonalwidth, keyFile);
saveToKeyfile(!pedited || pedited->sh.radius, "Shadows & Highlights", "Radius", sh.radius, keyFile);
saveToKeyfile(!pedited || pedited->sh.lab, "Shadows & Highlights", "Lab", sh.lab, keyFile);
// Crop
saveToKeyfile(!pedited || pedited->crop.enabled, "Crop", "Enabled", crop.enabled, keyFile);
@ -3409,6 +3416,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->raw.bayersensor.dcbIterations, "RAW Bayer", "DCBIterations", raw.bayersensor.dcb_iterations, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.dcbEnhance, "RAW Bayer", "DCBEnhance", raw.bayersensor.dcb_enhance, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.lmmseIterations, "RAW Bayer", "LMMSEIterations", raw.bayersensor.lmmse_iterations, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.dualDemosaicAutoContrast, "RAW Bayer", "DualDemosaicAutoContrast", raw.bayersensor.dualDemosaicAutoContrast, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.dualDemosaicContrast, "RAW Bayer", "DualDemosaicContrast", raw.bayersensor.dualDemosaicContrast, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod, "RAW Bayer", "PixelShiftMotionCorrectionMethod", toUnderlying(raw.bayersensor.pixelShiftMotionCorrectionMethod), keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEperIso, "RAW Bayer", "PixelShiftEperIso", raw.bayersensor.pixelShiftEperIso, keyFile);
@ -3426,6 +3434,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftDemosaicMethod, "RAW Bayer", "pixelShiftDemosaicMethod", raw.bayersensor.pixelShiftDemosaicMethod, keyFile);
saveToKeyfile(!pedited || pedited->raw.bayersensor.pdafLinesFilter, "RAW Bayer", "PDAFLinesFilter", raw.bayersensor.pdafLinesFilter, keyFile);
saveToKeyfile(!pedited || pedited->raw.xtranssensor.method, "RAW X-Trans", "Method", raw.xtranssensor.method, keyFile);
saveToKeyfile(!pedited || pedited->raw.xtranssensor.dualDemosaicAutoContrast, "RAW X-Trans", "DualDemosaicAutoContrast", raw.xtranssensor.dualDemosaicAutoContrast, keyFile);
saveToKeyfile(!pedited || pedited->raw.xtranssensor.dualDemosaicContrast, "RAW X-Trans", "DualDemosaicContrast", raw.xtranssensor.dualDemosaicContrast, keyFile);
saveToKeyfile(!pedited || pedited->raw.xtranssensor.ccSteps, "RAW X-Trans", "CcSteps", raw.xtranssensor.ccSteps, keyFile);
saveToKeyfile(!pedited || pedited->raw.xtranssensor.exBlackRed, "RAW X-Trans", "PreBlackRed", raw.xtranssensor.blackred, keyFile);
@ -4022,6 +4031,11 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "Shadows & Highlights", "Shadows", pedited, sh.shadows, pedited->sh.shadows);
assignFromKeyfile(keyFile, "Shadows & Highlights", "ShadowTonalWidth", pedited, sh.stonalwidth, pedited->sh.stonalwidth);
assignFromKeyfile(keyFile, "Shadows & Highlights", "Radius", pedited, sh.radius, pedited->sh.radius);
if (ppVersion >= 344) {
assignFromKeyfile(keyFile, "Shadows & Highlights", "Lab", pedited, sh.lab, pedited->sh.lab);
} else {
sh.lab = true;
}
if (keyFile.has_key("Shadows & Highlights", "LocalContrast") && ppVersion < 329) {
int lc = keyFile.get_integer("Shadows & Highlights", "LocalContrast");
@ -4836,6 +4850,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "RAW Bayer", "DCBIterations", pedited, raw.bayersensor.dcb_iterations, pedited->raw.bayersensor.dcbIterations);
assignFromKeyfile(keyFile, "RAW Bayer", "DCBEnhance", pedited, raw.bayersensor.dcb_enhance, pedited->raw.bayersensor.dcbEnhance);
assignFromKeyfile(keyFile, "RAW Bayer", "LMMSEIterations", pedited, raw.bayersensor.lmmse_iterations, pedited->raw.bayersensor.lmmseIterations);
assignFromKeyfile(keyFile, "RAW Bayer", "DualDemosaicAutoContrast", pedited, raw.bayersensor.dualDemosaicAutoContrast, pedited->raw.bayersensor.dualDemosaicAutoContrast);
if (ppVersion < 345) {
raw.bayersensor.dualDemosaicAutoContrast = false;
if (pedited) {
pedited->raw.bayersensor.dualDemosaicAutoContrast = true;
}
}
assignFromKeyfile(keyFile, "RAW Bayer", "DualDemosaicContrast", pedited, raw.bayersensor.dualDemosaicContrast, pedited->raw.bayersensor.dualDemosaicContrast);
if (keyFile.has_key("RAW Bayer", "PixelShiftMotionCorrectionMethod")) {
@ -4883,6 +4904,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
if (keyFile.has_group("RAW X-Trans")) {
assignFromKeyfile(keyFile, "RAW X-Trans", "Method", pedited, raw.xtranssensor.method, pedited->raw.xtranssensor.method);
assignFromKeyfile(keyFile, "RAW X-Trans", "DualDemosaicAutoContrast", pedited, raw.xtranssensor.dualDemosaicAutoContrast, pedited->raw.xtranssensor.dualDemosaicAutoContrast);
if (ppVersion < 345) {
raw.xtranssensor.dualDemosaicAutoContrast = false;
if (pedited) {
pedited->raw.xtranssensor.dualDemosaicAutoContrast = true;
}
}
assignFromKeyfile(keyFile, "RAW X-Trans", "DualDemosaicContrast", pedited, raw.xtranssensor.dualDemosaicContrast, pedited->raw.xtranssensor.dualDemosaicContrast);
assignFromKeyfile(keyFile, "RAW X-Trans", "CcSteps", pedited, raw.xtranssensor.ccSteps, pedited->raw.xtranssensor.ccSteps);
assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackRed", pedited, raw.xtranssensor.blackred, pedited->raw.xtranssensor.exBlackRed);

View File

@ -749,6 +749,7 @@ struct SHParams {
int shadows;
int stonalwidth;
int radius;
bool lab;
SHParams();
@ -1285,6 +1286,7 @@ struct RAWParams {
int greenthresh;
int dcb_iterations;
int lmmse_iterations;
bool dualDemosaicAutoContrast;
double dualDemosaicContrast;
PSMotionCorrectionMethod pixelShiftMotionCorrectionMethod;
double pixelShiftEperIso;
@ -1332,6 +1334,7 @@ struct RAWParams {
};
Glib::ustring method;
bool dualDemosaicAutoContrast;
double dualDemosaicContrast;
int ccSteps;
double blackred;

View File

@ -39,14 +39,14 @@ class ProfileStoreListener
{
public:
virtual ~ProfileStoreListener() {}
virtual ~ProfileStoreListener() = default;
/** @brief Called whenever the current value has to be stored before update. */
virtual void storeCurrentValue() {}
virtual void storeCurrentValue() = 0;
/** @brief Called whenever the file list has been updated and the content of the listener has to be updated. */
virtual void updateProfileList() = 0;
/** @brief Called whenever the profile list has changed and the old value have to be restored (if possible). */
virtual void restoreValue() {}
virtual void restoreValue() = 0;
};
/// @brief ProfileStoreEntry type (folder or file)

View File

@ -2074,7 +2074,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c
double threshold = raw.bayersensor.dualDemosaicContrast;
dual_demosaic_RT (true, raw, W, H, rawData, red, green, blue, threshold, false);
} else {
dual_demosaic_RT (true, raw, W, H, rawData, red, green, blue, contrastThreshold, true, 0, 0);
dual_demosaic_RT (true, raw, W, H, rawData, red, green, blue, contrastThreshold, true);
}
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT) ) {
pixelshift(0, 0, W, H, raw, currFrame, ri->get_maker(), ri->get_model(), raw.expos);
@ -2107,7 +2107,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c
double threshold = raw.xtranssensor.dualDemosaicContrast;
dual_demosaic_RT (false, raw, W, H, rawData, red, green, blue, threshold, false);
} else {
dual_demosaic_RT (false, raw, W, H, rawData, red, green, blue, contrastThreshold, true, 0, 0);
dual_demosaic_RT (false, raw, W, H, rawData, red, green, blue, contrastThreshold, true);
}
} else if(raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO) ) {
nodemosaic(true);
@ -2872,8 +2872,6 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
float limitFactor = 1.f;
if(raw.ff_AutoClipControl) {
// int clipControlGui = 0;
for (int m = 0; m < 2; m++)
for (int n = 0; n < 2; n++) {
float maxval = 0.f;
@ -2917,7 +2915,7 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
}
}
// clipControlGui = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui
flatFieldAutoClipValue = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui
} else {
limitFactor = max((float)(100 - raw.ff_clipControl) / 100.f, 0.01f);
}
@ -3003,7 +3001,6 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
if(raw.ff_AutoClipControl) {
// determine maximum calculated value to avoid clipping
// int clipControlGui = 0;
float maxval = 0.f;
// xtrans files have only one black level actually, so we can simplify the code a bit
#ifdef _OPENMP
@ -3038,7 +3035,7 @@ void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile
// there's only one white level for xtrans
if(maxval + black[0] > ri->get_white(0)) {
limitFactor = ri->get_white(0) / (maxval + black[0]);
// clipControlGui = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui
flatFieldAutoClipValue = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui
}
} else {
limitFactor = max((float)(100 - raw.ff_clipControl) / 100.f, 0.01f);

View File

@ -74,7 +74,7 @@ protected:
RawImage* riFrames[4] = {nullptr};
unsigned int currFrame = 0;
unsigned int numFrames = 0;
int flatFieldAutoClipValue = 0;
array2D<float> rawData; // holds preprocessed pixel values, rowData[i][j] corresponds to the ith row and jth column
array2D<float> *rawDataFrames[4] = {nullptr};
array2D<float> *rawDataBuffer[3] = {nullptr};
@ -212,6 +212,7 @@ public:
ri = riFrames[currFrame];
}
int getFrameCount() {return numFrames;}
int getFlatFieldAutoClipValue() {return flatFieldAutoClipValue;}
class GreenEqulibrateThreshold {
public:
@ -274,7 +275,7 @@ protected:
void igv_interpolate(int winw, int winh);
void lmmse_interpolate_omp(int winw, int winh, array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, int iterations);
void amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue);//Emil's code for AMaZE
void dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast = false, int autoX = -1, int autoY = -1);
void dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast = false);
void fast_demosaic();//Emil's code for fast demosaicing
void dcb_demosaic(int iterations, bool dcb_enhance);
void ahd_demosaic();

99
rtengine/rescale.h Normal file
View File

@ -0,0 +1,99 @@
/* -*- C++ -*-
*
* This file is part of RawTherapee.
*
* Copyright (c) 2018 Alberto Griggio <alberto.griggio@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "array2D.h"
namespace rtengine {
inline float getBilinearValue(const array2D<float> &src, float x, float y)
{
const int W = src.width();
const int H = src.height();
// Get integer and fractional parts of numbers
int xi = x;
int yi = y;
float xf = x - xi;
float yf = y - yi;
int xi1 = std::min(xi + 1, W - 1);
int yi1 = std::min(yi + 1, H - 1);
float bl = src[yi][xi];
float br = src[yi][xi1];
float tl = src[yi1][xi];
float tr = src[yi1][xi1];
// interpolate
float b = xf * br + (1.f - xf) * bl;
float t = xf * tr + (1.f - xf) * tl;
float pxf = yf * t + (1.f - yf) * b;
return pxf;
}
inline void rescaleBilinear(const array2D<float> &src, array2D<float> &dst, bool multithread)
{
const int Ws = src.width();
const int Hs = src.height();
const int Wd = dst.width();
const int Hd = dst.height();
float col_scale = float (Ws) / float (Wd);
float row_scale = float (Hs) / float (Hd);
#ifdef _OPENMP
#pragma omp parallel for if (multithread)
#endif
for (int y = 0; y < Hd; ++y) {
float ymrs = y * row_scale;
for (int x = 0; x < Wd; ++x) {
dst[y][x] = getBilinearValue(src, x * col_scale, ymrs);
}
}
}
inline void rescaleNearest(const array2D<float> &src, array2D<float> &dst, bool multithread)
{
const int width = src.width();
const int height = src.height();
const int nw = dst.width();
const int nh = dst.height();
#ifdef _OPENMP
#pragma omp parallel for if (multithread)
#endif
for (int y = 0; y < nh; ++y) {
int sy = y * height / nh;
for (int x = 0; x < nw; ++x) {
int sx = x * width / nw;
dst[y][x] = src[sy][sx];
}
}
}
} // namespace rtengine

View File

@ -23,6 +23,7 @@
#include <cstdint>
#include <vector>
#include <iostream>
#include <vector>
#ifdef _OPENMP
#include <omp.h>
#endif
@ -32,6 +33,7 @@
#include "rt_algo.h"
#include "rt_math.h"
#include "sleef.c"
#include "jaggedarray.h"
namespace {
float calcBlendFactor(float val, float threshold) {
@ -190,75 +192,166 @@ void findMinMaxPercentile(const float* data, size_t size, float minPrct, float&
maxOut += minVal;
}
void buildBlendMask(float** luminance, float **blend, int W, int H, float contrastThreshold, float amount) {
void buildBlendMask(float** luminance, float **blend, int W, int H, float &contrastThreshold, float amount, bool autoContrast) {
constexpr float scale = 0.0625f / 327.68f;
if(contrastThreshold == 0.f) {
if(contrastThreshold == 0.f && !autoContrast) {
for(int j = 0; j < H; ++j) {
for(int i = 0; i < W; ++i) {
blend[j][i] = amount;
}
}
} else {
#ifdef _OPENMP
#pragma omp parallel
#endif
{
#ifdef __SSE2__
const vfloat contrastThresholdv = F2V(contrastThreshold);
const vfloat scalev = F2V(scale);
const vfloat amountv = F2V(amount);
#endif
#ifdef _OPENMP
#pragma omp for schedule(dynamic,16)
#endif
constexpr float scale = 0.0625f / 327.68f;
if (autoContrast) {
for (int pass = 0; pass < 2; ++pass) {
const int tilesize = 80 / (pass + 1);
const int numTilesW = W / tilesize;
const int numTilesH = H / tilesize;
std::vector<std::vector<std::pair<float, float>>> variances(numTilesH, std::vector<std::pair<float, float>>(numTilesW));
for(int j = 2; j < H - 2; ++j) {
int i = 2;
#pragma omp parallel for
for (int i = 0; i < numTilesH; ++i) {
int tileY = i * tilesize;
for (int j = 0; j < numTilesW; ++j) {
int tileX = j * tilesize;
#ifdef __SSE2__
for(; i < W - 5; i += 4) {
vfloat contrastv = vsqrtf(SQRV(LVFU(luminance[j][i+1]) - LVFU(luminance[j][i-1])) + SQRV(LVFU(luminance[j+1][i]) - LVFU(luminance[j-1][i])) +
SQRV(LVFU(luminance[j][i+2]) - LVFU(luminance[j][i-2])) + SQRV(LVFU(luminance[j+2][i]) - LVFU(luminance[j-2][i]))) * scalev;
STVFU(blend[j][i], amountv * calcBlendFactor(contrastv, contrastThresholdv));
vfloat avgv = ZEROV;
for (int y = tileY; y < tileY + tilesize; ++y) {
for (int x = tileX; x < tileX + tilesize; x += 4) {
avgv += LVFU(luminance[y][x]);
}
}
float avg = vhadd(avgv);
#else
float avg = 0.;
for (int y = tileY; y < tileY + tilesize; ++y) {
for (int x = tileX; x < tileX + tilesize; ++x) {
avg += luminance[y][x];
}
}
#endif
avg /= SQR(tilesize);
#ifdef __SSE2__
vfloat varv = ZEROV;
avgv = F2V(avg);
for (int y = tileY; y < tileY + tilesize; ++y) {
for (int x = tileX; x < tileX + tilesize; x +=4) {
varv += SQRV(LVFU(luminance[y][x]) - avgv);
}
}
float var = vhadd(varv);
#else
float var = 0.0;
for (int y = tileY; y < tileY + tilesize; ++y) {
for (int x = tileX; x < tileX + tilesize; ++x) {
var += SQR(luminance[y][x] - avg);
}
}
#endif
var /= (SQR(tilesize) * avg);
variances[i][j].first = var;
variances[i][j].second = avg;
}
}
#endif
for(; i < W - 2; ++i) {
float contrast = sqrtf(rtengine::SQR(luminance[j][i+1] - luminance[j][i-1]) + rtengine::SQR(luminance[j+1][i] - luminance[j-1][i]) +
rtengine::SQR(luminance[j][i+2] - luminance[j][i-2]) + rtengine::SQR(luminance[j+2][i] - luminance[j-2][i])) * scale;
float minvar = RT_INFINITY_F;
int minI = 0, minJ = 0;
for (int i = 0; i < numTilesH; ++i) {
for (int j = 0; j < numTilesW; ++j) {
if (variances[i][j].first < minvar && variances[i][j].second > 2000.f && variances[i][j].second < 20000.f) {
minvar = variances[i][j].first;
minI = i;
minJ = j;
}
}
}
blend[j][i] = amount * calcBlendFactor(contrast, contrastThreshold);
const int minY = tilesize * minI;
const int minX = tilesize * minJ;
// std::cout << pass << ": minvar : " << minvar << std::endl;
if (minvar <= 1.f || pass == 1) {
// a variance <= 1 means we already found a flat region and can skip second pass
// in second pass we allow a variance of 2
JaggedArray<float> Lum(tilesize, tilesize);
JaggedArray<float> Blend(tilesize, tilesize);
for (int i = 0; i < tilesize; ++i) {
for (int j = 0; j < tilesize; ++j) {
Lum[i][j] = luminance[i + minY][j + minX];
}
}
contrastThreshold = (pass == 0 || minvar <= 2.f) ? calcContrastThreshold(Lum, Blend, tilesize, tilesize) / 100.f : 0.f;
break;
}
}
}
if(contrastThreshold == 0.f) {
for(int j = 0; j < H; ++j) {
for(int i = 0; i < W; ++i) {
blend[j][i] = amount;
}
}
} else {
#ifdef _OPENMP
#pragma omp single
#pragma omp parallel
#endif
{
// upper border
for(int j = 0; j < 2; ++j) {
for(int i = 2; i < W - 2; ++i) {
blend[j][i] = blend[2][i];
}
}
// lower border
for(int j = H - 2; j < H; ++j) {
for(int i = 2; i < W - 2; ++i) {
blend[j][i] = blend[H-3][i];
}
}
for(int j = 0; j < H; ++j) {
// left border
blend[j][0] = blend[j][1] = blend[j][2];
// right border
blend[j][W - 2] = blend[j][W - 1] = blend[j][W - 3];
}
}
#ifdef __SSE2__
const vfloat contrastThresholdv = F2V(contrastThreshold);
const vfloat scalev = F2V(scale);
const vfloat amountv = F2V(amount);
#endif
#ifdef _OPENMP
#pragma omp for schedule(dynamic,16)
#endif
// blur blend mask to smooth transitions
gaussianBlur(blend, blend, W, H, 2.0);
for(int j = 2; j < H - 2; ++j) {
int i = 2;
#ifdef __SSE2__
for(; i < W - 5; i += 4) {
vfloat contrastv = vsqrtf(SQRV(LVFU(luminance[j][i+1]) - LVFU(luminance[j][i-1])) + SQRV(LVFU(luminance[j+1][i]) - LVFU(luminance[j-1][i])) +
SQRV(LVFU(luminance[j][i+2]) - LVFU(luminance[j][i-2])) + SQRV(LVFU(luminance[j+2][i]) - LVFU(luminance[j-2][i]))) * scalev;
STVFU(blend[j][i], amountv * calcBlendFactor(contrastv, contrastThresholdv));
}
#endif
for(; i < W - 2; ++i) {
float contrast = sqrtf(rtengine::SQR(luminance[j][i+1] - luminance[j][i-1]) + rtengine::SQR(luminance[j+1][i] - luminance[j-1][i]) +
rtengine::SQR(luminance[j][i+2] - luminance[j][i-2]) + rtengine::SQR(luminance[j+2][i] - luminance[j-2][i])) * scale;
blend[j][i] = amount * calcBlendFactor(contrast, contrastThreshold);
}
}
#ifdef _OPENMP
#pragma omp single
#endif
{
// upper border
for(int j = 0; j < 2; ++j) {
for(int i = 2; i < W - 2; ++i) {
blend[j][i] = blend[2][i];
}
}
// lower border
for(int j = H - 2; j < H; ++j) {
for(int i = 2; i < W - 2; ++i) {
blend[j][i] = blend[H-3][i];
}
}
for(int j = 0; j < H; ++j) {
// left border
blend[j][0] = blend[j][1] = blend[j][2];
// right border
blend[j][W - 2] = blend[j][W - 1] = blend[j][W - 3];
}
}
// blur blend mask to smooth transitions
gaussianBlur(blend, blend, W, H, 2.0);
}
}
}
}
@ -289,7 +382,7 @@ int calcContrastThreshold(float** luminance, float **blend, int W, int H) {
}
}
const float limit = (W - 2) * (H - 2) / 100.f;
const float limit = (W - 4) * (H - 4) / 100.f;
int c;
for (c = 1; c < 100; ++c) {
@ -318,6 +411,7 @@ int calcContrastThreshold(float** luminance, float **blend, int W, int H) {
break;
}
}
return c;
}
}

View File

@ -24,6 +24,6 @@
namespace rtengine
{
void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multiThread = true);
void buildBlendMask(float** luminance, float **blend, int W, int H, float contrastThreshold, float amount = 1.f);
void buildBlendMask(float** luminance, float **blend, int W, int H, float &contrastThreshold, float amount = 1.f, bool autoContrast = false);
int calcContrastThreshold(float** luminance, float **blend, int W, int H);
}

View File

@ -154,21 +154,20 @@ public:
/** This listener interface is used to indicate the progress of time consuming operations */
class ProgressListener
{
public:
virtual ~ProgressListener() {}
virtual ~ProgressListener() = default;
/** This member function is called when the percentage of the progress has been changed.
* @param p is a number between 0 and 1 */
virtual void setProgress (double p) {}
virtual void setProgress(double p) = 0;
/** This member function is called when a textual information corresponding to the progress has been changed.
* @param str is the textual information corresponding to the progress */
virtual void setProgressStr (Glib::ustring str) {}
virtual void setProgressStr(const Glib::ustring& str) = 0;
/** This member function is called when the state of the processing has been changed.
* @param inProcessing =true if the processing has been started, =false if it has been stopped */
virtual void setProgressState (bool inProcessing) {}
virtual void setProgressState(bool inProcessing) = 0;
/** This member function is called when an error occurs during the operation.
* @param descr is the error message */
virtual void error (Glib::ustring descr) {}
virtual void error(const Glib::ustring& descr) = 0;
};
class ImageSource;
@ -219,20 +218,20 @@ public:
class PreviewImageListener
{
public:
virtual ~PreviewImageListener() {}
virtual ~PreviewImageListener() = default;
/** With this member function the staged processor notifies the listener that it allocated a new
* image to store the end result of the processing. It can be used in a shared manner.
* @param img is a pointer to the image
* @param scale describes the current scaling applied compared to the 100% size (preview scale)
* @param cp holds the coordinates of the current crop rectangle */
virtual void setImage (IImage8* img, double scale, procparams::CropParams cp) {}
virtual void setImage(IImage8* img, double scale, const procparams::CropParams& cp) = 0;
/** With this member function the staged processor notifies the listener that the image passed as parameter
* will be deleted, and no longer used to store the preview image.
* @param img the pointer to the image to be destroyed. The listener has to free the image! */
virtual void delImage (IImage8* img) {}
virtual void delImage(IImage8* img) = 0;
/** With this member function the staged processor notifies the listener that the preview image has been updated.
* @param cp holds the coordinates of the current crop rectangle */
virtual void imageReady (procparams::CropParams cp) {}
virtual void imageReady(const procparams::CropParams& cp) = 0;
};
/** When the detailed crop image is ready for display during staged processing (thus the changes have been updated),
@ -242,52 +241,70 @@ public:
class DetailedCropListener
{
public:
virtual ~DetailedCropListener() {}
virtual ~DetailedCropListener() = default;
/** With this member function the staged processor notifies the listener that the detailed crop image has been updated.
* @param img is a pointer to the detailed crop image */
virtual void setDetailedCrop (IImage8* img, IImage8* imgtrue, procparams::ColorManagementParams cmp,
procparams::CropParams cp, int cx, int cy, int cw, int ch, int skip) {}
virtual bool getWindow (int& cx, int& cy, int& cw, int& ch, int& skip)
{
return false;
}
// virtual void setPosition (int x, int y, bool update=true) {}
virtual void setDetailedCrop(
IImage8* img,
IImage8* imgtrue,
const procparams::ColorManagementParams& cmp,
const procparams::CropParams& cp,
int cx,
int cy,
int cw,
int ch,
int skip
) = 0;
virtual void getWindow(int& cx, int& cy, int& cw, int& ch, int& skip) = 0;
};
/** This listener is used when the full size of the final image has been changed (e.g. rotated by 90 deg.) */
class SizeListener
{
public:
virtual ~SizeListener() {}
virtual ~SizeListener() = default;
/** This member function is called when the size of the final image has been changed
* @param w is the width of the final image (without cropping)
* @param h is the height of the final image (without cropping)
* @param ow is the width of the final image (without resizing and cropping)
* @param oh is the height of the final image (without resizing and cropping) */
virtual void sizeChanged (int w, int h, int ow, int oh) {}
virtual void sizeChanged(int w, int h, int ow, int oh) = 0;
};
/** This listener is used when the histogram of the final image has changed. */
class HistogramListener
{
public:
virtual ~HistogramListener() {}
virtual ~HistogramListener() = default;
/** This member function is called when the histogram of the final image has changed.
* @param histRed is the array of size 256 containing the histogram of the red channel
* @param histGreen is the array of size 256 containing the histogram of the green channel
* @param histBlue is the array of size 256 containing the histogram of the blue channel
* @param histLuma is the array of size 256 containing the histogram of the luminance channel
* other for curves backgrounds, histRAW is RAW without colors */
virtual void histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve,LUTu & histLLCurve, */LUTu & histLCAM, LUTu & histCCAM,
LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw, LUTu & histChroma, LUTu & histLRETI) {}
virtual void histogramChanged(
const LUTu& histRed,
const LUTu& histGreen,
const LUTu& histBlue,
const LUTu& histLuma,
const LUTu& histToneCurve,
const LUTu& histLCurve,
const LUTu& histCCurve,
const LUTu& histLCAM,
const LUTu& histCCAM,
const LUTu& histRedRaw,
const LUTu& histGreenRaw,
const LUTu& histBlueRaw,
const LUTu& histChroma,
const LUTu& histLRETI
) = 0;
};
/** This listener is used when the auto exposure has been recomputed (e.g. when the clipping ratio changed). */
class AutoExpListener
{
public:
virtual ~AutoExpListener() {}
virtual ~AutoExpListener() = default;
/** This member function is called when the auto exposure has been recomputed.
* @param brightness is the new brightness value (in logarithmic scale)
* @param bright is the new ...
@ -296,84 +313,93 @@ public:
* @param hlcompr is the new highlight recovery amount
* @param hlcomprthresh is the new threshold for hlcompr
* @param hlrecons set to true if HighLight Reconstruction is enabled */
virtual void autoExpChanged (double brightness, int bright, int contrast, int black, int hlcompr, int hlcomprthresh, bool hlrecons) {}
virtual void autoExpChanged(double brightness, int bright, int contrast, int black, int hlcompr, int hlcomprthresh, bool hlrecons) = 0;
virtual void autoMatchedToneCurveChanged(procparams::ToneCurveParams::TcMode curveMode, const std::vector<double> &curve) {}
virtual void autoMatchedToneCurveChanged(procparams::ToneCurveParams::TcMode curveMode, const std::vector<double>& curve) = 0;
};
class AutoCamListener
{
public :
virtual ~AutoCamListener() {}
virtual void autoCamChanged (double ccam, double ccamout) {}
virtual void adapCamChanged (double cadap) {}
virtual void ybCamChanged (int yb) {}
virtual ~AutoCamListener() = default;
virtual void autoCamChanged(double ccam, double ccamout) = 0;
virtual void adapCamChanged(double cadap) = 0;
virtual void ybCamChanged(int yb) = 0;
};
class AutoChromaListener
{
public :
virtual ~AutoChromaListener() {}
virtual void chromaChanged (double autchroma, double autred, double autblue) {}
virtual void noiseChanged (double nresid, double highresid) {}
virtual void noiseTilePrev (int tileX, int tileY, int prevX, int prevY, int sizeT, int sizeP) {}
virtual ~AutoChromaListener() = default;
virtual void chromaChanged(double autchroma, double autred, double autblue) = 0;
virtual void noiseChanged(double nresid, double highresid) = 0;
virtual void noiseTilePrev(int tileX, int tileY, int prevX, int prevY, int sizeT, int sizeP) = 0;
};
class RetinexListener
{
public :
virtual ~RetinexListener() {}
virtual void minmaxChanged (double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax) {}
public:
virtual ~RetinexListener() = default;
virtual void minmaxChanged(double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax) = 0;
};
class AutoColorTonListener
{
public :
virtual ~AutoColorTonListener() {}
virtual void autoColorTonChanged (int bwct, int satthres, int satprot) {}
public:
virtual ~AutoColorTonListener() = default;
virtual void autoColorTonChanged(int bwct, int satthres, int satprot) = 0;
};
class AutoBWListener
{
public :
virtual ~AutoBWListener() {}
virtual void BWChanged (double redbw, double greenbw, double bluebw) {}
public:
virtual ~AutoBWListener() = default;
virtual void BWChanged(double redbw, double greenbw, double bluebw) = 0;
};
class AutoWBListener
{
public :
public:
virtual ~AutoWBListener() = default;
virtual void WBChanged (double temp, double green) = 0;
virtual void WBChanged(double temp, double green) = 0;
};
class FrameCountListener
{
public :
public:
virtual ~FrameCountListener() = default;
virtual void FrameCountChanged (int n, int frameNum) = 0;
virtual void FrameCountChanged(int n, int frameNum) = 0;
};
class FlatFieldAutoClipListener
{
public:
virtual ~FlatFieldAutoClipListener() = default;
virtual void flatFieldAutoClipValueChanged(int n) = 0;
};
class ImageTypeListener
{
public :
public:
virtual ~ImageTypeListener() = default;
virtual void imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool is_Mono = false) = 0;
virtual void imageTypeChanged(bool isRaw, bool isBayer, bool isXtrans, bool is_Mono = false) = 0;
};
class AutoContrastListener
{
public :
virtual ~AutoContrastListener() = default;
virtual void autoContrastChanged (double autoContrast) = 0;
};
class WaveletListener
{
public :
virtual ~WaveletListener() {}
virtual void wavChanged (double nlevel) {}
public:
virtual ~WaveletListener() = default;
virtual void wavChanged(double nlevel) = 0;
};
/** This class represents a detailed part of the image (looking through a kind of window).
* It can be created and destroyed with the appropriate members of StagedImageProcessor.
* Several crops can be assigned to the same image. */
@ -469,7 +495,10 @@ public:
virtual void setHistogramListener (HistogramListener *l) = 0;
virtual void setPreviewImageListener (PreviewImageListener* l) = 0;
virtual void setAutoCamListener (AutoCamListener* l) = 0;
virtual void setFlatFieldAutoClipListener (FlatFieldAutoClipListener* l) = 0;
virtual void setFrameCountListener (FrameCountListener* l) = 0;
virtual void setBayerAutoContrastListener (AutoContrastListener* l) = 0;
virtual void setXtransAutoContrastListener (AutoContrastListener* l) = 0;
virtual void setAutoBWListener (AutoBWListener* l) = 0;
virtual void setAutoWBListener (AutoWBListener* l) = 0;
virtual void setAutoColorTonListener (AutoColorTonListener* l) = 0;
@ -554,8 +583,7 @@ public:
* there is no jobs left.
* @param img is the result of the last ProcessingJob
* @return the next ProcessingJob to process */
virtual ProcessingJob* imageReady (IImagefloat* img) = 0;
virtual void error (Glib::ustring message) = 0;
virtual ProcessingJob* imageReady(IImagefloat* img) = 0;
};
/** This function performs all the image processing steps corresponding to the given ProcessingJob. It runs in the background, thus it returns immediately,
* When it finishes, it calls the BatchProcessingListener with the resulting image and asks for the next job. It the listener gives a new job, it goes on

View File

@ -21,23 +21,28 @@
//#include <giomm.h>
#include <helpers.h>
class PListener : public rtengine::ProgressListener
class PListener :
public rtengine::ProgressListener
{
public:
void setProgressStr (Glib::ustring str)
void setProgressStr(const Glib::ustring& str)
{
std::cout << str << std::endl;
}
void setProgress (double p)
void setProgress(double p)
{
std::cout << p << std::endl;
}
void setProgressState(bool inProcessing)
{
}
void error(const Glib::ustring& descr)
{
}
};
int main (int argc, char* argv[])
{
if (argc < 4) {
std::cout << "Usage: rtcmd <infile> <paramfile> <outfile>" << std::endl;
exit(1);

View File

@ -209,8 +209,10 @@ private:
if (pl) {
pl->setProgress (0.20);
}
double contrastThresholdDummy;
imgsrc->demosaic (params.raw, false, contrastThresholdDummy);
bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicAutoContrast : params.raw.xtranssensor.dualDemosaicAutoContrast;
double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicContrast : params.raw.xtranssensor.dualDemosaicContrast;
imgsrc->demosaic (params.raw, autoContrast, contrastThreshold);
if (pl) {

View File

@ -100,6 +100,7 @@ public:
}
void setCurrentFrame(unsigned int frameNum) {}
int getFrameCount() {return 1;}
int getFlatFieldAutoClipValue() {return 0;}
void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) { R = G = B = 0;}

View File

@ -73,6 +73,7 @@
#include "sleef.c"
#include "opthelper.h"
#include "rt_algo.h"
#include "rescale.h"
namespace rtengine
{
@ -938,66 +939,14 @@ void solve_pde_fft (Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread)/*
* RT code from here on
*****************************************************************************/
inline float get_bilinear_value (const Array2Df &src, float x, float y)
inline void rescale_bilinear (const Array2Df &src, Array2Df &dst, bool multithread)
{
// Get integer and fractional parts of numbers
int xi = x;
int yi = y;
float xf = x - xi;
float yf = y - yi;
int xi1 = std::min (xi + 1, src.getCols() - 1);
int yi1 = std::min (yi + 1, src.getRows() - 1);
float bl = src (xi, yi);
float br = src (xi1, yi);
float tl = src (xi, yi1);
float tr = src (xi1, yi1);
// interpolate
float b = xf * br + (1.f - xf) * bl;
float t = xf * tr + (1.f - xf) * tl;
float pxf = yf * t + (1.f - yf) * b;
return pxf;
rescaleBilinear(src, dst, multithread);
}
void rescale_bilinear (const Array2Df &src, Array2Df &dst, bool multithread)
inline void rescale_nearest (const Array2Df &src, Array2Df &dst, bool multithread)
{
float col_scale = float (src.getCols()) / float (dst.getCols());
float row_scale = float (src.getRows()) / float (dst.getRows());
#ifdef _OPENMP
#pragma omp parallel for if (multithread)
#endif
for (int y = 0; y < dst.getRows(); ++y) {
float ymrs = y * row_scale;
for (int x = 0; x < dst.getCols(); ++x) {
dst (x, y) = get_bilinear_value (src, x * col_scale, ymrs);
}
}
}
void rescale_nearest (const Array2Df &src, Array2Df &dst, bool multithread)
{
const int width = src.getCols();
const int height = src.getRows();
const int nw = dst.getCols();
const int nh = dst.getRows();
#ifdef _OPENMP
#pragma omp parallel for if (multithread)
#endif
for (int y = 0; y < nh; ++y) {
int sy = y * height / nh;
for (int x = 0; x < nw; ++x) {
int sx = x * width / nw;
dst (x, y) = src (sx, sy);
}
}
rescaleNearest(src, dst, multithread);
}

View File

@ -3043,7 +3043,7 @@ void ExifManager::parse (bool isRaw, bool skipIgnored)
if (!sftTagList.empty()) {
for (auto sft : sftTagList) {
int sftVal = sft->toInt();
if (sftVal == (isRaw ? 0 : 2)) {
if (sftVal == 0 || (!isRaw && sftVal == 2)) {
frames.push_back(sft->getParent());
frameRootDetected = true;

View File

@ -239,10 +239,12 @@ void Adjuster::autoToggled ()
// Disable the slider and spin button
spin->set_sensitive(false);
slider->set_sensitive(false);
reset->set_sensitive(false);
} else {
// Enable the slider and spin button
spin->set_sensitive(true);
slider->set_sensitive(true);
reset->set_sensitive(true);
}
}
@ -471,10 +473,12 @@ void Adjuster::setAutoValue (bool a)
// Disable the slider and spin button
spin->set_sensitive(false);
slider->set_sensitive(false);
reset->set_sensitive(false);
} else {
// Enable the slider and spin button
spin->set_sensitive(true);
slider->set_sensitive(true);
reset->set_sensitive(true);
}
}
}

View File

@ -24,13 +24,13 @@
#include "guiutils.h"
class Adjuster;
class AdjusterListener
{
public:
virtual ~AdjusterListener() {};
virtual void adjusterChanged (Adjuster* a, double newval) {}
virtual void adjusterAutoToggled (Adjuster* a, bool newval) {}
virtual ~AdjusterListener() = default;
virtual void adjusterChanged (Adjuster* a, double newval) = 0;
virtual void adjusterAutoToggled (Adjuster* a, bool newval) = 0;
};
typedef double(*double2double_fun)(double val);

View File

@ -39,6 +39,27 @@
using namespace std;
using namespace rtengine;
namespace
{
struct NLParams {
BatchQueueListener* listener;
int qsize;
bool queueEmptied;
bool queueError;
Glib::ustring queueErrorMessage;
};
int bqnotifylistenerUI (void* data)
{
NLParams* params = static_cast<NLParams*>(data);
params->listener->queueSizeChanged (params->qsize, params->queueEmptied, params->queueError, params->queueErrorMessage);
delete params;
return 0;
}
}
BatchQueue::BatchQueue (FileCatalog* aFileCatalog) : processing(nullptr), fileCatalog(aFileCatalog), sequence(0), listener(nullptr)
{
@ -580,9 +601,54 @@ void BatchQueue::startProcessing ()
}
}
rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImagefloat* img)
void BatchQueue::setProgress(double p)
{
if (processing) {
processing->progress = p;
}
// No need to acquire the GUI, setProgressUI will do it
const auto func = [](gpointer data) -> gboolean {
static_cast<BatchQueue*>(data)->redraw();
return FALSE;
};
idle_register.add(func, this);
}
void BatchQueue::setProgressStr(const Glib::ustring& str)
{
}
void BatchQueue::setProgressState(bool inProcessing)
{
}
void BatchQueue::error(const Glib::ustring& descr)
{
if (processing && processing->processing) {
// restore failed thumb
BatchQueueButtonSet* bqbs = new BatchQueueButtonSet (processing);
bqbs->setButtonListener (this);
processing->addButtonSet (bqbs);
processing->processing = false;
processing->job = rtengine::ProcessingJob::create(processing->filename, processing->thumbnail->getType() == FT_Raw, processing->params);
processing = nullptr;
redraw ();
}
if (listener) {
NLParams* params = new NLParams;
params->listener = listener;
params->queueEmptied = false;
params->queueError = true;
params->queueErrorMessage = descr;
idle_register.add(bqnotifylistenerUI, params);
}
}
rtengine::ProcessingJob* BatchQueue::imageReady(rtengine::IImagefloat* img)
{
// save image img
Glib::ustring fname;
SaveFormat saveFormat;
@ -892,22 +958,6 @@ Glib::ustring BatchQueue::autoCompleteFileName (const Glib::ustring& fileName, c
return "";
}
void BatchQueue::setProgress (double p)
{
if (processing) {
processing->progress = p;
}
// No need to acquire the GUI, setProgressUI will do it
const auto func = [](gpointer data) -> gboolean {
static_cast<BatchQueue*>(data)->redraw();
return FALSE;
};
idle_register.add(func, this);
}
void BatchQueue::buttonPressed (LWButton* button, int actionCode, void* actionData)
{
@ -923,22 +973,6 @@ void BatchQueue::buttonPressed (LWButton* button, int actionCode, void* actionDa
}
}
struct NLParams {
BatchQueueListener* listener;
int qsize;
bool queueEmptied;
bool queueError;
Glib::ustring queueErrorMessage;
};
int bqnotifylistenerUI (void* data)
{
NLParams* params = static_cast<NLParams*>(data);
params->listener->queueSizeChanged (params->qsize, params->queueEmptied, params->queueError, params->queueErrorMessage);
delete params;
return 0;
}
void BatchQueue::notifyListener (bool queueEmptied)
{
@ -960,27 +994,3 @@ void BatchQueue::redrawNeeded (LWButton* button)
GThreadLock lock;
queue_draw ();
}
void BatchQueue::error (Glib::ustring msg)
{
if (processing && processing->processing) {
// restore failed thumb
BatchQueueButtonSet* bqbs = new BatchQueueButtonSet (processing);
bqbs->setButtonListener (this);
processing->addButtonSet (bqbs);
processing->processing = false;
processing->job = rtengine::ProcessingJob::create(processing->filename, processing->thumbnail->getType() == FT_Raw, processing->params);
processing = nullptr;
redraw ();
}
if (listener) {
NLParams* params = new NLParams;
params->listener = listener;
params->queueEmptied = false;
params->queueError = true;
params->queueErrorMessage = msg;
idle_register.add(bqnotifylistenerUI, params);
}
}

View File

@ -30,9 +30,9 @@ class BatchQueueListener
{
public:
virtual ~BatchQueueListener () {}
virtual void queueSizeChanged (int qsize, bool queueEmptied, bool queueError, Glib::ustring queueErrorMessage) = 0;
virtual bool canStartNext () = 0;
virtual ~BatchQueueListener() = default;
virtual void queueSizeChanged(int qsize, bool queueEmptied, bool queueError, const Glib::ustring& queueErrorMessage) = 0;
virtual bool canStartNext() = 0;
};
class FileCatalog;
@ -62,9 +62,12 @@ public:
return (!fd.empty());
}
rtengine::ProcessingJob* imageReady (rtengine::IImagefloat* img);
void error (Glib::ustring msg);
void setProgress (double p);
void setProgress(double p);
void setProgressStr(const Glib::ustring& str);
void setProgressState(bool inProcessing);
void error(const Glib::ustring& descr);
rtengine::ProcessingJob* imageReady(rtengine::IImagefloat* img);
void rightClicked (ThumbBrowserEntryBase* entry);
void doubleClicked (ThumbBrowserEntryBase* entry);
bool keyPressed (GdkEventKey* event);

View File

@ -245,9 +245,9 @@ void BatchQueuePanel::updateTab (int qsize, int forceOrientation)
}
}
void BatchQueuePanel::queueSizeChanged (int qsize, bool queueEmptied, bool queueError, Glib::ustring queueErrorMessage)
void BatchQueuePanel::queueSizeChanged(int qsize, bool queueEmptied, bool queueError, const Glib::ustring& queueErrorMessage)
{
updateTab ( qsize);
updateTab (qsize);
if (qsize == 0 || (qsize == 1 && !fdir->get_sensitive())) {
qStartStop->set_sensitive(false);
@ -311,10 +311,9 @@ void BatchQueuePanel::stopBatchProc ()
updateTab (batchQueue->getEntries().size());
}
void BatchQueuePanel::addBatchQueueJobs ( std::vector<BatchQueueEntry*> &entries, bool head)
void BatchQueuePanel::addBatchQueueJobs(const std::vector<BatchQueueEntry*>& entries, bool head)
{
batchQueue->addEntries (entries, head);
batchQueue->addEntries(entries, head);
if (!qStartStop->get_active() && qAutoStart->get_active()) {
startBatchProc ();
@ -323,7 +322,7 @@ void BatchQueuePanel::addBatchQueueJobs ( std::vector<BatchQueueEntry*> &entries
bool BatchQueuePanel::canStartNext ()
{
// GThreadLock lock;
if (qStartStop->get_active()) {
return true;
} else {
@ -363,15 +362,12 @@ void BatchQueuePanel::pathFolderButtonPressed ()
// since these settings are shared with editorpanel :
void BatchQueuePanel::pathFolderChanged ()
{
options.savePathFolder = outdirFolder->get_filename();
}
void BatchQueuePanel::formatChanged (Glib::ustring f)
void BatchQueuePanel::formatChanged(const Glib::ustring& format)
{
options.saveFormatBatch = saveFormatPanel->getFormat ();
options.saveFormatBatch = saveFormatPanel->getFormat();
}
bool BatchQueuePanel::handleShortcutKey (GdkEventKey* event)

View File

@ -59,11 +59,11 @@ public:
void init (RTWindow* parent);
void addBatchQueueJobs (std::vector<BatchQueueEntry*> &entries , bool head = false);
void addBatchQueueJobs(const std::vector<BatchQueueEntry*>& entries , bool head = false);
// batchqueuelistener interface
void queueSizeChanged (int qsize, bool queueEmptied, bool queueError, Glib::ustring queueErrorMessage);
bool canStartNext ();
void queueSizeChanged(int qsize, bool queueEmptied, bool queueError, const Glib::ustring& queueErrorMessage);
bool canStartNext();
void startBatchProc ();
void stopBatchProc ();
@ -72,7 +72,7 @@ public:
void saveOptions ();
void pathFolderChanged ();
void pathFolderButtonPressed ();
void formatChanged (Glib::ustring f);
void formatChanged(const Glib::ustring& format) override;
void updateTab (int qsize, int forceOrientation = 0); // forceOrientation=0: base on options / 1: horizontal / 2: vertical
bool handleShortcutKey (GdkEventKey* event);

View File

@ -383,9 +383,8 @@ void BatchToolPanelCoordinator::initSession ()
}
}
void BatchToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr)
void BatchToolPanelCoordinator::panelChanged(const rtengine::ProcEvent& event, const Glib::ustring& descr)
{
if (selected.empty()) {
return;
}
@ -611,9 +610,14 @@ void BatchToolPanelCoordinator::endBatchPParamsChange()
* Using a Profile panel in the batch tool panel editor is actually
* not supported by BatchToolPanelCoordinator::profileChange!
*/
void BatchToolPanelCoordinator::profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited)
void BatchToolPanelCoordinator::profileChange(
const PartialProfile* nparams,
const rtengine::ProcEvent& event,
const Glib::ustring& descr,
const ParamsEdited* paramsEdited,
bool fromLastSave
)
{
if (event == rtengine::EvProfileChanged) {
// a profile has been selected in a hypothetical Profile panel
// -> ACTUALLY NOT SUPPORTED

View File

@ -51,30 +51,36 @@ public:
explicit BatchToolPanelCoordinator (FilePanel* parent);
// FileSelectionChangeListener interface
void selectionChanged (const std::vector<Thumbnail*>& selected);
void selectionChanged (const std::vector<Thumbnail*>& selected) override;
// toolpanellistener interface
void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr);
void panelChanged(const rtengine::ProcEvent& event, const Glib::ustring& descr) override;
// profilechangelistener interface
void profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited = nullptr);
void profileChange(
const rtengine::procparams::PartialProfile* nparams,
const rtengine::ProcEvent& event,
const Glib::ustring& descr,
const ParamsEdited* paramsEdited = nullptr,
bool fromLastSave = false
) override;
// wbprovider interface
void getAutoWB (double& temp, double& green, double equal, double tempBias);
void getAutoWB (double& temp, double& green, double equal, double tempBias) override;
void getCamWB (double& temp, double& green);
// thumbnaillistener interface
void procParamsChanged (Thumbnail* thm, int whoChangedIt);
void procParamsChanged (Thumbnail* thm, int whoChangedIt) override;
// batchpparamschangelistener interface
void beginBatchPParamsChange(int numberOfEntries);
void endBatchPParamsChange();
void beginBatchPParamsChange(int numberOfEntries) override;
void endBatchPParamsChange() override;
// imageareatoollistener interface
void spotWBselected (int x, int y, Thumbnail* thm = nullptr);
void cropSelectionReady ();
void rotateSelectionReady (double rotate_deg, Thumbnail* thm = nullptr);
CropGUIListener* startCropEditing (Thumbnail* thm = nullptr);
void spotWBselected (int x, int y, Thumbnail* thm = nullptr) override;
void cropSelectionReady () override;
void rotateSelectionReady (double rotate_deg, Thumbnail* thm = nullptr) override;
CropGUIListener* startCropEditing (Thumbnail* thm = nullptr) override;
void optionsChanged ();
};

View File

@ -134,6 +134,10 @@ void BayerPreProcess::adjusterChanged (Adjuster* a, double newval)
}
}
void BayerPreProcess::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
void BayerPreProcess::setBatchMode(bool batchMode)
{
ToolPanel::setBatchMode (batchMode);

View File

@ -46,7 +46,9 @@ public:
void setBatchMode (bool batchMode);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
void adjusterChanged (Adjuster* a, double newval);
void adjusterChanged(Adjuster* a, double newval);
void adjusterAutoToggled(Adjuster* a, bool newval);
void hotDeadPixelChanged();
void setAdjusterBehavior (bool linedenoiseadd, bool greenequiladd);
void trimValues (rtengine::procparams::ProcParams* pp);

View File

@ -30,6 +30,7 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA
auto m = ProcEventMapper::getInstance();
EvDemosaicBorder = m->newEvent(DEMOSAIC, "HISTORY_MSG_RAW_BORDER");
EvDemosaicContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_CONTRAST");
EvDemosaicAutoContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST");
EvDemosaicPixelshiftDemosaicMethod = m->newEvent(DEMOSAIC, "HISTORY_MSG_PIXELSHIFT_DEMOSAIC");
Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ());
@ -46,12 +47,12 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA
hb1->pack_end (*method, Gtk::PACK_EXPAND_WIDGET, 4);
pack_start( *hb1, Gtk::PACK_SHRINK, 4);
dualDemosaicOptions = Gtk::manage(new Gtk::VBox());
dualDemosaicOptions = Gtk::manage (new Gtk::VBox ());
dualDemosaicContrast = Gtk::manage(new Adjuster (M("TP_RAW_DUALDEMOSAICCONTRAST"), 0, 100, 1, 20));
dualDemosaicContrast->setAdjusterListener (this);
dualDemosaicContrast = Gtk::manage(new Adjuster(M("TP_RAW_DUALDEMOSAICCONTRAST"), 0, 100, 1, 20));
dualDemosaicContrast->setAdjusterListener(this);
dualDemosaicContrast->addAutoButton(M("TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP"));
dualDemosaicContrast->setAutoValue(true);
if (dualDemosaicContrast->delay < options.adjusterMaxDelay) {
dualDemosaicContrast->delay = options.adjusterMaxDelay;
}
@ -250,6 +251,10 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA
}
BayerProcess::~BayerProcess ()
{
idle_register.destroy();
}
void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited)
{
@ -300,7 +305,9 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params
pixelShiftNonGreenCross->setValue (pp->raw.bayersensor.pixelShiftNonGreenCross);
ccSteps->setValue (pp->raw.bayersensor.ccSteps);
lmmseIterations->setValue (pp->raw.bayersensor.lmmse_iterations);
dualDemosaicContrast->setAutoValue(pp->raw.bayersensor.dualDemosaicAutoContrast);
dualDemosaicContrast->setValue (pp->raw.bayersensor.dualDemosaicContrast);
pixelShiftMotionMethod->set_active ((int)pp->raw.bayersensor.pixelShiftMotionCorrectionMethod);
pixelShiftEperIso->setValue (pp->raw.bayersensor.pixelShiftEperIso);
pixelShiftSigma->setValue (pp->raw.bayersensor.pixelShiftSigma);
@ -325,6 +332,7 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params
pixelShiftNonGreenCross->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenCross);
lmmseIterations->setEditedState ( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited);
dualDemosaicContrast->setEditedState ( pedited->raw.bayersensor.dualDemosaicContrast ? Edited : UnEdited);
dualDemosaicContrast->setAutoInconsistent (multiImage && !pedited->raw.bayersensor.dualDemosaicAutoContrast);
pixelShiftEperIso->setEditedState ( pedited->raw.bayersensor.pixelShiftEperIso ? Edited : UnEdited);
pixelShiftSigma->setEditedState ( pedited->raw.bayersensor.pixelShiftSigma ? Edited : UnEdited);
@ -345,6 +353,7 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params
}
}
lastAutoContrast = pp->raw.bayersensor.dualDemosaicAutoContrast;
if (!batchMode) {
dcbOptions->set_visible(pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCB) || pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBVNG4));
@ -385,6 +394,7 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe
pp->raw.bayersensor.dcb_enhance = dcbEnhance->getLastActive ();
pp->raw.bayersensor.border = border->getIntValue();
pp->raw.bayersensor.lmmse_iterations = lmmseIterations->getIntValue();
pp->raw.bayersensor.dualDemosaicAutoContrast = dualDemosaicContrast->getAutoValue();
pp->raw.bayersensor.dualDemosaicContrast = dualDemosaicContrast->getValue();
pp->raw.bayersensor.pixelShiftMotionCorrectionMethod = (RAWParams::BayerSensor::PSMotionCorrectionMethod)pixelShiftMotionMethod->get_active_row_number();
pp->raw.bayersensor.pixelShiftEperIso = pixelShiftEperIso->getValue();
@ -425,6 +435,7 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe
pedited->raw.bayersensor.dcbEnhance = !dcbEnhance->get_inconsistent();
//pedited->raw.bayersensor.allEnhance = !allEnhance->get_inconsistent();
pedited->raw.bayersensor.lmmseIterations = lmmseIterations->getEditedState ();
pedited->raw.bayersensor.dualDemosaicAutoContrast = !dualDemosaicContrast->getAutoInconsistent ();
pedited->raw.bayersensor.dualDemosaicContrast = dualDemosaicContrast->getEditedState ();
pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod = pixelShiftMotionMethod->get_active_text() != M("GENERAL_UNCHANGED");
pedited->raw.bayersensor.pixelShiftDemosaicMethod = pixelShiftDemosaicMethod->get_active_text() != M("GENERAL_UNCHANGED");
@ -656,6 +667,33 @@ void BayerProcess::checkBoxToggled (CheckBox* c, CheckValue newval)
}
}
void BayerProcess::adjusterAutoToggled(Adjuster* a, bool newval)
{
if (multiImage) {
if (dualDemosaicContrast->getAutoInconsistent()) {
dualDemosaicContrast->setAutoInconsistent (false);
dualDemosaicContrast->setAutoValue (false);
} else if (lastAutoContrast) {
dualDemosaicContrast->setAutoInconsistent (true);
}
lastAutoContrast = dualDemosaicContrast->getAutoValue();
}
if (listener) {
if (a == dualDemosaicContrast) {
if (dualDemosaicContrast->getAutoInconsistent()) {
listener->panelChanged (EvDemosaicAutoContrast, M ("GENERAL_UNCHANGED"));
} else if (dualDemosaicContrast->getAutoValue()) {
listener->panelChanged (EvDemosaicAutoContrast, M ("GENERAL_ENABLED"));
} else {
listener->panelChanged (EvDemosaicAutoContrast, M ("GENERAL_DISABLED"));
}
}
}
}
void BayerProcess::pixelShiftMotionMethodChanged ()
{
if (!batchMode) {
@ -711,23 +749,23 @@ void BayerProcess::FrameCountChanged(int n, int frameNum)
};
idle_register.add(func, new Data { this, n, frameNum });
// GThreadLock lock;
// imageNumber->block (true);
// imageNumber->remove_all();
// imageNumber->append("1");
// for(int i = 2; i <= std::min(n, 4); ++i) {
// std::ostringstream entry;
// entry << i;
// imageNumber->append(entry.str());
// }
// imageNumber->set_active(std::min(frameNum, n - 1));
// if(n == 1) {
// imageNumberBox->hide();
// } else {
// imageNumberBox->show();
// }
// imageNumber->block (false);
}
void BayerProcess::autoContrastChanged (double autoContrast)
{
struct Data {
BayerProcess *me;
double autoContrast;
};
const auto func = [](gpointer data) -> gboolean {
Data *d = static_cast<Data *>(data);
BayerProcess *me = d->me;
me->disableListener();
me->dualDemosaicContrast->setValue(d->autoContrast);
me->enableListener();
delete d;
return FALSE;
};
idle_register.add(func, new Data { this, autoContrast });
}

View File

@ -25,7 +25,7 @@
#include "guiutils.h"
#include "toolpanel.h"
class BayerProcess : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, public FoldableToolPanel, public rtengine::FrameCountListener
class BayerProcess : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, public FoldableToolPanel, public rtengine::FrameCountListener, public rtengine::AutoContrastListener
{
protected:
@ -60,15 +60,17 @@ protected:
Gtk::VBox *dualDemosaicOptions;
Adjuster* dualDemosaicContrast;
int oldMethod;
bool lastAutoContrast;
IdleRegister idle_register;
rtengine::ProcEvent EvDemosaicBorder;
rtengine::ProcEvent EvDemosaicAutoContrast;
rtengine::ProcEvent EvDemosaicContrast;
rtengine::ProcEvent EvDemosaicPixelshiftDemosaicMethod;
public:
BayerProcess ();
~BayerProcess ();
void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
void write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
@ -80,9 +82,11 @@ public:
void methodChanged();
void imageNumberChanged();
void adjusterChanged(Adjuster* a, double newval);
void adjusterAutoToggled (Adjuster* a, bool newval);
void checkBoxToggled(CheckBox* c, CheckValue newval);
void pixelShiftMotionMethodChanged();
void pixelShiftDemosaicMethodChanged();
void autoContrastChanged (double autoContrast);
void FrameCountChanged(int n, int frameNum);
};

View File

@ -121,7 +121,7 @@ void BayerRAWExposure::write( rtengine::procparams::ProcParams* pp, ParamsEdited
}
void BayerRAWExposure::adjusterChanged (Adjuster* a, double newval)
void BayerRAWExposure::adjusterChanged(Adjuster* a, double newval)
{
if (listener) {
Glib::ustring value = a->getTextValue();
@ -148,6 +148,10 @@ void BayerRAWExposure::adjusterChanged (Adjuster* a, double newval)
}
}
void BayerRAWExposure::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
void BayerRAWExposure::checkBoxToggled (CheckBox* c, CheckValue newval)
{
if (c == PextwoGreen) {

View File

@ -43,6 +43,7 @@ public:
void setBatchMode (bool batchMode);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled (Adjuster* a, bool newval);
void checkBoxToggled (CheckBox* c, CheckValue newval);
void setAdjusterBehavior (bool pexblackadd);
void trimValues (rtengine::procparams::ProcParams* pp);

View File

@ -1094,9 +1094,8 @@ void BlackWhite::autoch_toggled ()
}
void BlackWhite::adjusterChanged (Adjuster* a, double newval)
void BlackWhite::adjusterChanged(Adjuster* a, double newval)
{
// Checking "listener" to avoid "autoch" getting toggled off because it has to change the sliders when toggling on
if (listener && (a == mixerRed || a == mixerGreen || a == mixerBlue || a == mixerOrange || a == mixerYellow || a == mixerMagenta || a == mixerPurple || a == mixerCyan) ) {
if (multiImage && autoch->get_inconsistent()) {
@ -1147,6 +1146,10 @@ void BlackWhite::adjusterChanged (Adjuster* a, double newval)
}
}
void BlackWhite::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
void BlackWhite::updateRGBLabel ()
{
if (!batchMode) {

View File

@ -53,6 +53,7 @@ public:
void updateRGBLabel ();
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled (Adjuster* a, bool newval);
void setAdjusterBehavior (bool bwadd, bool bwgadd);
void trimValues (rtengine::procparams::ProcParams* pp);
void enabledcc_toggled ();

View File

@ -28,8 +28,8 @@ class BQEntryUpdateListener
{
public:
virtual ~BQEntryUpdateListener () {}
virtual void updateImage (guint8* img, int w, int h, int origw, int origh, guint8* newOPreview) {}
virtual ~BQEntryUpdateListener() = default;
virtual void updateImage(guint8* img, int w, int h, int origw, int origh, guint8* newOPreview) = 0;
};
class BatchQueueEntryUpdater

View File

@ -97,6 +97,10 @@ void CACorrection::adjusterChanged (Adjuster* a, double newval)
}
}
void CACorrection::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
void CACorrection::setAdjusterBehavior (bool badd)
{

View File

@ -40,6 +40,7 @@ public:
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled(Adjuster* a, bool newval);
void setAdjusterBehavior (bool badd);
void trimValues (rtengine::procparams::ProcParams* pp);
};

View File

@ -33,10 +33,9 @@ enum class CheckValue {
class CheckBoxListener
{
public:
virtual ~CheckBoxListener() {};
virtual void checkBoxToggled (CheckBox* c, CheckValue newval) {}
virtual ~CheckBoxListener() = default;
virtual void checkBoxToggled(CheckBox* c, CheckValue newval) = 0;
};

View File

@ -167,7 +167,7 @@ void ChMixer::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi
}
}
void ChMixer::adjusterChanged (Adjuster* a, double newval)
void ChMixer::adjusterChanged(Adjuster* a, double newval)
{
if (listener && getEnabled()) {
@ -179,6 +179,9 @@ void ChMixer::adjusterChanged (Adjuster* a, double newval)
}
}
void ChMixer::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
void ChMixer::enabledChanged()
{

View File

@ -42,6 +42,7 @@ public:
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled(Adjuster* a, bool newval);
void setAdjusterBehavior (bool rgbadd);
void trimValues (rtengine::procparams::ProcParams* pp);
void enabledChanged();

View File

@ -1544,9 +1544,8 @@ void ColorAppearance::colorForValue (double valX, double valY, enum ColorCaller:
caller->ccBlue = double (B);
}
void ColorAppearance::adjusterChanged (Adjuster* a, double newval)
void ColorAppearance::adjusterChanged(Adjuster* a, double newval)
{
if (listener && (multiImage || getEnabled()) ) {
if (a == degree) {
listener->panelChanged (EvCATDegree, a->getTextValue());
@ -1594,9 +1593,8 @@ void ColorAppearance::adjusterChanged (Adjuster* a, double newval)
}
}
void ColorAppearance::adjusterAutoToggled (Adjuster* a, bool newval)
void ColorAppearance::adjusterAutoToggled(Adjuster* a, bool newval)
{
if (multiImage) {
if (degree->getAutoInconsistent()) {
degree->setAutoInconsistent (false);
@ -1844,11 +1842,21 @@ void ColorAppearance::setBatchMode (bool batchMode)
curveEditorG3->setBatchMode (batchMode);
}
void ColorAppearance::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histLRETI)
void ColorAppearance::updateCurveBackgroundHistogram(
const LUTu& histToneCurve,
const LUTu& histLCurve,
const LUTu& histCCurve,
const LUTu& histLCAM,
const LUTu& histCCAM,
const LUTu& histRed,
const LUTu& histGreen,
const LUTu& histBlue,
const LUTu& histLuma,
const LUTu& histLRETI
)
{
shape->updateBackgroundHistogram (histLCAM);
shape3->updateBackgroundHistogram (histCCAM);
shape->updateBackgroundHistogram(histLCAM);
shape3->updateBackgroundHistogram(histCCAM);
}

View File

@ -80,7 +80,18 @@ public:
void setAdjusterBehavior (bool degreeadd, bool adapscenadd, bool adaplumadd, bool badpixsladd, bool jlightadd, bool chromaadd, bool contrastadd, bool rstprotectionadd, bool qbrightadd, bool qcontrastadd, bool schromaadd, bool mchromaadd, bool colorhadd);
void trimValues (rtengine::procparams::ProcParams* pp);
void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histLRETI);
void updateCurveBackgroundHistogram(
const LUTu& histToneCurve,
const LUTu& histLCurve,
const LUTu& histCCurve,
const LUTu& histLCAM,
const LUTu& histCCAM,
const LUTu& histRed,
const LUTu& histGreen,
const LUTu& histBlue,
const LUTu& histLuma,
const LUTu& histLRETI
);
virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller);
void updateToolState (std::vector<int> &tpOpen);
void writeOptions (std::vector<int> &tpOpen);

View File

@ -318,7 +318,7 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR
//------------------------------------------------------------------------
// LAB grid
auto m = ProcEventMapper::getInstance();
auto m = ProcEventMapper::getInstance();
EvColorToningLabGridValue = m->newEvent(RGBCURVE, "HISTORY_MSG_COLORTONING_LABGRID_VALUE");
labgridBox = Gtk::manage(new Gtk::HBox());
labgrid = Gtk::manage(new LabGrid(EvColorToningLabGridValue));
@ -688,13 +688,6 @@ void ColorToning::setAdjusterBehavior (bool splitAdd, bool satThresholdAdd, bool
}
void ColorToning::adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop)
{
if (listener && getEnabled())
listener->panelChanged (a == hlColSat ? EvColorToningHighights : EvColorToningShadows,
Glib::ustring::compose(Glib::ustring(M("TP_COLORTONING_HUE") + ": %1" + "\n" + M("TP_COLORTONING_STRENGTH") + ": %2"), int(newTop), int(newBottom)));
}
void ColorToning::autoColorTonChanged(int bwct, int satthres, int satprot)
{
nextbw = bwct;
@ -731,40 +724,32 @@ bool ColorToning::CTComp_ ()
return false;
}
void ColorToning::adjusterChanged (Adjuster* a, double newval)
void ColorToning::adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop)
{
if (!listener || !getEnabled()) {
return;
if (listener && getEnabled()) {
listener->panelChanged(
a == hlColSat
? EvColorToningHighights
: EvColorToningShadows,
Glib::ustring::compose(Glib::ustring(M("TP_COLORTONING_HUE") + ": %1" + "\n" + M("TP_COLORTONING_STRENGTH") + ": %2"), int(newTop), int(newBottom))
);
}
}
if (a == redlow) {
listener->panelChanged (EvColorToningredlow, redlow->getTextValue());
} else if (a == greenlow) {
listener->panelChanged (EvColorToninggreenlow, greenlow->getTextValue());
} else if (a == bluelow) {
listener->panelChanged (EvColorToningbluelow, bluelow->getTextValue());
} else if (a == redmed) {
listener->panelChanged (EvColorToningredmed, redmed->getTextValue());
} else if (a == greenmed) {
listener->panelChanged (EvColorToninggreenmed, greenmed->getTextValue());
} else if (a == bluemed) {
listener->panelChanged (EvColorToningbluemed, bluemed->getTextValue());
} else if (a == redhigh) {
listener->panelChanged (EvColorToningredhigh, redhigh->getTextValue());
} else if (a == greenhigh) {
listener->panelChanged (EvColorToninggreenhigh, greenhigh->getTextValue());
} else if (a == bluehigh) {
listener->panelChanged (EvColorToningbluehigh, bluehigh->getTextValue());
} else if (a == balance) {
listener->panelChanged (EvColorToningbalance, balance->getTextValue());
} else if (a == satProtectionThreshold) {
listener->panelChanged (EvColorToningSatThreshold, a->getTextValue());
} else if (a == saturatedOpacity) {
listener->panelChanged (EvColorToningSatProtection, a->getTextValue());
} else if (a == strength) {
listener->panelChanged (EvColorToningStrength, a->getTextValue());
}
void ColorToning::adjusterChanged(ThresholdAdjuster* a, double newBottomLeft, double newTopLeft, double newBottomRight, double newTopRight)
{
}
void ColorToning::adjusterChanged(ThresholdAdjuster* a, int newBottom, int newTop)
{
}
void ColorToning::adjusterChanged(ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight)
{
}
void ColorToning::adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR)
{
}
//Two Color changed
@ -829,7 +814,7 @@ void ColorToning::methodChanged ()
if (!batchMode) {
labgridBox->hide();
if (method->get_active_row_number() == 0) { // Lab
colorSep->show();
colorCurveEditorG->show();
@ -1141,6 +1126,45 @@ void ColorToning::trimValues (rtengine::procparams::ProcParams* pp)
bluehigh->trimValue(pp->colorToning.bluehigh);
}
void ColorToning::adjusterChanged(Adjuster* a, double newval)
{
if (!listener || !getEnabled()) {
return;
}
if (a == redlow) {
listener->panelChanged (EvColorToningredlow, redlow->getTextValue());
} else if (a == greenlow) {
listener->panelChanged (EvColorToninggreenlow, greenlow->getTextValue());
} else if (a == bluelow) {
listener->panelChanged (EvColorToningbluelow, bluelow->getTextValue());
} else if (a == redmed) {
listener->panelChanged (EvColorToningredmed, redmed->getTextValue());
} else if (a == greenmed) {
listener->panelChanged (EvColorToninggreenmed, greenmed->getTextValue());
} else if (a == bluemed) {
listener->panelChanged (EvColorToningbluemed, bluemed->getTextValue());
} else if (a == redhigh) {
listener->panelChanged (EvColorToningredhigh, redhigh->getTextValue());
} else if (a == greenhigh) {
listener->panelChanged (EvColorToninggreenhigh, greenhigh->getTextValue());
} else if (a == bluehigh) {
listener->panelChanged (EvColorToningbluehigh, bluehigh->getTextValue());
} else if (a == balance) {
listener->panelChanged (EvColorToningbalance, balance->getTextValue());
} else if (a == satProtectionThreshold) {
listener->panelChanged (EvColorToningSatThreshold, a->getTextValue());
} else if (a == saturatedOpacity) {
listener->panelChanged (EvColorToningSatProtection, a->getTextValue());
} else if (a == strength) {
listener->panelChanged (EvColorToningStrength, a->getTextValue());
}
}
void ColorToning::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
void ColorToning::setBatchMode (bool batchMode)
{
ToolPanel::setBatchMode (batchMode);

View File

@ -32,13 +32,19 @@ public:
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
void trimValues (rtengine::procparams::ProcParams* pp);
void adjusterChanged (Adjuster* a, double newval);
void adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop);
void adjusterAutoToggled (Adjuster* a, bool newval);
void setAdjusterBehavior (bool splitAdd, bool satThresholdAdd, bool satOpacityAdd, bool strprotectAdd, bool balanceAdd);
void neutral_pressed ();
//void neutralCurves_pressed ();
void autoColorTonChanged (int bwct, int satthres, int satprot);
bool CTComp_ ();
void adjusterChanged(ThresholdAdjuster* a, double newBottom, double newTop);
void adjusterChanged(ThresholdAdjuster* a, double newBottomLeft, double newTopLeft, double newBottomRight, double newTopRight);
void adjusterChanged(ThresholdAdjuster* a, int newBottom, int newTop);
void adjusterChanged(ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight);
void adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR);
void enabledChanged ();
void curveChanged (CurveEditor* ce);
void autosatChanged ();
@ -51,7 +57,7 @@ public:
void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller);
void setListener(ToolPanelListener *tpl);
private:
bool resetPressed(GdkEventButton* event);

View File

@ -728,7 +728,7 @@ void Crop::setDimensions (int mw, int mh)
refreshSize ();
}
void Crop::sizeChanged (int x, int y, int ow, int oh)
void Crop::sizeChanged(int x, int y, int ow, int oh)
{
struct Params {
Crop* crop;
@ -1261,9 +1261,8 @@ void Crop::cropManipReady ()
idle_register.add(notifyListenerUI, this);
}
double Crop::getRatio ()
double Crop::getRatio () const
{
double r = -1.0;
if (!fixr->get_active()) {

View File

@ -76,7 +76,7 @@ public:
void cropResized (int &x, int &y, int& x2, int& y2);
void cropManipReady ();
bool inImageArea (int x, int y);
double getRatio ();
double getRatio () const;
void setCropPanelListener (CropPanelListener* cl)
{

View File

@ -23,21 +23,21 @@ class CropGUIListener
{
public:
virtual ~CropGUIListener() {}
virtual void cropMoved (int &x, int &y, int &w, int &h) = 0;
virtual void cropWidth1Resized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0;
virtual void cropWidth2Resized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0;
virtual void cropHeight1Resized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0;
virtual void cropHeight2Resized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0;
virtual void cropTopLeftResized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0;
virtual void cropTopRightResized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0;
virtual void cropBottomLeftResized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0;
virtual void cropBottomRightResized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0;
virtual void cropInit (int &x, int &y, int &w, int &h) = 0;
virtual void cropResized (int &x, int &y, int& x2, int& y2) = 0;
virtual void cropManipReady () = 0;
virtual bool inImageArea (int x, int y) = 0;
virtual double getRatio () = 0;
virtual ~CropGUIListener() = default;
virtual void cropMoved(int &x, int &y, int &w, int &h) = 0;
virtual void cropWidth1Resized(int &x, int &y, int &w, int &h, float custom_ratio = 0.f) = 0;
virtual void cropWidth2Resized(int &x, int &y, int &w, int &h, float custom_ratio = 0.f) = 0;
virtual void cropHeight1Resized(int &x, int &y, int &w, int &h, float custom_ratio = 0.f) = 0;
virtual void cropHeight2Resized(int &x, int &y, int &w, int &h, float custom_ratio = 0.f) = 0;
virtual void cropTopLeftResized(int &x, int &y, int &w, int &h, float custom_ratio = 0.f) = 0;
virtual void cropTopRightResized(int &x, int &y, int &w, int &h, float custom_ratio = 0.f) = 0;
virtual void cropBottomLeftResized(int &x, int &y, int &w, int &h, float custom_ratio = 0.f) = 0;
virtual void cropBottomRightResized(int &x, int &y, int &w, int &h, float custom_ratio = 0.f) = 0;
virtual void cropInit(int &x, int &y, int &w, int &h) = 0;
virtual void cropResized(int &x, int &y, int& x2, int& y2) = 0;
virtual void cropManipReady() = 0;
virtual bool inImageArea(int x, int y) = 0;
virtual double getRatio() const = 0;
};
#endif

View File

@ -106,15 +106,9 @@ void CropHandler::newImage (StagedImageProcessor* ipc_, bool isDetailWindow)
initial = true;
}
void CropHandler::sizeChanged (int x, int y, int ow, int oh) // the ipc notifies it to keep track size changes like rotation
void CropHandler::sizeChanged(int x, int y, int ow, int oh) // the ipc notifies it to keep track size changes like rotation
{
compDim ();
// this should be put into an idle source!!!
/* if (listener)
listener->cropWindowChanged ();
*/
}
bool CropHandler::isFullDisplay ()
@ -300,10 +294,18 @@ void CropHandler::getPosition (int& x, int& y)
}
void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procparams::ColorManagementParams cmp,
rtengine::procparams::CropParams cp, int ax, int ay, int aw, int ah, int askip)
void CropHandler::setDetailedCrop(
IImage8* im,
IImage8* imtrue,
const rtengine::procparams::ColorManagementParams& cmp,
const rtengine::procparams::CropParams& cp,
int ax,
int ay,
int aw,
int ah,
int askip
)
{
if (!enabled) {
return;
}
@ -406,9 +408,8 @@ void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procp
cimg.unlock ();
}
bool CropHandler::getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip)
void CropHandler::getWindow(int& cwx, int& cwy, int& cww, int& cwh, int& cskip)
{
cwx = cropX;
cwy = cropY;
cww = cropW;
@ -424,8 +425,6 @@ bool CropHandler::getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip)
}
cskip = zoom >= 1000 ? 1 : zoom/10;
return true;
}
void CropHandler::update ()

View File

@ -86,9 +86,19 @@ public:
}
// DetailedCropListener interface
void setDetailedCrop (rtengine::IImage8* im, rtengine::IImage8* imworking, rtengine::procparams::ColorManagementParams cmp,
rtengine::procparams::CropParams cp, int cx, int cy, int cw, int ch, int skip);
bool getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip);
void setDetailedCrop(
rtengine::IImage8* im,
rtengine::IImage8* imworking,
const rtengine::procparams::ColorManagementParams& cmp,
const rtengine::procparams::CropParams& cp,
int cx,
int cy,
int cw,
int ch,
int skip
);
void getWindow(int& cwx, int& cwy, int& cww, int& cwh, int& cskip);
// SizeListener interface
void sizeChanged (int w, int h, int ow, int oh);

View File

@ -267,15 +267,22 @@ void CropWindow::flawnOver (bool isFlawnOver)
this->isFlawnOver = isFlawnOver;
}
void CropWindow::scroll (int state, GdkScrollDirection direction, int x, int y)
void CropWindow::scroll (int state, GdkScrollDirection direction, int x, int y, double deltaX, double deltaY)
{
double delta = 0.0;
if (abs(deltaX) > abs(deltaY)) {
delta = deltaX;
} else {
delta = deltaY;
}
bool isUp = direction == GDK_SCROLL_UP || (direction == GDK_SCROLL_SMOOTH && delta < 0.0);
if ((state & GDK_CONTROL_MASK) && onArea(ColorPicker, x, y)) {
// resizing a color picker
if (direction == GDK_SCROLL_UP) {
if (isUp) {
hoveredPicker->incSize();
updateHoveredPicker();
iarea->redraw ();
}else if (direction == GDK_SCROLL_DOWN) {
} else {
hoveredPicker->decSize();
updateHoveredPicker();
iarea->redraw ();
@ -287,9 +294,9 @@ void CropWindow::scroll (int state, GdkScrollDirection direction, int x, int y)
screenCoordToImage(newCenterX, newCenterY, newCenterX, newCenterY);
if (direction == GDK_SCROLL_UP && !isMaxZoom()) {
if (isUp && !isMaxZoom()) {
zoomIn (true, newCenterX, newCenterY);
} else if (direction == GDK_SCROLL_DOWN && !isMinZoom()) {
} else if (!isUp && !isMinZoom()) {
zoomOut (true, newCenterX, newCenterY);
}
}

View File

@ -32,15 +32,15 @@
#include "edit.h"
class CropWindow;
class CropWindowListener
{
public:
virtual ~CropWindowListener() {}
virtual void cropPositionChanged (CropWindow*) {}
virtual void cropWindowSizeChanged (CropWindow*) {}
virtual void cropZoomChanged (CropWindow*) {}
virtual void initialImageArrived () {}
virtual ~CropWindowListener() = default;
virtual void cropPositionChanged(CropWindow*) = 0;
virtual void cropWindowSizeChanged(CropWindow*) = 0;
virtual void cropZoomChanged(CropWindow*) = 0;
virtual void initialImageArrived() = 0;
};
class ImageArea;
@ -187,7 +187,7 @@ public:
bool isInside (int x, int y);
void scroll (int state, GdkScrollDirection direction, int x, int y);
void scroll (int state, GdkScrollDirection direction, int x, int y, double deltaX=0.0, double deltaY=0.0);
void buttonPress (int button, int num, int state, int x, int y);
void buttonRelease (int button, int num, int state, int x, int y);
void pointerMoved (int bstate, int x, int y);

View File

@ -254,7 +254,7 @@ void CurveEditor::setUnChanged (bool uc)
/*
* Update the backgrounds histograms
*/
void CurveEditor::updateBackgroundHistogram (LUTu & hist)
void CurveEditor::updateBackgroundHistogram(const LUTu& hist)
{
// Copy the histogram in the curve editor cache
if (hist) {
@ -265,7 +265,7 @@ void CurveEditor::updateBackgroundHistogram (LUTu & hist)
}
// Then call the curve editor group to eventually update the histogram
subGroup->updateBackgroundHistogram (this);
subGroup->updateBackgroundHistogram(this);
}
// Open up the curve if it has modifications and it's not already opened

View File

@ -93,7 +93,7 @@ public:
void curveTypeToggled();
bool isUnChanged ();
void setUnChanged (bool uc);
void updateBackgroundHistogram (LUTu & hist);
void updateBackgroundHistogram(const LUTu& hist);
void setLeftBarColorProvider(ColorProvider* cp, int callerId);
void setBottomBarColorProvider(ColorProvider* cp, int callerId);

View File

@ -149,9 +149,8 @@ void Defringe::curveChanged ()
}
}
void Defringe::adjusterChanged (Adjuster* a, double newval)
void Defringe::adjusterChanged(Adjuster* a, double newval)
{
if (listener && getEnabled()) {
if (a == radius) {
@ -162,6 +161,10 @@ void Defringe::adjusterChanged (Adjuster* a, double newval)
}
}
void Defringe::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
void Defringe::enabledChanged ()
{

View File

@ -50,6 +50,7 @@ public:
void curveChanged ();
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled(Adjuster* a, bool newval);
void enabledChanged ();
virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller);

View File

@ -1154,14 +1154,17 @@ void DiagonalCurveEditorSubGroup::shcChanged ()
/*
* Listener
*/
void DiagonalCurveEditorSubGroup::adjusterChanged (Adjuster* a, double newval)
void DiagonalCurveEditorSubGroup::adjusterChanged(Adjuster* a, double newval)
{
paramCurve->setPoints (getCurveFromGUI(DCT_Parametric));
storeDisplayedCurve();
parent->curveChanged ();
}
void DiagonalCurveEditorSubGroup::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
/*
* Listener called when the mouse is over a parametric curve's slider
*/

View File

@ -105,6 +105,7 @@ protected:
const std::vector<double> getCurveFromGUI (int type);
void shcChanged ();
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled(Adjuster* a, bool newval);
bool adjusterEntered (GdkEventCrossing* ev, int ac);
bool adjusterLeft (GdkEventCrossing* ev, int ac);
void setSubGroupRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4);

View File

@ -1009,11 +1009,9 @@ void DirPyrDenoise::setDefaults (const ProcParams* defParams, const ParamsEdited
}
}
void DirPyrDenoise::adjusterChanged (Adjuster* a, double newval)
void DirPyrDenoise::adjusterChanged(Adjuster* a, double newval)
{
Glib::ustring costr;
costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue());
const Glib::ustring costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue());
if (listener && getEnabled()) {
if (a == Ldetail) {
@ -1034,6 +1032,10 @@ void DirPyrDenoise::adjusterChanged (Adjuster* a, double newval)
}
}
void DirPyrDenoise::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
void DirPyrDenoise::enabledChanged ()
{

View File

@ -49,6 +49,7 @@ public:
void autoOpenCurve ();
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled(Adjuster* a, bool newval);
void enabledChanged ();
void medianChanged ();
void chromaChanged (double autchroma, double autred, double autblue);

View File

@ -297,13 +297,28 @@ void DirPyrEqualizer::setDefaults (const ProcParams* defParams, const ParamsEdit
}
}
void DirPyrEqualizer::adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight)
void DirPyrEqualizer::adjusterChanged(ThresholdAdjuster* a, double newBottom, double newTop)
{
}
void DirPyrEqualizer::adjusterChanged(ThresholdAdjuster* a, double newBottomLeft, double newTopLeft, double newBottomRight, double newTopRight)
{
}
void DirPyrEqualizer::adjusterChanged(ThresholdAdjuster* a, int newBottom, int newTop)
{
}
void DirPyrEqualizer::adjusterChanged(ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight)
{
if (listener && (multiImage || getEnabled()) ) {
listener->panelChanged (EvDirPyrEqualizerHueskin, hueskin->getHistoryString());
}
}
void DirPyrEqualizer::adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR)
{
}
void DirPyrEqualizer::setBatchMode (bool batchMode)
{
@ -330,9 +345,8 @@ void DirPyrEqualizer::cbdlMethodChanged()
void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval)
void DirPyrEqualizer::adjusterChanged(Adjuster* a, double newval)
{
if (listener && getEnabled()) {
if (a == threshold) {
listener->panelChanged (EvDirPyrEqualizerThreshold,
@ -359,6 +373,10 @@ void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval)
}
}
void DirPyrEqualizer::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
void DirPyrEqualizer::enabledChanged ()
{

View File

@ -63,15 +63,20 @@ public:
void setBatchMode (bool batchMode);
void setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool skinadd);
void trimValues (rtengine::procparams::ProcParams* pp);
void adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight);
// void algoChanged ();
void cbdlMethodChanged();
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled(Adjuster* a, bool newval);
void enabledChanged();
void gamutlabToggled ();
void lumaneutralPressed ();
void lumacontrastPlusPressed ();
void lumacontrastMinusPressed ();
void adjusterChanged(ThresholdAdjuster* a, double newBottom, double newTop);
void adjusterChanged(ThresholdAdjuster* a, double newBottomLeft, double newTopLeft, double newBottomRight, double newTopRight);
void adjusterChanged(ThresholdAdjuster* a, int newBottom, int newTop);
void adjusterChanged(ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight);
void adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR);
};
#endif

View File

@ -84,14 +84,17 @@ void Distortion::setDefaults (const ProcParams* defParams, const ParamsEdited* p
}
}
void Distortion::adjusterChanged (Adjuster* a, double newval)
void Distortion::adjusterChanged(Adjuster* a, double newval)
{
if (listener) {
listener->panelChanged (EvDISTAmount, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue()));
}
}
void Distortion::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
void Distortion::setBatchMode (bool batchMode)
{

View File

@ -43,6 +43,7 @@ public:
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled (Adjuster* a, bool newval);
void setAdjusterBehavior (bool vadd);
void trimValues (rtengine::procparams::ProcParams* pp);
void idPressed ();

View File

@ -1159,7 +1159,12 @@ Glib::ustring EditorPanel::getFileName ()
}
// TODO!!!
void EditorPanel::procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited)
void EditorPanel::procParamsChanged(
const rtengine::procparams::ProcParams* params,
const rtengine::ProcEvent& ev,
const Glib::ustring& descr,
const ParamsEdited* paramsEdited
)
{
// if (ev!=EvPhotoLoaded)
@ -1178,7 +1183,28 @@ void EditorPanel::procParamsChanged (rtengine::procparams::ProcParams* params, r
info_toggled();
}
void EditorPanel::setProgressState (bool inProcessing)
void EditorPanel::clearParamChanges()
{
}
void EditorPanel::setProgress(double p)
{
spparams *s = new spparams;
s->val = p;
s->pProgress = progressLabel;
idle_register.add(setprogressStrUI, s);
}
void EditorPanel::setProgressStr(const Glib::ustring& str)
{
spparams *s = new spparams;
s->str = str;
s->val = -1;
s->pProgress = progressLabel;
idle_register.add(setprogressStrUI, s);
}
void EditorPanel::setProgressState(bool inProcessing)
{
struct spsparams {
bool inProcessing;
@ -1217,21 +1243,63 @@ void EditorPanel::setProgressState (bool inProcessing)
idle_register.add (func, p);
}
void EditorPanel::setProgress (double p)
void EditorPanel::error(const Glib::ustring& descr)
{
spparams *s = new spparams;
s->val = p;
s->pProgress = progressLabel;
idle_register.add (setprogressStrUI, s);
}
void EditorPanel::setProgressStr (Glib::ustring str)
void EditorPanel::error(const Glib::ustring& title, const Glib::ustring& descr)
{
spparams *s = new spparams;
s->str = str;
s->val = -1;
s->pProgress = progressLabel;
idle_register.add (setprogressStrUI, s);
struct errparams {
Glib::ustring descr;
Glib::ustring title;
EditorPanelIdleHelper* epih;
};
epih->pending++;
errparams* const p = new errparams;
p->descr = descr;
p->title = title;
p->epih = epih;
const auto func = [] (gpointer data) -> gboolean {
errparams* const p = static_cast<errparams*> (data);
if (p->epih->destroyed)
{
if (p->epih->pending == 1) {
delete p->epih;
} else {
p->epih->pending--;
}
delete p;
return 0;
}
p->epih->epanel->displayError (p->title, p->descr);
p->epih->pending--;
delete p;
return FALSE;
};
idle_register.add (func, p);
}
void EditorPanel::displayError(const Glib::ustring& title, const Glib::ustring& descr)
{
GtkWidget* msgd = gtk_message_dialog_new_with_markup (nullptr,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
"<b>%s</b>",
descr.data());
gtk_window_set_title ((GtkWindow*)msgd, title.data());
g_signal_connect_swapped (msgd, "response",
G_CALLBACK (gtk_widget_destroy),
msgd);
gtk_widget_show_all (msgd);
}
// This is only called from the ThreadUI, so within the gtk thread
@ -1286,61 +1354,6 @@ void EditorPanel::refreshProcessingState (bool inProcessingP)
setprogressStrUI (s);
}
void EditorPanel::displayError (Glib::ustring title, Glib::ustring descr)
{
GtkWidget* msgd = gtk_message_dialog_new_with_markup (nullptr,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
"<b>%s</b>",
descr.data());
gtk_window_set_title ((GtkWindow*)msgd, title.data());
g_signal_connect_swapped (msgd, "response",
G_CALLBACK (gtk_widget_destroy),
msgd);
gtk_widget_show_all (msgd);
}
void EditorPanel::error (Glib::ustring title, Glib::ustring descr)
{
struct errparams {
Glib::ustring descr;
Glib::ustring title;
EditorPanelIdleHelper* epih;
};
epih->pending++;
errparams* const p = new errparams;
p->descr = descr;
p->title = title;
p->epih = epih;
const auto func = [] (gpointer data) -> gboolean {
errparams* const p = static_cast<errparams*> (data);
if (p->epih->destroyed)
{
if (p->epih->pending == 1) {
delete p->epih;
} else {
p->epih->pending--;
}
delete p;
return 0;
}
p->epih->epanel->displayError (p->title, p->descr);
p->epih->pending--;
delete p;
return FALSE;
};
idle_register.add (func, p);
}
void EditorPanel::info_toggled ()
{
@ -2249,15 +2262,28 @@ void EditorPanel::tbBeforeLock_toggled ()
tbBeforeLock->get_active() ? tbBeforeLock->set_image (*iBeforeLockON) : tbBeforeLock->set_image (*iBeforeLockOFF);
}
void EditorPanel::histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve, /*LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM,
LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw, LUTu & histChroma, LUTu & histLRETI)
void EditorPanel::histogramChanged(
const LUTu& histRed,
const LUTu& histGreen,
const LUTu& histBlue,
const LUTu& histLuma,
const LUTu& histToneCurve,
const LUTu& histLCurve,
const LUTu& histCCurve,
const LUTu& histLCAM,
const LUTu& histCCAM,
const LUTu& histRedRaw,
const LUTu& histGreenRaw,
const LUTu& histBlueRaw,
const LUTu& histChroma,
const LUTu& histLRETI
)
{
if (histogramPanel) {
histogramPanel->histogramChanged (histRed, histGreen, histBlue, histLuma, histChroma, histRedRaw, histGreenRaw, histBlueRaw);
histogramPanel->histogramChanged(histRed, histGreen, histBlue, histLuma, histChroma, histRedRaw, histGreenRaw, histBlueRaw);
}
tpc->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histCCurve,/*histCLurve, histLLCurve,*/ histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI);
tpc->updateCurveBackgroundHistogram(histToneCurve, histLCurve, histCCurve, histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI);
}
bool EditorPanel::CheckSidePanelsVisibility()

View File

@ -45,13 +45,14 @@ struct EditorPanelIdleHelper {
};
class RTWindow;
class EditorPanel final :
public Gtk::VBox,
public PParamsChangeListener,
public rtengine::ProgressListener,
public ThumbnailListener,
public HistoryBeforeLineListener,
public rtengine::HistogramListener
public Gtk::VBox,
public PParamsChangeListener,
public rtengine::ProgressListener,
public ThumbnailListener,
public HistoryBeforeLineListener,
public rtengine::HistogramListener
{
public:
explicit EditorPanel (FilePanel* filePanel = nullptr);
@ -81,16 +82,24 @@ public:
{
return realized;
}
// progresslistener interface
void setProgress (double p);
void setProgressStr (Glib::ustring str);
void setProgressState (bool inProcessing);
void error (Glib::ustring title, Glib::ustring descr);
void displayError (Glib::ustring title, Glib::ustring descr); // this is called by error in the gtk thread
// ProgressListener interface
void setProgress(double p);
void setProgressStr(const Glib::ustring& str);
void setProgressState(bool inProcessing);
void error(const Glib::ustring& descr);
void error(const Glib::ustring& title, const Glib::ustring& descr);
void displayError(const Glib::ustring& title, const Glib::ustring& descr); // this is called by error in the gtk thread
void refreshProcessingState (bool inProcessing); // this is called by setProcessingState in the gtk thread
// PParamsChangeListener interface
void procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited = nullptr);
void procParamsChanged(
const rtengine::procparams::ProcParams* params,
const rtengine::ProcEvent& ev,
const Glib::ustring& descr,
const ParamsEdited* paramsEdited = nullptr
);
void clearParamChanges();
// thumbnaillistener interface
void procParamsChanged (Thumbnail* thm, int whoChangedIt);
@ -99,8 +108,22 @@ public:
void historyBeforeLineChanged (const rtengine::procparams::ProcParams& params);
// HistogramListener
void histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM,
LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw, LUTu & histChroma, LUTu & histLRETI);
void histogramChanged(
const LUTu& histRed,
const LUTu& histGreen,
const LUTu& histBlue,
const LUTu& histLuma,
const LUTu& histToneCurve,
const LUTu& histLCurve,
const LUTu& histCCurve,
const LUTu& histLCAM,
const LUTu& histCCAM,
const LUTu& histRedRaw,
const LUTu& histGreenRaw,
const LUTu& histBlueRaw,
const LUTu& histChroma,
const LUTu& histLRETI
);
// event handlers
void info_toggled ();

View File

@ -143,7 +143,7 @@ void EdgePreservingDecompositionUI::setDefaults(const ProcParams *defParams, con
void EdgePreservingDecompositionUI::adjusterChanged(Adjuster* a, double newval)
{
if(listener && getEnabled()) {
if (listener && getEnabled()) {
if(a == strength) {
listener->panelChanged(EvEPDStrength, Glib::ustring::format(std::setw(2), std::fixed, std::setprecision(2), a->getValue()));
} else if(a == gamma) {
@ -158,6 +158,10 @@ void EdgePreservingDecompositionUI::adjusterChanged(Adjuster* a, double newval)
}
}
void EdgePreservingDecompositionUI::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
void EdgePreservingDecompositionUI::enabledChanged ()
{
if (listener) {

View File

@ -42,6 +42,7 @@ public:
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled(Adjuster* a, bool newval);
void enabledChanged ();
void setAdjusterBehavior (bool stAdd, bool gAdd, bool esAdd, bool scAdd, bool rAdd);
};

View File

@ -26,9 +26,10 @@
class ExportPanelListener
{
public:
virtual void exportRequested () {}
virtual ~ExportPanelListener() = default;
virtual void exportRequested() = 0;
};
class ExportPanel : public Gtk::VBox

View File

@ -113,6 +113,10 @@ void FattalToneMapping::adjusterChanged(Adjuster* a, double newval)
}
}
void FattalToneMapping::adjusterAutoToggled(Adjuster* a, bool newval)
{
}
void FattalToneMapping::enabledChanged ()
{
if (listener) {

View File

@ -42,6 +42,7 @@ public:
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled(Adjuster* a, bool newval);
void enabledChanged ();
void setAdjusterBehavior(bool amountAdd, bool thresholdAdd, bool anchorAdd);
};

View File

@ -981,7 +981,7 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m)
// Empty run to update the thumb
rtengine::procparams::ProcParams params = mselected[i]->thumbnail->getProcParams ();
mselected[i]->thumbnail->setProcParams (params, nullptr, FILEBROWSER);
mselected[i]->thumbnail->setProcParams (params, nullptr, FILEBROWSER, true, true);
}
if (!mselected.empty() && bppcl) {
@ -1991,7 +1991,11 @@ void FileBrowser::setExportPanel (ExportPanel* expanel)
exportPanel->setExportPanelListener (this);
}
void FileBrowser::updateProfileList ()
void FileBrowser::storeCurrentValue()
{
}
void FileBrowser::updateProfileList()
{
// submenu applmenu
int p = 0;
@ -2085,6 +2089,10 @@ void FileBrowser::updateProfileList ()
subMenuList.clear();
}
void FileBrowser::restoreValue()
{
}
void FileBrowser::openRequested( std::vector<FileBrowserEntry*> mselected)
{
std::vector<Thumbnail*> entries;

View File

@ -34,23 +34,20 @@
class ProfileStoreLabel;
class FileBrowser;
class FileBrowserEntry;
class FileBrowserListener
{
public:
virtual ~FileBrowserListener () {}
virtual void filterApplied () {}
virtual void openRequested (std::vector<Thumbnail*> tbe) {}
virtual void developRequested (std::vector<FileBrowserEntry*> tbe, bool fastmode) {}
virtual void renameRequested (std::vector<FileBrowserEntry*> tbe) {}
virtual void deleteRequested (std::vector<FileBrowserEntry*> tbe, bool inclBatchProcessed) {}
virtual void copyMoveRequested (std::vector<FileBrowserEntry*> tbe, bool moveRequested) {}
virtual void selectionChanged (std::vector<Thumbnail*> tbe) {}
virtual void clearFromCacheRequested(std::vector<FileBrowserEntry*> tbe, bool leavenotrace) {}
virtual bool isInTabMode ()
{
return false;
}
virtual ~FileBrowserListener() = default;
virtual void filterApplied() = 0;
virtual void openRequested(const std::vector<Thumbnail*>& tbe) = 0;
virtual void developRequested(const std::vector<FileBrowserEntry*>& tbe, bool fastmode) = 0;
virtual void renameRequested(const std::vector<FileBrowserEntry*>& tbe) = 0;
virtual void deleteRequested(const std::vector<FileBrowserEntry*>& tbe, bool inclBatchProcessed) = 0;
virtual void copyMoveRequested(const std::vector<FileBrowserEntry*>& tbe, bool moveRequested) = 0;
virtual void selectionChanged(const std::vector<Thumbnail*>& tbe) = 0;
virtual void clearFromCacheRequested(const std::vector<FileBrowserEntry*>& tbe, bool leavenotrace) = 0;
virtual bool isInTabMode() const = 0;
};
/*
@ -203,7 +200,9 @@ public:
// exportpanel interface
void exportRequested();
void updateProfileList ();
void storeCurrentValue();
void updateProfileList();
void restoreValue();
type_trash_changed trash_changed();
};

View File

@ -209,7 +209,7 @@ void FileBrowserEntry::procParamsChanged (Thumbnail* thm, int whoChangedIt)
}
}
void FileBrowserEntry::updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams)
void FileBrowserEntry::updateImage(rtengine::IImage8* img, double scale, const rtengine::procparams::CropParams& cropParams)
{
if (!feih) {
return;
@ -260,7 +260,7 @@ void FileBrowserEntry::updateImage (rtengine::IImage8* img, double scale, rtengi
idle_register.add(func, param, priority);
}
void FileBrowserEntry::_updateImage (rtengine::IImage8* img, double s, rtengine::procparams::CropParams cropParams)
void FileBrowserEntry::_updateImage(rtengine::IImage8* img, double s, const rtengine::procparams::CropParams& cropParams)
{
MYWRITERLOCK(l, lockRW);

View File

@ -99,8 +99,8 @@ public:
// thumbnaillistener interface
void procParamsChanged (Thumbnail* thm, int whoChangedIt);
// thumbimageupdatelistener interface
void updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams);
void _updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams); // inside gtk thread
void updateImage(rtengine::IImage8* img, double scale, const rtengine::procparams::CropParams& cropParams);
void _updateImage(rtengine::IImage8* img, double scale, const rtengine::procparams::CropParams& cropParams); // inside gtk thread
virtual bool motionNotify (int x, int y);
virtual bool pressNotify (int button, int type, int bstate, int x, int y);

View File

@ -749,18 +749,6 @@ void FileCatalog::_refreshProgressBar ()
}
}
void FileCatalog::filterApplied()
{
const auto func = [](gpointer data) -> gboolean {
static_cast<FileCatalog*>(data)->_refreshProgressBar();
return FALSE;
};
idle_register.add(func, this);
}
void FileCatalog::previewReady (int dir_id, FileBrowserEntry* fdn)
{
@ -962,9 +950,19 @@ int openRequestedUI (void* p)
return 0;
}
void FileCatalog::openRequested (std::vector<Thumbnail*> tmb)
void FileCatalog::filterApplied()
{
const auto func = [](gpointer data) -> gboolean {
static_cast<FileCatalog*>(data)->_refreshProgressBar();
return FALSE;
};
idle_register.add(func, this);
}
void FileCatalog::openRequested(const std::vector<Thumbnail*>& tmb)
{
FCOIParams* params = new FCOIParams;
params->catalog = this;
params->tmb = tmb;
@ -976,9 +974,8 @@ void FileCatalog::openRequested (std::vector<Thumbnail*> tmb)
idle_register.add(openRequestedUI, params);
}
void FileCatalog::deleteRequested (std::vector<FileBrowserEntry*> tbe, bool inclBatchProcessed)
void FileCatalog::deleteRequested(const std::vector<FileBrowserEntry*>& tbe, bool inclBatchProcessed)
{
if (tbe.empty()) {
return;
}
@ -1017,15 +1014,12 @@ void FileCatalog::deleteRequested (std::vector<FileBrowserEntry*> tbe, bool inc
}
}
void FileCatalog::copyMoveRequested (std::vector<FileBrowserEntry*> tbe, bool moveRequested)
void FileCatalog::copyMoveRequested(const std::vector<FileBrowserEntry*>& tbe, bool moveRequested)
{
if (tbe.empty()) {
return;
}
Glib::ustring fc_title;
if (moveRequested) {
@ -1129,9 +1123,9 @@ void FileCatalog::copyMoveRequested (std::vector<FileBrowserEntry*> tbe, bool m
_refreshProgressBar();
} // Gtk::RESPONSE_OK
}
void FileCatalog::developRequested (std::vector<FileBrowserEntry*> tbe, bool fastmode)
{
void FileCatalog::developRequested(const std::vector<FileBrowserEntry*>& tbe, bool fastmode)
{
if (listener) {
std::vector<BatchQueueEntry*> entries;
@ -1262,23 +1256,8 @@ void FileCatalog::developRequested (std::vector<FileBrowserEntry*> tbe, bool fas
}
}
void FileCatalog::exportRequested ()
void FileCatalog::renameRequested(const std::vector<FileBrowserEntry*>& tbe)
{
}
void FileCatalog::setExportPanel (ExportPanel* expanel)
{
exportPanel = expanel;
exportPanel->set_sensitive (false);
exportPanel->setExportPanelListener (this);
fileBrowser->setExportPanel(expanel);
}
void FileCatalog::renameRequested (std::vector<FileBrowserEntry*> tbe)
{
RenameDialog* renameDlg = new RenameDialog ((Gtk::Window*)get_toplevel());
for (size_t i = 0; i < tbe.size(); i++) {
@ -1333,9 +1312,15 @@ void FileCatalog::renameRequested (std::vector<FileBrowserEntry*> tbe)
delete renameDlg;
}
void FileCatalog::clearFromCacheRequested (std::vector<FileBrowserEntry*> tbe, bool leavenotrace)
void FileCatalog::selectionChanged(const std::vector<Thumbnail*>& tbe)
{
if (fslistener) {
fslistener->selectionChanged (tbe);
}
}
void FileCatalog::clearFromCacheRequested(const std::vector<FileBrowserEntry*>& tbe, bool leavenotrace)
{
if (tbe.empty()) {
return;
}
@ -1347,6 +1332,11 @@ void FileCatalog::clearFromCacheRequested (std::vector<FileBrowserEntry*> tbe,
}
}
bool FileCatalog::isInTabMode() const
{
return inTabMode;
}
void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b, bool isMouseClick)
{
@ -1966,12 +1956,8 @@ void FileCatalog::refreshEditedState (const std::set<Glib::ustring>& efiles)
fileBrowser->refreshEditedState (efiles);
}
void FileCatalog::selectionChanged (std::vector<Thumbnail*> tbe)
void FileCatalog::exportRequested()
{
if (fslistener) {
fslistener->selectionChanged (tbe);
}
}
// Called within GTK UI thread
@ -1991,6 +1977,15 @@ void FileCatalog::setFilterPanel (FilterPanel* fpanel)
filterPanel->set_sensitive (false);
filterPanel->setFilterPanelListener (this);
}
void FileCatalog::setExportPanel(ExportPanel* expanel)
{
exportPanel = expanel;
exportPanel->set_sensitive (false);
exportPanel->setExportPanelListener (this);
fileBrowser->setExportPanel(expanel);
}
void FileCatalog::trashChanged ()
{
if (trashIsEmpty()) {

View File

@ -212,13 +212,16 @@ public:
void refreshThumbImages ();
void refreshHeight ();
void openRequested (std::vector<Thumbnail*> tbe);
void deleteRequested (std::vector<FileBrowserEntry*> tbe, bool inclBatchProcessed);
void copyMoveRequested (std::vector<FileBrowserEntry*> tbe, bool moveRequested);
void developRequested (std::vector<FileBrowserEntry*> tbe, bool fastmode);
void renameRequested (std::vector<FileBrowserEntry*> tbe);
void clearFromCacheRequested(std::vector<FileBrowserEntry*> tbe, bool leavenotrace);
void selectionChanged (std::vector<Thumbnail*> tbe);
void filterApplied();
void openRequested(const std::vector<Thumbnail*>& tbe);
void deleteRequested(const std::vector<FileBrowserEntry*>& tbe, bool inclBatchProcessed);
void copyMoveRequested(const std::vector<FileBrowserEntry*>& tbe, bool moveRequested);
void developRequested(const std::vector<FileBrowserEntry*>& tbe, bool fastmode);
void renameRequested(const std::vector<FileBrowserEntry*>& tbe);
void selectionChanged(const std::vector<Thumbnail*>& tbe);
void clearFromCacheRequested(const std::vector<FileBrowserEntry*>& tbe, bool leavenotrace);
bool isInTabMode() const;
void emptyTrash ();
bool trashIsEmpty ();
@ -277,11 +280,6 @@ public:
bool handleShortcutKey (GdkEventKey* event);
bool isInTabMode()
{
return inTabMode;
}
bool CheckSidePanelsVisibility();
void toggleSidePanels();
void toggleLeftPanel();
@ -289,7 +287,6 @@ public:
void showToolBar();
void hideToolBar();
void filterApplied();
#ifndef _WIN32
void on_dir_changed (const Glib::RefPtr<Gio::File>& file, const Glib::RefPtr<Gio::File>& other_file, Gio::FileMonitorEvent event_type, bool internal);

Some files were not shown because too many files have changed in this diff Show More