diff --git a/CMakeLists.txt b/CMakeLists.txt index b027ea5f7..b5626512a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,6 +136,9 @@ option(TRACE_MYRWMUTEX "Trace custom R/W Mutex (Debug builds only); redirecting option(AUTO_GDK_FLUSH "Use gdk_flush on all gdk_thread_leave other than the GUI thread; set it ON if you experience X Server warning/errors" OFF) #option(TARGET32BIT "Build for 32-bit architecture when ON, otherwise 64-bit. Default is OFF" OFF) +option(ENABLE_TCMALLOC "Use the tcmalloc library if available" OFF) +set(TCMALLOC_LIB_DIR "" CACHE PATH "Custom path for the tcmalloc library") + # Set installation directories: if(WIN32 OR APPLE) if(BUILD_BUNDLE) @@ -564,6 +567,23 @@ int main() return 0; }" LENSFUN_HAS_LOAD_DIRECTORY) +set(TCMALLOC_LIB_DIR) +if(ENABLE_TCMALLOC) + if(TCMALLOC_LIB_DIR) + find_library(TCMALLOC_LIBRARIES tcmalloc PATHS ${TCMALLOC_LIB_DIR} NO_DEFAULT_PATH) + else() + find_library(TCMALLOC_LIBRARIES tcmalloc) + endif() + if(TCMALLOC_LIBRARIES) + message(STATUS "using tcmalloc library in ${TCMALLOC_LIBRARIES}") + else() + set(TCMALLOC_LIBRARIES "" CACHE INTERNAL "" FORCE) + message(STATUS "tcmalloc not found") + endif() +else() + set(TCMALLOC_LIBRARIES "" CACHE INTERNAL "" FORCE) +endif() + add_subdirectory(rtexif) add_subdirectory(rtengine) diff --git a/com.rawtherapee.RawTherapee.appdata.xml b/com.rawtherapee.RawTherapee.appdata.xml index 0e5dfef50..3a55109ba 100644 --- a/com.rawtherapee.RawTherapee.appdata.xml +++ b/com.rawtherapee.RawTherapee.appdata.xml @@ -8,31 +8,17 @@ Zaawansowany program do wywoływania zdjęć typu raw rawtherapee -

- RawTherapee is a powerful, cross-platform raw photo processing program. It is written mostly in C++ using a GTK+ front-end. It uses a patched version of dcraw for reading raw files, with an in-house solution which adds the highest quality support for certain camera models unsupported by dcraw and enhances the accuracy of certain raw files already supported by dcraw. It is notable for the advanced control it gives the user over the demosaicing and development process. -

-

- RawTherapee is designed for developing raw files from a broad range of digital cameras, as well as HDR DNG files and non-raw image formats (JPEG, TIFF and PNG). The target audience ranges from enthusiast newcomers who wish to broaden their understanding of how digital imaging works to semi-professional photographers. Knowledge in color science is not compulsory, but it is recommended that you are eager to learn and ready to read our documentation (RawPedia) as well as look up basic concepts which lie outside the scope of RawPedia, such as color balance, elsewhere. -

-

- Of course, professionals may use RawTherapee too while enjoying complete freedom, but will probably lack some peripheral features such as Digital Asset Management, printing, uploading, etc. RawTherapee is not aimed at being an inclusive all-in-one program, and the open-source community is sufficiently developed by now to offer all those peripheral features in other specialized software. -

+

RawTherapee is a powerful, cross-platform raw photo processing program. It is written mostly in C++ using a GTK+ front-end. It uses a patched version of dcraw for reading raw files, with an in-house solution which adds the highest quality support for certain camera models unsupported by dcraw and enhances the accuracy of certain raw files already supported by dcraw. It is notable for the advanced control it gives the user over the demosaicing and development process.

+

RawTherapee is designed for developing raw files from a broad range of digital cameras, as well as HDR DNG files and non-raw image formats (JPEG, TIFF and PNG). The target audience ranges from enthusiast newcomers who wish to broaden their understanding of how digital imaging works to semi-professional photographers. Knowledge in color science is not compulsory, but it is recommended that you are eager to learn and ready to read our documentation (RawPedia) as well as look up basic concepts which lie outside the scope of RawPedia, such as color balance, elsewhere.

+

Of course, professionals may use RawTherapee too while enjoying complete freedom, but will probably lack some peripheral features such as Digital Asset Management, printing, uploading, etc. RawTherapee is not aimed at being an inclusive all-in-one program, and the open-source community is sufficiently developed by now to offer all those peripheral features in other specialized software.

- - raw - photo - photography - develop - pp3 - graphics - CC-BY-SA-4.0 GPL-3.0+ - https://github.com/Beep6581/RawTherapee/issues/new + https://github.com/Beep6581/RawTherapee/issues https://www.paypal.me/rawtherapee - https://rawpedia.rawtherapee.com/ - https://www.rawtherapee.com/ + https://rawpedia.rawtherapee.com + https://www.rawtherapee.com https://discuss.pixls.us/t/localization-how-to-translate-rawtherapee-and-rawpedia/2594 rawtherapee.desktop @@ -48,20 +34,20 @@ - Color-correcting a drosera rotundifolia in RawTherapee 5.7. - https://rawtherapee.com/images/screenshots/rt570_1.jpg + Color correction + https://rawtherapee.com/images/screenshots/rt57_drosera_rotundifolia.png - HDR DNG of a misty morning in the countryside - https://rawtherapee.com/images/screenshots/rt540_1.jpg + File browser + https://rawtherapee.com/images/screenshots/rt57_file_browser.png - - Straight-out-of-camera vs RawTherapee - https://rawtherapee.com/images/screenshots/rt540_2.jpg + + High dynamic range compression + https://rawtherapee.com/images/screenshots/rt57_field_sunset.png - - RawTherapee using the Auto-Matched Tone Curve tool - https://rawtherapee.com/images/screenshots/rt540_3.jpg + + Developing a film negative + https://rawtherapee.com/images/screenshots/rt57_film_negative.png contactus@rawtherapee.com diff --git a/rtdata/languages/default b/rtdata/languages/default index 3c7d921bf..f85fdd312 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2047,6 +2047,7 @@ TP_SHARPENING_LABEL;Sharpening TP_SHARPENING_METHOD;Method TP_SHARPENING_ONLYEDGES;Sharpen only edges TP_SHARPENING_RADIUS;Radius +TP_SHARPENING_RADIUS_OFFSET;Radius corner offset TP_SHARPENING_RLD;RL Deconvolution TP_SHARPENING_RLD_AMOUNT;Amount TP_SHARPENING_RLD_DAMPING;Damping diff --git a/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 b/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 index 882c0130f..c94077b21 100644 --- a/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 +++ b/rtdata/profiles/Auto-Matched Curve - ISO Low.pp3 @@ -21,3 +21,6 @@ DCPIlluminant=0 [RAW] CA=true + +[PostDemosaicSharpening] +Enabled=true diff --git a/rtdata/profiles/Standard Film Curve - ISO Low.pp3 b/rtdata/profiles/Standard Film Curve - ISO Low.pp3 index c23b5b8a4..45fcca730 100644 --- a/rtdata/profiles/Standard Film Curve - ISO Low.pp3 +++ b/rtdata/profiles/Standard Film Curve - ISO Low.pp3 @@ -23,3 +23,6 @@ DCPIlluminant=0 [RAW] CA=true + +[PostDemosaicSharpening] +Enabled=true diff --git a/rtdata/rawtherapee.desktop.in b/rtdata/rawtherapee.desktop.in index 233a737b6..c6c675c4d 100644 --- a/rtdata/rawtherapee.desktop.in +++ b/rtdata/rawtherapee.desktop.in @@ -1,8 +1,8 @@ [Desktop Entry] Type=Application -Version=1.0 +Version=1.1 Name=RawTherapee -GenericName=Raw photo editor +GenericName=Raw Photo Editor GenericName[cs]=Editor raw obrázků GenericName[fr]=Éditeur d'images raw GenericName[pl]=Edytor zdjęć raw @@ -11,9 +11,10 @@ Comment[cs]=Program pro konverzi a zpracování digitálních raw fotografií Comment[fr]=Logiciel de conversion et de traitement de photos numériques de format raw (but de capteur) Comment[pl]=Zaawansowany program do wywoływania zdjęć typu raw Icon=rawtherapee +TryExec=rawtherapee Exec=rawtherapee %f Terminal=false MimeType=image/jpeg;image/png;image/tiff;image/x-adobe-dng;image/x-canon-cr2;image/x-canon-crf;image/x-canon-crw;image/x-fuji-raf;image/x-hasselblad-3fr;image/x-hasselblad-fff;image/x-jpg;image/x-kodak-dcr;image/x-kodak-k25;image/x-kodak-kdc;image/x-leaf-mos;image/x-leica-rwl;image/x-mamiya-mef;image/x-minolta-mrw;image/x-nikon-nef;image/x-nikon-nrw;image/x-olympus-orf;image/x-panasonic-raw;image/x-panasonic-rw2;image/x-pentax-pef;image/x-pentax-raw;image/x-phaseone-iiq;image/x-raw;image/x-rwz;image/x-samsung-srw;image/x-sigma-x3f;image/x-sony-arq;image/x-sony-arw;image/x-sony-sr2;image/x-sony-srf;image/x-tif; -Categories=Photography;Graphics;2DGraphics;RasterGraphics;GTK; -Keywords=raw;photography;develop;pp3;graphics; +Categories=Graphics;Photography;2DGraphics;RasterGraphics;GTK; +Keywords=raw;photo;photography;develop;pp3;graphics; StartupWMClass=rawtherapee diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index df2b1d908..e08243713 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -513,11 +513,11 @@ float calcRadiusXtrans(const float * const *rawData, int W, int H, float lowerLi } return std::sqrt((1.f / (std::log(1.f / maxRatio))) / -2.f); } -void CaptureDeconvSharpening (float** luminance, float** oldLuminance, const float * const * blend, int W, int H, double sigma, int iterations, rtengine::ProgressListener* plistener, double startVal, double endVal) +void CaptureDeconvSharpening (float** luminance, float** oldLuminance, const float * const * blend, int W, int H, double sigma, double sigmaCornerOffset, int iterations, rtengine::ProgressListener* plistener, double startVal, double endVal) { BENCHFUN - const bool is5x5 = (sigma <= 0.84); - const bool is3x3 = (sigma < 0.6); + const bool is5x5 = (sigma <= 0.84 && sigmaCornerOffset == 0.0); + const bool is3x3 = (sigma < 0.6 && sigmaCornerOffset == 0.0); float kernel7[7][7]; float kernel5[5][5]; float kernel3[3][3]; @@ -532,6 +532,9 @@ BENCHFUN constexpr int tileSize = 194; constexpr int border = 5; constexpr int fullTileSize = tileSize + 2 * border; + const float maxRadius = std::min(1.15f, sigma + sigmaCornerOffset); + const float maxDistance = sqrt(rtengine::SQR(W * 0.5f) + rtengine::SQR(H * 0.5f)); + const float distanceFactor = (maxRadius - sigma) / maxDistance; double progress = startVal; const double progressStep = (endVal - startVal) * rtengine::SQR(tileSize) / (W * H); @@ -578,10 +581,21 @@ BENCHFUN gauss5x5mult(tmpThr, tmpIThr, fullTileSize, fullTileSize, kernel5); } } else { - for (int k = 0; k < iterations; ++k) { - // apply 7x7 gaussian blur and divide luminance by result of gaussian blur - gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, fullTileSize, kernel7); - gauss7x7mult(tmpThr, tmpIThr, fullTileSize, fullTileSize, kernel7); + if (sigmaCornerOffset > 0.0) { + float lkernel7[7][7]; + const float distance = sqrt(rtengine::SQR(i + tileSize / 2 - H / 2) + rtengine::SQR(j + tileSize / 2 - W / 2)); + compute7x7kernel(sigma + distanceFactor * distance, lkernel7); + for (int k = 0; k < iterations - 1; ++k) { + // apply 7x7 gaussian blur and divide luminance by result of gaussian blur + gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, fullTileSize, lkernel7); + gauss7x7mult(tmpThr, tmpIThr, fullTileSize, fullTileSize, lkernel7); + } + } else { + for (int k = 0; k < iterations; ++k) { + // apply 7x7 gaussian blur and divide luminance by result of gaussian blur + gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, fullTileSize, kernel7); + gauss7x7mult(tmpThr, tmpIThr, fullTileSize, fullTileSize, kernel7); + } } } if (endOfRow || endOfCol) { @@ -760,7 +774,7 @@ BENCHFUN } conrastThreshold = contrast * 100.f; - CaptureDeconvSharpening(YNew, YOld, blend, W, H, radius, sharpeningParams.deconviter, plistener, 0.2, 0.9); + CaptureDeconvSharpening(YNew, YOld, blend, W, H, radius, sharpeningParams.deconvradiusOffset, sharpeningParams.deconviter, plistener, 0.2, 0.9); if (plistener) { plistener->setProgress(0.9); } diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index e15a2bb0f..d2c68e2e8 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -4216,8 +4216,8 @@ void CLASS foveon_interpolate() foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3 - ddft[0][c][0] ) / 4 - ddft[0][c][1]; } - memcpy (black, black+8, sizeof *black*8); - memcpy (black+height-11, black+height-22, 11*sizeof *black); + memmove (black, black+8, sizeof *black*8); + memmove (black+height-11, black+height-22, 11*sizeof *black); memcpy (last, black, sizeof last); for (row=1; row < height-1; row++) { diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 1a7270b82..4293c6b2a 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -77,8 +77,8 @@ bool channelsAvg( } std::array pxCount = {}; // Per-channel sample counts - for (int c = spotPos.x - spotSize; c < spotPos.x + spotSize; ++c) { - for (int r = spotPos.y - spotSize; r < spotPos.y + spotSize; ++r) { + for (int c = x1; c < x2; ++c) { + for (int r = y1; r < y2; ++r) { const int ch = ri->getSensorType() == rtengine::ST_BAYER ? ri->FC(r,c) : ri->XTRANSFC(r,c); ++pxCount[ch]; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 7794c6edb..3d8583097 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -4248,11 +4248,9 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW if (params->labCurve.chromaticity > -100) { chCurve = new FlatCurve (params->labCurve.chcurve); - if (!chCurve || chCurve->isIdentity()) { - if (chCurve) { - delete chCurve; - chCurve = nullptr; - } + if (chCurve->isIdentity()) { + delete chCurve; + chCurve = nullptr; }//do not use "Munsell" if Chcurve not used else { chutili = true; @@ -4265,11 +4263,9 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW if (params->labCurve.chromaticity > -100) { lhCurve = new FlatCurve (params->labCurve.lhcurve); - if (!lhCurve || lhCurve->isIdentity()) { - if (lhCurve) { - delete lhCurve; - lhCurve = nullptr; - } + if (lhCurve->isIdentity()) { + delete lhCurve; + lhCurve = nullptr; }//do not use "Munsell" if Chcurve not used else { lhutili = true; @@ -4282,11 +4278,9 @@ void ImProcFunctions::chromiLuminanceCurve (PipetteBuffer *pipetteBuffer, int pW if (params->labCurve.chromaticity > -100) { hhCurve = new FlatCurve (params->labCurve.hhcurve); - if (!hhCurve || hhCurve->isIdentity()) { - if (hhCurve) { - delete hhCurve; - hhCurve = nullptr; - } + if (hhCurve->isIdentity()) { + delete hhCurve; + hhCurve = nullptr; }//do not use "Munsell" if Chcurve not used else { hhutili = true; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 86da5131f..bd91ae8e7 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1156,6 +1156,7 @@ CaptureSharpeningParams::CaptureSharpeningParams() : contrast(10.0), gamma(1.00), deconvradius(0.75), + deconvradiusOffset(0.0), deconviter(20) { } @@ -1169,6 +1170,7 @@ bool CaptureSharpeningParams::operator ==(const CaptureSharpeningParams& other) && autoContrast == other.autoContrast && autoRadius == other.autoRadius && deconvradius == other.deconvradius + && deconvradiusOffset == other.deconvradiusOffset && deconviter == other.deconviter; } @@ -3395,6 +3397,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->pdsharpening.autoRadius, "PostDemosaicSharpening", "AutoRadius", pdsharpening.autoRadius, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.gamma, "PostDemosaicSharpening", "DeconvGamma", pdsharpening.gamma, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconvradius, "PostDemosaicSharpening", "DeconvRadius", pdsharpening.deconvradius, keyFile); + saveToKeyfile(!pedited || pedited->pdsharpening.deconvradiusOffset, "PostDemosaicSharpening", "DeconvRadiusOffset", pdsharpening.deconvradiusOffset, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconviter, "PostDemosaicSharpening", "DeconvIterations", pdsharpening.deconviter, keyFile); // Post resize sharpening @@ -4495,6 +4498,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvGamma", pedited, pdsharpening.gamma, pedited->pdsharpening.gamma); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadius", pedited, pdsharpening.deconvradius, pedited->pdsharpening.deconvradius); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadiusOffset", pedited, pdsharpening.deconvradiusOffset, pedited->pdsharpening.deconvradiusOffset); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterations", pedited, pdsharpening.deconviter, pedited->pdsharpening.deconviter); } diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 46de303ef..82dfe9697 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -549,6 +549,7 @@ struct CaptureSharpeningParams { double contrast; double gamma; double deconvradius; + double deconvradiusOffset; int deconviter; CaptureSharpeningParams(); diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index bc52b64b0..edc2b8202 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -286,6 +286,7 @@ target_link_libraries(rth rtengine ${ZLIB_LIBRARIES} ${LENSFUN_LIBRARIES} ${RSVG_LIBRARIES} + ${TCMALLOC_LIBRARIES} ) target_link_libraries(rth-cli rtengine @@ -307,6 +308,7 @@ target_link_libraries(rth-cli rtengine ${ZLIB_LIBRARIES} ${LENSFUN_LIBRARIES} ${RSVG_LIBRARIES} + ${TCMALLOC_LIBRARIES} ) # Install executables diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 0ab0a9682..1cdcacf13 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -171,6 +171,7 @@ void ParamsEdited::set(bool v) pdsharpening.autoRadius = v; pdsharpening.gamma = v; pdsharpening.deconvradius = v; + pdsharpening.deconvradiusOffset = v; pdsharpening.deconviter = v; prsharpening.enabled = v; prsharpening.contrast = v; @@ -766,6 +767,7 @@ void ParamsEdited::initFrom(const std::vector& pdsharpening.autoRadius = pdsharpening.autoRadius && p.pdsharpening.autoRadius == other.pdsharpening.autoRadius; pdsharpening.gamma = pdsharpening.gamma && p.pdsharpening.gamma == other.pdsharpening.gamma; pdsharpening.deconvradius = pdsharpening.deconvradius && p.pdsharpening.deconvradius == other.pdsharpening.deconvradius; + pdsharpening.deconvradiusOffset = pdsharpening.deconvradiusOffset && p.pdsharpening.deconvradiusOffset == other.pdsharpening.deconvradiusOffset; pdsharpening.deconviter = pdsharpening.deconviter && p.pdsharpening.deconviter == other.pdsharpening.deconviter; prsharpening.enabled = prsharpening.enabled && p.prsharpening.enabled == other.prsharpening.enabled; prsharpening.contrast = prsharpening.contrast && p.prsharpening.contrast == other.prsharpening.contrast; @@ -1766,6 +1768,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.pdsharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.pdsharpening.deconvradius + mods.pdsharpening.deconvradius : mods.pdsharpening.deconvradius; } + if (pdsharpening.deconvradiusOffset) { + toEdit.pdsharpening.deconvradiusOffset = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.pdsharpening.deconvradiusOffset + mods.pdsharpening.deconvradiusOffset : mods.pdsharpening.deconvradiusOffset; + } + if (pdsharpening.deconviter) { toEdit.pdsharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.pdsharpening.deconviter + mods.pdsharpening.deconviter : mods.pdsharpening.deconviter; } @@ -3355,5 +3361,5 @@ bool FilmNegativeParamsEdited::isUnchanged() const bool CaptureSharpeningParamsEdited::isUnchanged() const { - return enabled && contrast && autoContrast && autoRadius && gamma && deconvradius && deconviter; + return enabled && contrast && autoContrast && autoRadius && gamma && deconvradius && deconvradiusOffset && deconviter; } \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 3264e62fd..0f4ad85ea 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -205,6 +205,7 @@ struct CaptureSharpeningParamsEdited { bool autoRadius; bool gamma; bool deconvradius; + bool deconvradiusOffset; bool deconviter; bool isUnchanged() const; }; diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index ef0ad90c2..f25e44e69 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -33,6 +33,7 @@ PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDS EvPdShrContrast = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_CONTRAST"); EvPdSharpenGamma = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_GAMMA"); EvPdShrDRadius = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS"); + EvPdShrDRadiusOffset = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS_OFFSET"); EvPdShrDIterations = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); EvPdShrAutoContrast = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST"); EvPdShrAutoRadius = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_AUTO_RADIUS"); @@ -51,25 +52,30 @@ PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDS Gtk::VBox* rld = Gtk::manage(new Gtk::VBox()); gamma = Gtk::manage(new Adjuster(M("TP_SHARPENING_GAMMA"), 0.5, 6.0, 0.05, 1.00)); - dradius = Gtk::manage(new Adjuster(M("TP_SHARPENING_EDRADIUS"), 0.4, 1.15, 0.01, 0.75)); + dradius = Gtk::manage(new Adjuster(M("TP_SHARPENING_RADIUS"), 0.4, 1.15, 0.01, 0.75)); dradius->addAutoButton(M("TP_PDSHARPENING_AUTORADIUS_TOOLTIP")); dradius->setAutoValue(true); + dradiusOffset = Gtk::manage(new Adjuster(M("TP_SHARPENING_RADIUS_OFFSET"), 0.0, 0.5, 0.01, 0.0)); diter = Gtk::manage(new Adjuster(M("TP_SHARPENING_RLD_ITERATIONS"), 1, 100, 1, 20)); rld->pack_start(*gamma); rld->pack_start(*dradius); + rld->pack_start(*dradiusOffset); rld->pack_start(*diter); gamma->show(); dradius->show(); + dradiusOffset->show(); diter->show(); rld->show(); pack_start(*rld); dradius->setAdjusterListener(this); + dradiusOffset->setAdjusterListener(this); gamma->setAdjusterListener(this); diter->setAdjusterListener(this); contrast->delay = std::max(contrast->delay, options.adjusterMaxDelay); dradius->delay = std::max(dradius->delay, options.adjusterMaxDelay); + dradiusOffset->delay = std::max(dradiusOffset->delay, options.adjusterMaxDelay); gamma->delay = std::max(gamma->delay, options.adjusterMaxDelay); diter->delay = std::max(diter->delay, options.adjusterMaxDelay); } @@ -91,6 +97,7 @@ void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) dradius->setAutoInconsistent(multiImage && !pedited->pdsharpening.autoRadius); gamma->setEditedState(pedited->pdsharpening.gamma ? Edited : UnEdited); dradius->setEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); + dradiusOffset->setEditedState(pedited->pdsharpening.deconvradiusOffset ? Edited : UnEdited); diter->setEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); set_inconsistent(multiImage && !pedited->pdsharpening.enabled); @@ -103,6 +110,7 @@ void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) gamma->setValue(pp->pdsharpening.gamma); dradius->setValue(pp->pdsharpening.deconvradius); dradius->setAutoValue(pp->pdsharpening.autoRadius); + dradiusOffset->setValue(pp->pdsharpening.deconvradiusOffset); diter->setValue(pp->pdsharpening.deconviter); lastAutoContrast = pp->pdsharpening.autoContrast; lastAutoRadius = pp->pdsharpening.autoRadius; @@ -119,6 +127,7 @@ void PdSharpening::write(ProcParams* pp, ParamsEdited* pedited) pp->pdsharpening.gamma = gamma->getValue(); pp->pdsharpening.deconvradius = dradius->getValue(); pp->pdsharpening.autoRadius = dradius->getAutoValue(); + pp->pdsharpening.deconvradiusOffset = dradiusOffset->getValue(); pp->pdsharpening.deconviter =(int)diter->getValue(); if (pedited) { @@ -127,6 +136,7 @@ void PdSharpening::write(ProcParams* pp, ParamsEdited* pedited) pedited->pdsharpening.gamma = gamma->getEditedState(); pedited->pdsharpening.deconvradius = dradius->getEditedState(); pedited->pdsharpening.autoRadius = !dradius->getAutoInconsistent(); + pedited->pdsharpening.deconvradiusOffset = dradiusOffset->getEditedState(); pedited->pdsharpening.deconviter = diter->getEditedState(); pedited->pdsharpening.enabled = !get_inconsistent(); } @@ -138,17 +148,20 @@ void PdSharpening::setDefaults(const ProcParams* defParams, const ParamsEdited* contrast->setDefault(defParams->pdsharpening.contrast); gamma->setDefault(defParams->pdsharpening.gamma); dradius->setDefault(defParams->pdsharpening.deconvradius); + dradiusOffset->setDefault(defParams->pdsharpening.deconvradiusOffset); diter->setDefault(defParams->pdsharpening.deconviter); if (pedited) { contrast->setDefaultEditedState(pedited->pdsharpening.contrast ? Edited : UnEdited); gamma->setDefaultEditedState(pedited->pdsharpening.gamma ? Edited : UnEdited); dradius->setDefaultEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); + dradiusOffset->setDefaultEditedState(pedited->pdsharpening.deconvradiusOffset ? Edited : UnEdited); diter->setDefaultEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); } else { contrast->setDefaultEditedState(Irrelevant); gamma->setDefaultEditedState(Irrelevant); dradius->setDefaultEditedState(Irrelevant); + dradiusOffset->setDefaultEditedState(Irrelevant); diter->setDefaultEditedState(Irrelevant); } } @@ -159,7 +172,7 @@ void PdSharpening::adjusterChanged(Adjuster* a, double newval) Glib::ustring costr; - if (a == gamma || a == dradius) { + if (a == gamma || a == dradius || a == dradiusOffset) { costr = Glib::ustring::format(std::setw(3), std::fixed, std::setprecision(2), a->getValue()); } else { costr = Glib::ustring::format((int)a->getValue()); @@ -171,6 +184,8 @@ void PdSharpening::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvPdSharpenGamma, costr); } else if (a == dradius) { listener->panelChanged(EvPdShrDRadius, costr); + } else if (a == dradiusOffset) { + listener->panelChanged(EvPdShrDRadiusOffset, costr); } else if (a == diter) { listener->panelChanged(EvPdShrDIterations, costr); } @@ -198,6 +213,7 @@ void PdSharpening::setBatchMode(bool batchMode) contrast->showEditedCB(); gamma->showEditedCB(); dradius->showEditedCB(); + dradiusOffset->showEditedCB(); diter->showEditedCB(); } @@ -207,6 +223,7 @@ void PdSharpening::setAdjusterBehavior(bool contrastadd, bool gammaadd, bool rad contrast->setAddMode(contrastadd); gamma->setAddMode(gammaadd); dradius->setAddMode(radiusadd); + dradiusOffset->setAddMode(radiusadd); diter->setAddMode(iteradd); } @@ -216,6 +233,7 @@ void PdSharpening::trimValues(rtengine::procparams::ProcParams* pp) contrast->trimValue(pp->pdsharpening.contrast); gamma->trimValue(pp->pdsharpening.gamma); dradius->trimValue(pp->pdsharpening.deconvradius); + dradiusOffset->trimValue(pp->pdsharpening.deconvradiusOffset); diter->trimValue(pp->pdsharpening.deconviter); } diff --git a/rtgui/pdsharpening.h b/rtgui/pdsharpening.h index e56b4b085..f621fd0a5 100644 --- a/rtgui/pdsharpening.h +++ b/rtgui/pdsharpening.h @@ -28,12 +28,14 @@ protected: Adjuster* contrast; Adjuster* gamma; Adjuster* dradius; + Adjuster* dradiusOffset; Adjuster* diter; bool lastAutoContrast; bool lastAutoRadius; rtengine::ProcEvent EvPdShrContrast; rtengine::ProcEvent EvPdShrDRadius; + rtengine::ProcEvent EvPdShrDRadiusOffset; rtengine::ProcEvent EvPdSharpenGamma; rtengine::ProcEvent EvPdShrDIterations; rtengine::ProcEvent EvPdShrAutoContrast;