diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7e79edc27..85776d557 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,11 +16,12 @@ The most useful feedback is based on the latest development code, and in the cas - Announce and discuss your plans in GitHub before starting work. - Work in a new branch. Fork if necessary. - Keep branches small so that completed and working features can be merged into the "dev" branch often, and so that they can be abandoned if they head in the wrong direction. -- Use C++11 +- Use C++11. - The naming isn't homogeneous throughout the code but here is a rough guideline: - - *Types* (classes, structs, enums, typedefs...) should be named with `UpperCamelCase` - - *Functions* and *methods* should be named with `lowerCamelCase` - - *Variables* should be either named with `lowerCamelCase` or better with `lower_underscores` to avoid conflicts - - *Enum values* should be named with `UPPER_UNDERSCORES` - - Most important: Be consistent, even when not sticking to the rules + - *Identifiers* (variables, functions, methods, keys, enums, etc.) should be clear and unambiguous. Make them as long as necessary to ensure that your code is understandable to others. + - *Types* (classes, structs, enums, typedefs...) should be named with `UpperCamelCase`. + - *Functions* and *methods* should be named with `lowerCamelCase`. + - *Variables* should be either named with `lowerCamelCase` or better with `lower_underscores` to avoid conflicts. + - *Enum values* should be named with `UPPER_UNDERSCORES`. + - Be consistent, even when not sticking to the rules. - Code may be run through astyle version 3 or newer. If using astyle, it is important that the astyle changes go into their own commit, so that style changes are not mixed with actual code changes. Command: `astyle --options=rawtherapee.astylerc code.cc` diff --git a/rtdata/languages/default b/rtdata/languages/default index c0dc19353..343100124 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -775,6 +775,7 @@ HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correction - Iterations HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correction - Avoid color shift HISTORY_MSG_RAW_BORDER;Raw border HISTORY_MSG_RESIZE_ALLOWUPSCALING;Resize - Allow upscaling +HISTORY_MSG_SHARPENING_BLUR;Sharpening - Blur radius HISTORY_MSG_SHARPENING_CONTRAST;Sharpening - Contrast threshold HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light @@ -2035,6 +2036,7 @@ TP_SHARPENEDGE_LABEL;Edges TP_SHARPENEDGE_PASSES;Iterations TP_SHARPENEDGE_THREE;Luminance only TP_SHARPENING_AMOUNT;Amount +TP_SHARPENING_BLUR;Blur radius TP_SHARPENING_CONTRAST;Contrast threshold TP_SHARPENING_EDRADIUS;Radius TP_SHARPENING_EDTOLERANCE;Edge tolerance diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc index dbb42db0d..57e4c2225 100644 --- a/rtengine/PF_correct_RT.cc +++ b/rtengine/PF_correct_RT.cc @@ -396,26 +396,26 @@ void ImProcFunctions::PF_correct_RTcam(CieImage * ncie, double radius, int thres } } } // end of ab channel averaging + } #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for #endif - for(int i = 0; i < height; i++) { - int j = 0; + for(int i = 0; i < height; i++) { + int j = 0; #ifdef __SSE2__ - for (; j < width - 3; j += 4) { - const vfloat interav = LVFU(tmaa[i][j]); - const vfloat interbv = LVFU(tmbb[i][j]); - STVFU(ncie->h_p[i][j], xatan2f(interbv, interav) / F2V(RT_PI_F_180)); - STVFU(ncie->C_p[i][j], vsqrtf(SQRV(interbv) + SQRV(interav))); - } + for (; j < width - 3; j += 4) { + const vfloat interav = LVFU(tmaa[i][j]); + const vfloat interbv = LVFU(tmbb[i][j]); + STVFU(ncie->h_p[i][j], xatan2f(interbv, interav) / F2V(RT_PI_F_180)); + STVFU(ncie->C_p[i][j], vsqrtf(SQRV(interbv) + SQRV(interav))); + } #endif - for (; j < width; j++) { - const float intera = tmaa[i][j]; - const float interb = tmbb[i][j]; - ncie->h_p[i][j] = xatan2f(interb, intera) / RT_PI_F_180; - ncie->C_p[i][j] = sqrt(SQR(interb) + SQR(intera)); - } + for (; j < width; j++) { + const float intera = tmaa[i][j]; + const float interb = tmbb[i][j]; + ncie->h_p[i][j] = xatan2f(interb, intera) / RT_PI_F_180; + ncie->C_p[i][j] = sqrt(SQR(interb) + SQR(intera)); } } } diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc index 321dd635f..8437fae47 100644 --- a/rtengine/ipsharpen.cc +++ b/rtengine/ipsharpen.cc @@ -159,7 +159,7 @@ extern const Settings* settings; void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, int W, int H, const SharpeningParams &sharpenParam) { - if (sharpenParam.deconvamount < 1) { + if (sharpenParam.deconvamount == 0 && sharpenParam.blurradius < 0.25f) { return; } BENCHFUN @@ -177,11 +177,31 @@ BENCHFUN // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); float contrast = sharpenParam.contrast / 100.f; - buildBlendMask(luminance, blend, W, H, contrast, sharpenParam.deconvamount / 100.f); + buildBlendMask(luminance, blend, W, H, contrast, 1.f); + JaggedArray* blurbuffer = nullptr; + if (sharpenParam.blurradius >= 0.25f) { + blurbuffer = new JaggedArray(W, H); + JaggedArray &blur = *blurbuffer; +#ifdef _OPENMP + #pragma omp parallel +#endif + { + gaussianBlur(tmpI, blur, W, H, sharpenParam.blurradius); +#ifdef _OPENMP + #pragma omp for +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + blur[i][j] = intp(blend[i][j], luminance[i][j], std::max(blur[i][j], 0.0f)); + } + } + } + } const float damping = sharpenParam.deconvdamping / 5.0; const bool needdamp = sharpenParam.deconvdamping > 0; const double sigma = sharpenParam.deconvradius / scale; + const float amount = sharpenParam.deconvamount / 100.f; #ifdef _OPENMP #pragma omp parallel @@ -205,10 +225,23 @@ BENCHFUN for (int i = 0; i < H; ++i) { for (int j = 0; j < W; ++j) { - luminance[i][j] = intp(blend[i][j], max(tmpI[i][j], 0.0f), luminance[i][j]); + luminance[i][j] = intp(blend[i][j] * amount, max(tmpI[i][j], 0.0f), luminance[i][j]); + } + } + + if (sharpenParam.blurradius >= 0.25f) { + JaggedArray &blur = *blurbuffer; +#ifdef _OPENMP + #pragma omp for +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + luminance[i][j] = intp(blend[i][j], luminance[i][j], max(blur[i][j], 0.0f)); + } } } } // end parallel + delete blurbuffer; } void ImProcFunctions::sharpening (LabImage* lab, const SharpeningParams &sharpenParam, bool showMask) @@ -224,7 +257,7 @@ void ImProcFunctions::sharpening (LabImage* lab, const SharpeningParams &sharpen // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); float contrast = sharpenParam.contrast / 100.f; - buildBlendMask(lab->L, blend, W, H, contrast, sharpenParam.method == "rld" ? sharpenParam.deconvamount / 100.f : 1.f); + buildBlendMask(lab->L, blend, W, H, contrast, 1.f); #ifdef _OPENMP #pragma omp parallel for #endif @@ -261,6 +294,26 @@ BENCHFUN float contrast = sharpenParam.contrast / 100.f; buildBlendMask(lab->L, blend, W, H, contrast); + JaggedArray blur(W, H); + + if (sharpenParam.blurradius >= 0.25f) { +#ifdef _OPENMP + #pragma omp parallel +#endif + { + gaussianBlur(lab->L, blur, W, H, sharpenParam.blurradius); +#ifdef _OPENMP + #pragma omp for +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + blur[i][j] = intp(blend[i][j], lab->L[i][j], std::max(blur[i][j], 0.0f)); + } + } + } + } + + #ifdef _OPENMP #pragma omp parallel #endif @@ -322,6 +375,18 @@ BENCHFUN delete [] b3; } + + if (sharpenParam.blurradius >= 0.25f) { +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + lab->L[i][j] = intp(blend[i][j], lab->L[i][j], max(blur[i][j], 0.0f)); + } + } + } + } // To the extent possible under law, Manuel Llorens diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 01ad4b8bb..5c4596745 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1079,6 +1079,7 @@ void ColorToningParams::getCurves(ColorGradientCurve& colorCurveLUT, OpacityCurv SharpeningParams::SharpeningParams() : enabled(false), contrast(20.0), + blurradius(0.2), radius(0.5), amount(200), threshold(20, 80, 2000, 1200, false), @@ -1100,6 +1101,7 @@ bool SharpeningParams::operator ==(const SharpeningParams& other) const return enabled == other.enabled && contrast == other.contrast + && blurradius == other.blurradius && radius == other.radius && amount == other.amount && threshold == other.threshold @@ -3022,6 +3024,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->sharpening.contrast, "Sharpening", "Contrast", sharpening.contrast, keyFile); saveToKeyfile(!pedited || pedited->sharpening.method, "Sharpening", "Method", sharpening.method, keyFile); saveToKeyfile(!pedited || pedited->sharpening.radius, "Sharpening", "Radius", sharpening.radius, keyFile); + saveToKeyfile(!pedited || pedited->sharpening.blurradius, "Sharpening", "BlurRadius", sharpening.blurradius, keyFile); saveToKeyfile(!pedited || pedited->sharpening.amount, "Sharpening", "Amount", sharpening.amount, keyFile); saveToKeyfile(!pedited || pedited->sharpening.threshold, "Sharpening", "Threshold", sharpening.threshold.toVector(), keyFile); saveToKeyfile(!pedited || pedited->sharpening.edgesonly, "Sharpening", "OnlyEdges", sharpening.edgesonly, keyFile); @@ -3908,6 +3911,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } assignFromKeyfile(keyFile, "Sharpening", "Radius", pedited, sharpening.radius, pedited->sharpening.radius); + assignFromKeyfile(keyFile, "Sharpening", "BlurRadius", pedited, sharpening.blurradius, pedited->sharpening.blurradius); assignFromKeyfile(keyFile, "Sharpening", "Amount", pedited, sharpening.amount, pedited->sharpening.amount); if (keyFile.has_key("Sharpening", "Threshold")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 79f3fc7ec..d1b70b9c2 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -493,6 +493,7 @@ struct ColorToningParams { struct SharpeningParams { bool enabled; double contrast; + double blurradius; double radius; int amount; Threshold threshold; diff --git a/rtengine/sleefsseavx.c b/rtengine/sleefsseavx.c index 83d937bd1..3000c1c10 100644 --- a/rtengine/sleefsseavx.c +++ b/rtengine/sleefsseavx.c @@ -1427,5 +1427,21 @@ static INLINE void vconvertrgbrgbrgbrgb2rrrrggggbbbb (const float * src, vfloat bv = _mm_setr_ps(src[2],src[5],src[8],src[11]); } +#if defined( __SSE4_1__ ) && defined( __x86_64__ ) +static INLINE vfloat vceilf(vfloat x) { + return _mm_round_ps(x, _MM_FROUND_TO_POS_INF |_MM_FROUND_NO_EXC); +} + +#else + +static INLINE vfloat vceilf(vfloat x) { + __m128i zerov = _mm_setzero_si128(); + zerov = _mm_cmpeq_epi32(zerov, zerov); + const vfloat onev = (vfloat)_mm_slli_epi32(_mm_srli_epi32(zerov, 25), 23); //create vector 1.0f + const vfloat xi = _mm_cvtepi32_ps(_mm_cvttps_epi32(x)); + return xi + _mm_and_ps(_mm_cmplt_ps(xi, x), onev); +} +#endif + #endif // __SSE2__ #endif // SLEEFSSEAVX diff --git a/rtengine/xtrans_demosaic.cc b/rtengine/xtrans_demosaic.cc index ed253749b..26cd9071b 100644 --- a/rtengine/xtrans_demosaic.cc +++ b/rtengine/xtrans_demosaic.cc @@ -960,59 +960,62 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab) #undef CLIP void RawImageSource::fast_xtrans_interpolate (const array2D &rawData, array2D &red, array2D &green, array2D &blue) { -// if (settings->verbose) { -// printf("fast X-Trans interpolation...\n"); -// } - double progress = 0.0; - const bool plistenerActive = plistener; - - if (plistenerActive) { - plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "fast Xtrans")); - plistener->setProgress (progress); + if (plistener) { + plistener->setProgressStr(Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "fast Xtrans")); + plistener->setProgress(0.0); } - const int height = H, width = W; - - xtransborder_interpolate (1, red, green, blue); + xtransborder_interpolate(1, red, green, blue); int xtrans[6][6]; ri->getXtransMatrix(xtrans); - #pragma omp parallel for + const float weight[3][3] = { + {0.25f, 0.5f, 0.25f}, + {0.5f, 0.f, 0.5f}, + {0.25f, 0.5f, 0.25f} + }; +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + for (int row = 1; row < H - 1; ++row) { + for (int col = 1; col < W - 1; ++col) { + float sum[3] = {}; - for(int row = 1; row < height - 1; row++) { - for(int col = 1; col < width - 1; col++) { - float sum[3] = {0.f}; - - for(int v = -1; v <= 1; v++) { - for(int h = -1; h <= 1; h++) { - sum[fcol(row + v, col + h)] += rawData[row + v][(col + h)]; + for (int v = -1; v <= 1; v++) { + for (int h = -1; h <= 1; h++) { + sum[fcol(row + v, col + h)] += rawData[row + v][(col + h)] * weight[v + 1][h + 1]; } } switch(fcol(row, col)) { - case 0: + case 0: // red pixel red[row][col] = rawData[row][col]; - green[row][col] = sum[1] * 0.2f; - blue[row][col] = sum[2] * 0.33333333f; + green[row][col] = sum[1] * 0.5f; + blue[row][col] = sum[2]; break; - case 1: - red[row][col] = sum[0] * 0.5f; + case 1: // green pixel green[row][col] = rawData[row][col]; - blue[row][col] = sum[2] * 0.5f; + if (fcol(row, col - 1) == fcol(row, col + 1)) { // Solitary green pixel always has exactly two direct red and blue neighbors in 3x3 grid + red[row][col] = sum[0]; + blue[row][col] = sum[2]; + } else { // Non solitary green pixel always has one direct and one diagonal red and blue neighbor in 3x3 grid + red[row][col] = sum[0] * 1.3333333f; + blue[row][col] = sum[2] * 1.3333333f; + } break; - case 2: - red[row][col] = sum[0] * 0.33333333f; - green[row][col] = sum[1] * 0.2f; + case 2: // blue pixel + red[row][col] = sum[0]; + green[row][col] = sum[1] * 0.5f; blue[row][col] = rawData[row][col]; break; } } } - if (plistenerActive) { + if (plistener) { plistener->setProgress (1.0); } } diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index f44e682f2..fc19f7f27 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1083,6 +1083,10 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) history->resetSnapShotNumber(); navigator->setInvalid(ipc->getFullWidth(),ipc->getFullHeight()); + + // When passing a photo as an argument to the RawTherapee executable, the user wants + // this auto-loaded photo's thumbnail to be selected and visible in the Filmstrip. + EditorPanel::syncFileBrowser(); } void EditorPanel::close () diff --git a/rtgui/main.cc b/rtgui/main.cc index 1db73655f..c84f074dd 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -580,7 +580,7 @@ int main (int argc, char **argv) bool Console = true; for (int i = 1; i < argc; i++) - if (!strcmp (argv[i], "-w") || !strcmp (argv[i], "-R")) { + if (!strcmp (argv[i], "-w") || !strcmp (argv[i], "-R") || !strcmp (argv[i], "-gimp")) { Console = false; break; } diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 27b06c4f7..7f44c7738 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -147,6 +147,7 @@ void ParamsEdited::set(bool v) sharpening.enabled = v; sharpening.contrast = v; sharpening.radius = v; + sharpening.blurradius = v; sharpening.amount = v; sharpening.threshold = v; sharpening.edgesonly = v; @@ -719,6 +720,7 @@ void ParamsEdited::initFrom(const std::vector& sharpening.enabled = sharpening.enabled && p.sharpening.enabled == other.sharpening.enabled; sharpening.contrast = sharpening.contrast && p.sharpening.contrast == other.sharpening.contrast; sharpening.radius = sharpening.radius && p.sharpening.radius == other.sharpening.radius; + sharpening.blurradius = sharpening.blurradius && p.sharpening.blurradius == other.sharpening.blurradius; sharpening.amount = sharpening.amount && p.sharpening.amount == other.sharpening.amount; sharpening.threshold = sharpening.threshold && p.sharpening.threshold == other.sharpening.threshold; sharpening.edgesonly = sharpening.edgesonly && p.sharpening.edgesonly == other.sharpening.edgesonly; @@ -1639,6 +1641,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.sharpening.radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.radius + mods.sharpening.radius : mods.sharpening.radius; } + if (sharpening.blurradius) { + toEdit.sharpening.blurradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.blurradius + mods.sharpening.blurradius : mods.sharpening.blurradius; + } + if (sharpening.amount) { toEdit.sharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.amount + mods.sharpening.amount : mods.sharpening.amount; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 7b4b9c061..3e77fcf56 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -209,6 +209,7 @@ class SharpeningParamsEdited public: bool enabled; bool contrast; + bool blurradius; bool radius; bool amount; bool threshold; diff --git a/rtgui/sharpening.cc b/rtgui/sharpening.cc index 3614594ea..8a7b8e591 100644 --- a/rtgui/sharpening.cc +++ b/rtgui/sharpening.cc @@ -27,6 +27,7 @@ Sharpening::Sharpening () : FoldableToolPanel(this, "sharpening", M("TP_SHARPENI { auto m = ProcEventMapper::getInstance(); EvSharpenContrast = m->newEvent(SHARPENING, "HISTORY_MSG_SHARPENING_CONTRAST"); + EvSharpenBlur = m->newEvent(SHARPENING, "HISTORY_MSG_SHARPENING_BLUR"); Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); hb->show (); @@ -34,6 +35,10 @@ Sharpening::Sharpening () : FoldableToolPanel(this, "sharpening", M("TP_SHARPENI contrast->setAdjusterListener (this); pack_start(*contrast); contrast->show(); + blur = Gtk::manage(new Adjuster (M("TP_SHARPENING_BLUR"), 0.2, 2.0, 0.05, 0.2)); + blur->setAdjusterListener (this); + pack_start(*blur); + blur->show(); Gtk::Label* ml = Gtk::manage (new Gtk::Label (M("TP_SHARPENING_METHOD") + ":")); ml->show (); @@ -152,7 +157,8 @@ void Sharpening::read (const ProcParams* pp, const ParamsEdited* pedited) disableListener (); if (pedited) { - contrast->setEditedState (pedited->sharpening.contrast ? Edited : UnEdited); + contrast->setEditedState (pedited->sharpening.contrast ? Edited : UnEdited); + blur->setEditedState (pedited->sharpening.blurradius ? Edited : UnEdited); amount->setEditedState (pedited->sharpening.amount ? Edited : UnEdited); radius->setEditedState (pedited->sharpening.radius ? Edited : UnEdited); threshold->setEditedState (pedited->sharpening.threshold ? Edited : UnEdited); @@ -182,6 +188,7 @@ void Sharpening::read (const ProcParams* pp, const ParamsEdited* pedited) lastHaloControl = pp->sharpening.halocontrol; contrast->setValue (pp->sharpening.contrast); + blur->setValue (pp->sharpening.blurradius); amount->setValue (pp->sharpening.amount); radius->setValue (pp->sharpening.radius); threshold->setValue(pp->sharpening.threshold); @@ -224,6 +231,7 @@ void Sharpening::write (ProcParams* pp, ParamsEdited* pedited) { pp->sharpening.contrast = contrast->getValue (); + pp->sharpening.blurradius = blur->getValue (); pp->sharpening.amount = (int)amount->getValue(); pp->sharpening.enabled = getEnabled (); pp->sharpening.radius = radius->getValue (); @@ -246,6 +254,7 @@ void Sharpening::write (ProcParams* pp, ParamsEdited* pedited) if (pedited) { pedited->sharpening.contrast = contrast->getEditedState (); + pedited->sharpening.blurradius = blur->getEditedState (); pedited->sharpening.amount = amount->getEditedState (); pedited->sharpening.radius = radius->getEditedState (); pedited->sharpening.threshold = threshold->getEditedState (); @@ -266,6 +275,7 @@ void Sharpening::write (ProcParams* pp, ParamsEdited* pedited) void Sharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { contrast->setDefault (defParams->sharpening.contrast); + blur->setDefault (defParams->sharpening.blurradius); amount->setDefault (defParams->sharpening.amount); radius->setDefault (defParams->sharpening.radius); threshold->setDefault (defParams->sharpening.threshold); @@ -279,6 +289,7 @@ void Sharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* p if (pedited) { contrast->setDefaultEditedState (pedited->sharpening.contrast ? Edited : UnEdited); + blur->setDefaultEditedState (pedited->sharpening.blurradius ? Edited : UnEdited); amount->setDefaultEditedState (pedited->sharpening.amount ? Edited : UnEdited); radius->setDefaultEditedState (pedited->sharpening.radius ? Edited : UnEdited); threshold->setDefaultEditedState (pedited->sharpening.threshold ? Edited : UnEdited); @@ -291,6 +302,7 @@ void Sharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* p ddamping->setDefaultEditedState (pedited->sharpening.deconvdamping ? Edited : UnEdited); } else { contrast->setDefaultEditedState (Irrelevant); + blur->setDefaultEditedState (Irrelevant); amount->setDefaultEditedState (Irrelevant); radius->setDefaultEditedState (Irrelevant); threshold->setDefaultEditedState (Irrelevant); @@ -310,7 +322,7 @@ void Sharpening::adjusterChanged(Adjuster* a, double newval) Glib::ustring costr; - if (a == radius || a == dradius) { + if (a == radius || a == dradius || a == blur) { costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); } else if (a == eradius) { costr = Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue()); @@ -324,6 +336,8 @@ void Sharpening::adjusterChanged(Adjuster* a, double newval) listener->panelChanged (EvShrAmount, costr); } else if (a == radius) { listener->panelChanged (EvShrRadius, costr); + } else if (a == blur) { + listener->panelChanged (EvSharpenBlur, costr); } else if (a == eradius) { listener->panelChanged (EvShrEdgeRadius, costr); } else if (a == etolerance) { @@ -487,6 +501,7 @@ void Sharpening::setBatchMode (bool batchMode) pack_start (*rld); contrast->showEditedCB (); + blur->showEditedCB (); radius->showEditedCB (); amount->showEditedCB (); threshold->showEditedCB (); @@ -518,6 +533,7 @@ void Sharpening::setAdjusterBehavior (bool contrastadd, bool radiusadd, bool amo void Sharpening::trimValues (rtengine::procparams::ProcParams* pp) { contrast->trimValue(pp->sharpening.contrast); + blur->trimValue(pp->sharpening.blurradius); radius->trimValue(pp->sharpening.radius); dradius->trimValue(pp->sharpening.deconvradius); amount->trimValue(pp->sharpening.amount); diff --git a/rtgui/sharpening.h b/rtgui/sharpening.h index fa5c956da..75ea083c9 100644 --- a/rtgui/sharpening.h +++ b/rtgui/sharpening.h @@ -29,6 +29,7 @@ class Sharpening : public ToolParamBlock, public ThresholdAdjusterListener, publ protected: Adjuster* contrast; + Adjuster* blur; MyComboBoxText* method; Adjuster* dradius; Adjuster* damount; @@ -55,6 +56,7 @@ protected: sigc::connection hcConn; rtengine::ProcEvent EvSharpenContrast; + rtengine::ProcEvent EvSharpenBlur; public: Sharpening ();