diff --git a/rtdata/languages/default b/rtdata/languages/default index 1c6a1acba..36e441015 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1639,9 +1639,11 @@ TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points TP_EXPOS_WHITEPOINT_LABEL;Raw White Points TP_FILMNEGATIVE_BLUE;Blue exponent -TP_FILMNEGATIVE_GREEN;Green exponent +TP_FILMNEGATIVE_GREEN;Green exponent (lead) TP_FILMNEGATIVE_GUESS_TOOLTIP;Calculate exponents by picking 2 neutral reference spots in the image; one white (light gray) and one black (dark gray).\nThe order does not matter. The exponents will be updated after the second spot is picked. TP_FILMNEGATIVE_LABEL;Film Negative +TP_FILMNEGATIVE_LOCKCHANNELS;Lock exponent ratios +TP_FILMNEGATIVE_LOCKCHANNELS_TOOLTIP;Unlock to adjust channel exponents independently. This allows to adapt to the color characteristics of different film types. TP_FILMNEGATIVE_PICK;Pick white and black spots TP_FILMNEGATIVE_RED;Red exponent TP_FILMNEGATIVE_REF_SPOTS;Film negative reference spots diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 51bd52365..f367c4368 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -189,17 +189,36 @@ void rtengine::RawImageSource::filmNegativeProcess(const procparams::FilmNegativ // Choose an odd step, not a multiple of the CFA size, to get a chance to visit each channel. if (ri->getSensorType() == ST_BAYER) { for (int row = 0; row < H; row += 5) { - for (int col = 0; col < W; col += 5) { - const int c = FC(row, col); // three colors: 0=R, 1=G, 2=B - cvs[c].push_back(rawData[row][col]); + const int c0 = ri->FC(row, 0); + const int c1 = ri->FC(row, 5); + int col = 0; + for (; col < W - 5; col += 10) { + cvs[c0].push_back(rawData[row][col]); + cvs[c1].push_back(rawData[row][col + 5]); + } + if (col < W) { + cvs[c0].push_back(rawData[row][col]); } } } else if (ri->getSensorType() == ST_FUJI_XTRANS) { for (int row = 0; row < H; row += 5) { - for (int col = 0; col < W; col += 5) { - const int c = ri->XTRANSFC(row, col); // three colors: 0=R, 1=G, 2=B - cvs[c].push_back(rawData[row][col]); + const std::array cs = { + ri->XTRANSFC(row, 0), + ri->XTRANSFC(row, 5), + ri->XTRANSFC(row, 10), + ri->XTRANSFC(row, 15), + ri->XTRANSFC(row, 20), + ri->XTRANSFC(row, 25) + }; + int col = 0; + for (; col < W - 25; col += 30) { + for (int c = 0; c < 6; ++c) { + cvs[cs[c]].push_back(rawData[row][col + c * 5]); + } + } + for (int c = 0; col < W; col += 5, ++c) { + cvs[cs[c]].push_back(rawData[row][col]); } } } diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index fef4fc6c6..0e0f1ee51 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -54,11 +54,18 @@ FilmNegative::FilmNegative() : redExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_RED"), 2.72)), greenExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_GREEN"), 2.0)), blueExp(createExponentAdjuster(this, M("TP_FILMNEGATIVE_BLUE"), 1.72)), + lockChannels(Gtk::manage(new Gtk::CheckButton(M("TP_FILMNEGATIVE_LOCKCHANNELS")))), spotgrid(Gtk::manage(new Gtk::Grid())), spotbutton(Gtk::manage(new Gtk::ToggleButton(M("TP_FILMNEGATIVE_PICK")))), redRatio(redExp->getValue() / greenExp->getValue()), blueRatio(blueExp->getValue() / greenExp->getValue()) { + redExp->set_sensitive(false); + blueExp->set_sensitive(false); + + lockChannels->set_tooltip_text(M("TP_FILMNEGATIVE_LOCKCHANNELS_TOOLTIP")); + lockChannels->set_active (true); + spotgrid->get_style_context()->add_class("grid-spacing"); setExpandAlignProperties(spotgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); @@ -86,11 +93,13 @@ FilmNegative::FilmNegative() : // spotgrid->attach (*slab, 1, 0, 1, 1); // spotgrid->attach (*wbsizehelper, 2, 0, 1, 1); + pack_start(*lockChannels, Gtk::PACK_SHRINK, 0); pack_start(*redExp, Gtk::PACK_SHRINK, 0); pack_start(*greenExp, Gtk::PACK_SHRINK, 0); pack_start(*blueExp, Gtk::PACK_SHRINK, 0); pack_start(*spotgrid, Gtk::PACK_SHRINK, 0); + lockChannels->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::lockChannelsToggled)); spotbutton->signal_toggled().connect(sigc::mem_fun(*this, &FilmNegative::editToggled)); // spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); @@ -102,7 +111,7 @@ FilmNegative::FilmNegative() : // Stick a dummy rectangle over the whole image in mouseOverGeometry. // This is to make sure the getCursor() call is fired everywhere. - Rectangle* imgRect = new Rectangle(); + Rectangle* const imgRect = new Rectangle(); imgRect->filled = true; mouseOverGeometry.push_back(imgRect); @@ -172,12 +181,18 @@ void FilmNegative::setDefaults(const rtengine::procparams::ProcParams* defParams void FilmNegative::setBatchMode(bool batchMode) { - spotConn.disconnect(); - removeIfThere(this, spotgrid, false); - ToolPanel::setBatchMode(batchMode); - redExp->showEditedCB(); - greenExp->showEditedCB(); - blueExp->showEditedCB(); + if (batchMode) { + spotConn.disconnect(); + lockChannelsConn.disconnect(); + removeIfThere(this, spotgrid, false); + removeIfThere(this, lockChannels, false); + redExp->set_sensitive(true); + blueExp->set_sensitive(true); + ToolPanel::setBatchMode(batchMode); + redExp->showEditedCB(); + greenExp->showEditedCB(); + blueExp->showEditedCB(); + } } void FilmNegative::adjusterChanged(Adjuster* a, double newval) @@ -231,9 +246,9 @@ void FilmNegative::enabledChanged() } } -void FilmNegative::setFilmNegProvider(FilmNegProvider* p) +void FilmNegative::setFilmNegProvider(FilmNegProvider* provider) { - fnp = p; + fnp = provider; } void FilmNegative::setEditProvider(EditDataProvider* provider) @@ -349,3 +364,10 @@ void FilmNegative::editToggled() unsubscribe(); } } + +void FilmNegative::lockChannelsToggled() +{ + const bool unlocked = !lockChannels->get_active(); + redExp->set_sensitive(unlocked); + blueExp->set_sensitive(unlocked); +} diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 31d561127..e29a20103 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -58,7 +58,7 @@ public: void adjusterAutoToggled(Adjuster* a, bool newval) override; void enabledChanged() override; - void setFilmNegProvider(FilmNegProvider* p); + void setFilmNegProvider(FilmNegProvider* provider); void setEditProvider(EditDataProvider* provider) override; @@ -72,6 +72,7 @@ public: private: void editToggled(); + void lockChannelsToggled(); const rtengine::ProcEvent evFilmNegativeExponents; const rtengine::ProcEvent evFilmNegativeEnabled; @@ -84,6 +85,9 @@ private: Adjuster* const greenExp; Adjuster* const blueExp; + Gtk::CheckButton* const lockChannels; + sigc::connection lockChannelsConn; + Gtk::Grid* const spotgrid; Gtk::ToggleButton* const spotbutton; sigc::connection spotConn;