diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index b9a8e892e..318f1e05e 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -288,6 +288,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } else { imgsrc->setBorder(std::max(params.raw.bayersensor.border, 2)); } + } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) { + imgsrc->setBorder(params.raw.xtranssensor.border); } bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicAutoContrast : params.raw.xtranssensor.dualDemosaicAutoContrast; double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicContrast : params.raw.xtranssensor.dualDemosaicContrast; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index afee412a2..9f8779d33 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2968,6 +2968,7 @@ RAWParams::XTransSensor::XTransSensor() : method(getMethodString(Method::THREE_PASS)), dualDemosaicAutoContrast(true), dualDemosaicContrast(20), + border(7), ccSteps(0), blackred(0.0), blackgreen(0.0), @@ -2981,6 +2982,7 @@ bool RAWParams::XTransSensor::operator ==(const XTransSensor& other) const method == other.method && dualDemosaicAutoContrast == other.dualDemosaicAutoContrast && dualDemosaicContrast == other.dualDemosaicContrast + && border == other.border && ccSteps == other.ccSteps && blackred == other.blackred && blackgreen == other.blackgreen @@ -4077,6 +4079,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->raw.xtranssensor.method, "RAW X-Trans", "Method", raw.xtranssensor.method, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.dualDemosaicAutoContrast, "RAW X-Trans", "DualDemosaicAutoContrast", raw.xtranssensor.dualDemosaicAutoContrast, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.dualDemosaicContrast, "RAW X-Trans", "DualDemosaicContrast", raw.xtranssensor.dualDemosaicContrast, keyFile); + saveToKeyfile(!pedited || pedited->raw.xtranssensor.border, "RAW X-Trans", "Border", raw.xtranssensor.border, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.ccSteps, "RAW X-Trans", "CcSteps", raw.xtranssensor.ccSteps, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.exBlackRed, "RAW X-Trans", "PreBlackRed", raw.xtranssensor.blackred, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.exBlackGreen, "RAW X-Trans", "PreBlackGreen", raw.xtranssensor.blackgreen, keyFile); @@ -5829,6 +5832,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } assignFromKeyfile(keyFile, "RAW X-Trans", "DualDemosaicContrast", pedited, raw.xtranssensor.dualDemosaicContrast, pedited->raw.xtranssensor.dualDemosaicContrast); + assignFromKeyfile(keyFile, "RAW X-Trans", "Border", pedited, raw.xtranssensor.border, pedited->raw.xtranssensor.border); assignFromKeyfile(keyFile, "RAW X-Trans", "CcSteps", pedited, raw.xtranssensor.ccSteps, pedited->raw.xtranssensor.ccSteps); assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackRed", pedited, raw.xtranssensor.blackred, pedited->raw.xtranssensor.exBlackRed); assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackGreen", pedited, raw.xtranssensor.blackgreen, pedited->raw.xtranssensor.exBlackGreen); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index fb7192e4c..9b2006209 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1569,6 +1569,7 @@ struct RAWParams { Glib::ustring method; bool dualDemosaicAutoContrast; double dualDemosaicContrast; + int border; int ccSteps; double blackred; double blackgreen; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index ba5db6008..782055a24 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -167,6 +167,8 @@ private: } else { imgsrc->setBorder(std::max(params.raw.bayersensor.border, 2)); } + } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) { + imgsrc->setBorder(params.raw.xtranssensor.border); } imgsrc->getFullSize(fw, fh, tr); diff --git a/rtengine/xtrans_demosaic.cc b/rtengine/xtrans_demosaic.cc index 26cd9071b..f32969d17 100644 --- a/rtengine/xtrans_demosaic.cc +++ b/rtengine/xtrans_demosaic.cc @@ -120,6 +120,11 @@ void RawImageSource::xtransborder_interpolate (int border, array2D &red, int xtrans[6][6]; ri->getXtransMatrix(xtrans); + const float weight[3][3] = { + {0.25f, 0.5f, 0.25f}, + {0.5f, 0.f, 0.5f}, + {0.25f, 0.5f, 0.25f} + }; for (int row = 0; row < height; row++) for (int col = 0; col < width; col++) { @@ -129,11 +134,11 @@ void RawImageSource::xtransborder_interpolate (int border, array2D &red, float sum[6] = {0.f}; - for (int y = MAX(0, row - 1); y <= MIN(row + 1, height - 1); y++) - for (int x = MAX(0, col - 1); x <= MIN(col + 1, width - 1); x++) { + for (int y = MAX(0, row - 1), v = row == 0 ? 0 : -1; y <= MIN(row + 1, height - 1); y++, v++) + for (int x = MAX(0, col - 1), h = col == 0 ? 0 : -1; x <= MIN(col + 1, width - 1); x++, h++) { int f = fcol(y, x); - sum[f] += rawData[y][x]; - sum[f + 3]++; + sum[f] += rawData[y][x] * weight[v + 1][h + 1]; + sum[f + 3] += weight[v + 1][h + 1]; } switch(fcol(row, col)) { @@ -197,12 +202,6 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab) const int height = H, width = W; -// if (settings->verbose) { -// printf("%d-pass X-Trans interpolation using %s conversion...\n", passes, useCieLab ? "lab" : "yuv"); -// } - - xtransborder_interpolate(6, red, green, blue); - float xyz_cam[3][3]; { float rgb_cam[3][4]; @@ -956,6 +955,7 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab) free(buffer); } + xtransborder_interpolate(8, red, green, blue); } #undef CLIP void RawImageSource::fast_xtrans_interpolate (const array2D &rawData, array2D &red, array2D &green, array2D &blue) diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index fdf4bbc32..ac1354bc7 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -442,6 +442,7 @@ void ParamsEdited::set(bool v) raw.xtranssensor.method = v; raw.xtranssensor.dualDemosaicAutoContrast = v; raw.xtranssensor.dualDemosaicContrast = v; + raw.xtranssensor.border = v; raw.xtranssensor.ccSteps = v; raw.xtranssensor.exBlackRed = v; raw.xtranssensor.exBlackGreen = v; @@ -1188,6 +1189,7 @@ void ParamsEdited::initFrom(const std::vector& raw.xtranssensor.method = raw.xtranssensor.method && p.raw.xtranssensor.method == other.raw.xtranssensor.method; raw.xtranssensor.dualDemosaicAutoContrast = raw.xtranssensor.dualDemosaicAutoContrast && p.raw.xtranssensor.dualDemosaicAutoContrast == other.raw.xtranssensor.dualDemosaicAutoContrast; raw.xtranssensor.dualDemosaicContrast = raw.xtranssensor.dualDemosaicContrast && p.raw.xtranssensor.dualDemosaicContrast == other.raw.xtranssensor.dualDemosaicContrast; + raw.xtranssensor.border = raw.xtranssensor.border && p.raw.xtranssensor.border == other.raw.xtranssensor.border; raw.xtranssensor.ccSteps = raw.xtranssensor.ccSteps && p.raw.xtranssensor.ccSteps == other.raw.xtranssensor.ccSteps; raw.xtranssensor.exBlackRed = raw.xtranssensor.exBlackRed && p.raw.xtranssensor.blackred == other.raw.xtranssensor.blackred; raw.xtranssensor.exBlackGreen = raw.xtranssensor.exBlackGreen && p.raw.xtranssensor.blackgreen == other.raw.xtranssensor.blackgreen; @@ -3445,6 +3447,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.raw.xtranssensor.ccSteps = mods.raw.xtranssensor.ccSteps; } + if (raw.xtranssensor.border) { + toEdit.raw.xtranssensor.border = mods.raw.xtranssensor.border; + } + if (raw.xtranssensor.exBlackRed) { toEdit.raw.xtranssensor.blackred = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_BLACKS] ? toEdit.raw.xtranssensor.blackred + mods.raw.xtranssensor.blackred : mods.raw.xtranssensor.blackred; } @@ -3977,7 +3983,7 @@ bool RAWParamsEdited::BayerSensor::isUnchanged() const bool RAWParamsEdited::XTransSensor::isUnchanged() const { - return method && exBlackRed && exBlackGreen && exBlackBlue && dualDemosaicAutoContrast && dualDemosaicContrast; + return method && border && exBlackRed && exBlackGreen && exBlackBlue && dualDemosaicAutoContrast && dualDemosaicContrast; } bool RAWParamsEdited::isUnchanged() const diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index ac0d8906a..b7cc65fb6 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -958,6 +958,7 @@ public: bool method; bool dualDemosaicAutoContrast; bool dualDemosaicContrast; + bool border; bool ccSteps; bool exBlackRed; bool exBlackGreen; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index 463529c38..86ae96d28 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -857,6 +857,7 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param if (!raw_border->get_active ()) { filterPE.raw.bayersensor.border = falsePE.raw.bayersensor.border; + filterPE.raw.xtranssensor.border = falsePE.raw.xtranssensor.border; } if (!raw_imagenum->get_active ()) { diff --git a/rtgui/xtransprocess.cc b/rtgui/xtransprocess.cc index 9639ce29d..49d64bd8f 100644 --- a/rtgui/xtransprocess.cc +++ b/rtgui/xtransprocess.cc @@ -27,6 +27,7 @@ using namespace rtengine::procparams; XTransProcess::XTransProcess () : FoldableToolPanel(this, "xtransprocess", M("TP_RAW_LABEL"), true) { auto m = ProcEventMapper::getInstance(); + EvDemosaicBorder = m->newEvent(DEMOSAIC, "HISTORY_MSG_RAW_BORDER"); EvDemosaicContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_CONTRAST"); EvDemosaicAutoContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST"); @@ -83,6 +84,18 @@ XTransProcess::XTransProcess () : FoldableToolPanel(this, "xtransprocess", M("TP dualDemosaicOptions->pack_start(*dualDemosaicContrast); pack_start( *dualDemosaicOptions, Gtk::PACK_SHRINK, 4); + borderbox = Gtk::manage(new Gtk::HBox()); + border = Gtk::manage(new Adjuster(M("TP_RAW_BORDER"), 0, 16, 1, 7)); + border->setAdjusterListener (this); + + if (border->delay < options.adjusterMaxDelay) { + border->delay = options.adjusterMaxDelay; + } + + border->show(); + borderbox->pack_start(*border); + pack_start(*borderbox, Gtk::PACK_SHRINK, 4); + pack_start( *Gtk::manage( new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0 ); ccSteps = Gtk::manage (new Adjuster (M("TP_RAW_FALSECOLOR"), 0, 5, 1, 0 )); ccSteps->setAdjusterListener (this); @@ -106,6 +119,7 @@ void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const Param disableListener (); methodconn.block (true); + border->setValue(pp->raw.xtranssensor.border); for (size_t i = 0; i < RAWParams::XTransSensor::getMethodStrings().size(); ++i) if( pp->raw.xtranssensor.method == RAWParams::XTransSensor::getMethodStrings()[i]) { method->set_active(i); @@ -114,6 +128,7 @@ void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const Param } if(pedited ) { + border->setEditedState (pedited->raw.xtranssensor.border ? Edited : UnEdited); dualDemosaicContrast->setAutoInconsistent (multiImage && !pedited->raw.xtranssensor.dualDemosaicAutoContrast); dualDemosaicContrast->setEditedState ( pedited->raw.xtranssensor.dualDemosaicContrast ? Edited : UnEdited); ccSteps->setEditedState (pedited->raw.xtranssensor.ccSteps ? Edited : UnEdited); @@ -126,7 +141,7 @@ void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const Param dualDemosaicContrast->setValue (pp->raw.xtranssensor.dualDemosaicContrast); ccSteps->setValue (pp->raw.xtranssensor.ccSteps); - lastAutoContrast = pp->raw.bayersensor.dualDemosaicAutoContrast; + lastAutoContrast = pp->raw.xtranssensor.dualDemosaicAutoContrast; if (!batchMode) { dualDemosaicOptions->set_visible(pp->raw.xtranssensor.method == procparams::RAWParams::XTransSensor::getMethodString(procparams::RAWParams::XTransSensor::Method::FOUR_PASS) @@ -142,6 +157,7 @@ void XTransProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* p { pp->raw.xtranssensor.dualDemosaicAutoContrast = dualDemosaicContrast->getAutoValue(); pp->raw.xtranssensor.dualDemosaicContrast = dualDemosaicContrast->getValue(); + pp->raw.xtranssensor.border = border->getIntValue(); pp->raw.xtranssensor.ccSteps = ccSteps->getIntValue(); int currentRow = method->get_active_row_number(); @@ -151,6 +167,7 @@ void XTransProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* p } if (pedited) { + pedited->raw.xtranssensor.border = border->getEditedState (); pedited->raw.xtranssensor.method = method->get_active_text() != M("GENERAL_UNCHANGED"); pedited->raw.xtranssensor.dualDemosaicAutoContrast = !dualDemosaicContrast->getAutoInconsistent (); pedited->raw.xtranssensor.dualDemosaicContrast = dualDemosaicContrast->getEditedState (); @@ -160,6 +177,7 @@ void XTransProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* p void XTransProcess::setAdjusterBehavior (bool falsecoloradd, bool dualDemosaicContrastAdd) { + border->setAddMode(false); dualDemosaicContrast->setAddMode(dualDemosaicContrastAdd); ccSteps->setAddMode(falsecoloradd); } @@ -170,19 +188,23 @@ void XTransProcess::setBatchMode(bool batchMode) method->set_active_text(M("GENERAL_UNCHANGED")); ToolPanel::setBatchMode (batchMode); dualDemosaicContrast->showEditedCB (); + border->showEditedCB (); ccSteps->showEditedCB (); } void XTransProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) { dualDemosaicContrast->setDefault( defParams->raw.xtranssensor.dualDemosaicContrast); + border->setDefault (defParams->raw.xtranssensor.border); ccSteps->setDefault (defParams->raw.xtranssensor.ccSteps); if (pedited) { dualDemosaicContrast->setDefaultEditedState( pedited->raw.xtranssensor.dualDemosaicContrast ? Edited : UnEdited); + border->setDefaultEditedState(pedited->raw.xtranssensor.border ? Edited : UnEdited); ccSteps->setDefaultEditedState(pedited->raw.xtranssensor.ccSteps ? Edited : UnEdited); } else { dualDemosaicContrast->setDefaultEditedState(Irrelevant ); + border->setDefaultEditedState(Irrelevant); ccSteps->setDefaultEditedState(Irrelevant ); } } @@ -194,6 +216,8 @@ void XTransProcess::adjusterChanged(Adjuster* a, double newval) listener->panelChanged (EvDemosaicFalseColorIter, a->getTextValue() ); } else if (a == dualDemosaicContrast) { listener->panelChanged (EvDemosaicContrast, a->getTextValue() ); + } else if (a == border) { + listener->panelChanged (EvDemosaicBorder, a->getTextValue() ); } } } diff --git a/rtgui/xtransprocess.h b/rtgui/xtransprocess.h index cd60337dc..e5389b566 100644 --- a/rtgui/xtransprocess.h +++ b/rtgui/xtransprocess.h @@ -32,6 +32,8 @@ class XTransProcess : public ToolParamBlock, public AdjusterListener, public Che protected: MyComboBoxText* method; + Gtk::HBox* borderbox; + Adjuster* border; Adjuster* ccSteps; Gtk::VBox *dualDemosaicOptions; Adjuster* dualDemosaicContrast; @@ -40,6 +42,8 @@ protected: int oldSelection; sigc::connection methodconn; IdleRegister idle_register; + + rtengine::ProcEvent EvDemosaicBorder; rtengine::ProcEvent EvDemosaicAutoContrast; rtengine::ProcEvent EvDemosaicContrast;