From affa336680877a6bba43a7f7307eef646a947b00 Mon Sep 17 00:00:00 2001 From: rfranke Date: Tue, 4 Aug 2020 12:24:02 +0200 Subject: [PATCH 01/14] Delay update of inspector window until it is visible (#5867) This reduces CPU load if the inspector window is not used. --- rtgui/inspector.cc | 15 +++++++++++++++ rtgui/inspector.h | 1 + 2 files changed, 16 insertions(+) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 7d5d44e44..3f9fab4fe 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -114,6 +114,10 @@ void Inspector::showWindow(bool scaled) window.fullscreen(); window.set_visible(true); pinned = false; + + // update content when becoming visible + switchImage(next_image_path); + mouseMove(next_image_pos, 0); } bool Inspector::on_key_release(GdkEventKey *event) @@ -423,6 +427,12 @@ void Inspector::mouseMove (rtengine::Coord2D pos, int transform) return; } + next_image_pos = pos; + + // skip actual update of content when not visible + if (!window.get_visible()) + return; + if (currImage) { center.set(int(rtengine::LIM01(pos.x)*double(currImage->imgBuffer.getWidth())), int(rtengine::LIM01(pos.y)*double(currImage->imgBuffer.getHeight()))); } else { @@ -443,6 +453,11 @@ void Inspector::switchImage (const Glib::ustring &fullPath) } next_image_path = fullPath; + + // skip actual update of content when not visible + if (!window.get_visible()) + return; + if (!options.inspectorDelay) { doSwitchImage(); } else { diff --git a/rtgui/inspector.h b/rtgui/inspector.h index 9a99fb8a6..00a8e24a7 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -57,6 +57,7 @@ private: sigc::connection delayconn; Glib::ustring next_image_path; + rtengine::Coord2D next_image_pos; Gtk::Window window; bool on_key_release(GdkEventKey *event); From e82c7873699e03c7204ac6fac79559d670746719 Mon Sep 17 00:00:00 2001 From: rfranke Date: Tue, 4 Aug 2020 18:25:44 +0200 Subject: [PATCH 02/14] Implement panning in inspector window with mouse drag (#5867) --- rtgui/inspector.cc | 22 +++++++++++++++++++++- rtgui/inspector.h | 3 +++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 3f9fab4fe..8c5abefc8 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -92,7 +92,7 @@ Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomSca window.signal_key_release_event().connect(sigc::mem_fun(*this, &Inspector::on_key_release)); window.signal_key_press_event().connect(sigc::mem_fun(*this, &Inspector::on_key_press)); - add_events(Gdk::BUTTON_PRESS_MASK | Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); + add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_MOTION_MASK | Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); gestureZoom = Gtk::GestureZoom::create(*this); gestureZoom->signal_begin().connect(sigc::mem_fun(*this, &Inspector::on_zoom_begin)); gestureZoom->signal_scale_changed().connect(sigc::mem_fun(*this, &Inspector::on_zoom_scale_changed)); @@ -162,6 +162,7 @@ bool Inspector::on_key_press(GdkEventKey *event) bool Inspector::on_button_press_event(GdkEventButton *event) { if (event->type == GDK_BUTTON_PRESS) { + button_pos.set(event->x, event->y); if (!pinned) // pin window with mouse click pinned = true; @@ -170,6 +171,25 @@ bool Inspector::on_button_press_event(GdkEventButton *event) return false; } +bool Inspector::on_motion_notify_event(GdkEventMotion *event) +{ + int deviceScale = get_scale_factor(); + int delta_x = (button_pos.x - event->x)*deviceScale; + int delta_y = (button_pos.y - event->y)*deviceScale; + int imW = currImage->imgBuffer.getWidth(); + int imH = currImage->imgBuffer.getHeight(); + + moveCenter(delta_x, delta_y, imW, imH, deviceScale); + button_pos.set(event->x, event->y); + + if (!dirty) { + dirty = true; + queue_draw(); + } + + return true; +} + bool Inspector::on_scroll_event(GdkEventScroll *event) { if (!currImage) diff --git a/rtgui/inspector.h b/rtgui/inspector.h index 00a8e24a7..08eb87e1c 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -63,7 +63,10 @@ private: bool on_key_release(GdkEventKey *event); bool on_key_press(GdkEventKey *event); + rtengine::Coord button_pos; bool on_button_press_event(GdkEventButton *event) override; + bool on_motion_notify_event(GdkEventMotion *event) override; + bool on_scroll_event(GdkEventScroll *event) override; void moveCenter(int delta_x, int delta_y, int imW, int imH, int deviceScale); From 691523d8dd4d82645d486128f9c4ce4c4190c53f Mon Sep 17 00:00:00 2001 From: rfranke Date: Tue, 4 Aug 2020 18:39:01 +0200 Subject: [PATCH 03/14] Let inspector window zoom on scroll wheel events (#5867) A scroll wheel should emit GDK_SCROLL_UP/DOWN/LEFT_RIGHT. The ALT key is left as backup in case a scroll wheel emits GDK_SCROLL_SMOOTH that results in panning (used with trackpads). --- rtgui/inspector.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 8c5abefc8..f09e9e89d 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -225,15 +225,19 @@ bool Inspector::on_scroll_event(GdkEventScroll *event) break; case GDK_SCROLL_DOWN: delta_y = step_y * deviceScale * imH / 100; + alt = true; // zoom for non smooth scroll events (scroll wheel) break; case GDK_SCROLL_UP: delta_y = -step_y * deviceScale * imH / 100; + alt = true; // zoom for non smooth scroll events (scroll wheel) break; case GDK_SCROLL_LEFT: delta_x = step_x * deviceScale * imW / 100; + alt = true; // zoom for non smooth scroll events (scroll wheel) break; case GDK_SCROLL_RIGHT: delta_x = -step_x * deviceScale * imW / 100; + alt = true; // zoom for non smooth scroll events (scroll wheel) break; } From 947f3dca00b75c32f74d395009c3c83a9e34746d Mon Sep 17 00:00:00 2001 From: rfranke Date: Sun, 9 Aug 2020 17:17:15 +0200 Subject: [PATCH 04/14] Toggle fullscreen status of inspector window with F11 (#5867) Moreover add two null pointer checks (thanks for review @Lawrence37). --- rtgui/inspector.cc | 26 ++++++++++++++++++++++++-- rtgui/inspector.h | 3 ++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index f09e9e89d..35c795d64 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -98,6 +98,7 @@ Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomSca gestureZoom->signal_scale_changed().connect(sigc::mem_fun(*this, &Inspector::on_zoom_scale_changed)); window.add(*this); + window.set_size_request(400, 400); window.show_all(); window.set_visible(false); active = true; // always track inspected thumbnails @@ -108,10 +109,14 @@ Inspector::~Inspector() deleteBuffers(); } -void Inspector::showWindow(bool scaled) +void Inspector::showWindow(bool scaled, bool fullscreen) { this->scaled = scaled; - window.fullscreen(); + if (fullscreen) + window.fullscreen(); + else + window.unfullscreen(); + this->fullscreen = fullscreen; window.set_visible(true); pinned = false; @@ -139,18 +144,29 @@ bool Inspector::on_key_press(GdkEventKey *event) switch (event->keyval) { case GDK_KEY_z: case GDK_KEY_F: + // show image unscaled in 100% view if (pinned || scaled) zoomScale = 1.0; // reset if not key hold scaled = false; queue_draw(); return true; case GDK_KEY_f: + // show image scaled to window size if (pinned || !scaled) zoomScale = 1.0; // reset if not key hold scaled = true; queue_draw(); return true; + case GDK_KEY_F11: + // toggle fullscreen + if (fullscreen) + window.unfullscreen(); + else + window.fullscreen(); + fullscreen = !fullscreen; + return true; case GDK_KEY_Escape: + // hide window zoomScale = 1.0; window.set_visible(false); return true; @@ -173,6 +189,9 @@ bool Inspector::on_button_press_event(GdkEventButton *event) bool Inspector::on_motion_notify_event(GdkEventMotion *event) { + if (!currImage) + return false; + int deviceScale = get_scale_factor(); int delta_x = (button_pos.x - event->x)*deviceScale; int delta_y = (button_pos.y - event->y)*deviceScale; @@ -273,6 +292,9 @@ void Inspector::moveCenter(int delta_x, int delta_y, int imW, int imH, int devic void Inspector::beginZoom(double x, double y) { + if (!currImage) + return; + int deviceScale = get_scale_factor(); int imW = currImage->imgBuffer.getWidth(); int imH = currImage->imgBuffer.getHeight(); diff --git a/rtgui/inspector.h b/rtgui/inspector.h index 08eb87e1c..bf53ee2a2 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -54,6 +54,7 @@ private: bool active; bool pinned; bool dirty; + bool fullscreen; // window is shown in fullscreen mode sigc::connection delayconn; Glib::ustring next_image_path; @@ -87,7 +88,7 @@ public: /** @brief Show or hide window * @param scaled fit image into window */ - void showWindow(bool scaled); + void showWindow(bool scaled, bool fullscreen = true); /** @brief Mouse movement to a new position * @param pos Location of the mouse, in percentage (i.e. [0;1] range) relative to the full size image ; -1,-1 == out of the image From a449a01690756067279dbd4a3ced957eb8414ce7 Mon Sep 17 00:00:00 2001 From: rfranke Date: Sun, 9 Aug 2020 17:21:15 +0200 Subject: [PATCH 05/14] Extend context menu of filebrowser with inspect entry (#5867) This opens a popup inspector window at the current mouse position. --- rtdata/languages/default | 1 + rtgui/filebrowser.cc | 14 +++++++++++++- rtgui/filebrowser.h | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index a5f77403e..5b1d88deb 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -151,6 +151,7 @@ FILEBROWSER_POPUPMOVEHEAD;Move to head of queue FILEBROWSER_POPUPMOVETO;Move to... FILEBROWSER_POPUPOPEN;Open FILEBROWSER_POPUPOPENINEDITOR;Open in Editor +FILEBROWSER_POPUPINSPECT;Inspect FILEBROWSER_POPUPPROCESS;Put to queue FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 42aafd2e0..43ff8755d 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -27,6 +27,7 @@ #include "batchqueue.h" #include "clipboard.h" +#include "inspector.h" #include "multilangmgr.h" #include "options.h" #include "paramsedited.h" @@ -152,6 +153,8 @@ FileBrowser::FileBrowser () : pmenu = new Gtk::Menu (); pmenu->attach (*Gtk::manage(open = new Gtk::MenuItem (M("FILEBROWSER_POPUPOPEN"))), 0, 1, p, p + 1); p++; + pmenu->attach (*Gtk::manage(inspect = new Gtk::MenuItem (M("FILEBROWSER_POPUPINSPECT"))), 0, 1, p, p + 1); + p++; pmenu->attach (*Gtk::manage(develop = new MyImageMenuItem (M("FILEBROWSER_POPUPPROCESS"), "gears.png")), 0, 1, p, p + 1); p++; pmenu->attach (*Gtk::manage(developfast = new Gtk::MenuItem (M("FILEBROWSER_POPUPPROCESSFAST"))), 0, 1, p, p + 1); @@ -405,6 +408,7 @@ FileBrowser::FileBrowser () : trash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_Delete, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); untrash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_Delete, Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); open->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_Return, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); + inspect->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_F, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); develop->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_B, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); developfast->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_B, Gdk::CONTROL_MASK | Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); copyprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_C, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); @@ -416,6 +420,8 @@ FileBrowser::FileBrowser () : // Bind to event handlers open->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), open)); + inspect->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), inspect)); + for (int i = 0; i < 6; i++) { rank[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rank[i])); } @@ -698,7 +704,6 @@ void FileBrowser::menuColorlabelActivated (Gtk::MenuItem* m) void FileBrowser::menuItemActivated (Gtk::MenuItem* m) { - std::vector mselected; { @@ -751,6 +756,8 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) if (m == open) { openRequested(mselected); + } else if (m == inspect) { + inspectRequested(mselected); } else if (m == remove) { tbl->deleteRequested (mselected, false, true); } else if (m == removeInclProc) { @@ -2077,3 +2084,8 @@ void FileBrowser::openRequested( std::vector mselected) tbl->openRequested (entries); } + +void FileBrowser::inspectRequested(std::vector mselected) +{ + getInspector()->showWindow(false, false); +} diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index 53f3f1f2b..03a8636e5 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -81,6 +81,7 @@ protected: Gtk::MenuItem* remove; Gtk::MenuItem* removeInclProc; Gtk::MenuItem* open; + Gtk::MenuItem* inspect; Gtk::MenuItem* selall; Gtk::MenuItem* copyTo; Gtk::MenuItem* moveTo; @@ -136,6 +137,7 @@ protected: void requestColorLabel(int colorlabel); void notifySelectionListener (); void openRequested( std::vector mselected); + void inspectRequested( std::vector mselected); ExportPanel* exportPanel; type_trash_changed m_trash_changed; From e63b800864905a85a51d54dabdc0cf706e794e32 Mon Sep 17 00:00:00 2001 From: rfranke Date: Tue, 11 Aug 2020 18:27:50 +0200 Subject: [PATCH 06/14] Re-add inspector tab as an option (#5867) - add option "inspectorWindow" to switch from tab to fullscreen view - add option "zoomOnScroll" to configure scroll device for zoom or pan - add both options to preferences - filepanel creates tab if not inspectorWindow - inspector adapts to settings inspectorWindow and zoomOnScroll - filebrowser shows context menu item for inspector only if inspectorWindow --- rtdata/languages/default | 2 + rtgui/filebrowser.cc | 15 +++-- rtgui/filepanel.cc | 12 ++-- rtgui/inspector.cc | 141 +++++++++++++++++++++++---------------- rtgui/inspector.h | 3 +- rtgui/options.cc | 11 +++ rtgui/options.h | 2 + rtgui/preferences.cc | 19 +++++- rtgui/preferences.h | 3 + 9 files changed, 139 insertions(+), 69 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 5b1d88deb..83c1025f3 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1604,6 +1604,8 @@ PREFERENCES_CMMBPC;Black point compensation PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments PREFERENCES_COMPLEXITY_EXP;Expert PREFERENCES_COMPLEXITY_NORM;Normal +PREFERENCES_INSPECTORWINDOW;Open inspector in own window or fullscreen +PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling PREFERENCES_CROP;Crop Editing PREFERENCES_CROP_AUTO_FIT;Automatically zoom to fit the crop PREFERENCES_CROP_GUIDES;Guides shown when not editing the crop diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 43ff8755d..a8ce94e7f 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -153,8 +153,10 @@ FileBrowser::FileBrowser () : pmenu = new Gtk::Menu (); pmenu->attach (*Gtk::manage(open = new Gtk::MenuItem (M("FILEBROWSER_POPUPOPEN"))), 0, 1, p, p + 1); p++; - pmenu->attach (*Gtk::manage(inspect = new Gtk::MenuItem (M("FILEBROWSER_POPUPINSPECT"))), 0, 1, p, p + 1); - p++; + if (options.inspectorWindow) { + pmenu->attach (*Gtk::manage(inspect = new Gtk::MenuItem (M("FILEBROWSER_POPUPINSPECT"))), 0, 1, p, p + 1); + p++; + } pmenu->attach (*Gtk::manage(develop = new MyImageMenuItem (M("FILEBROWSER_POPUPPROCESS"), "gears.png")), 0, 1, p, p + 1); p++; pmenu->attach (*Gtk::manage(developfast = new Gtk::MenuItem (M("FILEBROWSER_POPUPPROCESSFAST"))), 0, 1, p, p + 1); @@ -408,7 +410,8 @@ FileBrowser::FileBrowser () : trash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_Delete, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); untrash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_Delete, Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); open->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_Return, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); - inspect->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_F, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); + if (options.inspectorWindow) + inspect->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_F, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); develop->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_B, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); developfast->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_B, Gdk::CONTROL_MASK | Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); copyprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_C, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); @@ -420,7 +423,9 @@ FileBrowser::FileBrowser () : // Bind to event handlers open->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), open)); - inspect->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), inspect)); + if (options.inspectorWindow) { + inspect->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), inspect)); + } for (int i = 0; i < 6; i++) { rank[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rank[i])); @@ -756,7 +761,7 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) if (m == open) { openRequested(mselected); - } else if (m == inspect) { + } else if (options.inspectorWindow && m == inspect) { inspectRequested(mselected); } else if (m == remove) { tbl->deleteRequested (mselected, false, true); diff --git a/rtgui/filepanel.cc b/rtgui/filepanel.cc index 983a0840c..17a5c9c5b 100644 --- a/rtgui/filepanel.cc +++ b/rtgui/filepanel.cc @@ -115,9 +115,12 @@ FilePanel::FilePanel () : parent(nullptr), error(0) Gtk::Label* devLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_DEVELOP")) ); devLab->set_name ("LabelRightNotebook"); devLab->set_angle (90); - //Gtk::Label* inspectLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_INSPECT")) ); - //inspectLab->set_name ("LabelRightNotebook"); - //inspectLab->set_angle (90); + Gtk::Label* inspectLab = nullptr; + if (!options.inspectorWindow) { + inspectLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_INSPECT")) ); + inspectLab->set_name ("LabelRightNotebook"); + inspectLab->set_angle (90); + } Gtk::Label* filtLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_FILTER")) ); filtLab->set_name ("LabelRightNotebook"); filtLab->set_angle (90); @@ -132,7 +135,8 @@ FilePanel::FilePanel () : parent(nullptr), error(0) tpcPaned->pack2 (*history, true, false); rightNotebook->append_page (*sFilterPanel, *filtLab); - //rightNotebook->append_page (*inspectorPanel, *inspectLab); + if (!options.inspectorWindow) + rightNotebook->append_page (*inspectorPanel, *inspectLab); rightNotebook->append_page (*tpcPaned, *devLab); //rightNotebook->append_page (*taggingBox, *tagLab); commented out: currently the tab is empty ... rightNotebook->append_page (*sExportPanel, *exportLab); diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 35c795d64..37ed20207 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -85,39 +85,57 @@ InspectorBuffer::~InspectorBuffer() { Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomScale(1.0), zoomScaleBegin(1.0), active(false), pinned(false), dirty(false) { set_name("Inspector"); - window.set_visible(false); - window.set_title("RawTherapee Inspector"); - window.add_events(Gdk::KEY_PRESS_MASK); - window.signal_key_release_event().connect(sigc::mem_fun(*this, &Inspector::on_key_release)); - window.signal_key_press_event().connect(sigc::mem_fun(*this, &Inspector::on_key_press)); + if (!options.inspectorWindow) { + window = nullptr; + } + else { + window = new Gtk::Window(); + window->set_title("RawTherapee Inspector"); + window->set_visible(false); + window->add_events(Gdk::KEY_PRESS_MASK); + window->signal_key_release_event().connect(sigc::mem_fun(*this, &Inspector::on_key_release)); + window->signal_key_press_event().connect(sigc::mem_fun(*this, &Inspector::on_key_press)); - add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_MOTION_MASK | Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); - gestureZoom = Gtk::GestureZoom::create(*this); - gestureZoom->signal_begin().connect(sigc::mem_fun(*this, &Inspector::on_zoom_begin)); - gestureZoom->signal_scale_changed().connect(sigc::mem_fun(*this, &Inspector::on_zoom_scale_changed)); + add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_MOTION_MASK | Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); + gestureZoom = Gtk::GestureZoom::create(*this); + gestureZoom->signal_begin().connect(sigc::mem_fun(*this, &Inspector::on_zoom_begin)); + gestureZoom->signal_scale_changed().connect(sigc::mem_fun(*this, &Inspector::on_zoom_scale_changed)); - window.add(*this); - window.set_size_request(400, 400); - window.show_all(); - window.set_visible(false); - active = true; // always track inspected thumbnails + window->add(*this); + window->set_size_request(500, 500); + initialized = false; // delay init to avoid flickering on some systems + active = true; // always track inspected thumbnails + } } Inspector::~Inspector() { deleteBuffers(); + if (window) + delete window; } void Inspector::showWindow(bool scaled, bool fullscreen) { + if (!window) + return; + + // initialize when shown first + if (!initialized) { + window->show_all(); + window->set_visible(false); + initialized = true; + } + + // show inspector window this->scaled = scaled; if (fullscreen) - window.fullscreen(); + window->fullscreen(); else - window.unfullscreen(); + window->unfullscreen(); this->fullscreen = fullscreen; - window.set_visible(true); + window->set_visible(true); pinned = false; // update content when becoming visible @@ -127,12 +145,15 @@ void Inspector::showWindow(bool scaled, bool fullscreen) bool Inspector::on_key_release(GdkEventKey *event) { + if (!window) + return false; + if (!pinned) { switch (event->keyval) { case GDK_KEY_f: case GDK_KEY_F: zoomScale = 1.0; - window.set_visible(false); + window->set_visible(false); return true; } } @@ -141,6 +162,9 @@ bool Inspector::on_key_release(GdkEventKey *event) bool Inspector::on_key_press(GdkEventKey *event) { + if (!window) + return false; + switch (event->keyval) { case GDK_KEY_z: case GDK_KEY_F: @@ -160,15 +184,15 @@ bool Inspector::on_key_press(GdkEventKey *event) case GDK_KEY_F11: // toggle fullscreen if (fullscreen) - window.unfullscreen(); + window->unfullscreen(); else - window.fullscreen(); + window->fullscreen(); fullscreen = !fullscreen; return true; case GDK_KEY_Escape: // hide window zoomScale = 1.0; - window.set_visible(false); + window->set_visible(false); return true; } @@ -177,6 +201,9 @@ bool Inspector::on_key_press(GdkEventKey *event) bool Inspector::on_button_press_event(GdkEventButton *event) { + if (!window) + return false; + if (event->type == GDK_BUTTON_PRESS) { button_pos.set(event->x, event->y); if (!pinned) @@ -189,7 +216,7 @@ bool Inspector::on_button_press_event(GdkEventButton *event) bool Inspector::on_motion_notify_event(GdkEventMotion *event) { - if (!currImage) + if (!currImage || !window) return false; int deviceScale = get_scale_factor(); @@ -211,7 +238,7 @@ bool Inspector::on_motion_notify_event(GdkEventMotion *event) bool Inspector::on_scroll_event(GdkEventScroll *event) { - if (!currImage) + if (!currImage || !window) return false; bool alt = event->state & GDK_MOD1_MASK; @@ -244,23 +271,19 @@ bool Inspector::on_scroll_event(GdkEventScroll *event) break; case GDK_SCROLL_DOWN: delta_y = step_y * deviceScale * imH / 100; - alt = true; // zoom for non smooth scroll events (scroll wheel) break; case GDK_SCROLL_UP: delta_y = -step_y * deviceScale * imH / 100; - alt = true; // zoom for non smooth scroll events (scroll wheel) break; case GDK_SCROLL_LEFT: delta_x = step_x * deviceScale * imW / 100; - alt = true; // zoom for non smooth scroll events (scroll wheel) break; case GDK_SCROLL_RIGHT: delta_x = -step_x * deviceScale * imW / 100; - alt = true; // zoom for non smooth scroll events (scroll wheel) break; } - if (alt) { + if ((options.zoomOnScroll && !alt) || (!options.zoomOnScroll && alt)) { // zoom beginZoom(event->x, event->y); if (std::fabs(delta_y) > std::fabs(delta_x)) @@ -284,15 +307,15 @@ bool Inspector::on_scroll_event(GdkEventScroll *event) void Inspector::moveCenter(int delta_x, int delta_y, int imW, int imH, int deviceScale) { rtengine::Coord margin; // limit to image size - margin.x = rtengine::min(window.get_width() * deviceScale / scale, imW) / 2; - margin.y = rtengine::min(window.get_height() * deviceScale / scale, imH) / 2; + margin.x = rtengine::min(window->get_width() * deviceScale / scale, imW) / 2; + margin.y = rtengine::min(window->get_height() * deviceScale / scale, imH) / 2; center.set(rtengine::LIM(center.x + delta_x, margin.x, imW - margin.x), rtengine::LIM(center.y + delta_y, margin.y, imH - margin.y)); } void Inspector::beginZoom(double x, double y) { - if (!currImage) + if (!currImage || !window) return; int deviceScale = get_scale_factor(); @@ -303,8 +326,8 @@ void Inspector::beginZoom(double x, double y) moveCenter(0, 0, imW, imH, deviceScale); // store center and current position for zooming - dcenterBegin.x = (x - window.get_width()/2) / scale * deviceScale; - dcenterBegin.y = (y - window.get_height()/2) / scale * deviceScale; + dcenterBegin.x = (x - window->get_width()/2) / scale * deviceScale; + dcenterBegin.y = (y - window->get_height()/2) / scale * deviceScale; centerBegin = center; zoomScaleBegin = zoomScale; @@ -319,7 +342,7 @@ void Inspector::on_zoom_begin(GdkEventSequence *s) void Inspector::on_zoom_scale_changed(double zscale) { - if (!currImage) + if (!currImage || !window) return; zoomScale = rtengine::LIM(zoomScaleBegin * zscale, 0.01, 16.0); @@ -358,7 +381,7 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) rtengine::Coord availableSize; rtengine::Coord topLeft; rtengine::Coord dest(0, 0); - int deviceScale = get_scale_factor(); + int deviceScale = window? get_scale_factor(): 1; availableSize.x = win->get_width() * deviceScale; availableSize.y = win->get_height() * deviceScale; int imW = rtengine::max(currImage->imgBuffer.getWidth(), 1); @@ -417,19 +440,22 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) Gdk::RGBA c; Glib::RefPtr style = get_style_context(); - // draw the background - //style->render_background(cr, 0, 0, get_width(), get_height()); - - ///* --- old method (the new method does not seem to work) - c = style->get_background_color (Gtk::STATE_FLAG_NORMAL); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->set_line_width (0); - cr->rectangle (0, 0, availableSize.x, availableSize.y); - cr->fill (); - //*/ + if (!window) { + // draw the background + style->render_background(cr, 0, 0, get_width(), get_height()); + } + else { + ///* --- old method (the new method does not seem to work) + c = style->get_background_color (Gtk::STATE_FLAG_NORMAL); + cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); + cr->set_line_width (0); + cr->rectangle (0, 0, availableSize.x, availableSize.y); + cr->fill (); + //*/ + } bool scaledImage = scale != 1.0; - if (deviceScale == 1 && !scaledImage) { + if (!window || (deviceScale == 1 && !scaledImage)) { // standard drawing currImage->imgBuffer.copySurface(win); } @@ -454,14 +480,14 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) cr->paint(); } - /* --- not for separate window - // draw the frame - c = style->get_border_color (Gtk::STATE_FLAG_NORMAL); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->set_line_width (1); - cr->rectangle (0.5, 0.5, availableSize.x - 1, availableSize.y - 1); - cr->stroke (); - */ + if (!window) { + // draw the frame + c = style->get_border_color (Gtk::STATE_FLAG_NORMAL); + cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); + cr->set_line_width (1); + cr->rectangle (0.5, 0.5, availableSize.x - 1, availableSize.y - 1); + cr->stroke (); + } } return true; @@ -476,7 +502,7 @@ void Inspector::mouseMove (rtengine::Coord2D pos, int transform) next_image_pos = pos; // skip actual update of content when not visible - if (!window.get_visible()) + if (window && !window->get_visible()) return; if (currImage) { @@ -501,7 +527,7 @@ void Inspector::switchImage (const Glib::ustring &fullPath) next_image_path = fullPath; // skip actual update of content when not visible - if (!window.get_visible()) + if (window && !window->get_visible()) return; if (!options.inspectorDelay) { @@ -601,7 +627,8 @@ void Inspector::setActive(bool state) flushBuffers(); } - //active = state; + if (!window) + active = state; } diff --git a/rtgui/inspector.h b/rtgui/inspector.h index bf53ee2a2..726bc947c 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -54,13 +54,14 @@ private: bool active; bool pinned; bool dirty; + bool initialized; bool fullscreen; // window is shown in fullscreen mode sigc::connection delayconn; Glib::ustring next_image_path; rtengine::Coord2D next_image_pos; - Gtk::Window window; + Gtk::Window *window; bool on_key_release(GdkEventKey *event); bool on_key_press(GdkEventKey *event); diff --git a/rtgui/options.cc b/rtgui/options.cc index cc49f1fcd..7beffdc8e 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -452,6 +452,8 @@ void Options::setDefaults() histogramDrawMode = 0; curvebboxpos = 1; complexity = 1; + inspectorWindow = false; + zoomOnScroll = true; prevdemo = PD_Sidecar; rgbDenoiseThreadLimit = 0; @@ -1463,6 +1465,13 @@ void Options::readFromFile(Glib::ustring fname) complexity = keyFile.get_integer("GUI", "Complexity"); } + if (keyFile.has_key("GUI", "InspectorWindow")) { + inspectorWindow = keyFile.get_boolean("GUI", "InspectorWindow"); + } + + if (keyFile.has_key("GUI", "ZoomOnScroll")) { + zoomOnScroll = keyFile.get_boolean("GUI", "ZoomOnScroll"); + } } if (keyFile.has_group("Crop Settings")) { @@ -2242,6 +2251,8 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_integer("GUI", "CurveBBoxPosition", curvebboxpos); keyFile.set_boolean("GUI", "Showtooltip", showtooltip); keyFile.set_integer("GUI", "Complexity", complexity); + keyFile.set_boolean("GUI", "InspectorWindow", inspectorWindow); + keyFile.set_boolean("GUI", "ZoomOnScroll", zoomOnScroll); //Glib::ArrayHandle crvopen = crvOpen; //keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen); diff --git a/rtgui/options.h b/rtgui/options.h index 02d62292c..fcac5c7bb 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -289,6 +289,8 @@ public: bool internalThumbIfUntouched; bool overwriteOutputFile; int complexity; + bool inspectorWindow; // open inspector in spearate window + bool zoomOnScroll; // translate scroll events to zoom std::vector thumbnailZoomRatios; bool overlayedFileNames; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index aba30fbf2..72ad32391 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -950,16 +950,27 @@ Gtk::Widget* Preferences::getGeneralPanel() workflowGrid->attach_next_to(*complexityL, *curveBBoxPosL, Gtk::POS_BOTTOM, 1, 1); workflowGrid->attach_next_to(*complexitylocal, *curveBBoxPosC, Gtk::POS_BOTTOM, 1, 1); + zoomOnScrollCB = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_ZOOMONSCROLL"))); + setExpandAlignProperties(zoomOnScrollCB, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); + workflowGrid->attach_next_to(*zoomOnScrollCB, *complexityL, Gtk::POS_BOTTOM, 1, 1); + + inspectorWindowCB = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_INSPECTORWINDOW"))); + setExpandAlignProperties(inspectorWindowCB, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); + workflowGrid->attach_next_to(*inspectorWindowCB, *complexitylocal, Gtk::POS_BOTTOM, 1, 1); + Gtk::Label* inspectorNextStartL = Gtk::manage(new Gtk::Label(Glib::ustring("(") + M("PREFERENCES_APPLNEXTSTARTUP") + ")")); + setExpandAlignProperties(inspectorNextStartL, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); + workflowGrid->attach_next_to(*inspectorNextStartL, *inspectorWindowCB, Gtk::POS_RIGHT, 1, 1); + ckbHistogramPositionLeft = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_HISTOGRAMPOSITIONLEFT"))); setExpandAlignProperties(ckbHistogramPositionLeft, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); - workflowGrid->attach_next_to(*ckbHistogramPositionLeft, *complexityL, Gtk::POS_BOTTOM, 1, 1); + workflowGrid->attach_next_to(*ckbHistogramPositionLeft, *zoomOnScrollCB, Gtk::POS_BOTTOM, 1, 1); ckbFileBrowserToolbarSingleRow = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_FILEBROWSERTOOLBARSINGLEROW"))); setExpandAlignProperties(ckbFileBrowserToolbarSingleRow, false, false, Gtk::ALIGN_START, Gtk::ALIGN_START); ckbShowFilmStripToolBar = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_SHOWFILMSTRIPTOOLBAR"))); setExpandAlignProperties(ckbShowFilmStripToolBar, false, false, Gtk::ALIGN_START, Gtk::ALIGN_START); workflowGrid->attach_next_to(*ckbFileBrowserToolbarSingleRow, *ckbHistogramPositionLeft, Gtk::POS_BOTTOM, 1, 1); - workflowGrid->attach_next_to(*ckbShowFilmStripToolBar, *complexitylocal, Gtk::POS_BOTTOM, 2, 1); + workflowGrid->attach_next_to(*ckbShowFilmStripToolBar, *inspectorWindowCB, Gtk::POS_BOTTOM, 2, 1); Gtk::Label* hb4label = Gtk::manage(new Gtk::Label(M("PREFERENCES_TP_LABEL"))); setExpandAlignProperties(hb4label, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); @@ -1814,6 +1825,8 @@ void Preferences::storePreferences() moptions.curvebboxpos = curveBBoxPosC->get_active_row_number(); moptions.complexity = complexitylocal->get_active_row_number(); + moptions.inspectorWindow = inspectorWindowCB->get_active(); + moptions.zoomOnScroll = zoomOnScrollCB->get_active(); moptions.histogramPosition = ckbHistogramPositionLeft->get_active() ? 1 : 2; moptions.FileBrowserToolbarSingleRow = ckbFileBrowserToolbarSingleRow->get_active(); moptions.showFilmStripToolBar = ckbShowFilmStripToolBar->get_active(); @@ -2028,6 +2041,8 @@ void Preferences::fillPreferences() curveBBoxPosC->set_active(moptions.curvebboxpos); complexitylocal->set_active(moptions.complexity); + inspectorWindowCB->set_active(moptions.inspectorWindow); + zoomOnScrollCB->set_active(moptions.zoomOnScroll); ckbHistogramPositionLeft->set_active(moptions.histogramPosition == 1); ckbFileBrowserToolbarSingleRow->set_active(moptions.FileBrowserToolbarSingleRow); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 3cf6b2043..60ca00ea2 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -148,6 +148,9 @@ class Preferences final : Gtk::ComboBoxText* complexitylocal; + Gtk::CheckButton* inspectorWindowCB; + Gtk::CheckButton* zoomOnScrollCB; + Gtk::ComboBoxText* themeCBT; Gtk::FontButton* mainFontFB; Gtk::FontButton* colorPickerFontFB; From ca5d6e44ee94442d06cf0bdbdb6e115d90bd0ce1 Mon Sep 17 00:00:00 2001 From: Desmis Date: Wed, 28 Oct 2020 16:38:17 +0100 Subject: [PATCH 07/14] LA Log encoding clamp values --- rtengine/color.cc | 1 + rtengine/iplocallab.cc | 24 ++++++++++++++++++------ rtgui/locallabtools.cc | 1 + rtgui/locallabtools2.cc | 11 ++++++----- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/rtengine/color.cc b/rtengine/color.cc index 23f1ad9f6..de6f6f64b 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -1553,6 +1553,7 @@ void Color::calcGamma (double pwr, double ts, GammaValues &gamma) gamma[4] = g[4]; gamma[5] = g[5]; gamma[6] = 0.; + printf("g0=%f g1=%f g2=%f g3=%f g4=%f g5=%f\n", g[0], g[1], g[2], g[3], g[4], g[5] ); } void Color::gammaf2lut (LUTf &gammacurve, float gamma, float start, float slope, float divisor, float factor) { diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 729a0bb0c..b9f256dc8 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -1570,12 +1570,14 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool // BENCHFUN const float gray = lp.sourcegray / 100.f; const float shadows_range = lp.blackev; + /* if(lp.whiteev < 1.5f) { lp.whiteev = 1.5f; } + */ float dynamic_range = lp.whiteev - lp.blackev; - if (dynamic_range < 1.f) { - dynamic_range = 1.f; + if (dynamic_range < 0.5f) { + dynamic_range = 0.5f; } const float noise = pow_F(2.f, -16.f); const float log2 = xlogf(lp.baselog); @@ -1654,9 +1656,14 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool if (m > noise) { float mm = apply(m); float f = mm / m; + f = min(f, 1000000.f); + r *= f; b *= f; g *= f; + r = CLIP(r); + g = CLIP(g); + b = CLIP(b); } assert(r == r); @@ -1710,13 +1717,18 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool // float t2 = norm(r, g, b); float f2 = apply(t2) / t2; f = intp(blend, f, f2); - assert(std::isfinite(f)); + f = min(f, 1000000.f); + + // assert(std::isfinite(f)); r *= f; g *= f; b *= f; - assert(std::isfinite(r)); - assert(std::isfinite(g)); - assert(std::isfinite(b)); + r = CLIP(r); + g = CLIP(g); + b = CLIP(b); + // assert(std::isfinite(r)); + // assert(std::isfinite(g)); + // assert(std::isfinite(b)); } } } diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index f9dbab2eb..68908b33a 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -3611,6 +3611,7 @@ LocallabShadow::LocallabShadow(): blurSHde->setAdjusterListener(this); gamSH->setAdjusterListener(this); + sloSH->setLogScale(16, 0); sloSH->setAdjusterListener(this); diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index 00f36cd9c..c2535ed0a 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -4655,13 +4655,13 @@ LocallabLog::LocallabLog(): autocompute(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_LOGAUTO")))), logPFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGPFRA")))), blackEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLACK_EV"), -16.0, 0.0, 0.1, -5.0))), - whiteEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_WHITE_EV"), 1.5, 32.0, 0.1, 10.0))), + whiteEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_WHITE_EV"), 0., 32.0, 0.1, 10.0))), fullimage(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_FULLIMAGE")))), Autogray(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_AUTOGRAY")))), sourceGray(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_GRAY"), 1.0, 100.0, 0.1, 10.0))), targetGray(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TARGET_GRAY"), 5.0, 80.0, 0.1, 18.0))), detail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAIL"), 0., 1., 0.01, 0.6))), - baselog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BASELOG"), 1.4, 8., 0.05, 2., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + baselog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BASELOG"), 1.3, 8., 0.05, 2., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), sensilog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), strlog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -2.0, 2.0, 0.05, 0.))), anglog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))) @@ -4669,10 +4669,10 @@ LocallabLog::LocallabLog(): // Parameter Log encoding specific widgets autoconn = autocompute->signal_toggled().connect(sigc::mem_fun(*this, &LocallabLog::autocomputeToggled)); - // blackEv->setLogScale(2, -8); + blackEv->setLogScale(2, -8); blackEv->setAdjusterListener(this); - // whiteEv->setLogScale(16, 0); + whiteEv->setLogScale(16, 0); whiteEv->setAdjusterListener(this); fullimageConn = fullimage->signal_toggled().connect(sigc::mem_fun(*this, &LocallabLog::fullimageChanged)); @@ -4802,9 +4802,10 @@ void LocallabLog::read(const rtengine::procparams::ProcParams* pp, const ParamsE blackEv->setValue(spot.blackEv); whiteEv->setValue(spot.whiteEv); - if(whiteEv->getValue() < 1.5){ +/* if(whiteEv->getValue() < 1.5){ whiteEv->setValue(1.5); } +*/ fullimage->set_active(spot.fullimage); Autogray->set_active(spot.Autogray); sourceGray->setValue(spot.sourceGray); From 6f7f41237e861bc101500f9e5c0a7a88e69896e3 Mon Sep 17 00:00:00 2001 From: Desmis Date: Wed, 28 Oct 2020 16:49:55 +0100 Subject: [PATCH 08/14] Suppress warning in console --- rtengine/color.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtengine/color.cc b/rtengine/color.cc index de6f6f64b..11a94d1dc 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -1553,7 +1553,9 @@ void Color::calcGamma (double pwr, double ts, GammaValues &gamma) gamma[4] = g[4]; gamma[5] = g[5]; gamma[6] = 0.; - printf("g0=%f g1=%f g2=%f g3=%f g4=%f g5=%f\n", g[0], g[1], g[2], g[3], g[4], g[5] ); + // if (rtengine::settings->verbose) { + // printf("g0=%f g1=%f g2=%f g3=%f g4=%f g5=%f\n", g[0], g[1], g[2], g[3], g[4], g[5]); + // } } void Color::gammaf2lut (LUTf &gammacurve, float gamma, float start, float slope, float divisor, float factor) { From 393c9f3461a3726c2d5c6e637ab385149b95ff01 Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 29 Oct 2020 11:57:30 +0100 Subject: [PATCH 09/14] Change GUI labels -Log encoding --- rtdata/languages/default | 7 ++++--- rtengine/iplocallab.cc | 6 +----- rtgui/locallabtools.h | 1 + rtgui/locallabtools2.cc | 12 +++++++++--- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 5cff0da90..2213978b6 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2626,7 +2626,8 @@ TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic rang TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. TP_LOCALLAB_LOGBLACKWHEV_TOOLTIP;Estimated values of Dynamic Range i.e. Black Ev and White Ev TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process : 1) Dynamic Range calculation 2) Manual adjustment -TP_LOCALLAB_LOGFRA;Source Gray Point +TP_LOCALLAB_LOGFRA;Source +TP_LOCALLAB_LOG2FRA;Target TP_LOCALLAB_LOGFRAME_TOOLTIP;Allows you to calculate and adjust the Ev levels and the Source Gray Point for the spot area. The resulting values will be used by all Lab operations and most RGB operations in the pipeline.\n Takes into account exposure compensation in the main-menu Exposure tab. TP_LOCALLAB_LOGLIN;Logarithm mode TP_LOCALLAB_LOGPFRA;Relative Exposure Levels @@ -2849,7 +2850,7 @@ TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Applies a guided filter to the output image to TP_LOCALLAB_SOFTRETI;Reduce ΔE artifacts TP_LOCALLAB_SOFTRETI_TOOLTIP;Take into account deltaE to improve Transmission map TP_LOCALLAB_SOFT_TOOLNAME;Soft Light & Original Retinex - 6 -TP_LOCALLAB_SOURCE_GRAY;Value +TP_LOCALLAB_SOURCE_GRAY;Mean luminance (Yb%) TP_LOCALLAB_SPECCASE;Specific cases TP_LOCALLAB_SPECIAL;Special use of RGB curves TP_LOCALLAB_SPECIAL_TOOLTIP;The checkbox allows you to remove all other actions i.e. “Scope”, masks, sliders etc., (except for transitions) and use just the effect of the RGB tone-curve. @@ -2875,7 +2876,7 @@ TP_LOCALLAB_STYPE;Shape method TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. TP_LOCALLAB_SYM;Symmetrical (mouse) TP_LOCALLAB_SYMSL;Symmetrical (mouse + sliders) -TP_LOCALLAB_TARGET_GRAY;Target gray point +TP_LOCALLAB_TARGET_GRAY;Mean luminance (Yb%) TP_LOCALLAB_THRES;Threshold structure TP_LOCALLAB_THRESDELTAE;ΔE scope threshold TP_LOCALLAB_THRESRETI;Threshold diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index b9f256dc8..8f4c17a39 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -1570,11 +1570,7 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool // BENCHFUN const float gray = lp.sourcegray / 100.f; const float shadows_range = lp.blackev; - /* - if(lp.whiteev < 1.5f) { - lp.whiteev = 1.5f; - } - */ + float dynamic_range = lp.whiteev - lp.blackev; if (dynamic_range < 0.5f) { dynamic_range = 0.5f; diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index 4ae593225..d66f6ab33 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -1197,6 +1197,7 @@ private: Gtk::CheckButton* const fullimage; Gtk::CheckButton* const Autogray; Adjuster* const sourceGray; + Gtk::Frame* const log2Frame; Adjuster* const targetGray; Adjuster* const detail; Adjuster* const baselog; diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index c2535ed0a..918d1897c 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -4659,6 +4659,7 @@ LocallabLog::LocallabLog(): fullimage(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_FULLIMAGE")))), Autogray(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_AUTOGRAY")))), sourceGray(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_GRAY"), 1.0, 100.0, 0.1, 10.0))), + log2Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOG2FRA")))), targetGray(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TARGET_GRAY"), 5.0, 80.0, 0.1, 18.0))), detail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAIL"), 0., 1., 0.01, 0.6))), baselog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BASELOG"), 1.3, 8., 0.05, 2., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), @@ -4707,11 +4708,16 @@ LocallabLog::LocallabLog(): ToolParamBlock* const logFBox = Gtk::manage(new ToolParamBlock()); logFBox->pack_start(*Autogray); logFBox->pack_start(*sourceGray); + logFBox->pack_start(*baselog); logFrame->add(*logFBox); pack_start(*logFrame); - pack_start(*targetGray); - pack_start(*detail); - pack_start(*baselog); + log2Frame->set_label_align(0.025, 0.5); + ToolParamBlock* const logP2Box = Gtk::manage(new ToolParamBlock()); + logP2Box->pack_start(*targetGray); + logP2Box->pack_start(*detail); + log2Frame->add(*logP2Box); + pack_start(*log2Frame); +// pack_start(*baselog); pack_start(*sensilog); Gtk::Frame* const gradlogFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GRADLOGFRA"))); gradlogFrame->set_label_align(0.025, 0.5); From 021db69b80833429ac377b25ad81149b3aede114 Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 29 Oct 2020 12:31:33 +0100 Subject: [PATCH 10/14] Another label change Log encoding --- rtdata/languages/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 2213978b6..bb33ef2ff 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2348,7 +2348,7 @@ TP_LOCALLAB_BALAN;ab-L balance (ΔE) TP_LOCALLAB_BALANEXP;Laplacian balance TP_LOCALLAB_BALANH;C-H balance (ΔE) TP_LOCALLAB_BALAN_TOOLTIP;Changes the ΔE algorithm parameters.\nTakes into account more or less a*b* or L*, or more or less C or H.\nNot for Denoise -TP_LOCALLAB_BASELOG;Logarithm base +TP_LOCALLAB_BASELOG;Shadows range (logarithm base) TP_LOCALLAB_BILATERAL;Bilateral filter TP_LOCALLAB_BLACK_EV;Black Ev TP_LOCALLAB_BLCO;Chrominance only From 95df31b29628f05d555e04ea7bb0d67f1e94dd8c Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 29 Oct 2020 15:08:20 +0100 Subject: [PATCH 11/14] added cat02 adpatation to log encoding --- rtdata/languages/default | 13 +++++++++++++ rtengine/iplocallab.cc | 14 ++++++++++++-- rtengine/procevents.h | 1 + rtengine/procparams.cc | 4 ++++ rtengine/procparams.h | 1 + rtengine/refreshmap.cc | 3 ++- rtgui/locallabtools.h | 1 + rtgui/locallabtools2.cc | 13 +++++++++++++ rtgui/paramsedited.cc | 7 +++++++ rtgui/paramsedited.h | 1 + 10 files changed, 55 insertions(+), 3 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index bb33ef2ff..15303048a 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1096,6 +1096,17 @@ HISTORY_MSG_840;Local - CL Curve HISTORY_MSG_841;Local - LC curve HISTORY_MSG_842;Local - Contrast Threshold HISTORY_MSG_843;Local - Radius +HISTORY_MSG_845;Local - Log encoding +HISTORY_MSG_846;Local - Log encoding auto +HISTORY_MSG_847;Local - Log encoding Source +HISTORY_MSG_849;Local - Log encoding Source auto +HISTORY_MSG_850;Local - Log encoding B_Ev +HISTORY_MSG_851;Local - Log encoding W_Ev +HISTORY_MSG_852;Local - Log encoding Target +HISTORY_MSG_853;Local - Log encodind loc contrast +HISTORY_MSG_854;Local - Log encodind Scope +HISTORY_MSG_855;Local - Log encoding Entire image +HISTORY_MSG_856;Local - Log encoding Shadows range HISTORY_MSG_888;Local - Contrast Wavelet Balance Threshold HISTORY_MSG_889;Local - Contrast Wavelet Graduated Strength HISTORY_MSG_890;Local - Contrast Wavelet Graduated angle @@ -1166,6 +1177,7 @@ HISTORY_MSG_956;Local - CH Curve HISTORY_MSG_957;Local - Denoise mode HISTORY_MSG_958;Local - Show/hide settings HISTORY_MSG_959;Local - Inverse blur +HISTORY_MSG_960;Local - Log encoding - cat02 HISTORY_MSG_BLSHAPE;Blur by level HISTORY_MSG_BLURCWAV;Blur chroma HISTORY_MSG_BLURWAV;Blur luminance @@ -2386,6 +2398,7 @@ TP_LOCALLAB_BUTTON_DEL;Delete TP_LOCALLAB_BUTTON_DUPL;Duplicate TP_LOCALLAB_BUTTON_REN;Rename TP_LOCALLAB_BUTTON_VIS;Show/Hide +TP_LOCALLAB_CATAD;Chromatic adaptation - Cat02 TP_LOCALLAB_CBDL;Contrast by Detail Levels TP_LOCALLAB_CBDLCLARI_TOOLTIP;Enhances local contrast of the midtones. TP_LOCALLAB_CBDL_ADJ_TOOLTIP;Same as wavelets.\nThe first level (0) acts on 2x2 pixel details.\nThe last level (5) acts on 64x64 pixel details. diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 8f4c17a39..53d37ecad 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -2088,14 +2088,21 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) double Xwout, Zwout; double Xwsc, Zwsc; - int tempo; + int tempo = 5000; if (params->locallab.spots.at(sp).warm > 0) { tempo = 5000 - 30 * params->locallab.spots.at(sp).warm; - } else { + } else if (params->locallab.spots.at(sp).warm < 0){ tempo = 5000 - 49 * params->locallab.spots.at(sp).warm; } + if (params->locallab.spots.at(sp).catad > 0) { + tempo = 5000 - 30 * params->locallab.spots.at(sp).catad; + } else if (params->locallab.spots.at(sp).catad < 0){ + tempo = 5000 - 49 * params->locallab.spots.at(sp).catad; + } + + ColorTemp::temp2mulxyz(params->wb.temperature, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB ColorTemp::temp2mulxyz(tempo, "Custom", Xwout, Zwout); ColorTemp::temp2mulxyz(5000, "Custom", Xwsc, Zwsc); @@ -9686,6 +9693,9 @@ void ImProcFunctions::Lab_Local( log_encode(tmpImage.get(), lp, multiThread, bfw, bfh); rgb2lab(*(tmpImage.get()), *bufexpfin, params->icm.workingProfile); tmpImage.reset(); + if (params->locallab.spots.at(sp).catad != 0) { + ImProcFunctions::ciecamloc_02float(sp, bufexpfin.get()); + } //here begin graduated filter //first solution "easy" but we can do other with log_encode...to see the results diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 7c711a3da..b9d815612 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -982,6 +982,7 @@ enum ProcEventCode { EvlocallabquaMethod = 956, Evlocallabhishow = 957, Evlocallabinvbl = 958, + Evlocallabcatad = 959, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 0528f0e49..574123762 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3838,6 +3838,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : autocompute(false), sourceGray(10.), targetGray(18.), + catad(0.), Autogray(true), fullimage(true), blackEv(-5.0), @@ -4415,6 +4416,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && autocompute == other.autocompute && sourceGray == other.sourceGray && targetGray == other.targetGray + && catad == other.catad && Autogray == other.Autogray && fullimage == other.fullimage && blackEv == other.blackEv @@ -5949,6 +5951,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->autocompute, "Locallab", "Autocompute_" + index_str, spot.autocompute, keyFile); saveToKeyfile(!pedited || spot_edited->sourceGray, "Locallab", "SourceGray_" + index_str, spot.sourceGray, keyFile); saveToKeyfile(!pedited || spot_edited->targetGray, "Locallab", "TargetGray_" + index_str, spot.targetGray, keyFile); + saveToKeyfile(!pedited || spot_edited->catad, "Locallab", "Catad_" + index_str, spot.catad, keyFile); saveToKeyfile(!pedited || spot_edited->Autogray, "Locallab", "Autogray_" + index_str, spot.Autogray, keyFile); saveToKeyfile(!pedited || spot_edited->fullimage, "Locallab", "Fullimage_" + index_str, spot.fullimage, keyFile); saveToKeyfile(!pedited || spot_edited->blackEv, "Locallab", "BlackEv_" + index_str, spot.blackEv, keyFile); @@ -7725,6 +7728,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Autocompute_" + index_str, pedited, spot.autocompute, spotEdited.autocompute); assignFromKeyfile(keyFile, "Locallab", "SourceGray_" + index_str, pedited, spot.sourceGray, spotEdited.sourceGray); assignFromKeyfile(keyFile, "Locallab", "TargetGray_" + index_str, pedited, spot.targetGray, spotEdited.targetGray); + assignFromKeyfile(keyFile, "Locallab", "Catad_" + index_str, pedited, spot.catad, spotEdited.catad); assignFromKeyfile(keyFile, "Locallab", "AutoGray_" + index_str, pedited, spot.Autogray, spotEdited.Autogray); assignFromKeyfile(keyFile, "Locallab", "Fullimage_" + index_str, pedited, spot.fullimage, spotEdited.fullimage); assignFromKeyfile(keyFile, "Locallab", "BlackEv_" + index_str, pedited, spot.blackEv, spotEdited.blackEv); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 7cf8bf4a2..53a008a29 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1425,6 +1425,7 @@ struct LocallabParams { bool autocompute; double sourceGray; double targetGray; + double catad; bool Autogray; bool fullimage; double blackEv; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 255d080ac..6daf01621 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -985,7 +985,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvlocallabCHshape LUMINANCECURVE, //EvlocallabquaMethod LUMINANCECURVE, //Evlocallabhishow - LUMINANCECURVE // Evlocallabinvbl + LUMINANCECURVE, // Evlocallabinvbl + LUMINANCECURVE // Evlocallabcatad }; diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index d66f6ab33..ff4062f0f 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -1200,6 +1200,7 @@ private: Gtk::Frame* const log2Frame; Adjuster* const targetGray; Adjuster* const detail; + Adjuster* const catad; Adjuster* const baselog; Adjuster* const sensilog; Adjuster* const strlog; diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index 918d1897c..67917c700 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -4662,6 +4662,7 @@ LocallabLog::LocallabLog(): log2Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOG2FRA")))), targetGray(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TARGET_GRAY"), 5.0, 80.0, 0.1, 18.0))), detail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAIL"), 0., 1., 0.01, 0.6))), + catad(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CATAD"), -100., 100., 0.5, 0.))), baselog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BASELOG"), 1.3, 8., 0.05, 2., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), sensilog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), strlog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -2.0, 2.0, 0.05, 0.))), @@ -4686,6 +4687,8 @@ LocallabLog::LocallabLog(): detail->setAdjusterListener(this); + catad->setAdjusterListener(this); + baselog->setAdjusterListener(this); sensilog->setAdjusterListener(this); @@ -4715,6 +4718,7 @@ LocallabLog::LocallabLog(): ToolParamBlock* const logP2Box = Gtk::manage(new ToolParamBlock()); logP2Box->pack_start(*targetGray); logP2Box->pack_start(*detail); + logP2Box->pack_start(*catad); log2Frame->add(*logP2Box); pack_start(*log2Frame); // pack_start(*baselog); @@ -4849,6 +4853,7 @@ void LocallabLog::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.Autogray = Autogray->get_active(); spot.sourceGray = sourceGray->getValue(); spot.targetGray = targetGray->getValue(); + spot.catad = catad->getValue(); spot.detail = detail->getValue(); spot.baselog = baselog->getValue(); spot.sensilog = sensilog->getIntValue(); @@ -4871,6 +4876,7 @@ void LocallabLog::setDefaults(const rtengine::procparams::ProcParams* defParams, whiteEv->setDefault(defSpot.whiteEv); sourceGray->setDefault(defSpot.sourceGray); targetGray->setDefault(defSpot.targetGray); + catad->setDefault(defSpot.catad); detail->setDefault(defSpot.detail); baselog->setDefault(defSpot.baselog); sensilog->setDefault((double)defSpot.sensilog); @@ -4912,6 +4918,13 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) } } + if (a == catad) { + if (listener) { + listener->panelChanged(Evlocallabcatad, + catad->getTextValue() + " (" + escapeHtmlChars(spotName) + ")"); + } + } + if (a == detail) { if (listener) { listener->panelChanged(Evlocallabdetail, diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 94d706dc7..ae756feeb 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1497,6 +1497,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).autocompute = locallab.spots.at(j).autocompute && pSpot.autocompute == otherSpot.autocompute; locallab.spots.at(j).sourceGray = locallab.spots.at(j).sourceGray && pSpot.sourceGray == otherSpot.sourceGray; locallab.spots.at(j).targetGray = locallab.spots.at(j).targetGray && pSpot.targetGray == otherSpot.targetGray; + locallab.spots.at(j).catad = locallab.spots.at(j).catad && pSpot.catad == otherSpot.catad; locallab.spots.at(j).Autogray = locallab.spots.at(j).Autogray && pSpot.Autogray == otherSpot.Autogray; locallab.spots.at(j).fullimage = locallab.spots.at(j).fullimage && pSpot.fullimage == otherSpot.fullimage; locallab.spots.at(j).blackEv = locallab.spots.at(j).blackEv && pSpot.blackEv == otherSpot.blackEv; @@ -4855,6 +4856,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).targetGray = mods.locallab.spots.at(i).targetGray; } + if (locallab.spots.at(i).catad) { + toEdit.locallab.spots.at(i).catad = mods.locallab.spots.at(i).catad; + } + if (locallab.spots.at(i).Autogray) { toEdit.locallab.spots.at(i).Autogray = mods.locallab.spots.at(i).Autogray; } @@ -6641,6 +6646,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : autocompute(v), sourceGray(v), targetGray(v), + catad(v), Autogray(v), fullimage(v), blackEv(v), @@ -7136,6 +7142,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) autocompute = v; sourceGray = v; targetGray = v; + catad = v; Autogray = v; fullimage = v; blackEv = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 0cacef527..2a50b2cf1 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -833,6 +833,7 @@ public: bool autocompute; bool sourceGray; bool targetGray; + bool catad; bool Autogray; bool fullimage; bool blackEv; From 7d763f7df24cbaafd3ad2b015712bc720fb198d5 Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 29 Oct 2020 17:01:41 +0100 Subject: [PATCH 12/14] LA Add forgoten history messages --- rtdata/languages/default | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/rtdata/languages/default b/rtdata/languages/default index 15303048a..f0c4a64ac 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1107,6 +1107,35 @@ HISTORY_MSG_853;Local - Log encodind loc contrast HISTORY_MSG_854;Local - Log encodind Scope HISTORY_MSG_855;Local - Log encoding Entire image HISTORY_MSG_856;Local - Log encoding Shadows range +HISTORY_MSG_857;Local - Wavelet blur residual +HISTORY_MSG_858;Local - Wavelet blur luminance only +HISTORY_MSG_859;Local - Wavelet max blur +HISTORY_MSG_860;Local - Wavelet blur levels +HISTORY_MSG_861;Local - Wavelet contrast levels +HISTORY_MSG_862;Local - Wavelet contrast attenuation +HISTORY_MSG_863;Local - Wavelet merge original image +HISTORY_MSG_864;Local - Wavelet dir contrast attenuation +HISTORY_MSG_865;Local - Wavelet dir contrast delta +HISTORY_MSG_866;Local - Wavelet dir compression +HISTORY_MSG_869;Local - Denoise by level + +HISTORY_MSG_870;Local - Wavelet mask curve H +HISTORY_MSG_871;Local - Wavelet mask curve C +HISTORY_MSG_872;Local - Wavelet mask curve L +HISTORY_MSG_873;Local - Wavelet mask +HISTORY_MSG_875;Local - Wavelet mask blend +HISTORY_MSG_876;Local - Wavelet mask smooth +HISTORY_MSG_877;Local - Wavelet mask chroma +HISTORY_MSG_878;Local - Wavelet mask contrast curve +HISTORY_MSG_879;Local - Wavelet contrast chroma +HISTORY_MSG_880;Local - Wavelet blur chroma +HISTORY_MSG_881;Local - Wavelet contrast offset +HISTORY_MSG_882;Local - Wavelet blur +HISTORY_MSG_883;Local - Wavelet contrast by level +HISTORY_MSG_884;Local - Wavelet dir contrast +HISTORY_MSG_885;Local - Wavelet tone mapping +HISTORY_MSG_886;Local - Wavelet tone mapping compress +HISTORY_MSG_887;Local - Wavelet tone mapping compress residual HISTORY_MSG_888;Local - Contrast Wavelet Balance Threshold HISTORY_MSG_889;Local - Contrast Wavelet Graduated Strength HISTORY_MSG_890;Local - Contrast Wavelet Graduated angle From 7fd5707061fb940d3586831b7d10d5d0313c4b2b Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 2 Nov 2020 13:54:34 +0100 Subject: [PATCH 13/14] Local adjustments - Log encoding - addition of ciecam processes (#5973) * First LA log encoding ciecam * Some changes hide show and tooltip * Change label - tooltip * Change max slider shadow * Fixed bad behavior cat02 adaptation in some cases * Another fix Cat02 GUI * LA log encode add ciecam saturation * LA log encoding - added contrast J ciecam * LA Log encode various changes GUI labels tooltips * Change 2 tooltips * Clean code --- rtdata/languages/default | 29 +++- rtengine/improccoordinator.cc | 9 +- rtengine/improcfun.h | 4 +- rtengine/iplocallab.cc | 249 ++++++++++++++++++++++++++++++---- rtengine/procevents.h | 6 + rtengine/procparams.cc | 24 ++++ rtengine/procparams.h | 6 + rtengine/refreshmap.cc | 8 +- rtengine/rtengine.h | 2 +- rtgui/locallab.cc | 4 +- rtgui/locallab.h | 2 +- rtgui/locallabtools.h | 18 ++- rtgui/locallabtools2.cc | 230 +++++++++++++++++++++++++++++-- rtgui/paramsedited.cc | 42 ++++++ rtgui/paramsedited.h | 6 + 15 files changed, 584 insertions(+), 55 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index f0c4a64ac..656ade3cb 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1118,7 +1118,6 @@ HISTORY_MSG_864;Local - Wavelet dir contrast attenuation HISTORY_MSG_865;Local - Wavelet dir contrast delta HISTORY_MSG_866;Local - Wavelet dir compression HISTORY_MSG_869;Local - Denoise by level - HISTORY_MSG_870;Local - Wavelet mask curve H HISTORY_MSG_871;Local - Wavelet mask curve C HISTORY_MSG_872;Local - Wavelet mask curve L @@ -1204,9 +1203,15 @@ HISTORY_MSG_954;Local - Show-hide tools HISTORY_MSG_955;Local - Enable Spot HISTORY_MSG_956;Local - CH Curve HISTORY_MSG_957;Local - Denoise mode -HISTORY_MSG_958;Local - Show/hide settings HISTORY_MSG_959;Local - Inverse blur +HISTORY_MSG_958;Local - Show/hide settings HISTORY_MSG_960;Local - Log encoding - cat02 +HISTORY_MSG_961;Local - Log encoding Ciecam +HISTORY_MSG_962;Local - Log encoding Absolute luminance source +HISTORY_MSG_963;Local - Log encoding Absolute luminance target +HISTORY_MSG_964;Local - Log encoding Surround +HISTORY_MSG_965;Local - Log encoding Saturation s +HISTORY_MSG_966;Local - Log encoding Contrast J HISTORY_MSG_BLSHAPE;Blur by level HISTORY_MSG_BLURCWAV;Blur chroma HISTORY_MSG_BLURWAV;Blur luminance @@ -2446,6 +2451,9 @@ TP_LOCALLAB_CHROMASKCOL;Chroma TP_LOCALLAB_CHROMASK_TOOLTIP;Changes the chroma of the mask if one exists (i.e. C(C) or LC(H) is activated). TP_LOCALLAB_CHROMASK_TOOLTIP;You can use this slider to desaturated background (inverse mask - curve near 0).\nAlso to attenuate or enhance the action of a mask on the chroma TP_LOCALLAB_CHRRT;Chroma +TP_LOCALLAB_CIEC;Use Ciecam environment parameters +//TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM02 color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nOnly the third Ciecam process (Viewing conditions - Target) is taken into account, as well as part of the second (contrast J, saturation s) , as well as some data from the first process (Scene conditions - Source) which is used for the Log encoding.\nIt also adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. +TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM02 color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nThe first Ciecam process 'Scene conditions' is carried out by Log encoding, it also uses 'Absolute luminance' at the time of the shooting.\nThe second Ciecam process 'Image adjustments' is simplified and uses only 3 variables (local contrast, contrast J, saturation s).\nThe third Ciecam process 'Viewing conditions' adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. TP_LOCALLAB_CIRCRADIUS;Spot size TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the RT-spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for treating foliage.\nHigh values may be useful for treating skin TP_LOCALLAB_CLARICRES;Merge chroma @@ -2473,6 +2481,7 @@ TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping TP_LOCALLAB_COMPRESS_TOOLTIP;Use if necessary the module 'Clarity & Sharp mask and Blend & Soften Images' by adjusting 'Soft radius' to reduce artifacts. TP_LOCALLAB_CONTCOL;Contrast threshold TP_LOCALLAB_CONTFRA;Contrast by level +TP_LOCALLAB_CONTL;Contrast (J) TP_LOCALLAB_CONTTHMASK_TOOLTIP;Allows you to determine which parts of the image will be impacted based on the texture. TP_LOCALLAB_CONTRAST;Contrast TP_LOCALLAB_CONTRASTCURVMASK1_TOOLTIP;Allows you to freely modify the contrast of the mask (gamma & slope), instead of using a continuous & progressive curve. However it can create artifacts that have to be dealt with using the “Smooth radius” or “Laplacian threshold sliders”. @@ -2667,15 +2676,23 @@ TP_LOCALLAB_LOGAUTO;Automatic TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and Source Gray Point (if "Automatic Source Gray Point” enabled).\nPress the button again to adjust the automatically calculated values. TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. TP_LOCALLAB_LOGBLACKWHEV_TOOLTIP;Estimated values of Dynamic Range i.e. Black Ev and White Ev +TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM02 takes into account the increase in perceived coloration with luminance. +TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. +TP_LOCALLAB_LOGCATAD_TOOLTIP;The chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance is far from reference D50.\nAdapts colors to the illuminant of the output device. TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process : 1) Dynamic Range calculation 2) Manual adjustment -TP_LOCALLAB_LOGFRA;Source -TP_LOCALLAB_LOG2FRA;Target -TP_LOCALLAB_LOGFRAME_TOOLTIP;Allows you to calculate and adjust the Ev levels and the Source Gray Point for the spot area. The resulting values will be used by all Lab operations and most RGB operations in the pipeline.\n Takes into account exposure compensation in the main-menu Exposure tab. +TP_LOCALLAB_LOGFRA;Scene Conditions +TP_LOCALLAB_LOG1FRA;Image Adjustments +TP_LOCALLAB_LOG2FRA;Viewing Conditions +TP_LOCALLAB_LOGFRAME_TOOLTIP;Allows you to calculate and adjust the Ev levels and the Source Gray Point for the spot area. The resulting values will be used by all Lab operations and most RGB operations in the pipeline.\nTakes into account exposure compensation in the main-menu Exposure tab.\nAlso calculates the absolute luminance at the time of the shooting. +TP_LOCALLAB_LOGIMAGE_TOOLTIP;Takes into account corresponding Ciecam variables (mainly Contrast 'J' and Saturation 's'). TP_LOCALLAB_LOGLIN;Logarithm mode TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM02 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium and highlights tones +TP_LOCALLAB_LOGSCENE_TOOLTIP;Corresponds to the shooting conditions. TP_LOCALLAB_LOGSRCGREY_TOOLTIP;Estimated gray point value of the image. TP_LOCALLAB_LOGTARGGREY_TOOLTIP;You can adjust this value to suit. TP_LOCALLAB_LOG_TOOLNAME;Log Encoding - 0 +TP_LOCALLAB_LOGVIEWING_TOOLTIP;Corresponds to the medium on which the final image will be viewed (monitor, TV, projector, printer,..), as well as its environment. TP_LOCALLAB_LUM;Curves LL - CC TP_LOCALLAB_LUMADARKEST;Darkest TP_LOCALLAB_LUMASK;Background color for luminance and color masks @@ -2815,6 +2832,7 @@ TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted TP_LOCALLAB_ROW_NVIS;Not visible TP_LOCALLAB_ROW_VIS;Visible TP_LOCALLAB_SATUR;Saturation +TP_LOCALLAB_SATURV;Saturation (s) TP_LOCALLAB_SAVREST;Save - Restore Current Image TP_LOCALLAB_SCALEGR;Scale TP_LOCALLAB_SCALERETI;Scale @@ -2892,6 +2910,7 @@ TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Applies a guided filter to the output image to TP_LOCALLAB_SOFTRETI;Reduce ΔE artifacts TP_LOCALLAB_SOFTRETI_TOOLTIP;Take into account deltaE to improve Transmission map TP_LOCALLAB_SOFT_TOOLNAME;Soft Light & Original Retinex - 6 +TP_LOCALLAB_SOURCE_ABS;Absolute luminance TP_LOCALLAB_SOURCE_GRAY;Mean luminance (Yb%) TP_LOCALLAB_SPECCASE;Specific cases TP_LOCALLAB_SPECIAL;Special use of RGB curves diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index f9c4b786c..a564676ef 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -745,6 +745,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float *sourceg = nullptr; sourceg = new float[sizespot]; + float *sourceab = nullptr; + sourceab = new float[sizespot]; float *targetg = nullptr; targetg = new float[sizespot]; bool *log = nullptr; @@ -777,6 +779,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) blackev[sp] = params->locallab.spots.at(sp).blackEv; whiteev[sp] = params->locallab.spots.at(sp).whiteEv; sourceg[sp] = params->locallab.spots.at(sp).sourceGray; + sourceab[sp] = params->locallab.spots.at(sp).sourceabs; Autogr[sp] = params->locallab.spots.at(sp).Autogray; targetg[sp] = params->locallab.spots.at(sp).targetGray; locx[sp] = params->locallab.spots.at(sp).loc.at(0) / 2000.0; @@ -806,14 +809,15 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) xend = 1.f; } - ipf.getAutoLogloc(sp, imgsrc, sourceg, blackev, whiteev, Autogr, fw, fh, xsta, xend, ysta, yend, SCALE); + ipf.getAutoLogloc(sp, imgsrc, sourceg, blackev, whiteev, Autogr, sourceab, fw, fh, xsta, xend, ysta, yend, SCALE); params->locallab.spots.at(sp).blackEv = blackev[sp]; params->locallab.spots.at(sp).whiteEv = whiteev[sp]; params->locallab.spots.at(sp).sourceGray = sourceg[sp]; + params->locallab.spots.at(sp).sourceabs = sourceab[sp]; if (locallListener) { - locallListener->logencodChanged(blackev[sp], whiteev[sp], sourceg[sp], targetg[sp]); + locallListener->logencodChanged(blackev[sp], whiteev[sp], sourceg[sp], sourceab[sp], targetg[sp]); } } } @@ -829,6 +833,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) delete [] whiteev; delete [] blackev; delete [] targetg; + delete [] sourceab; delete [] sourceg; delete [] log; delete [] autocomput; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index a237e7c82..3f0d2c0e4 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -175,7 +175,7 @@ public: void moyeqt(Imagefloat* working, float &moyS, float &eqty); void luminanceCurve(LabImage* lold, LabImage* lnew, const LUTf &curve); - void ciecamloc_02float(int sp, LabImage* lab); + void ciecamloc_02float(int sp, LabImage* lab, int call); void ciecam_02float(CieImage* ncie, float adap, int pW, int pwb, LabImage* lab, const procparams::ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, @@ -264,7 +264,7 @@ public: //3 functions from Alberto Griggio, adapted J.Desmis 2019 void filmGrain(Imagefloat *rgb, int isogr, int strengr, int scalegr, int bfw, int bfh); void log_encode(Imagefloat *rgb, struct local_params & lp, bool multiThread, int bfw, int bfh); - void getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, int fw, int fh, float xsta, float xend, float ysta, float yend, int SCALE); + void getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, float *sourceab, int fw, int fh, float xsta, float xend, float ysta, float yend, int SCALE); void MSRLocal(int call, int sp, bool fftw, int lum, float** reducDE, LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, float** luminance, const float* const *originalLuminance, const int width, const int height, int bfwr, int bfhr, const procparams::LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const LocretitransCurve &locRETtransCcurve, diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 53d37ecad..a6e46b53a 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -36,7 +36,6 @@ #include "rt_algo.h" #include "settings.h" #include "../rtgui/options.h" - #include "utils.h" #ifdef _OPENMP #include @@ -1576,7 +1575,8 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool dynamic_range = 0.5f; } const float noise = pow_F(2.f, -16.f); - const float log2 = xlogf(lp.baselog); + // const float log2 = xlogf(lp.baselog); + const float log2 = xlogf(2.f); const float base = lp.targetgray > 1 && lp.targetgray < 100 && dynamic_range > 0 ? find_gray(std::abs(lp.blackev) / dynamic_range, lp.targetgray / 100.f) : 0.f; const float linbase = rtengine::max(base, 0.f); TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); @@ -1731,7 +1731,7 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool } } -void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, int fw, int fh, float xsta, float xend, float ysta, float yend, int SCALE) +void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, float *sourceab, int fw, int fh, float xsta, float xend, float ysta, float yend, int SCALE) { //BENCHFUN //adpatation to local adjustments Jacques Desmis 12 2019 @@ -1837,10 +1837,41 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, } } } - const float gray = sourceg[sp] / 100.f; whiteev[sp] = xlogf(maxVal / gray) / log2; blackev[sp] = whiteev[sp] - dynamic_range; + + + //calculate La - Absolute luminance shooting + + const FramesMetaData* metaData = imgsrc->getMetaData(); + int imgNum = 0; + + if (imgsrc->isRAW()) { + if (imgsrc->getSensorType() == ST_BAYER) { + imgNum = rtengine::LIM(params->raw.bayersensor.imageNum, 0, metaData->getFrameCount() - 1); + } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) { + //imgNum = rtengine::LIM(params->raw.xtranssensor.imageNum, 0, metaData->getFrameCount() - 1); + } + } + + float fnum = metaData->getFNumber(imgNum); // F number + float fiso = metaData->getISOSpeed(imgNum) ; // ISO + float fspeed = metaData->getShutterSpeed(imgNum) ; // Speed + double fcomp = metaData->getExpComp(imgNum); // Compensation +/- + double adap; + + if (fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { //if no exif data or wrong + adap = 2000.; + } else { + double E_V = fcomp + std::log2(double ((fnum * fnum) / fspeed / (fiso / 100.f))); + E_V += params->toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV + E_V += std::log2(params->raw.expos); // exposure raw white point ; log2 ==> linear to EV + adap = pow(2.0, E_V - 3.0); // cd / m2 + // end calculation adaptation scene luminosity + } + + sourceab[sp] = adap; } } @@ -2072,11 +2103,13 @@ void tone_eq(array2D &R, array2D &G, array2D &B, const str } -void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) +void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab, int call) { - //be careful quasi duplicate with branch cat02wb //BENCHFUN - + bool ciec = false; + if (params->locallab.spots.at(sp).ciecam && params->locallab.spots.at(sp).explog && call == 1) { + ciec = true; + } int width = lab->W, height = lab->H; float Yw; Yw = 1.0f; @@ -2088,18 +2121,119 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) double Xwout, Zwout; double Xwsc, Zwsc; - int tempo = 5000; + LUTu hist16J; + //for J light and contrast + LUTf CAMBrightCurveJ; + CAMBrightCurveJ(32768, LUT_CLIP_ABOVE); + CAMBrightCurveJ.dirty = true; - if (params->locallab.spots.at(sp).warm > 0) { - tempo = 5000 - 30 * params->locallab.spots.at(sp).warm; - } else if (params->locallab.spots.at(sp).warm < 0){ - tempo = 5000 - 49 * params->locallab.spots.at(sp).warm; + if (CAMBrightCurveJ.dirty) { + hist16J(32768); + hist16J.clear(); + + double sum = 0.0; // use double precision for large summations + +#ifdef _OPENMP + const int numThreads = min(max(width * height / 65536, 1), omp_get_max_threads()); + #pragma omp parallel num_threads(numThreads) if(numThreads>1) +#endif + { + LUTu hist16Jthr; + hist16Jthr(hist16J.getSize()); + hist16Jthr.clear(); + +#ifdef _OPENMP + #pragma omp for reduction(+:sum) +#endif + + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { //rough correspondence between L and J + float currL = lab->L[i][j] / 327.68f; + float koef; //rough correspondence between L and J + + if (currL > 50.f) { + if (currL > 70.f) { + if (currL > 80.f) { + if (currL > 85.f) { + koef = 0.97f; + } else { + koef = 0.93f; + } + } else { + koef = 0.87f; + } + } else { + if (currL > 60.f) { + koef = 0.85f; + } else { + koef = 0.8f; + } + } + } else { + if (currL > 10.f) { + if (currL > 20.f) { + if (currL > 40.f) { + koef = 0.75f; + } else { + koef = 0.7f; + } + } else { + koef = 0.9f; + } + } else { + koef = 1.0; + } + } + + hist16Jthr[(int)((koef * lab->L[i][j]))]++; //evaluate histogram luminance L # J + sum += static_cast(koef) * static_cast(lab->L[i][j]); //evaluate mean J to calculate Yb + //sum not used, but perhaps... + } + } + +#ifdef _OPENMP + #pragma omp critical +#endif + { + hist16J += hist16Jthr; + } + } +#ifdef _OPENMP + static_cast(numThreads); // to silence cppcheck warning +#endif + + //evaluate lightness, contrast + } + + + + + + float contL = 0.f; + if (ciec) { + contL = 0.6f *params->locallab.spots.at(sp).contl;//0.6 less effect, no need 1. + + if (CAMBrightCurveJ.dirty) { + Ciecam02::curveJfloat(0.f, contL, hist16J, CAMBrightCurveJ); //contrast J + CAMBrightCurveJ /= 327.68f; + CAMBrightCurveJ.dirty = false; + } + } + int tempo = 5000; + if(params->locallab.spots.at(sp).expvibrance && call == 2) { + if (params->locallab.spots.at(sp).warm > 0) { + tempo = 5000 - 30 * params->locallab.spots.at(sp).warm; + } else if (params->locallab.spots.at(sp).warm < 0){ + tempo = 5000 - 70 * params->locallab.spots.at(sp).warm; + } } - if (params->locallab.spots.at(sp).catad > 0) { - tempo = 5000 - 30 * params->locallab.spots.at(sp).catad; - } else if (params->locallab.spots.at(sp).catad < 0){ - tempo = 5000 - 49 * params->locallab.spots.at(sp).catad; + if(ciec) { + if (params->locallab.spots.at(sp).catad > 0) { + tempo = 5000 - 30 * params->locallab.spots.at(sp).catad; + } else if (params->locallab.spots.at(sp).catad < 0){ + tempo = 5000 - 70 * params->locallab.spots.at(sp).catad; + } } @@ -2113,8 +2247,25 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) nc = 1.00f; //viewing condition for surround f2 = 1.0f, c2 = 0.69f, nc2 = 1.0f; - //with which algorithm - // alg = 0; + if(ciec) { + //viewing condition for surround + if (params->locallab.spots.at(sp).surround == "Average") { + f2 = 1.0f, c2 = 0.69f, nc2 = 1.0f; + } else if (params->locallab.spots.at(sp).surround == "Dim") { + f2 = 0.9f; + c2 = 0.59f; + nc2 = 0.9f; + } else if (params->locallab.spots.at(sp).surround == "Dark") { + f2 = 0.8f; + c2 = 0.525f; + nc2 = 0.8f; + } else if (params->locallab.spots.at(sp).surround == "ExtremelyDark") { + f2 = 0.8f; + c2 = 0.41f; + nc2 = 0.8f; + } + } + xwd = 100.0 * Xwout; @@ -2126,18 +2277,42 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) yws = 100.f; - yb2 = 18; //La and la2 = ambiant luminosity scene and viewing la = 400.f; - const float la2 = 400.f; + float la2 = 400.f; + if(ciec) { + la = params->locallab.spots.at(sp).sourceabs; + + la2 = params->locallab.spots.at(sp).targabs; + } + const float pilot = 2.f; const float pilotout = 2.f; //algoritm's params - // const float rstprotection = 100. ;//- params->colorappearance.rstprotection; - LUTu hist16J; LUTu hist16Q; float yb = 18.f; + yb2 = 18; + if(ciec) { + yb = params->locallab.spots.at(sp).targetGray;//target because we are after Log encoding + + yb2 = params->locallab.spots.at(sp).targetGray; + } + + float schr = 0.f; + + if (ciec) { + schr = params->locallab.spots.at(sp).saturl; + + if (schr > 0.f) { + schr = schr / 2.f; //divide sensibility for saturation + } + + if (schr == -100.f) { + schr = -99.8f; + } + } + float d, dj; // const int gamu = 0; //(params->colorappearance.gamut) ? 1 : 0; @@ -2145,7 +2320,11 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) yw = 100.f * Yw; zw = 100.0 * Zw; float xw1 = xws, yw1 = yws, zw1 = zws, xw2 = xwd, yw2 = ywd, zw2 = zwd; - +/* + xw1 = 96.46f; //use RT WB; CAT 02 is used for output device (see prefreneces) + yw1 = 100.0f; + zw1 = 82.445f; +*/ float cz, wh, pfl; Ciecam02::initcam1float(yb, pilot, f, la, xw, yw, zw, n, d, nbb, ncb, cz, aw, wh, pfl, fl, c); // const float chr = 0.f; @@ -2156,6 +2335,8 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) const float reccmcz = 1.f / (c2 * czj); #endif const float pow1n = pow_F(1.64f - pow_F(0.29f, nj), 0.73f); + const float coe = pow_F(fl, 0.25f); + const float QproFactor = (0.4f / c) * (aw + 4.0f) ; #ifdef __SSE2__ int bufferLength = ((width + 3) / 4) * 4; // bufferLength has to be a multiple of 4 @@ -2267,7 +2448,21 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) spro = s; /* */ - + if(ciec) { + Jpro = CAMBrightCurveJ[Jpro * 327.68f]; //CIECAM02 + contrast + float sres; + float rstprotection = 50.f;//arbitrary 50% protection skin tones + float Sp = spro / 100.0f; + float parsat = 1.5f; //parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation) + Ciecam02::curvecolorfloat(schr, Sp, sres, parsat); + float dred = 100.f; // in C mode + float protect_red = 80.0f; // in C mode + dred = 100.0f * sqrtf((dred * coe) / Qpro); + protect_red = 100.0f * sqrtf((protect_red * coe) / Qpro); + Color::skinredfloat(Jpro, hpro, sres, Sp, dred, protect_red, 0, rstprotection, 100.f, spro); + Qpro = QproFactor * sqrtf(Jpro); + Cpro = (spro * spro * Qpro) / (10000.0f); + } //retrieve values C,J...s C = Cpro; @@ -9693,8 +9888,8 @@ void ImProcFunctions::Lab_Local( log_encode(tmpImage.get(), lp, multiThread, bfw, bfh); rgb2lab(*(tmpImage.get()), *bufexpfin, params->icm.workingProfile); tmpImage.reset(); - if (params->locallab.spots.at(sp).catad != 0) { - ImProcFunctions::ciecamloc_02float(sp, bufexpfin.get()); + if (params->locallab.spots.at(sp).ciecam) { + ImProcFunctions::ciecamloc_02float(sp, bufexpfin.get(), 1); } //here begin graduated filter @@ -10819,7 +11014,7 @@ void ImProcFunctions::Lab_Local( ImProcFunctions::vibrance(bufexpfin.get(), vibranceParams, params->toneCurve.hrenabled, params->icm.workingProfile); if (params->locallab.spots.at(sp).warm != 0) { - ImProcFunctions::ciecamloc_02float(sp, bufexpfin.get()); + ImProcFunctions::ciecamloc_02float(sp, bufexpfin.get(), 2); } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index b9d815612..22b967ee7 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -983,6 +983,12 @@ enum ProcEventCode { Evlocallabhishow = 957, Evlocallabinvbl = 958, Evlocallabcatad = 959, + Evlocallabciecam = 960, + Evlocallabsourceabs = 961, + Evlocallabtargabs = 962, + Evlocallabsurround = 963, + Evlocallabsaturl = 964, + Evlocallabcontl = 965, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 574123762..7a56248bf 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3837,14 +3837,20 @@ LocallabParams::LocallabSpot::LocallabSpot() : explog(false), autocompute(false), sourceGray(10.), + sourceabs(2000.), + targabs(16.), targetGray(18.), catad(0.), + saturl(0.), + contl(0.), Autogray(true), fullimage(true), + ciecam(false), blackEv(-5.0), whiteEv(10.0), detail(0.6), sensilog(60), + surround("Average"), baselog(2.), strlog(0.0), anglog(0.0), @@ -4415,15 +4421,21 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && explog == other.explog && autocompute == other.autocompute && sourceGray == other.sourceGray + && sourceabs == other.sourceabs + && targabs == other.targabs && targetGray == other.targetGray && catad == other.catad + && saturl == other.saturl + && contl == other.contl && Autogray == other.Autogray && fullimage == other.fullimage + && ciecam == other.ciecam && blackEv == other.blackEv && whiteEv == other.whiteEv && detail == other.detail && sensilog == other.sensilog && baselog == other.baselog + && surround == other.surround && strlog == other.strlog && anglog == other.anglog // mask @@ -5950,15 +5962,21 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->explog, "Locallab", "Explog_" + index_str, spot.explog, keyFile); saveToKeyfile(!pedited || spot_edited->autocompute, "Locallab", "Autocompute_" + index_str, spot.autocompute, keyFile); saveToKeyfile(!pedited || spot_edited->sourceGray, "Locallab", "SourceGray_" + index_str, spot.sourceGray, keyFile); + saveToKeyfile(!pedited || spot_edited->sourceabs, "Locallab", "Sourceabs_" + index_str, spot.sourceabs, keyFile); + saveToKeyfile(!pedited || spot_edited->targabs, "Locallab", "Targabs_" + index_str, spot.targabs, keyFile); saveToKeyfile(!pedited || spot_edited->targetGray, "Locallab", "TargetGray_" + index_str, spot.targetGray, keyFile); saveToKeyfile(!pedited || spot_edited->catad, "Locallab", "Catad_" + index_str, spot.catad, keyFile); + saveToKeyfile(!pedited || spot_edited->saturl, "Locallab", "Saturl_" + index_str, spot.saturl, keyFile); + saveToKeyfile(!pedited || spot_edited->contl, "Locallab", "Contl_" + index_str, spot.contl, keyFile); saveToKeyfile(!pedited || spot_edited->Autogray, "Locallab", "Autogray_" + index_str, spot.Autogray, keyFile); saveToKeyfile(!pedited || spot_edited->fullimage, "Locallab", "Fullimage_" + index_str, spot.fullimage, keyFile); + saveToKeyfile(!pedited || spot_edited->ciecam, "Locallab", "Ciecam_" + index_str, spot.ciecam, keyFile); saveToKeyfile(!pedited || spot_edited->blackEv, "Locallab", "BlackEv_" + index_str, spot.blackEv, keyFile); saveToKeyfile(!pedited || spot_edited->whiteEv, "Locallab", "WhiteEv_" + index_str, spot.whiteEv, keyFile); saveToKeyfile(!pedited || spot_edited->detail, "Locallab", "Detail_" + index_str, spot.detail, keyFile); saveToKeyfile(!pedited || spot_edited->sensilog, "Locallab", "Sensilog_" + index_str, spot.sensilog, keyFile); saveToKeyfile(!pedited || spot_edited->baselog, "Locallab", "Baselog_" + index_str, spot.baselog, keyFile); + saveToKeyfile(!pedited || spot_edited->surround, "Locallab", "Surround_" + index_str, spot.surround, keyFile); saveToKeyfile(!pedited || spot_edited->strlog, "Locallab", "Strlog_" + index_str, spot.strlog, keyFile); saveToKeyfile(!pedited || spot_edited->anglog, "Locallab", "Anglog_" + index_str, spot.anglog, keyFile); } @@ -7727,15 +7745,21 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Autocompute_" + index_str, pedited, spot.autocompute, spotEdited.autocompute); assignFromKeyfile(keyFile, "Locallab", "SourceGray_" + index_str, pedited, spot.sourceGray, spotEdited.sourceGray); + assignFromKeyfile(keyFile, "Locallab", "Sourceabs_" + index_str, pedited, spot.sourceabs, spotEdited.sourceabs); + assignFromKeyfile(keyFile, "Locallab", "Targabs_" + index_str, pedited, spot.targabs, spotEdited.targabs); assignFromKeyfile(keyFile, "Locallab", "TargetGray_" + index_str, pedited, spot.targetGray, spotEdited.targetGray); assignFromKeyfile(keyFile, "Locallab", "Catad_" + index_str, pedited, spot.catad, spotEdited.catad); + assignFromKeyfile(keyFile, "Locallab", "Saturl_" + index_str, pedited, spot.saturl, spotEdited.saturl); + assignFromKeyfile(keyFile, "Locallab", "Contl_" + index_str, pedited, spot.contl, spotEdited.contl); assignFromKeyfile(keyFile, "Locallab", "AutoGray_" + index_str, pedited, spot.Autogray, spotEdited.Autogray); assignFromKeyfile(keyFile, "Locallab", "Fullimage_" + index_str, pedited, spot.fullimage, spotEdited.fullimage); + assignFromKeyfile(keyFile, "Locallab", "Ciecam_" + index_str, pedited, spot.ciecam, spotEdited.ciecam); assignFromKeyfile(keyFile, "Locallab", "BlackEv_" + index_str, pedited, spot.blackEv, spotEdited.blackEv); assignFromKeyfile(keyFile, "Locallab", "WhiteEv_" + index_str, pedited, spot.whiteEv, spotEdited.whiteEv); assignFromKeyfile(keyFile, "Locallab", "Detail_" + index_str, pedited, spot.detail, spotEdited.detail); assignFromKeyfile(keyFile, "Locallab", "Sensilog_" + index_str, pedited, spot.sensilog, spotEdited.sensilog); assignFromKeyfile(keyFile, "Locallab", "Baselog_" + index_str, pedited, spot.baselog, spotEdited.baselog); + assignFromKeyfile(keyFile, "Locallab", "Surround_" + index_str, pedited, spot.surround, spotEdited.surround); assignFromKeyfile(keyFile, "Locallab", "Strlog_" + index_str, pedited, spot.strlog, spotEdited.strlog); assignFromKeyfile(keyFile, "Locallab", "Anglog_" + index_str, pedited, spot.anglog, spotEdited.anglog); // mask diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 53a008a29..1ba0f5e80 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1424,14 +1424,20 @@ struct LocallabParams { bool explog; bool autocompute; double sourceGray; + double sourceabs; + double targabs; double targetGray; double catad; + double saturl; + double contl; bool Autogray; bool fullimage; + bool ciecam; double blackEv; double whiteEv; double detail; int sensilog; + Glib::ustring surround; double baselog; double strlog; double anglog; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 6daf01621..593e5b9c9 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -986,7 +986,13 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //EvlocallabquaMethod LUMINANCECURVE, //Evlocallabhishow LUMINANCECURVE, // Evlocallabinvbl - LUMINANCECURVE // Evlocallabcatad + LUMINANCECURVE, // Evlocallabcatad + LUMINANCECURVE, // Evlocallabciecam + LUMINANCECURVE, // Evlocallabsourceabs + LUMINANCECURVE, // Evlocallabtargabs + LUMINANCECURVE, // Evlocallabsurround + LUMINANCECURVE, // Evlocallabsaturl + LUMINANCECURVE // Evlocallabcontl }; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 6f6baccd4..74214737e 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -439,7 +439,7 @@ public: virtual ~LocallabListener() = default; virtual void refChanged(const std::vector &ref, int selspot) = 0; virtual void minmaxChanged(const std::vector &minmax, int selspot) = 0; - virtual void logencodChanged(const float blackev, const float whiteev, const float sourceg, const float targetg) = 0; + virtual void logencodChanged(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg) = 0; }; class AutoColorTonListener diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 1710a060f..5ca46bc99 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -1017,10 +1017,10 @@ void Locallab::minmaxChanged(const std::vector &minmax, int } } -void Locallab::logencodChanged(const float blackev, const float whiteev, const float sourceg, const float targetg) +void Locallab::logencodChanged(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg) { // Update Locallab Log Encoding accordingly - explog->updateAutocompute(blackev, whiteev, sourceg, targetg); + explog->updateAutocompute(blackev, whiteev, sourceg, sourceab, targetg); } void Locallab::refChanged(const std::vector &ref, int selspot) diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 44e408d49..a6491ebd6 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -141,7 +141,7 @@ public: void minmaxChanged(const std::vector &minmax, int selspot) override; // Locallab Log Encoding autocompute function - void logencodChanged(const float blackev, const float whiteev, const float sourceg, const float targetg) override; + void logencodChanged(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg) override; // Locallab tools mask background management function void refChanged(const std::vector &ref, int selspot) override; diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index ff4062f0f..ff8d6e6f6 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -1190,27 +1190,39 @@ class LocallabLog: public LocallabTool { private: + Gtk::CheckButton* const ciecam; Gtk::ToggleButton* const autocompute; Gtk::Frame* const logPFrame; Adjuster* const blackEv; Adjuster* const whiteEv; Gtk::CheckButton* const fullimage; + Gtk::Frame* const logFrame; Gtk::CheckButton* const Autogray; Adjuster* const sourceGray; + Adjuster* const sourceabs; + Gtk::Frame* const log1Frame; Gtk::Frame* const log2Frame; Adjuster* const targetGray; Adjuster* const detail; Adjuster* const catad; + Adjuster* const contl; + Adjuster* const saturl; + Adjuster* const targabs; + MyComboBoxText* const surround; + Gtk::HBox* const surrHBox; + Adjuster* const baselog; Adjuster* const sensilog; Adjuster* const strlog; Adjuster* const anglog; - sigc::connection autoconn, fullimageConn, AutograyConn; + sigc::connection autoconn, ciecamconn, fullimageConn, AutograyConn; + sigc::connection surroundconn; public: LocallabLog(); void updateAdviceTooltips(const bool showTooltips) override; + void surroundChanged(); void disableListener() override; void enableListener() override; @@ -1219,7 +1231,7 @@ public: void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void adjusterChanged(Adjuster* a, double newval) override; - void updateAutocompute(const float blackev, const float whiteev, const float sourceg, const float targetg); + void updateAutocompute(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg); private: void enabledChanged() override; @@ -1227,8 +1239,10 @@ private: void autocomputeToggled(); void fullimageChanged(); void AutograyChanged(); + void ciecamChanged(); void updateLogGUI(); + void updateLogGUI2(); }; diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index 67917c700..a87e35786 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -4652,18 +4652,28 @@ LocallabLog::LocallabLog(): LocallabTool(this, M("TP_LOCALLAB_LOG_TOOLNAME"), M("TP_LOCALLAB_LOG"), false, false), // Log encoding specific widgets + ciecam(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_CIEC")))), autocompute(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_LOGAUTO")))), logPFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGPFRA")))), blackEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLACK_EV"), -16.0, 0.0, 0.1, -5.0))), whiteEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_WHITE_EV"), 0., 32.0, 0.1, 10.0))), fullimage(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_FULLIMAGE")))), + logFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGFRA")))), Autogray(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_AUTOGRAY")))), sourceGray(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_GRAY"), 1.0, 100.0, 0.1, 10.0))), + sourceabs(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_ABS"), 0.01, 16384.0, 0.01, 2000.0))), + log1Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOG1FRA")))), log2Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOG2FRA")))), targetGray(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TARGET_GRAY"), 5.0, 80.0, 0.1, 18.0))), detail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAIL"), 0., 1., 0.01, 0.6))), - catad(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CATAD"), -100., 100., 0.5, 0.))), - baselog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BASELOG"), 1.3, 8., 0.05, 2., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + catad(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CATAD"), -100., 100., 0.5, 0., Gtk::manage(new RTImage("circle-blue-small.png")), Gtk::manage(new RTImage("circle-orange-small.png"))))), + contl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CONTL"), -100., 100., 0.5, 0.))), + saturl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SATURV"), -100., 100., 0.5, 0.))), + targabs(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_ABS"), 0.01, 16384.0, 0.01, 16.0))), + surround(Gtk::manage (new MyComboBoxText ())), + surrHBox(Gtk::manage(new Gtk::HBox())), + + baselog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BASELOG"), 1.3, 3., 0.05, 2., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), sensilog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), strlog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -2.0, 2.0, 0.05, 0.))), anglog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))) @@ -4676,6 +4686,7 @@ LocallabLog::LocallabLog(): whiteEv->setLogScale(16, 0); whiteEv->setAdjusterListener(this); + ciecamconn = ciecam->signal_toggled().connect(sigc::mem_fun(*this, &LocallabLog::ciecamChanged)); fullimageConn = fullimage->signal_toggled().connect(sigc::mem_fun(*this, &LocallabLog::fullimageChanged)); @@ -4683,12 +4694,24 @@ LocallabLog::LocallabLog(): sourceGray->setAdjusterListener(this); + sourceabs->setLogScale(500, 0); + + sourceabs->setAdjusterListener(this); + targetGray->setAdjusterListener(this); detail->setAdjusterListener(this); catad->setAdjusterListener(this); + saturl->setAdjusterListener(this); + + contl->setAdjusterListener(this); + + targabs->setLogScale(500, 0); + + targabs->setAdjusterListener(this); + baselog->setAdjusterListener(this); sensilog->setAdjusterListener(this); @@ -4697,7 +4720,21 @@ LocallabLog::LocallabLog(): anglog->setAdjusterListener(this); +// Gtk::HBox* surrHBox = Gtk::manage (new Gtk::HBox ()); + surrHBox->set_spacing (2); + surrHBox->set_tooltip_markup (M ("TP_COLORAPP_SURROUND_TOOLTIP")); + Gtk::Label* surrLabel = Gtk::manage (new Gtk::Label (M ("TP_COLORAPP_SURROUND") + ":")); + surrHBox->pack_start (*surrLabel, Gtk::PACK_SHRINK); + surround->append (M ("TP_COLORAPP_SURROUND_AVER")); + surround->append (M ("TP_COLORAPP_SURROUND_DIM")); + surround->append (M ("TP_COLORAPP_SURROUND_DARK")); + surround->append (M ("TP_COLORAPP_SURROUND_EXDARK")); + surround->set_active (0); + surrHBox->pack_start (*surround); + surroundconn = surround->signal_changed().connect ( sigc::mem_fun (*this, &LocallabLog::surroundChanged) ); + // Add Log encoding specific widgets to GUI + pack_start(*ciecam); logPFrame->set_label_align(0.025, 0.5); ToolParamBlock* const logPBox = Gtk::manage(new ToolParamBlock()); logPBox->pack_start(*autocompute); @@ -4706,19 +4743,28 @@ LocallabLog::LocallabLog(): logPBox->pack_start(*fullimage); logPFrame->add(*logPBox); pack_start(*logPFrame); - Gtk::Frame* const logFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGFRA"))); +// Gtk::Frame* const logFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGFRA"))); logFrame->set_label_align(0.025, 0.5); ToolParamBlock* const logFBox = Gtk::manage(new ToolParamBlock()); logFBox->pack_start(*Autogray); logFBox->pack_start(*sourceGray); - logFBox->pack_start(*baselog); + logFBox->pack_start(*sourceabs); +// logFBox->pack_start(*baselog); logFrame->add(*logFBox); pack_start(*logFrame); - log2Frame->set_label_align(0.025, 0.5); + log1Frame->set_label_align(0.025, 0.5); + ToolParamBlock* const logP1Box = Gtk::manage(new ToolParamBlock()); + logP1Box->pack_start(*detail); + logP1Box->pack_start(*contl); + logP1Box->pack_start(*saturl); + log1Frame->add(*logP1Box); + pack_start(*log1Frame); + log2Frame->set_label_align(0.025, 0.5); ToolParamBlock* const logP2Box = Gtk::manage(new ToolParamBlock()); logP2Box->pack_start(*targetGray); - logP2Box->pack_start(*detail); + logP2Box->pack_start(*targabs); logP2Box->pack_start(*catad); + logP2Box->pack_start (*surrHBox); log2Frame->add(*logP2Box); pack_start(*log2Frame); // pack_start(*baselog); @@ -4737,31 +4783,44 @@ void LocallabLog::updateAdviceTooltips(const bool showTooltips) if (showTooltips) { exp->set_tooltip_text(M("TP_LOCALLAB_LOGENCOD_TOOLTIP")); logPFrame->set_tooltip_text(M("TP_LOCALLAB_LOGFRAME_TOOLTIP")); + logFrame->set_tooltip_text(M("TP_LOCALLAB_LOGSCENE_TOOLTIP")); + log1Frame->set_tooltip_text(M("TP_LOCALLAB_LOGIMAGE_TOOLTIP")); + log2Frame->set_tooltip_text(M("TP_LOCALLAB_LOGVIEWING_TOOLTIP")); autocompute->set_tooltip_text(M("TP_LOCALLAB_LOGAUTO_TOOLTIP")); // blackEv->set_tooltip_text(M("TP_LOCALLAB_LOGBLACKWHEV_TOOLTIP")); // whiteEv->set_tooltip_text(M("TP_LOCALLAB_LOGBLACKWHEV_TOOLTIP")); blackEv->set_tooltip_text(""); whiteEv->set_tooltip_text(""); sourceGray->set_tooltip_text(""); - targetGray->set_tooltip_text(M("TP_LOCALLAB_LOGTARGGREY_TOOLTIP")); + sourceabs->set_tooltip_text(M("TP_COLORAPP_ADAPSCEN_TOOLTIP")); + targabs->set_tooltip_text(M("TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP")); + targetGray->set_tooltip_text(M("TP_COLORAPP_YBOUT_TOOLTIP")); baselog->set_tooltip_text(M("TP_LOCALLAB_LOGBASE_TOOLTIP")); strlog->set_tooltip_text(M("TP_LOCALLAB_GRADGEN_TOOLTIP")); anglog->set_tooltip_text(M("TP_LOCALLAB_GRADANG_TOOLTIP")); - + contl->set_tooltip_text(M("TP_LOCALLAB_LOGCONTL_TOOLTIP")); + saturl->set_tooltip_text(M("TP_LOCALLAB_LOGSATURL_TOOLTIP")); + detail->set_tooltip_text(M("TP_LOCALLAB_LOGDETAIL_TOOLTIP")); + catad->set_tooltip_text(M("TP_LOCALLAB_LOGCATAD_TOOLTIP")); // detail->set_tooltip_text(M("TP_LOCALLAB_NUL_TOOLTIP")); // Autogray->set_tooltip_text(M("TP_LOCALLAB_NUL_TOOLTIP")); // sensilog->set_tooltip_text(M("TP_LOCALLAB_NUL_TOOLTIP")); - detail->set_tooltip_text(""); Autogray->set_tooltip_text(""); sensilog->set_tooltip_text(M("TP_LOCALLAB_SENSI_TOOLTIP")); fullimage->set_tooltip_text(M("TP_LOCALLAB_FULLIMAGELOG_TOOLTIP")); + ciecam->set_tooltip_text(M("TP_LOCALLAB_CIECAMLOG_TOOLTIP")); } else { exp->set_tooltip_text(""); logPFrame->set_tooltip_text(""); + logFrame->set_tooltip_text(""); + log1Frame->set_tooltip_text(""); + log2Frame->set_tooltip_text(""); autocompute->set_tooltip_text(""); blackEv->set_tooltip_text(""); whiteEv->set_tooltip_text(""); sourceGray->set_tooltip_text(""); + sourceabs->set_tooltip_text(""); + targabs->set_tooltip_text(""); targetGray->set_tooltip_text(""); baselog->set_tooltip_text(""); strlog->set_tooltip_text(""); @@ -4770,7 +4829,10 @@ void LocallabLog::updateAdviceTooltips(const bool showTooltips) Autogray->set_tooltip_text(""); sensilog->set_tooltip_text(""); fullimage->set_tooltip_text(""); - + ciecam->set_tooltip_text(""); + contl->set_tooltip_text(""); + saturl->set_tooltip_text(""); + catad->set_tooltip_text(""); } } @@ -4780,6 +4842,8 @@ void LocallabLog::disableListener() autoconn.block(true); fullimageConn.block(true); + ciecamconn.block(true); + surroundconn.block (true); AutograyConn.block(true); } @@ -4789,6 +4853,8 @@ void LocallabLog::enableListener() autoconn.block(false); fullimageConn.block(false); + ciecamconn.block(false); + surroundconn.block (false); AutograyConn.block(false); } @@ -4816,9 +4882,25 @@ void LocallabLog::read(const rtengine::procparams::ProcParams* pp, const ParamsE whiteEv->setValue(1.5); } */ + if (spot.surround == "Average") { + surround->set_active (0); + } else if (spot.surround == "Dim") { + surround->set_active (1); + } else if (spot.surround == "Dark") { + surround->set_active (2); + } else if (spot.surround == "ExtremelyDark") { + surround->set_active (3); + } + + ciecam->set_active(spot.ciecam); fullimage->set_active(spot.fullimage); Autogray->set_active(spot.Autogray); sourceGray->setValue(spot.sourceGray); + sourceabs->setValue(spot.sourceabs); + catad->setValue(spot.catad); + saturl->setValue(spot.saturl); + contl->setValue(spot.contl); + targabs->setValue(spot.targabs); targetGray->setValue(spot.targetGray); detail->setValue(spot.detail); baselog->setValue(spot.baselog); @@ -4832,6 +4914,7 @@ void LocallabLog::read(const rtengine::procparams::ProcParams* pp, const ParamsE // Update Log Encoding GUI according to autocompute button state updateLogGUI(); + updateLogGUI2(); // Note: No need to manage pedited as batch mode is deactivated for Locallab } @@ -4850,15 +4933,32 @@ void LocallabLog::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.blackEv = blackEv->getValue(); spot.whiteEv = whiteEv->getValue(); spot.fullimage = fullimage->get_active(); + spot.ciecam = ciecam->get_active(); spot.Autogray = Autogray->get_active(); spot.sourceGray = sourceGray->getValue(); + spot.sourceabs = sourceabs->getValue(); + spot.targabs = targabs->getValue(); spot.targetGray = targetGray->getValue(); spot.catad = catad->getValue(); + spot.saturl = saturl->getValue(); + spot.contl = contl->getValue(); spot.detail = detail->getValue(); spot.baselog = baselog->getValue(); spot.sensilog = sensilog->getIntValue(); spot.strlog = strlog->getValue(); spot.anglog = anglog->getValue(); + + + if (surround->get_active_row_number() == 0) { + spot.surround = "Average"; + } else if (surround->get_active_row_number() == 1) { + spot.surround = "Dim"; + } else if (surround->get_active_row_number() == 2) { + spot.surround = "Dark"; + } else if (surround->get_active_row_number() == 3) { + spot.surround = "ExtremelyDark"; + } + } // Note: No need to manage pedited as batch mode is deactivated for Locallab @@ -4875,8 +4975,12 @@ void LocallabLog::setDefaults(const rtengine::procparams::ProcParams* defParams, blackEv->setDefault(defSpot.blackEv); whiteEv->setDefault(defSpot.whiteEv); sourceGray->setDefault(defSpot.sourceGray); + sourceabs->setDefault(defSpot.sourceabs); + targabs->setDefault(defSpot.targabs); targetGray->setDefault(defSpot.targetGray); catad->setDefault(defSpot.catad); + saturl->setDefault(defSpot.saturl); + contl->setDefault(defSpot.contl); detail->setDefault(defSpot.detail); baselog->setDefault(defSpot.baselog); sensilog->setDefault((double)defSpot.sensilog); @@ -4911,6 +5015,20 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) } } + if (a == sourceabs) { + if (listener) { + listener->panelChanged(Evlocallabsourceabs, + sourceabs->getTextValue() + " (" + escapeHtmlChars(spotName) + ")"); + } + } + + if (a == targabs) { + if (listener) { + listener->panelChanged(Evlocallabtargabs, + targabs->getTextValue() + " (" + escapeHtmlChars(spotName) + ")"); + } + } + if (a == targetGray) { if (listener) { listener->panelChanged(EvlocallabtargetGray, @@ -4925,6 +5043,20 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) } } + if (a == saturl) { + if (listener) { + listener->panelChanged(Evlocallabsaturl, + saturl->getTextValue() + " (" + escapeHtmlChars(spotName) + ")"); + } + } + + if (a == contl) { + if (listener) { + listener->panelChanged(Evlocallabcontl, + contl->getTextValue() + " (" + escapeHtmlChars(spotName) + ")"); + } + } + if (a == detail) { if (listener) { listener->panelChanged(Evlocallabdetail, @@ -4962,10 +5094,10 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) } } -void LocallabLog::updateAutocompute(const float blackev, const float whiteev, const float sourceg, const float targetg) +void LocallabLog::updateAutocompute(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg) { idle_register.add( - [this, blackev, whiteev, sourceg, targetg]() -> bool { + [this, blackev, whiteev, sourceg, sourceab, targetg]() -> bool { GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected // Update adjuster values according to autocomputed ones @@ -4974,6 +5106,7 @@ void LocallabLog::updateAutocompute(const float blackev, const float whiteev, co blackEv->setValue(blackev); whiteEv->setValue(whiteev); sourceGray->setValue(sourceg); + sourceabs->setValue(sourceab); targetGray->setValue(targetg); enableListener(); @@ -4998,6 +5131,16 @@ void LocallabLog::enabledChanged() } } +void LocallabLog::surroundChanged() +{ + if (isLocActivated && exp->getEnabled()) { + if (listener) { + listener->panelChanged(Evlocallabsurround, + surround->get_active_text() + " (" + escapeHtmlChars(spotName) + ")"); + } + } +} + void LocallabLog::autocomputeToggled() { // Update Log Encoding GUI according to autocompute button state @@ -5016,6 +5159,43 @@ void LocallabLog::autocomputeToggled() } } +void LocallabLog::ciecamChanged() +{ + if(ciecam->get_active()){ + /* sourceabs->set_sensitive(true); + targabs->set_sensitive(true); + catad->set_sensitive(true); + surrHBox->set_sensitive(true); + */ + sourceabs->show(); + targabs->show(); + catad->show(); + saturl->show(); + contl->show(); + surrHBox->show(); + } else { + sourceabs->hide(); + targabs->hide(); + saturl->hide(); + contl->hide(); + catad->hide(); + surrHBox->hide(); + } + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (ciecam->get_active()) { + listener->panelChanged(Evlocallabciecam, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(spotName) + ")"); + } else { + listener->panelChanged(Evlocallabciecam, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(spotName) + ")"); + } + } + } +} + + void LocallabLog::fullimageChanged() { if (isLocActivated && exp->getEnabled()) { @@ -5046,16 +5226,42 @@ void LocallabLog::AutograyChanged() } } +void LocallabLog::updateLogGUI2() +{ + if(ciecam->get_active()){ + sourceabs->show(); + targabs->show(); + catad->show(); + saturl->show(); + contl->show(); + surrHBox->show(); + } else { + sourceabs->hide(); + targabs->hide(); + catad->hide(); + saturl->hide(); + contl->hide(); + surrHBox->hide(); + } +} + + void LocallabLog::updateLogGUI() { if (autocompute->get_active()) { blackEv->set_sensitive(false); whiteEv->set_sensitive(false); sourceGray->set_sensitive(false); + sourceabs->set_sensitive(false); } else { blackEv->set_sensitive(true); whiteEv->set_sensitive(true); sourceGray->set_sensitive(true); + if(ciecam->get_active()){ + sourceabs->set_sensitive(true); + } else { + sourceabs->set_sensitive(false); + } } } diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ae756feeb..fbe9d7315 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1496,13 +1496,19 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).explog = locallab.spots.at(j).explog && pSpot.explog == otherSpot.explog; locallab.spots.at(j).autocompute = locallab.spots.at(j).autocompute && pSpot.autocompute == otherSpot.autocompute; locallab.spots.at(j).sourceGray = locallab.spots.at(j).sourceGray && pSpot.sourceGray == otherSpot.sourceGray; + locallab.spots.at(j).sourceabs = locallab.spots.at(j).sourceabs && pSpot.sourceabs == otherSpot.sourceabs; + locallab.spots.at(j).targabs = locallab.spots.at(j).targabs && pSpot.targabs == otherSpot.targabs; locallab.spots.at(j).targetGray = locallab.spots.at(j).targetGray && pSpot.targetGray == otherSpot.targetGray; locallab.spots.at(j).catad = locallab.spots.at(j).catad && pSpot.catad == otherSpot.catad; + locallab.spots.at(j).saturl = locallab.spots.at(j).saturl && pSpot.saturl == otherSpot.saturl; + locallab.spots.at(j).contl = locallab.spots.at(j).contl && pSpot.contl == otherSpot.contl; locallab.spots.at(j).Autogray = locallab.spots.at(j).Autogray && pSpot.Autogray == otherSpot.Autogray; locallab.spots.at(j).fullimage = locallab.spots.at(j).fullimage && pSpot.fullimage == otherSpot.fullimage; + locallab.spots.at(j).ciecam = locallab.spots.at(j).ciecam && pSpot.ciecam == otherSpot.ciecam; locallab.spots.at(j).blackEv = locallab.spots.at(j).blackEv && pSpot.blackEv == otherSpot.blackEv; locallab.spots.at(j).whiteEv = locallab.spots.at(j).whiteEv && pSpot.whiteEv == otherSpot.whiteEv; locallab.spots.at(j).detail = locallab.spots.at(j).detail && pSpot.detail == otherSpot.detail; + locallab.spots.at(j).surround = locallab.spots.at(j).surround && pSpot.surround == otherSpot.surround; locallab.spots.at(j).sensilog = locallab.spots.at(j).sensilog && pSpot.sensilog == otherSpot.sensilog; locallab.spots.at(j).baselog = locallab.spots.at(j).baselog && pSpot.baselog == otherSpot.baselog; locallab.spots.at(j).strlog = locallab.spots.at(j).strlog && pSpot.strlog == otherSpot.strlog; @@ -4852,6 +4858,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).sourceGray = mods.locallab.spots.at(i).sourceGray; } + if (locallab.spots.at(i).sourceabs) { + toEdit.locallab.spots.at(i).sourceabs = mods.locallab.spots.at(i).sourceabs; + } + + if (locallab.spots.at(i).targabs) { + toEdit.locallab.spots.at(i).targabs = mods.locallab.spots.at(i).targabs; + } + if (locallab.spots.at(i).targetGray) { toEdit.locallab.spots.at(i).targetGray = mods.locallab.spots.at(i).targetGray; } @@ -4860,6 +4874,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).catad = mods.locallab.spots.at(i).catad; } + if (locallab.spots.at(i).saturl) { + toEdit.locallab.spots.at(i).saturl = mods.locallab.spots.at(i).saturl; + } + + if (locallab.spots.at(i).contl) { + toEdit.locallab.spots.at(i).contl = mods.locallab.spots.at(i).contl; + } + if (locallab.spots.at(i).Autogray) { toEdit.locallab.spots.at(i).Autogray = mods.locallab.spots.at(i).Autogray; } @@ -4868,6 +4890,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).fullimage = mods.locallab.spots.at(i).fullimage; } + if (locallab.spots.at(i).ciecam) { + toEdit.locallab.spots.at(i).ciecam = mods.locallab.spots.at(i).ciecam; + } + if (locallab.spots.at(i).blackEv) { toEdit.locallab.spots.at(i).blackEv = mods.locallab.spots.at(i).blackEv; } @@ -4888,6 +4914,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).baselog = mods.locallab.spots.at(i).baselog; } + if (locallab.spots.at(i).surround) { + toEdit.locallab.spots.at(i).surround = mods.locallab.spots.at(i).surround; + } + if (locallab.spots.at(i).strlog) { toEdit.locallab.spots.at(i).strlog = mods.locallab.spots.at(i).strlog; } @@ -6645,13 +6675,19 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : explog(v), autocompute(v), sourceGray(v), + sourceabs(v), + targabs(v), targetGray(v), catad(v), + saturl(v), + contl(v), Autogray(v), fullimage(v), + ciecam(v), blackEv(v), whiteEv(v), detail(v), + surround(v), sensilog(v), baselog(v), strlog(v), @@ -7141,13 +7177,19 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) explog = v; autocompute = v; sourceGray = v; + sourceabs = v; + targabs = v; targetGray = v; catad = v; + saturl = v; + contl = v; Autogray = v; fullimage = v; + ciecam = v; blackEv = v; whiteEv = v; detail = v; + surround = v; sensilog = v; baselog = v; strlog = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 2a50b2cf1..a66399883 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -832,13 +832,19 @@ public: bool explog; bool autocompute; bool sourceGray; + bool sourceabs; + bool targabs; bool targetGray; bool catad; + bool saturl; + bool contl; bool Autogray; bool fullimage; + bool ciecam; bool blackEv; bool whiteEv; bool detail; + bool surround; bool sensilog; bool baselog; bool strlog; From 444027fcf969f840d331af96215c622420951fa9 Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Tue, 3 Nov 2020 00:43:26 +0100 Subject: [PATCH 14/14] Added missing calls to `show()` on the preprocessWB toolpanel when image type is raw (fixes #5978) --- rtgui/toolpanelcoord.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index b5d133775..30c3d22ef 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -364,6 +364,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr bayerprocess->FoldableToolPanel::show(); bayerpreprocess->FoldableToolPanel::show(); rawcacorrection->FoldableToolPanel::show(); + preprocessWB->FoldableToolPanel::show(); preprocess->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show(); filmNegative->FoldableToolPanel::show(); @@ -384,6 +385,7 @@ void ToolPanelCoordinator::imageTypeChanged(bool isRaw, bool isBayer, bool isXtr bayerprocess->FoldableToolPanel::hide(); bayerpreprocess->FoldableToolPanel::hide(); rawcacorrection->FoldableToolPanel::hide(); + preprocessWB->FoldableToolPanel::show(); preprocess->FoldableToolPanel::show(); flatfield->FoldableToolPanel::show(); filmNegative->FoldableToolPanel::show();